summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKyle Meyer <kyle@kyleam.com>2019-12-03 21:27:42 -0500
committerKyle Meyer <kyle@kyleam.com>2019-12-03 21:27:42 -0500
commitfd7a417a5df14912480a842ed1b0584f4f16728d (patch)
tree2b606d993a9c2afe547abf84aca57e56b07d5756
parent1130e5bc892d005f595958c59e7bebfaa806fd46 (diff)
parentefe4c85fa2643fcb0ea98f9e7c463f96c0c142ba (diff)
downloadorg-mode-fd7a417a5df14912480a842ed1b0584f4f16728d.tar.gz
Merge tag 'release_9.3' into emacs-sync
Org-Mode 9.3
-rw-r--r--.dir-locals.el3
-rw-r--r--.gitignore2
-rw-r--r--README_maintainer4
-rw-r--r--contrib/README1
-rw-r--r--contrib/lisp/ob-clojure-literate.el56
-rw-r--r--contrib/lisp/ob-oz.el2
-rw-r--r--contrib/lisp/ob-smiles.el2
-rw-r--r--contrib/lisp/ob-spice.el6
-rw-r--r--contrib/lisp/ol-bookmark.el (renamed from contrib/lisp/org-bookmark.el)7
-rw-r--r--contrib/lisp/ol-elisp-symbol.el (renamed from contrib/lisp/org-elisp-symbol.el)8
-rw-r--r--contrib/lisp/ol-git-link.el (renamed from contrib/lisp/org-git-link.el)8
-rw-r--r--contrib/lisp/ol-man.el (renamed from contrib/lisp/org-man.el)7
-rw-r--r--contrib/lisp/ol-mew.el (renamed from contrib/lisp/org-mew.el)7
-rw-r--r--contrib/lisp/ol-notmuch.el (renamed from contrib/lisp/org-notmuch.el)39
-rw-r--r--contrib/lisp/ol-vm.el (renamed from contrib/lisp/org-vm.el)15
-rw-r--r--contrib/lisp/ol-wl.el (renamed from contrib/lisp/org-wl.el)13
-rw-r--r--contrib/lisp/org-annotate-file.el2
-rw-r--r--contrib/lisp/org-attach-embedded-images.el78
-rw-r--r--contrib/lisp/org-bibtex-extras.el2
-rw-r--r--contrib/lisp/org-collector.el2
-rw-r--r--contrib/lisp/org-contacts.el1
-rw-r--r--contrib/lisp/org-drill.el3416
-rw-r--r--contrib/lisp/org-eldoc.el2
-rw-r--r--contrib/lisp/org-expiry.el2
-rw-r--r--contrib/lisp/org-link-edit.el4
-rw-r--r--contrib/lisp/org-mac-link.el2
-rw-r--r--contrib/lisp/org-passwords.el2
-rw-r--r--contrib/lisp/org-screenshot.el6
-rw-r--r--contrib/lisp/org-sudoku.el2
-rw-r--r--contrib/lisp/org-toc.el2
-rw-r--r--contrib/lisp/orgtbl-sqlinsert.el2
-rw-r--r--contrib/lisp/ox-deck.el16
-rw-r--r--contrib/lisp/ox-groff.el2
-rw-r--r--contrib/lisp/ox-koma-letter.el2
-rw-r--r--contrib/lisp/ox-s5.el4
-rw-r--r--contrib/scripts/StartOzServer.oz4
-rw-r--r--doc/.aspell.org.conf2
-rw-r--r--doc/Makefile15
-rw-r--r--doc/dir3
-rw-r--r--doc/doc-setup.org36
-rw-r--r--doc/doclicense.texi505
-rw-r--r--doc/docstyle.texi10
-rw-r--r--doc/fdl.org490
-rw-r--r--doc/org-guide.org2656
-rw-r--r--doc/org-manual.org12905
-rw-r--r--doc/orgcard.tex32
-rw-r--r--doc/orgguide.texi2693
-rw-r--r--etc/ORG-NEWS490
-rw-r--r--lisp/Makefile2
-rw-r--r--lisp/ob-C.el10
-rw-r--r--lisp/ob-J.el2
-rw-r--r--lisp/ob-asymptote.el2
-rw-r--r--lisp/ob-awk.el4
-rw-r--r--lisp/ob-clojure.el97
-rw-r--r--lisp/ob-core.el89
-rw-r--r--lisp/ob-ebnf.el4
-rw-r--r--lisp/ob-emacs-lisp.el26
-rw-r--r--lisp/ob-eshell.el102
-rw-r--r--lisp/ob-exp.el1
-rw-r--r--lisp/ob-forth.el2
-rw-r--r--lisp/ob-fortran.el6
-rw-r--r--lisp/ob-groovy.el4
-rw-r--r--lisp/ob-io.el4
-rw-r--r--lisp/ob-js.el2
-rw-r--r--lisp/ob-keys.el106
-rw-r--r--lisp/ob-lilypond.el45
-rw-r--r--lisp/ob-lisp.el2
-rw-r--r--lisp/ob-lua.el14
-rw-r--r--lisp/ob-ocaml.el4
-rw-r--r--lisp/ob-picolisp.el4
-rw-r--r--lisp/ob-plantuml.el17
-rw-r--r--lisp/ob-processing.el2
-rw-r--r--lisp/ob-python.el2
-rw-r--r--lisp/ob-ruby.el2
-rw-r--r--lisp/ob-scheme.el13
-rw-r--r--lisp/ob-shell.el8
-rw-r--r--lisp/ob-shen.el2
-rw-r--r--lisp/ob-sql.el31
-rw-r--r--lisp/ob-sqlite.el1
-rw-r--r--lisp/ob-tangle.el64
-rw-r--r--lisp/ob.el2
-rw-r--r--lisp/ol-bbdb.el (renamed from lisp/org-bbdb.el)28
-rw-r--r--lisp/ol-bibtex.el (renamed from lisp/org-bibtex.el)26
-rw-r--r--lisp/ol-docview.el (renamed from lisp/org-docview.el)13
-rw-r--r--lisp/ol-eshell.el (renamed from lisp/org-eshell.el)14
-rw-r--r--lisp/ol-eww.el (renamed from lisp/org-eww.el)18
-rw-r--r--lisp/ol-gnus.el (renamed from lisp/org-gnus.el)34
-rw-r--r--lisp/ol-info.el (renamed from lisp/org-info.el)10
-rw-r--r--lisp/ol-irc.el (renamed from lisp/org-irc.el)12
-rw-r--r--lisp/ol-mhe.el (renamed from lisp/org-mhe.el)16
-rw-r--r--lisp/ol-rmail.el (renamed from lisp/org-rmail.el)16
-rw-r--r--lisp/ol-w3m.el (renamed from lisp/org-w3m.el)14
-rw-r--r--lisp/ol.el1907
-rw-r--r--lisp/org-agenda.el619
-rw-r--r--lisp/org-archive.el2
-rw-r--r--lisp/org-attach-git.el119
-rw-r--r--lisp/org-attach.el707
-rw-r--r--lisp/org-capture.el139
-rw-r--r--lisp/org-clock.el201
-rw-r--r--lisp/org-colview.el54
-rw-r--r--lisp/org-compat.el99
-rw-r--r--lisp/org-crypt.el2
-rw-r--r--lisp/org-element.el127
-rw-r--r--lisp/org-faces.el14
-rw-r--r--lisp/org-feed.el4
-rw-r--r--lisp/org-footnote.el4
-rw-r--r--lisp/org-goto.el2
-rw-r--r--lisp/org-habit.el71
-rw-r--r--lisp/org-id.el181
-rw-r--r--lisp/org-indent.el2
-rw-r--r--lisp/org-inlinetask.el11
-rw-r--r--lisp/org-keys.el924
-rw-r--r--lisp/org-lint.el38
-rw-r--r--lisp/org-list.el65
-rw-r--r--lisp/org-macro.el3
-rw-r--r--lisp/org-macs.el54
-rw-r--r--lisp/org-mobile.el16
-rw-r--r--lisp/org-num.el469
-rw-r--r--lisp/org-pcomplete.el10
-rw-r--r--lisp/org-plot.el2
-rw-r--r--lisp/org-protocol.el9
-rw-r--r--lisp/org-src.el67
-rw-r--r--lisp/org-table.el3081
-rw-r--r--lisp/org-timer.el9
-rw-r--r--lisp/org.el4690
-rw-r--r--lisp/ox-ascii.el19
-rw-r--r--lisp/ox-beamer.el25
-rw-r--r--lisp/ox-html.el127
-rw-r--r--lisp/ox-icalendar.el121
-rw-r--r--lisp/ox-latex.el355
-rw-r--r--lisp/ox-man.el4
-rw-r--r--lisp/ox-md.el22
-rw-r--r--lisp/ox-odt.el44
-rw-r--r--lisp/ox-publish.el11
-rw-r--r--lisp/ox-texinfo.el16
-rw-r--r--lisp/ox.el76
-rw-r--r--mk/default.mk4
-rw-r--r--mk/eldo.el2
-rw-r--r--mk/org-fixup.el17
-rw-r--r--mk/server.mk2
-rw-r--r--testing/README8
-rw-r--r--testing/examples/agenda-file.org2
-rw-r--r--testing/examples/att1/fileA1
-rw-r--r--testing/examples/att1/fileB1
-rw-r--r--testing/examples/att2/fileC1
-rw-r--r--testing/examples/att2/fileD1
-rw-r--r--testing/examples/attachments.org32
-rw-r--r--testing/examples/data/ab/cd123/fileE1
-rw-r--r--testing/examples/diary-file1
-rw-r--r--testing/examples/ob-awk-test.org4
-rw-r--r--testing/lisp/test-ob-clojure.el91
-rw-r--r--testing/lisp/test-ob-emacs-lisp.el89
-rw-r--r--testing/lisp/test-ob-eshell.el73
-rw-r--r--testing/lisp/test-ob-sqlite.el2
-rw-r--r--testing/lisp/test-ob-tangle.el84
-rw-r--r--testing/lisp/test-ob.el135
-rw-r--r--testing/lisp/test-ol-bbdb.el (renamed from testing/lisp/test-org-bbdb.el)4
-rw-r--r--testing/lisp/test-ol.el382
-rw-r--r--testing/lisp/test-org-agenda.el20
-rw-r--r--testing/lisp/test-org-attach-git.el (renamed from testing/lisp/test-org-attach-annex.el)34
-rw-r--r--testing/lisp/test-org-attach.el137
-rw-r--r--testing/lisp/test-org-capture.el58
-rw-r--r--testing/lisp/test-org-clock.el644
-rw-r--r--testing/lisp/test-org-colview.el26
-rw-r--r--testing/lisp/test-org-element.el20
-rw-r--r--testing/lisp/test-org-inlinetask.el2
-rw-r--r--testing/lisp/test-org-lint.el27
-rw-r--r--testing/lisp/test-org-num.el261
-rw-r--r--testing/lisp/test-org-table.el507
-rw-r--r--testing/lisp/test-org.el331
-rw-r--r--testing/lisp/test-ox.el118
-rw-r--r--testing/lisp/test-property-inheritance.el4
-rw-r--r--testing/org-test.el47
173 files changed, 21628 insertions, 20514 deletions
diff --git a/.dir-locals.el b/.dir-locals.el
index f003bcc..dcd979c 100644
--- a/.dir-locals.el
+++ b/.dir-locals.el
@@ -14,8 +14,7 @@
(org-footnote-auto-label . t)
(org-footnote-define-inline . nil)
(org-footnote-section . "Footnotes")
- (org-hide-emphasis-markers . nil)
- (org-list-description-max-indent . 5)))
+ (org-hide-emphasis-markers . nil)))
diff --git a/.gitignore b/.gitignore
index 68d94d5..2960fce 100644
--- a/.gitignore
+++ b/.gitignore
@@ -30,8 +30,10 @@
orgcard_letter.tex
orgcard.txt
org
+orgguide
org-loaddefs.el
org-version.el
+doc/orgguide.texi
doc/org-version.inc
doc/org-version.tex
org-*.tar*
diff --git a/README_maintainer b/README_maintainer
index a5eda1c..d2e9ada 100644
--- a/README_maintainer
+++ b/README_maintainer
@@ -42,7 +42,7 @@ The release number for minor releases look like this: =9.1.7=
Minor releases are small amends to main releases. Usually they fix
critical bugs discovered in a main release. Minor bugs are usually
-not fixed -- they will be adressed in the next main release.
+not fixed -- they will be addressed in the next main release.
Only the fix to the bug is bundled into a release, without the main
development work going on in the master branch. Since the bug fix
@@ -194,7 +194,7 @@ The list of all contributors from who we have the papers is kept on
Worg at https://orgmode.org/worg/org-contribute.html, so that
committers can check if a patch can go into the core.
-The assignment process does not allways go smoothly, and it has
+The assignment process does not always go smoothly, and it has
happened several times that it gets stuck or forgotten at the FSF.
The contact at the FSF for this is: mailto:copyright-clerk@fsf.org
diff --git a/contrib/README b/contrib/README
index 73d8830..73b4552 100644
--- a/contrib/README
+++ b/contrib/README
@@ -22,7 +22,6 @@ org-colview-xemacs.el --- Column View in Org-mode, XEmacs-specific version
org-contacts.el --- Contacts management
org-contribdir.el --- Dummy file to mark the org contrib Lisp directory
org-depend.el --- TODO dependencies for Org-mode
-org-drill.el --- Self-testing with org-learn
org-effectiveness.el --- Measuring your personal effectiveness
org-element.el --- Parser and applications for Org syntax
org-eldoc.el --- Eldoc documentation for SRC blocks
diff --git a/contrib/lisp/ob-clojure-literate.el b/contrib/lisp/ob-clojure-literate.el
index 4c4d38a..b1cc386 100644
--- a/contrib/lisp/ob-clojure-literate.el
+++ b/contrib/lisp/ob-clojure-literate.el
@@ -184,62 +184,6 @@ If it is a directory, `ob-clojure-literate' will try to create Clojure project a
(lambda (cons) (if (eq (car cons) :session) t cons))
org-babel-default-header-args:clojure)))))
-;;; Support `org-babel-initiate-session' / [C-c C-v z] to initialize Clojure session.
-
-(defun org-babel-clojure-initiate-session (&optional session _params)
- "Initiate a session named SESSION according to PARAMS."
- (when (and session (not (string= session "none")))
- (save-window-excursion
- (unless (org-babel-comint-buffer-livep session)
- ;; CIDER jack-in to the Clojure project directory.
- (cond
- ((eq org-babel-clojure-backend 'cider)
- (require 'cider)
- (let ((session-buffer (save-window-excursion
- (cider-jack-in t)
- (current-buffer))))
- (if (org-babel-comint-buffer-livep session-buffer)
- (progn (sit-for .25) session-buffer))))
- ((eq org-babel-clojure-backend 'slime)
- (error "Session evaluation with SLIME is not supported"))
- (t
- (error "Session initiate failed")))
- )
- (get-buffer session)
- )))
-
-(defun org-babel-prep-session:clojure (session params)
- "Prepare SESSION according to the header arguments specified in PARAMS."
- (let* ((session (org-babel-clojure-initiate-session session))
- (var-lines (org-babel-variable-assignments:clojure params)))
- (when session
- (org-babel-comint-in-buffer session
- (mapc (lambda (var)
- (insert var) (comint-send-input nil t)
- (org-babel-comint-wait-for-output session)
- (sit-for .1) (goto-char (point-max))) var-lines)))
- session))
-
-(defun org-babel-clojure-var-to-clojure (var)
- "Convert src block's `VAR' to Clojure variable."
- (if (listp var)
- (replace-regexp-in-string "(" "'(" var)
- (cond
- ((stringp var)
- ;; wrap org-babel passed in header argument value with quote in Clojure.
- (format "\"%s\"" var))
- (t
- (format "%s" var))))
- )
-
-(defun org-babel-variable-assignments:clojure (params)
- "Return a list of Clojure statements assigning the block's variables in `PARAMS'."
- (mapcar
- (lambda (pair)
- (format "(def %s %s)"
- (car pair)
- (org-babel-clojure-var-to-clojure (cdr pair))))
- (org-babel--get-vars params)))
;;; Support header arguments :results graphics :file "image.png" by inject Clojure code.
(defun ob-clojure-literate-inject-code (args)
diff --git a/contrib/lisp/ob-oz.el b/contrib/lisp/ob-oz.el
index 626c4f3..46bf536 100644
--- a/contrib/lisp/ob-oz.el
+++ b/contrib/lisp/ob-oz.el
@@ -106,7 +106,7 @@
;; back any results from Oz to Emacs. The following code creates a
;; socket for sending code to the OPI compiler and results are
;; returned by the same socket. On the Oz side, a socket is opened and
-;; conected to the compiler of the OPI (via oz-send-string). On the
+;; connected to the compiler of the OPI (via oz-send-string). On the
;; Emacs side, a connection to this socket is created for feeding code
;; and receiving results. This additional communication channel to the
;; OPI compiler ensures that results are returned cleanly (e.g., only
diff --git a/contrib/lisp/ob-smiles.el b/contrib/lisp/ob-smiles.el
index ef2ab15..9f4f140 100644
--- a/contrib/lisp/ob-smiles.el
+++ b/contrib/lisp/ob-smiles.el
@@ -25,7 +25,7 @@
(defun molecule-jump (name)
"Jump to molecule `NAME' definition."
(org-mark-ring-push)
- (org-open-link-from-string (format "[[%s]]" path)))
+ (org-link-open-from-string (format "[[%s]]" path)))
(defun molecule-export (path desc backend)
"Export molecule to HTML format on `PATH' with `DESC' and `BACKEND'."
diff --git a/contrib/lisp/ob-spice.el b/contrib/lisp/ob-spice.el
index 24ef3c8..c452c99 100644
--- a/contrib/lisp/ob-spice.el
+++ b/contrib/lisp/ob-spice.el
@@ -58,7 +58,7 @@
(progn ;loop through the words
(if (string-match "\\$\\(.*\\)\\[\\(.*\\)\\]" word)
(progn
- ;; if matchs a vector variable format
+ ;; if matches a vector variable format
(setq varname (match-string 1 word))
(setq varindex (match-string 2 word))
;; search varname in vars and use the value of varindex to word
@@ -75,7 +75,7 @@
) ; end of (if (string-match "\\$\\(.*\\)\\[\\(.*\\)\\]" word))
(if (string-match "\\$\\(.*\\)\\." word) ; if variable has a dot in the end
(progn
- ;; if matchs a non-vector variable format
+ ;; if matches a non-vector variable format
(setq varname (match-string 1 word))
(setq newword
(assoc-default varname vars
@@ -92,7 +92,7 @@
);; end of (if (string-match "\\$\\(.*\\)\\." word)
(if (string-match "\\$\\(.*\\)" word)
(progn
- ;; if matchs a non-vector variable format
+ ;; if matches a non-vector variable format
(setq varname (match-string 1 word))
(setq newword
(assoc-default varname vars
diff --git a/contrib/lisp/org-bookmark.el b/contrib/lisp/ol-bookmark.el
index 73c0bf0..5a6c7ac 100644
--- a/contrib/lisp/org-bookmark.el
+++ b/contrib/lisp/ol-bookmark.el
@@ -1,4 +1,4 @@
-;;; org-bookmark.el - Support for links to bookmark
+;;; ol-bookmark.el - Links to bookmarks
;; Copyright (C) 2008-2018 Free Software Foundation, Inc.
;;
;; Author: Tokuya Kameshima <kames AT fa2.so-net.ne.jp>
@@ -25,6 +25,7 @@
(require 'org)
(require 'bookmark)
+(require 'ol)
(defgroup org-bookmark nil
"Options concerning the bookmark link."
@@ -84,6 +85,6 @@ Otherwise prompt the user for the right bookmark to use."
(org-store-link-props :link (concat "bookmark:" bookmark)
:description bookmark))))
-(provide 'org-bookmark)
+(provide 'ol-bookmark)
-;;; org-bookmark.el ends here
+;;; ol-bookmark.el ends here
diff --git a/contrib/lisp/org-elisp-symbol.el b/contrib/lisp/ol-elisp-symbol.el
index a0f3517..e5aa158 100644
--- a/contrib/lisp/org-elisp-symbol.el
+++ b/contrib/lisp/ol-elisp-symbol.el
@@ -1,4 +1,4 @@
-;;; org-elisp-symbol.el --- Org links to emacs-lisp symbols
+;;; ol-elisp-symbol.el --- Links to Emacs-lisp symbols
;;
;; Copyright 2007-2018 Free Software Foundation, Inc.
;;
@@ -74,8 +74,8 @@
;;; Code:
-(provide 'org-elisp-symbol)
-
+(provide 'ol-elisp-symbol)
+(require 'ol)
(require 'org)
(org-link-set-parameters "elisp-symbol"
@@ -158,4 +158,4 @@
;;;; User Options, Variables
;;;;##########################################################################
-;;; org-elisp-symbol.el ends here
+;;; ol-elisp-symbol.el ends here
diff --git a/contrib/lisp/org-git-link.el b/contrib/lisp/ol-git-link.el
index 0028daf..9f3e12c 100644
--- a/contrib/lisp/org-git-link.el
+++ b/contrib/lisp/ol-git-link.el
@@ -1,4 +1,4 @@
-;;; org-git-link.el --- Provide org links to specific file version
+;;; ol-git-link.el --- Links to specific file version
;; Copyright (C) 2009-2014 Reimar Finken
@@ -62,6 +62,8 @@
;;; Code:
(require 'org)
+(require 'ol)
+
(defcustom org-git-program "git"
"Name of the git executable used to follow git links."
:type '(string)
@@ -224,6 +226,6 @@ than two double colons, str2 and/or str3 may be set the empty string."
(if (looking-at "^refs/heads/") ; 11 characters
(buffer-substring 12 (1- (point-max))))))) ; to strip off final newline
-(provide 'org-git-link)
+(provide 'ol-git-link)
-;;; org-git-link.el ends here
+;;; ol-git-link.el ends here
diff --git a/contrib/lisp/org-man.el b/contrib/lisp/ol-man.el
index 43e20e2..cdbf471 100644
--- a/contrib/lisp/org-man.el
+++ b/contrib/lisp/ol-man.el
@@ -1,4 +1,4 @@
-;;; org-man.el - Support for links to manpages in Org-mode
+;;; ol-man.el - Links to man pages
;;
;; Author: Carsten Dominik <carsten at orgmode dot org>
;; Keywords: outlines, hypermedia, calendar, wp
@@ -23,6 +23,7 @@
;;
;;; Commentary:
+(require 'ol)
(require 'org)
(org-link-set-parameters "man"
@@ -70,6 +71,6 @@ PATH should be a topic that can be thrown at the man command."
((eq format 'ascii) (format "%s (%s)" desc path))
(t path))))
-(provide 'org-man)
+(provide 'ol-man)
-;;; org-man.el ends here
+;;; ol-man.el ends here
diff --git a/contrib/lisp/org-mew.el b/contrib/lisp/ol-mew.el
index 84cc336..3fd3b40 100644
--- a/contrib/lisp/org-mew.el
+++ b/contrib/lisp/ol-mew.el
@@ -1,4 +1,4 @@
-;;; org-mew.el --- Support for links to Mew messages from within Org-mode
+;;; ol-mew.el --- Links to Mew messages
;; Copyright (C) 2008-2018 Free Software Foundation, Inc.
@@ -55,6 +55,7 @@
;;; Code:
(require 'org)
+(require 'ol)
(defgroup org-mew nil
"Options concerning the Mew link."
@@ -349,6 +350,6 @@ asks you to select the capture template."
(throw 'found (cdr elem))))
(setq alist (cdr alist))))))
-(provide 'org-mew)
+(provide 'ol-mew)
-;;; org-mew.el ends here
+;;; ol-mew.el ends here
diff --git a/contrib/lisp/org-notmuch.el b/contrib/lisp/ol-notmuch.el
index 39cf0e3..d26d775 100644
--- a/contrib/lisp/org-notmuch.el
+++ b/contrib/lisp/ol-notmuch.el
@@ -1,4 +1,4 @@
-;;; org-notmuch.el --- Support for links to notmuch messages from within Org-mode
+;;; org-notmuch.el --- Links to notmuch messages
;; Copyright (C) 2010-2014 Matthieu Lemerre
@@ -23,9 +23,9 @@
;;; Commentary:
-;; This file implements links to notmuch messages and "searchs". A
+;; This file implements links to notmuch messages and "searches". A
;; search is a query to be performed by notmuch; it is the equivalent
-;; to folders in other mail clients. Similarly, mails are refered to
+;; to folders in other mail clients. Similarly, mails are referred to
;; by a query, so both a link can refer to several mails.
;; Links have one the following form
@@ -35,10 +35,11 @@
;; The first form open the queries in notmuch-show mode, whereas the
;; second link open it in notmuch-search mode. Note that queries are
;; performed at the time the link is opened, and the result may be
-;; different from whet the link was stored.
+;; different from when the link was stored.
;;; Code:
+(require 'ol)
(require 'org)
;; customisable notmuch open functions
@@ -55,13 +56,14 @@ Should accept a notmuch search string as the sole argument."
(defcustom org-notmuch-search-open-function
'org-notmuch-search-follow-link
"Function used to follow notmuch-search links.
-
Should accept a notmuch search string as the sole argument."
:group 'org-notmuch
:version "24.4"
:package-version '(Org . "8.0")
:type 'function)
+(make-obsolete-variable 'org-notmuch-search-open-function nil "9.3")
+
;; Install the link type
@@ -71,7 +73,7 @@ Should accept a notmuch search string as the sole argument."
(defun org-notmuch-store-link ()
"Store a link to a notmuch search or message."
- (when (eq major-mode 'notmuch-show-mode)
+ (when (memq major-mode '(notmuch-show-mode notmuch-tree-mode))
(let* ((message-id (notmuch-show-get-message-id t))
(subject (notmuch-show-get-subject))
(to (notmuch-show-get-to))
@@ -115,7 +117,7 @@ Can link to more than one message, if so all matching messages are shown."
(defun org-notmuch-search-open (path)
"Follow a notmuch message link specified by PATH."
(message "%s" path)
- (funcall org-notmuch-search-open-function path))
+ (org-notmuch-search-follow-link path))
(defun org-notmuch-search-follow-link (search)
"Follow a notmuch link by displaying SEARCH in notmuch-search mode."
@@ -124,11 +126,30 @@ Can link to more than one message, if so all matching messages are shown."
+(org-link-set-parameters "notmuch-tree"
+ :follow #'org-notmuch-tree-open
+ :store #'org-notmuch-tree-store-link)
+
+(defun org-notmuch-tree-store-link ()
+ "Store a link to a notmuch search or message."
+ (when (eq major-mode 'notmuch-tree-mode)
+ (let ((link (concat "notmuch-tree:" (notmuch-tree-get-query)))
+ (desc (concat "Notmuch tree: " (notmuch-tree-get-query))))
+ (org-store-link-props :type "notmuch-tree"
+ :link link
+ :description desc)
+ link)))
+
+(defun org-notmuch-tree-open (path)
+ "Follow a notmuch message link specified by PATH."
+ (message "%s" path)
+ (org-notmuch-tree-follow-link path))
+
(defun org-notmuch-tree-follow-link (search)
"Follow a notmuch link by displaying SEARCH in notmuch-tree mode."
(require 'notmuch)
(notmuch-tree search))
-(provide 'org-notmuch)
+(provide 'ol-notmuch)
-;;; org-notmuch.el ends here
+;;; ol-notmuch.el ends here
diff --git a/contrib/lisp/org-vm.el b/contrib/lisp/ol-vm.el
index 1113e29..58c2cbd 100644
--- a/contrib/lisp/org-vm.el
+++ b/contrib/lisp/ol-vm.el
@@ -1,4 +1,4 @@
-;;; org-vm.el --- Support for links to VM messages from within Org-mode
+;;; ol-vm.el --- Links to VM messages
;; Copyright (C) 2004-2018 Free Software Foundation, Inc.
@@ -33,6 +33,7 @@
;;; Code:
+(require 'ol)
(require 'org)
;; Declare external functions and variables
@@ -107,7 +108,7 @@
(defun org-vm-follow-link (&optional folder article readonly)
"Follow a VM link to FOLDER and ARTICLE."
(require 'vm)
- (setq article (org-add-angle-brackets article))
+ (setq article (org-link-add-angle-brackets article))
(if (string-match "^//\\([a-zA-Z]+@\\)?\\([^:]+\\):\\(.*\\)" folder)
;; ange-ftp or efs or tramp access
(let ((user (or (match-string 1 folder) (user-login-name)))
@@ -124,7 +125,7 @@
(when folder
(funcall (cdr (assq 'vm org-link-frame-setup)) folder readonly)
(when article
- (org-vm-select-message (org-add-angle-brackets article)))))
+ (org-vm-select-message (org-link-add-angle-brackets article)))))
(defun org-vm-imap-open (path)
"Follow a VM link to an IMAP folder."
@@ -143,7 +144,7 @@
(funcall (cdr (assq 'vm-imap org-link-frame-setup))
mailbox-spec)
(when message-id
- (org-vm-select-message (org-add-angle-brackets message-id))))))
+ (org-vm-select-message (org-link-add-angle-brackets message-id))))))
(defun org-vm-select-message (message-id)
"Go to the message with message-id in the current folder."
@@ -161,8 +162,6 @@
(vm-preview-current-message)
(vm-summarize)))
-(provide 'org-vm)
+(provide 'ol-vm)
-
-
-;;; org-vm.el ends here
+;;; ol-vm.el ends here
diff --git a/contrib/lisp/org-wl.el b/contrib/lisp/ol-wl.el
index 4ac9a53..0e0e483 100644
--- a/contrib/lisp/org-wl.el
+++ b/contrib/lisp/ol-wl.el
@@ -1,4 +1,4 @@
-;;; org-wl.el --- Support for links to Wanderlust messages from within Org-mode
+;;; ol-wl.el --- Links to Wanderlust messages
;; Copyright (C) 2004-2018 Free Software Foundation, Inc.
@@ -31,6 +31,7 @@
;;; Code:
+(require 'ol)
(require 'org)
(defgroup org-wl nil
@@ -221,10 +222,10 @@ ENTITY is a message entity."
((and (eq folder-type 'nntp) org-wl-nntp-prefer-web-links)
(setq link
(format
- (if (string-match "gmane\\." folder-name)
+ (if (string-match-p "gmane\\." folder-name)
"http://mid.gmane.org/%s"
"http://groups.google.com/groups/search?as_umsgid=%s")
- (org-fixup-message-id-for-http message-id)))
+ (url-encode-url message-id)))
(org-store-link-props :type "http" :link link :description subject
:from from :to to :message-id message-id
:message-id-no-brackets message-id-no-brackets
@@ -291,12 +292,12 @@ for namazu index."
(goto-char old-point))
(when article
(if (string-match-p "@" article)
- (wl-summary-jump-to-msg-by-message-id (org-add-angle-brackets
+ (wl-summary-jump-to-msg-by-message-id (org-link-add-angle-brackets
article))
(or (wl-summary-jump-to-msg (string-to-number article))
(error "No such message: %s" article)))
(wl-summary-redisplay))))))
-(provide 'org-wl)
+(provide 'ol-wl)
-;;; org-wl.el ends here
+;;; ol-wl.el ends here
diff --git a/contrib/lisp/org-annotate-file.el b/contrib/lisp/org-annotate-file.el
index b8e8bd9..e1f1f13 100644
--- a/contrib/lisp/org-annotate-file.el
+++ b/contrib/lisp/org-annotate-file.el
@@ -51,7 +51,7 @@
;; C-c C-l (on the above line for example) you will get:
;; * ~/org-annotate-file.el
-;; ** `org-annotate-file-add-search` to non-nil value. Then whe...
+;; ** `org-annotate-file-add-search` to non-nil value. Then when...
;; Note that both of the above will be links.
diff --git a/contrib/lisp/org-attach-embedded-images.el b/contrib/lisp/org-attach-embedded-images.el
index 83d6757..c695ce3 100644
--- a/contrib/lisp/org-attach-embedded-images.el
+++ b/contrib/lisp/org-attach-embedded-images.el
@@ -1,9 +1,9 @@
;;; org-attach-embedded-images.el --- Transmute images to attachments
;;
-;; Copyright 2018 Free Software Foundation, Inc.
+;; Copyright 2018, 2019 Free Software Foundation, Inc.
;;
;; Author: Marco Wahl
-;; Version: 0.0
+;; Version: 0.1
;; Keywords: org, media
;;
;; This file is not part of GNU Emacs.
@@ -24,16 +24,25 @@
;;; Commentary:
;;
;; There are occasions when images are displayed in a subtree which
-;; are not (yet) org attachments. For example if you copy and paste a
-;; part of a web page (containing images) from eww to an org subtree.
+;; are not org attachments. For example if you copy and paste a part
+;; of a web page (containing images) from eww to an org subtree.
;; This module provides command `org-attach-embedded-images-in-subtree'
;; to save such images as attachments and insert org links to them.
-;; To use you might put the following in your .emacs:
+;; Install:
+
+;; To use this module insert it to `org-modules'. The insert can be
+;; performed via {M-x customize-variable RET org-modules RET} followed
+;; by insertion of `org-attach-embedded-images' to the external
+;; modules section.
+
+;; Alternatively you can add the line
;; (require 'org-attach-embedded-images)
+;; to your emacs configuration.
+
;; Use
;; M-x org-attach-embedded-images-in-subtree
@@ -43,9 +52,9 @@
;; Note: Possibly
-;; M-x org-toggle-inline-images is needed to see inline
+;; M-x org-toggle-inline-images
-;; images in Org mode.
+;; is needed to see the images in the Org mode window.
;; Code:
@@ -74,15 +83,15 @@ POSITION and LIMIT as in `next-single-property-change'."
Return the filename."
(let* ((extension (symbol-name (image-type-from-data data)))
(basename (concat (sha1 data) "." extension))
- (org-attach-filename
- (concat (org-attach-dir t) "/" basename)))
- (unless (file-exists-p org-attach-filename)
- (with-temp-file org-attach-filename
+ (dir (org-attach-dir t))
+ (filename (concat dir "/" basename)))
+ (unless (file-exists-p filename)
+ (with-temp-file filename
(setq buffer-file-coding-system 'binary)
(set-buffer-multibyte nil)
(insert data)))
(org-attach-sync)
- org-attach-filename))
+ basename))
;; Command
@@ -91,28 +100,29 @@ Return the filename."
(defun org-attach-embedded-images-in-subtree ()
"Save the displayed images as attachments and insert links to them."
(interactive)
- (if (org-before-first-heading-p)
- (message "Before first heading. Nothing has been attached.")
- (save-excursion
- (let ((beg (progn (org-back-to-heading) (point)))
- (end (progn (org-end-of-subtree) (point)))
- (names nil))
- ;; pass 1
- (goto-char beg)
- (while (< (goto-char (org-attach-embedded-images--next-property-display-data (point) end)) end)
- (let ((data (plist-get (cdr (plist-get (text-properties-at (point)) 'display)) :data)))
- (assert data)
- (push (org-attach-embedded-images--attach-with-sha1-name data)
- names)))
- ;; pass 2
- (setq names (nreverse names))
- (goto-char beg)
- (while names
- (goto-char (org-attach-embedded-images--next-property-display-data (point) end))
- (while (get-text-property (point) 'display)
- (goto-char (next-property-change (point) nil end)))
- (skip-chars-forward "]")
- (insert (concat "\n[[" (pop names) "]]")))))))
+ (when (org-before-first-heading-p)
+ (user-error "Before first heading. Nothing has been attached."))
+ (save-excursion
+ (org-attach-dir t)
+ (let ((beg (progn (org-back-to-heading) (point)))
+ (end (progn (org-end-of-subtree) (point)))
+ names)
+ ;; pass 1
+ (goto-char beg)
+ (while (< (goto-char (org-attach-embedded-images--next-property-display-data (point) end)) end)
+ (let ((data (plist-get (cdr (plist-get (text-properties-at (point)) 'display)) :data)))
+ (assert data)
+ (push (org-attach-embedded-images--attach-with-sha1-name data)
+ names)))
+ ;; pass 2
+ (setq names (nreverse names))
+ (goto-char beg)
+ (while names
+ (goto-char (org-attach-embedded-images--next-property-display-data (point) end))
+ (while (get-text-property (point) 'display)
+ (goto-char (next-property-change (point) nil end)))
+ (skip-chars-forward "]")
+ (insert (concat "\n[[attachment:" (pop names) "]]"))))))
(provide 'org-attach-embedded-images)
diff --git a/contrib/lisp/org-bibtex-extras.el b/contrib/lisp/org-bibtex-extras.el
index 991946e..533fbba 100644
--- a/contrib/lisp/org-bibtex-extras.el
+++ b/contrib/lisp/org-bibtex-extras.el
@@ -59,7 +59,7 @@
;; (obe-html-export-citations))))
;;; Code:
-(require 'org-bibtex)
+(require 'ol-bibtex)
(declare-function org-trim "org" (s &optional keep-lead))
diff --git a/contrib/lisp/org-collector.el b/contrib/lisp/org-collector.el
index 833ecbf..937d03e 100644
--- a/contrib/lisp/org-collector.el
+++ b/contrib/lisp/org-collector.el
@@ -111,7 +111,7 @@ a column, or through the generation of an error.")
(defun org-dblock-write:propview (params)
"collect the column specification from the #+cols line
-preceeding the dblock, then update the contents of the dblock."
+preceding the dblock, then update the contents of the dblock."
(interactive)
(condition-case er
(let ((cols (plist-get params :cols))
diff --git a/contrib/lisp/org-contacts.el b/contrib/lisp/org-contacts.el
index 34370fd..4b3693a 100644
--- a/contrib/lisp/org-contacts.el
+++ b/contrib/lisp/org-contacts.el
@@ -59,6 +59,7 @@
(require 'mail-utils)
(require 'org-agenda)
(require 'org-capture)
+(require 'ol)
(defgroup org-contacts nil
"Options about contacts management."
diff --git a/contrib/lisp/org-drill.el b/contrib/lisp/org-drill.el
deleted file mode 100644
index 89ede63..0000000
--- a/contrib/lisp/org-drill.el
+++ /dev/null
@@ -1,3416 +0,0 @@
-;; -*- coding: utf-8-unix -*-
-;;; org-drill.el - Self-testing using spaced repetition
-;;;
-;;; Copyright (C) 2010-2015 Paul Sexton
-;;;
-;;; Author: Paul Sexton <eeeickythump@gmail.com>
-;;; Version: 2.4.7
-;;; Keywords: flashcards, memory, learning, memorization
-;;; Repository at http://bitbucket.org/eeeickythump/org-drill/
-;;;
-;;; This file is not part of GNU Emacs.
-;;;
-;;; This program is free software; you can redistribute it and/or modify
-;;; it under the terms of the GNU General Public License as published by
-;;; the Free Software Foundation, either version 3 of the License, or
-;;; (at your option) any later version.
-;;;
-;;; This program is distaributed in the hope that it will be useful,
-;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;;; GNU General Public License for more details.
-;;;
-;;; You should have received a copy of the GNU General Public License
-;;; along with this program. If not, see <http://www.gnu.org/licenses/>.
-;;;
-;;;
-;;; Synopsis
-;;; ========
-;;;
-;;; Uses the SuperMemo spaced repetition algorithms to conduct interactive
-;;; "drill sessions", where the material to be remembered is presented to the
-;;; student in random order. The student rates his or her recall of each item,
-;;; and this information is used to schedule the item for later revision.
-;;;
-;;; Each drill session can be restricted to topics in the current buffer
-;;; (default), one or several files, all agenda files, or a subtree. A single
-;;; topic can also be drilled.
-;;;
-;;; Different "card types" can be defined, which present their information to
-;;; the student in different ways.
-;;;
-;;; See the file README.org for more detailed documentation.
-
-
-(eval-when-compile (require 'cl))
-(eval-when-compile (require 'hi-lock))
-(require 'cl-lib)
-(require 'hi-lock)
-(require 'org)
-(require 'org-id)
-(require 'org-learn)
-(require 'savehist)
-
-
-(defgroup org-drill nil
- "Options concerning interactive drill sessions in Org mode (org-drill)."
- :tag "Org-Drill"
- :group 'org-link)
-
-
-
-(defcustom org-drill-question-tag
- "drill"
- "Tag which topics must possess in order to be identified as review topics
-by `org-drill'."
- :group 'org-drill
- :type 'string)
-
-
-(defcustom org-drill-maximum-items-per-session
- 30
- "Each drill session will present at most this many topics for review.
-Nil means unlimited."
- :group 'org-drill
- :type '(choice integer (const nil)))
-
-
-
-(defcustom org-drill-maximum-duration
- 20
- "Maximum duration of a drill session, in minutes.
-Nil means unlimited."
- :group 'org-drill
- :type '(choice integer (const nil)))
-
-
-(defcustom org-drill-failure-quality
- 2
- "If the quality of recall for an item is this number or lower,
-it is regarded as an unambiguous failure, and the repetition
-interval for the card is reset to 0 days. If the quality is higher
-than this number, it is regarded as successfully recalled, but the
-time interval to the next repetition will be lowered if the quality
-was near to a fail.
-
-By default this is 2, for SuperMemo-like behaviour. For
-Mnemosyne-like behaviour, set it to 1. Other values are not
-really sensible."
- :group 'org-drill
- :type '(choice (const 2) (const 1)))
-
-
-(defcustom org-drill-forgetting-index
- 10
- "What percentage of items do you consider it is 'acceptable' to
-forget each drill session? The default is 10%. A warning message
-is displayed at the end of the session if the percentage forgotten
-climbs above this number."
- :group 'org-drill
- :type 'integer)
-
-
-(defcustom org-drill-leech-failure-threshold
- 15
- "If an item is forgotten more than this many times, it is tagged
-as a 'leech' item."
- :group 'org-drill
- :type '(choice integer (const nil)))
-
-
-(defcustom org-drill-leech-method
- 'skip
- "How should 'leech items' be handled during drill sessions?
-Possible values:
-- nil :: Leech items are treated the same as normal items.
-- skip :: Leech items are not included in drill sessions.
-- warn :: Leech items are still included in drill sessions,
- but a warning message is printed when each leech item is
- presented."
- :group 'org-drill
- :type '(choice (const warn) (const skip) (const nil)))
-
-
-(defface org-drill-visible-cloze-face
- '((t (:foreground "darkseagreen")))
- "The face used to hide the contents of cloze phrases."
- :group 'org-drill)
-
-
-(defface org-drill-visible-cloze-hint-face
- '((t (:foreground "dark slate blue")))
- "The face used to hide the contents of cloze phrases."
- :group 'org-drill)
-
-
-(defface org-drill-hidden-cloze-face
- '((t (:foreground "deep sky blue" :background "blue")))
- "The face used to hide the contents of cloze phrases."
- :group 'org-drill)
-
-
-(defcustom org-drill-use-visible-cloze-face-p
- nil
- "Use a special face to highlight cloze-deleted text in org mode
-buffers?"
- :group 'org-drill
- :type 'boolean)
-
-
-(defcustom org-drill-hide-item-headings-p
- nil
- "Conceal the contents of the main heading of each item during drill
-sessions? You may want to enable this behaviour if item headings or tags
-contain information that could 'give away' the answer."
- :group 'org-drill
- :type 'boolean)
-
-
-(defcustom org-drill-new-count-color
- "royal blue"
- "Foreground colour used to display the count of remaining new items
-during a drill session."
- :group 'org-drill
- :type 'color)
-
-(defcustom org-drill-mature-count-color
- "green"
- "Foreground colour used to display the count of remaining mature items
-during a drill session. Mature items are due for review, but are not new."
- :group 'org-drill
- :type 'color)
-
-(defcustom org-drill-failed-count-color
- "red"
- "Foreground colour used to display the count of remaining failed items
-during a drill session."
- :group 'org-drill
- :type 'color)
-
-(defcustom org-drill-done-count-color
- "sienna"
- "Foreground colour used to display the count of reviewed items
-during a drill session."
- :group 'org-drill
- :type 'color)
-
-(defcustom org-drill-left-cloze-delimiter
- "["
- "String used within org buffers to delimit cloze deletions."
- :group 'org-drill
- :type 'string)
-
-(defcustom org-drill-right-cloze-delimiter
- "]"
- "String used within org buffers to delimit cloze deletions."
- :group 'org-drill
- :type 'string)
-
-
-(setplist 'org-drill-cloze-overlay-defaults
- `(display ,(format "%s...%s"
- org-drill-left-cloze-delimiter
- org-drill-right-cloze-delimiter)
- face org-drill-hidden-cloze-face
- window t))
-
-(setplist 'org-drill-hidden-text-overlay
- '(invisible t))
-
-(setplist 'org-drill-replaced-text-overlay
- '(display "Replaced text"
- face default
- window t))
-
-(add-hook 'org-font-lock-set-keywords-hook 'org-drill-add-cloze-fontification)
-
-
-(defvar org-drill-hint-separator "||"
- "String which, if it occurs within a cloze expression, signifies that the
-rest of the expression after the string is a `hint', to be displayed instead of
-the hidden cloze during a test.")
-
-(defun org-drill--compute-cloze-regexp ()
- (concat "\\("
- (regexp-quote org-drill-left-cloze-delimiter)
- "[[:cntrl:][:graph:][:space:]]+?\\)\\(\\|"
- (regexp-quote org-drill-hint-separator)
- ".+?\\)\\("
- (regexp-quote org-drill-right-cloze-delimiter)
- "\\)"))
-
-(defun org-drill--compute-cloze-keywords ()
- (list (list (org-drill--compute-cloze-regexp)
- (list 1 'org-drill-visible-cloze-face nil)
- (list 2 'org-drill-visible-cloze-hint-face t)
- (list 3 'org-drill-visible-cloze-face nil))))
-
-(defvar-local org-drill-cloze-regexp
- (org-drill--compute-cloze-regexp))
-
-
-(defvar-local org-drill-cloze-keywords
- (org-drill--compute-cloze-keywords))
-
-
-;; Variables defining what keys can be pressed during drill sessions to quit the
-;; session, edit the item, etc.
-(defvar org-drill--quit-key ?q
- "If this character is pressed during a drill session, quit the session.")
-(defvar org-drill--edit-key ?e
- "If this character is pressed during a drill session, suspend the session
-with the cursor at the current item..")
-(defvar org-drill--help-key ??
- "If this character is pressed during a drill session, show help.")
-(defvar org-drill--skip-key ?s
- "If this character is pressed during a drill session, skip to the next
-item.")
-(defvar org-drill--tags-key ?t
- "If this character is pressed during a drill session, edit the tags for
-the current item.")
-(defvar org-drill--pronounce-key ?p
- "If this character is pressed during a drill session, pronounce for
-the current item.")
-
-
-(defcustom org-drill-card-type-alist
- '((nil org-drill-present-simple-card)
- ("simple" org-drill-present-simple-card)
- ("twosided" org-drill-present-two-sided-card nil t)
- ("multisided" org-drill-present-multi-sided-card nil t)
- ("hide1cloze" org-drill-present-multicloze-hide1)
- ("hide2cloze" org-drill-present-multicloze-hide2)
- ("show1cloze" org-drill-present-multicloze-show1)
- ("show2cloze" org-drill-present-multicloze-show2)
- ("multicloze" org-drill-present-multicloze-hide1)
- ("hidefirst" org-drill-present-multicloze-hide-first)
- ("hidelast" org-drill-present-multicloze-hide-last)
- ("hide1_firstmore" org-drill-present-multicloze-hide1-firstmore)
- ("show1_lastmore" org-drill-present-multicloze-show1-lastmore)
- ("show1_firstless" org-drill-present-multicloze-show1-firstless)
- ("conjugate"
- org-drill-present-verb-conjugation
- org-drill-show-answer-verb-conjugation)
- ("decline_noun"
- org-drill-present-noun-declension
- org-drill-show-answer-noun-declension)
- ("spanish_verb" org-drill-present-spanish-verb)
- ("translate_number" org-drill-present-translate-number))
- "Alist associating card types with presentation functions. Each
-entry in the alist takes the form:
-
-;;; (CARDTYPE QUESTION-FN [ANSWER-FN DRILL-EMPTY-P])
-
-Where CARDTYPE is a string or nil (for default), and QUESTION-FN
-is a function which takes no arguments and returns a boolean
-value.
-
-When supplied, ANSWER-FN is a function that takes one argument --
-that argument is a function of no arguments, which when called,
-prompts the user to rate their recall and performs rescheduling
-of the drill item. ANSWER-FN is called with the point on the
-active item's heading, just prior to displaying the item's
-'answer'. It can therefore be used to modify the appearance of
-the answer. ANSWER-FN must call its argument before returning.
-
-When supplied, DRILL-EMPTY-P is a boolean value, default nil.
-When non-nil, cards of this type will be presented during tests
-even if their bodies are empty."
- :group 'org-drill
- :type '(alist :key-type (choice string (const nil))
- :value-type function))
-
-
-(defcustom org-drill-scope
- 'file
- "The scope in which to search for drill items when conducting a
-drill session. This can be any of:
-
-file The current buffer, respecting the restriction if any.
- This is the default.
-tree The subtree started with the entry at point
-file-no-restriction The current buffer, without restriction
-file-with-archives The current buffer, and any archives associated with it.
-agenda All agenda files
-agenda-with-archives All agenda files with any archive files associated
- with them.
-directory All files with the extension '.org' in the same
- directory as the current file (includes the current
- file if it is an .org file.)
- (FILE1 FILE2 ...) If this is a list, all files in the list will be scanned.
-"
- ;; Note -- meanings differ slightly from the argument to org-map-entries:
- ;; 'file' means current file/buffer, respecting any restriction
- ;; 'file-no-restriction' means current file/buffer, ignoring restrictions
- ;; 'directory' means all *.org files in current directory
- :group 'org-drill
- :type '(choice (const :tag "The current buffer, respecting the restriction if any." file)
- (const :tag "The subtree started with the entry at point" tree)
- (const :tag "The current buffer, without restriction" file-no-restriction)
- (const :tag "The current buffer, and any archives associated with it." file-with-archives)
- (const :tag "All agenda files" agenda)
- (const :tag "All agenda files with any archive files associated with them." agenda-with-archives)
- (const :tag "All files with the extension '.org' in the same directory as the current file (includes the current file if it is an .org file.)" directory)
- (repeat :tag "List of files to scan for drill items." file)))
-
-
-(defcustom org-drill-match
- nil
- "If non-nil, a string specifying a tags/property/TODO query. During
-drill sessions, only items that match this query will be considered."
- :group 'org-drill
- :type '(choice (const nil) string))
-
-
-(defcustom org-drill-save-buffers-after-drill-sessions-p
- t
- "If non-nil, prompt to save all modified buffers after a drill session
-finishes."
- :group 'org-drill
- :type 'boolean)
-
-
-(defcustom org-drill-spaced-repetition-algorithm
- 'sm5
- "Which SuperMemo spaced repetition algorithm to use for scheduling items.
-Available choices are:
-- SM2 :: the SM2 algorithm, used in SuperMemo 2.0
-- SM5 :: the SM5 algorithm, used in SuperMemo 5.0
-- Simple8 :: a modified version of the SM8 algorithm. SM8 is used in
- SuperMemo 98. The version implemented here is simplified in that while it
- 'learns' the difficulty of each item using quality grades and number of
- failures, it does not modify the matrix of values that
- governs how fast the inter-repetition intervals increase. A method for
- adjusting intervals when items are reviewed early or late has been taken
- from SM11, a later version of the algorithm, and included in Simple8."
- :group 'org-drill
- :type '(choice (const sm2) (const sm5) (const simple8)))
-
-
-(defcustom org-drill-optimal-factor-matrix
- nil
- "Obsolete and will be removed in future. The SM5 optimal factor
-matrix data is now stored in the variable
-`org-drill-sm5-optimal-factor-matrix'."
- :group 'org-drill
- :type 'sexp)
-
-
-(defvar org-drill-sm5-optimal-factor-matrix
- nil
- "DO NOT CHANGE THE VALUE OF THIS VARIABLE.
-
-Persistent matrix of optimal factors, used by the SuperMemo SM5
-algorithm. The matrix is saved at the end of each drill session.
-
-Over time, values in the matrix will adapt to the individual user's
-pace of learning.")
-
-
-(add-to-list 'savehist-additional-variables
- 'org-drill-sm5-optimal-factor-matrix)
-(unless savehist-mode
- (savehist-mode 1))
-
-
-(defun org-drill--transfer-optimal-factor-matrix ()
- (if (and org-drill-optimal-factor-matrix
- (null org-drill-sm5-optimal-factor-matrix))
- (setq org-drill-sm5-optimal-factor-matrix
- org-drill-optimal-factor-matrix)))
-
-(add-hook 'after-init-hook 'org-drill--transfer-optimal-factor-matrix)
-
-
-(defcustom org-drill-sm5-initial-interval
- 4.0
- "In the SM5 algorithm, the initial interval after the first
-successful presentation of an item is always 4 days. If you wish to change
-this, you can do so here."
- :group 'org-drill
- :type 'float)
-
-
-(defcustom org-drill-add-random-noise-to-intervals-p
- nil
- "If true, the number of days until an item's next repetition
-will vary slightly from the interval calculated by the SM2
-algorithm. The variation is very small when the interval is
-small, but scales up with the interval."
- :group 'org-drill
- :type 'boolean)
-
-
-(defcustom org-drill-adjust-intervals-for-early-and-late-repetitions-p
- nil
- "If true, when the student successfully reviews an item 1 or more days
-before or after the scheduled review date, this will affect that date of
-the item's next scheduled review, according to the algorithm presented at
- [[http://www.supermemo.com/english/algsm11.htm#Advanced%20repetitions]].
-
-Items that were reviewed early will have their next review date brought
-forward. Those that were reviewed late will have their next review
-date postponed further.
-
-Note that this option currently has no effect if the SM2 algorithm
-is used."
- :group 'org-drill
- :type 'boolean)
-
-
-(defcustom org-drill-cloze-text-weight
- 4
- "For card types 'hide1_firstmore', 'show1_lastmore' and 'show1_firstless',
-this number determines how often the 'less favoured' situation
-should arise. It will occur 1 in every N trials, where N is the
-value of the variable.
-
-For example, with the hide1_firstmore card type, the first piece
-of clozed text should be hidden more often than the other
-pieces. If this variable is set to 4 (default), the first item
-will only be shown 25% of the time (1 in 4 trials). Similarly for
-show1_lastmore, the last item will be shown 75% of the time, and
-for show1_firstless, the first item would only be shown 25% of the
-time.
-
-If the value of this variable is NIL, then weighting is disabled, and
-all weighted card types are treated as their unweighted equivalents."
- :group 'org-drill
- :type '(choice integer (const nil)))
-
-
-(defcustom org-drill-cram-hours
- 12
- "When in cram mode, items are considered due for review if
-they were reviewed at least this many hours ago."
- :group 'org-drill
- :type 'integer)
-
-
-;;; NEW items have never been presented in a drill session before.
-;;; MATURE items HAVE been presented at least once before.
-;;; - YOUNG mature items were scheduled no more than
-;;; ORG-DRILL-DAYS-BEFORE-OLD days after their last
-;;; repetition. These items will have been learned 'recently' and will have a
-;;; low repetition count.
-;;; - OLD mature items have intervals greater than
-;;; ORG-DRILL-DAYS-BEFORE-OLD.
-;;; - OVERDUE items are past their scheduled review date by more than
-;;; LAST-INTERVAL * (ORG-DRILL-OVERDUE-INTERVAL-FACTOR - 1) days,
-;;; regardless of young/old status.
-
-
-(defcustom org-drill-days-before-old
- 10
- "When an item's inter-repetition interval rises above this value in days,
-it is no longer considered a 'young' (recently learned) item."
- :group 'org-drill
- :type 'integer)
-
-
-(defcustom org-drill-overdue-interval-factor
- 1.2
- "An item is considered overdue if its scheduled review date is
-more than (ORG-DRILL-OVERDUE-INTERVAL-FACTOR - 1) * LAST-INTERVAL
-days in the past. For example, a value of 1.2 means an additional
-20% of the last scheduled interval is allowed to elapse before
-the item is overdue. A value of 1.0 means no extra time is
-allowed at all - items are immediately considered overdue if
-there is even one day's delay in reviewing them. This variable
-should never be less than 1.0."
- :group 'org-drill
- :type 'float)
-
-
-(defcustom org-drill-learn-fraction
- 0.5
- "Fraction between 0 and 1 that governs how quickly the spaces
-between successive repetitions increase, for all items. The
-default value is 0.5. Higher values make spaces increase more
-quickly with each successful repetition. You should only change
-this in small increments (for example 0.05-0.1) as it has an
-exponential effect on inter-repetition spacing."
- :group 'org-drill
- :type 'float)
-
-(defcustom org-drill-entry-before-hook nil
- "A hook to run functions when every org-drill entry."
- :group 'org-drill
- :type 'hook)
-
-(defcustom org-drill-entry-after-hook nil
- "A hook to run functions when every org-drill entry."
- :group 'org-drill
- :type 'hook)
-
-(defcustom org-drill-auto-pronounce t
- "Auto pronounce org-drill word if non-nil."
- :group 'org-drill
- :type 'boolean
- :safe #'booleanp)
-
-(defcustom org-drill-pronounce-command (executable-find "espeak")
- "Org-drill pronounce command."
- :group 'org-drill
- :type 'string)
-
-(defcustom org-drill-pronounce-command-args
- (if (string= org-drill-pronounce-command "/usr/bin/espeak")
- "-v en")
- "Org-drill pronounce command arguments."
- :group 'org-drill
- :type 'string)
-
-
-(defvar drill-answer nil
- "Global variable that can be bound to a correct answer when an
-item is being presented. If this variable is non-nil, the default
-presentation function will show its value instead of the default
-behaviour of revealing the contents of the drilled item.
-
-This variable is useful for card types that compute their answers
--- for example, a card type that asks the student to translate a
-random number to another language. ")
-
-
-(defvar *org-drill-session-qualities* nil)
-(defvar *org-drill-start-time* 0)
-(defvar *org-drill-new-entries* nil)
-(defvar *org-drill-dormant-entry-count* 0)
-(defvar *org-drill-due-entry-count* 0)
-(defvar *org-drill-overdue-entry-count* 0)
-(defvar *org-drill-due-tomorrow-count* 0)
-(defvar *org-drill-overdue-entries* nil
- "List of markers for items that are considered 'overdue', based on
-the value of ORG-DRILL-OVERDUE-INTERVAL-FACTOR.")
-(defvar *org-drill-young-mature-entries* nil
- "List of markers for mature entries whose last inter-repetition
-interval was <= ORG-DRILL-DAYS-BEFORE-OLD days.")
-(defvar *org-drill-old-mature-entries* nil
- "List of markers for mature entries whose last inter-repetition
-interval was greater than ORG-DRILL-DAYS-BEFORE-OLD days.")
-(defvar *org-drill-failed-entries* nil)
-(defvar *org-drill-again-entries* nil)
-(defvar *org-drill-done-entries* nil)
-(defvar *org-drill-current-item* nil
- "Set to the marker for the item currently being tested.")
-(defvar *org-drill-cram-mode* nil
- "Are we in 'cram mode', where all items are considered due
-for review unless they were already reviewed in the recent past?")
-(defvar org-drill-scheduling-properties
- '("LEARN_DATA" "DRILL_LAST_INTERVAL" "DRILL_REPEATS_SINCE_FAIL"
- "DRILL_TOTAL_REPEATS" "DRILL_FAILURE_COUNT" "DRILL_AVERAGE_QUALITY"
- "DRILL_EASE" "DRILL_LAST_QUALITY" "DRILL_LAST_REVIEWED"))
-(defvar org-drill--lapse-very-overdue-entries-p nil
- "If non-nil, entries more than 90 days overdue are regarded as 'lapsed'.
-This means that when the item is eventually re-tested it will be
-treated as 'failed' (quality 2) for rescheduling purposes,
-regardless of whether the test was successful.")
-
-
-;;; Make the above settings safe as file-local variables.
-
-
-(put 'org-drill-question-tag 'safe-local-variable 'stringp)
-(put 'org-drill-maximum-items-per-session 'safe-local-variable
- '(lambda (val) (or (integerp val) (null val))))
-(put 'org-drill-maximum-duration 'safe-local-variable
- '(lambda (val) (or (integerp val) (null val))))
-(put 'org-drill-failure-quality 'safe-local-variable 'integerp)
-(put 'org-drill-forgetting-index 'safe-local-variable 'integerp)
-(put 'org-drill-leech-failure-threshold 'safe-local-variable 'integerp)
-(put 'org-drill-leech-method 'safe-local-variable
- '(lambda (val) (memq val '(nil skip warn))))
-(put 'org-drill-use-visible-cloze-face-p 'safe-local-variable 'booleanp)
-(put 'org-drill-hide-item-headings-p 'safe-local-variable 'booleanp)
-(put 'org-drill-spaced-repetition-algorithm 'safe-local-variable
- '(lambda (val) (memq val '(simple8 sm5 sm2))))
-(put 'org-drill-sm5-initial-interval 'safe-local-variable 'floatp)
-(put 'org-drill-add-random-noise-to-intervals-p 'safe-local-variable 'booleanp)
-(put 'org-drill-adjust-intervals-for-early-and-late-repetitions-p
- 'safe-local-variable 'booleanp)
-(put 'org-drill-cram-hours 'safe-local-variable 'integerp)
-(put 'org-drill-learn-fraction 'safe-local-variable 'floatp)
-(put 'org-drill-days-before-old 'safe-local-variable 'integerp)
-(put 'org-drill-overdue-interval-factor 'safe-local-variable 'floatp)
-(put 'org-drill-scope 'safe-local-variable
- '(lambda (val) (or (symbolp val) (listp val))))
-(put 'org-drill-match 'safe-local-variable
- '(lambda (val) (or (stringp val) (null val))))
-(put 'org-drill-save-buffers-after-drill-sessions-p 'safe-local-variable 'booleanp)
-(put 'org-drill-cloze-text-weight 'safe-local-variable
- '(lambda (val) (or (null val) (integerp val))))
-(put 'org-drill-left-cloze-delimiter 'safe-local-variable 'stringp)
-(put 'org-drill-right-cloze-delimiter 'safe-local-variable 'stringp)
-
-
-;;;; Utilities ================================================================
-
-
-(defun free-marker (m)
- (set-marker m nil))
-
-
-(defmacro pop-random (place)
- (let ((idx (cl-gensym)))
- `(if (null ,place)
- nil
- (let ((,idx (random* (length ,place))))
- (prog1 (nth ,idx ,place)
- (setq ,place (append (subseq ,place 0 ,idx)
- (subseq ,place (1+ ,idx)))))))))
-
-
-(defmacro push-end (val place)
- "Add VAL to the end of the sequence stored in PLACE. Return the new
-value."
- `(setq ,place (append ,place (list ,val))))
-
-
-(defun shuffle-list (list)
- "Randomly permute the elements of LIST (all permutations equally likely)."
- ;; Adapted from 'shuffle-vector' in cookie1.el
- (let ((i 0)
- j
- temp
- (len (length list)))
- (while (< i len)
- (setq j (+ i (random* (- len i))))
- (setq temp (nth i list))
- (setf (nth i list) (nth j list))
- (setf (nth j list) temp)
- (setq i (1+ i))))
- list)
-
-
-(defun round-float (floatnum fix)
- "Round the floating point number FLOATNUM to FIX decimal places.
-Example: (round-float 3.56755765 3) -> 3.568"
- (let ((n (expt 10 fix)))
- (/ (float (round (* floatnum n))) n)))
-
-
-(defun command-keybinding-to-string (cmd)
- "Return a human-readable description of the key/keys to which the command
-CMD is bound, or nil if it is not bound to a key."
- (let ((key (where-is-internal cmd overriding-local-map t)))
- (if key (key-description key))))
-
-
-(defun time-to-inactive-org-timestamp (time)
- (format-time-string
- (concat "[" (substring (cdr org-time-stamp-formats) 1 -1) "]")
- time))
-
-
-(defun time-to-active-org-timestamp (time)
- (format-time-string
- (concat "<" (substring (cdr org-time-stamp-formats) 1 -1) ">")
- time))
-
-
-(defun org-map-drill-entries (func &optional scope drill-match &rest skip)
- "Like `org-map-entries', but only drill entries are processed."
- (let ((org-drill-scope (or scope org-drill-scope))
- (org-drill-match (or drill-match org-drill-match)))
- (apply 'org-map-entries func
- (concat "+" org-drill-question-tag
- (if (and (stringp org-drill-match)
- (not (member '(?+ ?- ?|) (elt org-drill-match 0))))
- "+" "")
- (or org-drill-match ""))
- (case org-drill-scope
- (file nil)
- (file-no-restriction 'file)
- (directory
- (directory-files (file-name-directory (buffer-file-name))
- t "\\.org$"))
- (t org-drill-scope))
- skip)))
-
-
-(defmacro with-hidden-cloze-text (&rest body)
- `(progn
- (org-drill-hide-clozed-text)
- (unwind-protect
- (progn
- ,@body)
- (org-drill-unhide-clozed-text))))
-
-
-(defmacro with-hidden-cloze-hints (&rest body)
- `(progn
- (org-drill-hide-cloze-hints)
- (unwind-protect
- (progn
- ,@body)
- (org-drill-unhide-text))))
-
-
-(defmacro with-hidden-comments (&rest body)
- `(progn
- (if org-drill-hide-item-headings-p
- (org-drill-hide-heading-at-point))
- (org-drill-hide-comments)
- (unwind-protect
- (progn
- ,@body)
- (org-drill-unhide-text))))
-
-
-(defun org-drill-days-since-last-review ()
- "Nil means a last review date has not yet been stored for
-the item.
-Zero means it was reviewed today.
-A positive number means it was reviewed that many days ago.
-A negative number means the date of last review is in the future --
-this should never happen."
- (let ((datestr (org-entry-get (point) "DRILL_LAST_REVIEWED")))
- (when datestr
- (- (time-to-days (current-time))
- (time-to-days (apply 'encode-time
- (org-parse-time-string datestr)))))))
-
-
-(defun org-drill-hours-since-last-review ()
- "Like `org-drill-days-since-last-review', but return value is
-in hours rather than days."
- (let ((datestr (org-entry-get (point) "DRILL_LAST_REVIEWED")))
- (when datestr
- (floor
- (/ (- (time-to-seconds (current-time))
- (time-to-seconds (apply 'encode-time
- (org-parse-time-string datestr))))
- (* 60 60))))))
-
-
-(defun org-drill-entry-p (&optional marker)
- "Is MARKER, or the point, in a 'drill item'? This will return nil if
-the point is inside a subheading of a drill item -- to handle that
-situation use `org-part-of-drill-entry-p'."
- (save-excursion
- (when marker
- (org-drill-goto-entry marker))
- (member org-drill-question-tag (org-get-tags nil t))))
-
-
-(defun org-drill-goto-entry (marker)
- (switch-to-buffer (marker-buffer marker))
- (goto-char marker))
-
-
-(defun org-part-of-drill-entry-p ()
- "Is the current entry either the main heading of a 'drill item',
-or a subheading within a drill item?"
- (or (org-drill-entry-p)
- ;; Does this heading INHERIT the drill tag
- (member org-drill-question-tag (org-get-tags))))
-
-
-(defun org-drill-goto-drill-entry-heading ()
- "Move the point to the heading which holds the :drill: tag for this
-drill entry."
- (unless (org-at-heading-p)
- (org-back-to-heading))
- (unless (org-part-of-drill-entry-p)
- (error "Point is not inside a drill entry"))
- (while (not (org-drill-entry-p))
- (unless (org-up-heading-safe)
- (error "Cannot find a parent heading that is marked as a drill entry"))))
-
-
-
-(defun org-drill-entry-leech-p ()
- "Is the current entry a 'leech item'?"
- (and (org-drill-entry-p)
- (member "leech" (org-get-tags nil t))))
-
-
-;; (defun org-drill-entry-due-p ()
-;; (cond
-;; (*org-drill-cram-mode*
-;; (let ((hours (org-drill-hours-since-last-review)))
-;; (and (org-drill-entry-p)
-;; (or (null hours)
-;; (>= hours org-drill-cram-hours)))))
-;; (t
-;; (let ((item-time (org-get-scheduled-time (point))))
-;; (and (org-drill-entry-p)
-;; (or (not (eql 'skip org-drill-leech-method))
-;; (not (org-drill-entry-leech-p)))
-;; (or (null item-time) ; not scheduled
-;; (not (minusp ; scheduled for today/in past
-;; (- (time-to-days (current-time))
-;; (time-to-days item-time))))))))))
-
-
-(defun org-drill-entry-days-overdue ()
- "Returns:
-- NIL if the item is not to be regarded as scheduled for review at all.
- This is the case if it is not a drill item, or if it is a leech item
- that we wish to skip, or if we are in cram mode and have already reviewed
- the item within the last few hours.
-- 0 if the item is new, or if it scheduled for review today.
-- A negative integer - item is scheduled that many days in the future.
-- A positive integer - item is scheduled that many days in the past."
- (cond
- (*org-drill-cram-mode*
- (let ((hours (org-drill-hours-since-last-review)))
- (and (org-drill-entry-p)
- (or (null hours)
- (>= hours org-drill-cram-hours))
- 0)))
- (t
- (let ((item-time (org-get-scheduled-time (point))))
- (cond
- ((or (not (org-drill-entry-p))
- (and (eql 'skip org-drill-leech-method)
- (org-drill-entry-leech-p)))
- nil)
- ((null item-time) ; not scheduled -> due now
- 0)
- (t
- (- (time-to-days (current-time))
- (time-to-days item-time))))))))
-
-
-(defun org-drill-entry-overdue-p (&optional days-overdue last-interval)
- "Returns true if entry that is scheduled DAYS-OVERDUE dasy in the past,
-and whose last inter-repetition interval was LAST-INTERVAL, should be
-considered 'overdue'. If the arguments are not given they are extracted
-from the entry at point."
- (unless days-overdue
- (setq days-overdue (org-drill-entry-days-overdue)))
- (unless last-interval
- (setq last-interval (org-drill-entry-last-interval 1)))
- (and (numberp days-overdue)
- (> days-overdue 1) ; enforce a sane minimum 'overdue' gap
- ;;(> due org-drill-days-before-overdue)
- (> (/ (+ days-overdue last-interval 1.0) last-interval)
- org-drill-overdue-interval-factor)))
-
-
-
-(defun org-drill-entry-due-p ()
- (let ((due (org-drill-entry-days-overdue)))
- (and (not (null due))
- (not (minusp due)))))
-
-
-(defun org-drill-entry-new-p ()
- (and (org-drill-entry-p)
- (let ((item-time (org-get-scheduled-time (point))))
- (null item-time))))
-
-
-(defun org-drill-entry-last-quality (&optional default)
- (let ((quality (org-entry-get (point) "DRILL_LAST_QUALITY")))
- (if quality
- (string-to-number quality)
- default)))
-
-
-(defun org-drill-entry-failure-count ()
- (let ((quality (org-entry-get (point) "DRILL_FAILURE_COUNT")))
- (if quality
- (string-to-number quality)
- 0)))
-
-
-(defun org-drill-entry-average-quality (&optional default)
- (let ((val (org-entry-get (point) "DRILL_AVERAGE_QUALITY")))
- (if val
- (string-to-number val)
- (or default nil))))
-
-(defun org-drill-entry-last-interval (&optional default)
- (let ((val (org-entry-get (point) "DRILL_LAST_INTERVAL")))
- (if val
- (string-to-number val)
- (or default 0))))
-
-(defun org-drill-entry-repeats-since-fail (&optional default)
- (let ((val (org-entry-get (point) "DRILL_REPEATS_SINCE_FAIL")))
- (if val
- (string-to-number val)
- (or default 0))))
-
-(defun org-drill-entry-total-repeats (&optional default)
- (let ((val (org-entry-get (point) "DRILL_TOTAL_REPEATS")))
- (if val
- (string-to-number val)
- (or default 0))))
-
-(defun org-drill-entry-ease (&optional default)
- (let ((val (org-entry-get (point) "DRILL_EASE")))
- (if val
- (string-to-number val)
- default)))
-
-
-;;; From http://www.supermemo.com/english/ol/sm5.htm
-(defun org-drill-random-dispersal-factor ()
- "Returns a random number between 0.5 and 1.5."
- (let ((a 0.047)
- (b 0.092)
- (p (- (random* 1.0) 0.5)))
- (cl-flet ((sign (n)
- (cond ((zerop n) 0)
- ((plusp n) 1)
- (t -1))))
- (/ (+ 100 (* (* (/ -1 b) (log (- 1 (* (/ b a ) (abs p)))))
- (sign p)))
- 100.0))))
-
-(defun pseudonormal (mean variation)
- "Random numbers in a pseudo-normal distribution with mean MEAN, range
- MEAN-VARIATION to MEAN+VARIATION"
- (+ (random* variation)
- (random* variation)
- (- variation)
- mean))
-
-
-(defun org-drill-early-interval-factor (optimal-factor
- optimal-interval
- days-ahead)
- "Arguments:
-- OPTIMAL-FACTOR: interval-factor if the item had been tested
-exactly when it was supposed to be.
-- OPTIMAL-INTERVAL: interval for next repetition (days) if the item had been
-tested exactly when it was supposed to be.
-- DAYS-AHEAD: how many days ahead of time the item was reviewed.
-
-Returns an adjusted optimal factor which should be used to
-calculate the next interval, instead of the optimal factor found
-in the matrix."
- (let ((delta-ofmax (* (1- optimal-factor)
- (/ (+ optimal-interval
- (* 0.6 optimal-interval) -1) (1- optimal-interval)))))
- (- optimal-factor
- (* delta-ofmax (/ days-ahead (+ days-ahead (* 0.6 optimal-interval)))))))
-
-
-(defun org-drill-get-item-data ()
- "Returns a list of 6 items, containing all the stored recall
- data for the item at point:
-- LAST-INTERVAL is the interval in days that was used to schedule the item's
- current review date.
-- REPEATS is the number of items the item has been successfully recalled without
- without any failures. It is reset to 0 upon failure to recall the item.
-- FAILURES is the total number of times the user has failed to recall the item.
-- TOTAL-REPEATS includes both successful and unsuccessful repetitions.
-- AVERAGE-QUALITY is the mean quality of recall of the item over
- all its repetitions, successful and unsuccessful.
-- EASE is a number reflecting how easy the item is to learn. Higher is easier.
-"
- (let ((learn-str (org-entry-get (point) "LEARN_DATA"))
- (repeats (org-drill-entry-total-repeats :missing)))
- (cond
- (learn-str
- (let ((learn-data (or (and learn-str
- (read learn-str))
- (copy-sequence initial-repetition-state))))
- (list (nth 0 learn-data) ; last interval
- (nth 1 learn-data) ; repetitions
- (org-drill-entry-failure-count)
- (nth 1 learn-data)
- (org-drill-entry-last-quality)
- (nth 2 learn-data) ; EF
- )))
- ((not (eql :missing repeats))
- (list (org-drill-entry-last-interval)
- (org-drill-entry-repeats-since-fail)
- (org-drill-entry-failure-count)
- (org-drill-entry-total-repeats)
- (org-drill-entry-average-quality)
- (org-drill-entry-ease)))
- (t ; virgin item
- (list 0 0 0 0 nil nil)))))
-
-
-(defun org-drill-store-item-data (last-interval repeats failures
- total-repeats meanq
- ease)
- "Stores the given data in the item at point."
- (org-entry-delete (point) "LEARN_DATA")
- (org-set-property "DRILL_LAST_INTERVAL"
- (number-to-string (round-float last-interval 4)))
- (org-set-property "DRILL_REPEATS_SINCE_FAIL" (number-to-string repeats))
- (org-set-property "DRILL_TOTAL_REPEATS" (number-to-string total-repeats))
- (org-set-property "DRILL_FAILURE_COUNT" (number-to-string failures))
- (org-set-property "DRILL_AVERAGE_QUALITY"
- (number-to-string (round-float meanq 3)))
- (org-set-property "DRILL_EASE"
- (number-to-string (round-float ease 3))))
-
-
-
-;;; SM2 Algorithm =============================================================
-
-
-(defun determine-next-interval-sm2 (last-interval n ef quality
- failures meanq total-repeats)
- "Arguments:
-- LAST-INTERVAL -- the number of days since the item was last reviewed.
-- REPEATS -- the number of times the item has been successfully reviewed
-- EF -- the 'easiness factor'
-- QUALITY -- 0 to 5
-
-Returns a list: (INTERVAL REPEATS EF FAILURES MEAN TOTAL-REPEATS OFMATRIX), where:
-- INTERVAL is the number of days until the item should next be reviewed
-- REPEATS is incremented by 1.
-- EF is modified based on the recall quality for the item.
-- OF-MATRIX is not modified."
- (assert (> n 0))
- (assert (and (>= quality 0) (<= quality 5)))
- (if (<= quality org-drill-failure-quality)
- ;; When an item is failed, its interval is reset to 0,
- ;; but its EF is unchanged
- (list -1 1 ef (1+ failures) meanq (1+ total-repeats)
- org-drill-sm5-optimal-factor-matrix)
- ;; else:
- (let* ((next-ef (modify-e-factor ef quality))
- (interval
- (cond
- ((<= n 1) 1)
- ((= n 2)
- (cond
- (org-drill-add-random-noise-to-intervals-p
- (case quality
- (5 6)
- (4 4)
- (3 3)
- (2 1)
- (t -1)))
- (t 6)))
- (t (* last-interval next-ef)))))
- (list (if org-drill-add-random-noise-to-intervals-p
- (+ last-interval (* (- interval last-interval)
- (org-drill-random-dispersal-factor)))
- interval)
- (1+ n)
- next-ef
- failures meanq (1+ total-repeats)
- org-drill-sm5-optimal-factor-matrix))))
-
-
-;;; SM5 Algorithm =============================================================
-
-
-
-(defun initial-optimal-factor-sm5 (n ef)
- (if (= 1 n)
- org-drill-sm5-initial-interval
- ef))
-
-(defun get-optimal-factor-sm5 (n ef of-matrix)
- (let ((factors (assoc n of-matrix)))
- (or (and factors
- (let ((ef-of (assoc ef (cdr factors))))
- (and ef-of (cdr ef-of))))
- (initial-optimal-factor-sm5 n ef))))
-
-
-(defun inter-repetition-interval-sm5 (last-interval n ef &optional of-matrix)
- (let ((of (get-optimal-factor-sm5 n ef (or of-matrix
- org-drill-sm5-optimal-factor-matrix))))
- (if (= 1 n)
- of
- (* of last-interval))))
-
-
-(defun determine-next-interval-sm5 (last-interval n ef quality
- failures meanq total-repeats
- of-matrix &optional delta-days)
- (if (zerop n) (setq n 1))
- (if (null ef) (setq ef 2.5))
- (assert (> n 0))
- (assert (and (>= quality 0) (<= quality 5)))
- (unless of-matrix
- (setq of-matrix org-drill-sm5-optimal-factor-matrix))
- (setq of-matrix (cl-copy-tree of-matrix))
-
- (setq meanq (if meanq
- (/ (+ quality (* meanq total-repeats 1.0))
- (1+ total-repeats))
- quality))
-
- (let ((next-ef (modify-e-factor ef quality))
- (old-ef ef)
- (new-of (modify-of (get-optimal-factor-sm5 n ef of-matrix)
- quality org-drill-learn-fraction))
- (interval nil))
- (when (and org-drill-adjust-intervals-for-early-and-late-repetitions-p
- delta-days (minusp delta-days))
- (setq new-of (org-drill-early-interval-factor
- (get-optimal-factor-sm5 n ef of-matrix)
- (inter-repetition-interval-sm5
- last-interval n ef of-matrix)
- delta-days)))
-
- (setq of-matrix
- (set-optimal-factor n next-ef of-matrix
- (round-float new-of 3))) ; round OF to 3 d.p.
-
- (setq ef next-ef)
-
- (cond
- ;; "Failed" -- reset repetitions to 0,
- ((<= quality org-drill-failure-quality)
- (list -1 1 old-ef (1+ failures) meanq (1+ total-repeats)
- of-matrix)) ; Not clear if OF matrix is supposed to be
- ; preserved
- ;; For a zero-based quality of 4 or 5, don't repeat
- ;; ((and (>= quality 4)
- ;; (not org-learn-always-reschedule))
- ;; (list 0 (1+ n) ef failures meanq
- ;; (1+ total-repeats) of-matrix)) ; 0 interval = unschedule
- (t
- (setq interval (inter-repetition-interval-sm5
- last-interval n ef of-matrix))
- (if org-drill-add-random-noise-to-intervals-p
- (setq interval (* interval (org-drill-random-dispersal-factor))))
- (list interval
- (1+ n)
- ef
- failures
- meanq
- (1+ total-repeats)
- of-matrix)))))
-
-
-;;; Simple8 Algorithm =========================================================
-
-
-(defun org-drill-simple8-first-interval (failures)
- "Arguments:
-- FAILURES: integer >= 0. The total number of times the item has
- been forgotten, ever.
-
-Returns the optimal FIRST interval for an item which has previously been
-forgotten on FAILURES occasions."
- (* 2.4849 (exp (* -0.057 failures))))
-
-
-(defun org-drill-simple8-interval-factor (ease repetition)
- "Arguments:
-- EASE: floating point number >= 1.2. Corresponds to `AF' in SM8 algorithm.
-- REPETITION: the number of times the item has been tested.
-1 is the first repetition (ie the second trial).
-Returns:
-The factor by which the last interval should be
-multiplied to give the next interval. Corresponds to `RF' or `OF'."
- (+ 1.2 (* (- ease 1.2) (expt org-drill-learn-fraction (log repetition 2)))))
-
-
-(defun org-drill-simple8-quality->ease (quality)
- "Returns the ease (`AF' in the SM8 algorithm) which corresponds
-to a mean item quality of QUALITY."
- (+ (* 0.0542 (expt quality 4))
- (* -0.4848 (expt quality 3))
- (* 1.4916 (expt quality 2))
- (* -1.2403 quality)
- 1.4515))
-
-
-(defun determine-next-interval-simple8 (last-interval repeats quality
- failures meanq totaln
- &optional delta-days)
- "Arguments:
-- LAST-INTERVAL -- the number of days since the item was last reviewed.
-- REPEATS -- the number of times the item has been successfully reviewed
-- EASE -- the 'easiness factor'
-- QUALITY -- 0 to 5
-- DELTA-DAYS -- how many days overdue was the item when it was reviewed.
- 0 = reviewed on the scheduled day. +N = N days overdue.
- -N = reviewed N days early.
-
-Returns the new item data, as a list of 6 values:
-- NEXT-INTERVAL
-- REPEATS
-- EASE
-- FAILURES
-- AVERAGE-QUALITY
-- TOTAL-REPEATS.
-See the documentation for `org-drill-get-item-data' for a description of these."
- (assert (>= repeats 0))
- (assert (and (>= quality 0) (<= quality 5)))
- (assert (or (null meanq) (and (>= meanq 0) (<= meanq 5))))
- (let ((next-interval nil))
- (setf meanq (if meanq
- (/ (+ quality (* meanq totaln 1.0)) (1+ totaln))
- quality))
- (cond
- ((<= quality org-drill-failure-quality)
- (incf failures)
- (setf repeats 0
- next-interval -1))
- ((or (zerop repeats)
- (zerop last-interval))
- (setf next-interval (org-drill-simple8-first-interval failures))
- (incf repeats)
- (incf totaln))
- (t
- (let* ((use-n
- (if (and
- org-drill-adjust-intervals-for-early-and-late-repetitions-p
- (numberp delta-days) (plusp delta-days)
- (plusp last-interval))
- (+ repeats (min 1 (/ delta-days last-interval 1.0)))
- repeats))
- (factor (org-drill-simple8-interval-factor
- (org-drill-simple8-quality->ease meanq) use-n))
- (next-int (* last-interval factor)))
- (when (and org-drill-adjust-intervals-for-early-and-late-repetitions-p
- (numberp delta-days) (minusp delta-days))
- ;; The item was reviewed earlier than scheduled.
- (setf factor (org-drill-early-interval-factor
- factor next-int (abs delta-days))
- next-int (* last-interval factor)))
- (setf next-interval next-int)
- (incf repeats)
- (incf totaln))))
- (list
- (if (and org-drill-add-random-noise-to-intervals-p
- (plusp next-interval))
- (* next-interval (org-drill-random-dispersal-factor))
- next-interval)
- repeats
- (org-drill-simple8-quality->ease meanq)
- failures
- meanq
- totaln
- )))
-
-
-
-
-;;; Essentially copied from `org-learn.el', but modified to
-;;; optionally call the SM2 or simple8 functions.
-(defun org-drill-smart-reschedule (quality &optional days-ahead)
- "If DAYS-AHEAD is supplied it must be a positive integer. The
-item will be scheduled exactly this many days into the future."
- (let ((delta-days (- (time-to-days (current-time))
- (time-to-days (or (org-get-scheduled-time (point))
- (current-time)))))
- (ofmatrix org-drill-sm5-optimal-factor-matrix)
- ;; Entries can have weights, 1 by default. Intervals are divided by the
- ;; item's weight, so an item with a weight of 2 will have all intervals
- ;; halved, meaning you will end up reviewing it twice as often.
- ;; Useful for entries which randomly present any of several facts.
- (weight (org-entry-get (point) "DRILL_CARD_WEIGHT")))
- (if (stringp weight)
- (setq weight (read weight)))
- (destructuring-bind (last-interval repetitions failures
- total-repeats meanq ease)
- (org-drill-get-item-data)
- (destructuring-bind (next-interval repetitions ease
- failures meanq total-repeats
- &optional new-ofmatrix)
- (case org-drill-spaced-repetition-algorithm
- (sm5 (determine-next-interval-sm5 last-interval repetitions
- ease quality failures
- meanq total-repeats ofmatrix))
- (sm2 (determine-next-interval-sm2 last-interval repetitions
- ease quality failures
- meanq total-repeats))
- (simple8 (determine-next-interval-simple8 last-interval repetitions
- quality failures meanq
- total-repeats
- delta-days)))
- (if (numberp days-ahead)
- (setq next-interval days-ahead))
-
- (if (and (null days-ahead)
- (numberp weight) (plusp weight)
- (not (minusp next-interval)))
- (setq next-interval
- (max 1.0 (+ last-interval
- (/ (- next-interval last-interval) weight)))))
-
- (org-drill-store-item-data next-interval repetitions failures
- total-repeats meanq ease)
-
- (if (eql 'sm5 org-drill-spaced-repetition-algorithm)
- (setq org-drill-sm5-optimal-factor-matrix new-ofmatrix))
-
- (cond
- ((= 0 days-ahead)
- (org-schedule '(4)))
- ((minusp days-ahead)
- (org-schedule nil (current-time)))
- (t
- (org-schedule nil (time-add (current-time)
- (days-to-time
- (round next-interval))))))))))
-
-
-(defun org-drill-hypothetical-next-review-date (quality)
- "Returns an integer representing the number of days into the future
-that the current item would be scheduled, based on a recall quality
-of QUALITY."
- (let ((weight (org-entry-get (point) "DRILL_CARD_WEIGHT")))
- (destructuring-bind (last-interval repetitions failures
- total-repeats meanq ease)
- (org-drill-get-item-data)
- (if (stringp weight)
- (setq weight (read weight)))
- (destructuring-bind (next-interval repetitions ease
- failures meanq total-repeats
- &optional ofmatrix)
- (case org-drill-spaced-repetition-algorithm
- (sm5 (determine-next-interval-sm5 last-interval repetitions
- ease quality failures
- meanq total-repeats
- org-drill-sm5-optimal-factor-matrix))
- (sm2 (determine-next-interval-sm2 last-interval repetitions
- ease quality failures
- meanq total-repeats))
- (simple8 (determine-next-interval-simple8 last-interval repetitions
- quality failures meanq
- total-repeats)))
- (cond
- ((not (plusp next-interval))
- 0)
- ((and (numberp weight) (plusp weight))
- (+ last-interval
- (max 1.0 (/ (- next-interval last-interval) weight))))
- (t
- next-interval))))))
-
-
-(defun org-drill-hypothetical-next-review-dates ()
- (let ((intervals nil))
- (dotimes (q 6)
- (push (max (or (car intervals) 0)
- (org-drill-hypothetical-next-review-date q))
- intervals))
- (reverse intervals)))
-
-
-(defun org-drill-reschedule ()
- "Returns quality rating (0-5), or nil if the user quit."
- (let ((ch nil)
- (input nil)
- (next-review-dates (org-drill-hypothetical-next-review-dates))
- (key-prompt (format "(0-5, %c=help, %c=pronounce, %c=edit, %c=tags, %c=quit)"
- org-drill--help-key
- org-drill--pronounce-key
- org-drill--edit-key
- org-drill--tags-key
- org-drill--quit-key)))
- (save-excursion
- (while (not (memq ch (list org-drill--quit-key
- org-drill--edit-key
- 7 ; C-g
- ?0 ?1 ?2 ?3 ?4 ?5)))
- (setq input (read-key-sequence
- (if (eq ch org-drill--help-key)
- (format "0-2 Means you have forgotten the item.
-3-5 Means you have remembered the item.
-
-0 - Completely forgot.
-1 - Even after seeing the answer, it still took a bit to sink in.
-2 - After seeing the answer, you remembered it.
-3 - It took you awhile, but you finally remembered. (+%s days)
-4 - After a little bit of thought you remembered. (+%s days)
-5 - You remembered the item really easily. (+%s days)
-
-How well did you do? %s"
- (round (nth 3 next-review-dates))
- (round (nth 4 next-review-dates))
- (round (nth 5 next-review-dates))
- key-prompt)
- (format "How well did you do? %s" key-prompt))
- (when (eq ch org-drill--pronounce-key)
- (org-drill-pronounce-word))))
- (cond
- ((stringp input)
- (setq ch (elt input 0)))
- ((and (vectorp input) (symbolp (elt input 0)))
- (case (elt input 0)
- (up (ignore-errors (forward-line -1)))
- (down (ignore-errors (forward-line 1)))
- (left (ignore-errors (backward-char)))
- (right (ignore-errors (forward-char)))
- (prior (ignore-errors (scroll-down))) ; pgup
- (next (ignore-errors (scroll-up))))) ; pgdn
- ((and (vectorp input) (listp (elt input 0))
- (eventp (elt input 0)))
- (case (car (elt input 0))
- (wheel-up (ignore-errors (mwheel-scroll (elt input 0))))
- (wheel-down (ignore-errors (mwheel-scroll (elt input 0)))))))
- (if (eql ch org-drill--tags-key)
- (org-set-tags-command))))
- (cond
- ((and (>= ch ?0) (<= ch ?5))
- (let ((quality (- ch ?0))
- (failures (org-drill-entry-failure-count)))
- (unless *org-drill-cram-mode*
- (save-excursion
- (let ((quality (if (org-drill--entry-lapsed-p) 2 quality)))
- (org-drill-smart-reschedule quality
- (nth quality next-review-dates))))
- (push quality *org-drill-session-qualities*)
- (cond
- ((<= quality org-drill-failure-quality)
- (when org-drill-leech-failure-threshold
- ;;(setq failures (if failures (string-to-number failures) 0))
- ;; (org-set-property "DRILL_FAILURE_COUNT"
- ;; (format "%d" (1+ failures)))
- (if (> (1+ failures) org-drill-leech-failure-threshold)
- (org-toggle-tag "leech" 'on))))
- (t
- (let ((scheduled-time (org-get-scheduled-time (point))))
- (when scheduled-time
- (message "Next review in %d days"
- (- (time-to-days scheduled-time)
- (time-to-days (current-time))))
- (sit-for 0.5)))))
- (org-set-property "DRILL_LAST_QUALITY" (format "%d" quality))
- (org-set-property "DRILL_LAST_REVIEWED"
- (time-to-inactive-org-timestamp (current-time))))
- quality))
- ((= ch org-drill--edit-key)
- 'edit)
- (t
- nil))))
-
-
-;; (defun org-drill-hide-all-subheadings-except (heading-list)
-;; "Returns a list containing the position of each immediate subheading of
-;; the current topic."
-;; (let ((drill-entry-level (org-current-level))
-;; (drill-sections nil)
-;; (drill-heading nil))
-;; (org-show-subtree)
-;; (save-excursion
-;; (org-map-entries
-;; (lambda ()
-;; (when (and (not (org-invisible-p))
-;; (> (org-current-level) drill-entry-level))
-;; (setq drill-heading (org-get-heading t))
-;; (unless (and (= (org-current-level) (1+ drill-entry-level))
-;; (member drill-heading heading-list))
-;; (hide-subtree))
-;; (push (point) drill-sections)))
-;; "" 'tree))
-;; (reverse drill-sections)))
-
-
-
-(defun org-drill-hide-subheadings-if (test)
- "TEST is a function taking no arguments. TEST will be called for each
-of the immediate subheadings of the current drill item, with the point
-on the relevant subheading. TEST should return nil if the subheading is
-to be revealed, non-nil if it is to be hidden.
-Returns a list containing the position of each immediate subheading of
-the current topic."
- (let ((drill-entry-level (org-current-level))
- (drill-sections nil))
- (org-show-subtree)
- (save-excursion
- (org-map-entries
- (lambda ()
- (when (and (not (org-invisible-p))
- (> (org-current-level) drill-entry-level))
- (when (or (/= (org-current-level) (1+ drill-entry-level))
- (funcall test))
- (hide-subtree))
- (push (point) drill-sections)))
- nil 'tree))
- (reverse drill-sections)))
-
-
-(defun org-drill-hide-all-subheadings-except (heading-list)
- (org-drill-hide-subheadings-if
- (lambda () (let ((drill-heading (org-get-heading t)))
- (not (member drill-heading heading-list))))))
-
-
-(defun org-drill-presentation-prompt (&rest fmt-and-args)
- (let* ((item-start-time (current-time))
- (input nil)
- (ch nil)
- (last-second 0)
- (mature-entry-count (+ (length *org-drill-young-mature-entries*)
- (length *org-drill-old-mature-entries*)
- (length *org-drill-overdue-entries*)))
- (status (first (org-drill-entry-status)))
- (prompt
- (if fmt-and-args
- (apply 'format
- (first fmt-and-args)
- (rest fmt-and-args))
- (format (concat "Press key for answer, "
- "%c=pronounce, %c=edit, %c=tags, %c=skip, %c=quit.")
- org-drill--pronounce-key
- org-drill--edit-key
- org-drill--tags-key
- org-drill--skip-key
- org-drill--quit-key))))
- (setq prompt
- (format "%s %s %s %s %s %s"
- (propertize
- (char-to-string
- (cond
- ((eql status :failed) ?F)
- (*org-drill-cram-mode* ?C)
- (t
- (case status
- (:new ?N) (:young ?Y) (:old ?o) (:overdue ?!)
- (t ??)))))
- 'face `(:foreground
- ,(case status
- (:new org-drill-new-count-color)
- ((:young :old) org-drill-mature-count-color)
- ((:overdue :failed) org-drill-failed-count-color)
- (t org-drill-done-count-color))))
- (propertize
- (number-to-string (length *org-drill-done-entries*))
- 'face `(:foreground ,org-drill-done-count-color)
- 'help-echo "The number of items you have reviewed this session.")
- (propertize
- (number-to-string (+ (length *org-drill-again-entries*)
- (length *org-drill-failed-entries*)))
- 'face `(:foreground ,org-drill-failed-count-color)
- 'help-echo (concat "The number of items that you failed, "
- "and need to review again."))
- (propertize
- (number-to-string mature-entry-count)
- 'face `(:foreground ,org-drill-mature-count-color)
- 'help-echo "The number of old items due for review.")
- (propertize
- (number-to-string (length *org-drill-new-entries*))
- 'face `(:foreground ,org-drill-new-count-color)
- 'help-echo (concat "The number of new items that you "
- "have never reviewed."))
- prompt))
- (if (and (eql 'warn org-drill-leech-method)
- (org-drill-entry-leech-p))
- (setq prompt (concat
- (propertize "!!! LEECH ITEM !!!
-You seem to be having a lot of trouble memorising this item.
-Consider reformulating the item to make it easier to remember.\n"
- 'face '(:foreground "red"))
- prompt)))
- (while (memq ch '(nil org-drill--tags-key org-drill--pronounce-key))
- (setq ch nil)
- (while (not (input-pending-p))
- (let ((elapsed (time-subtract (current-time) item-start-time)))
- (message (concat (if (>= (time-to-seconds elapsed) (* 60 60))
- "++:++ "
- (format-time-string "%M:%S " elapsed))
- prompt))
- (sit-for 1)))
- (setq input (read-key-sequence nil))
- (if (stringp input) (setq ch (elt input 0)))
- (if (eql ch org-drill--tags-key)
- (org-set-tags-command))
- (when (eq ch org-drill--pronounce-key)
- (org-drill-pronounce-word)))
- (case ch
- (org-drill--quit-key nil)
- (org-drill--edit-key 'edit)
- (org-drill--skip-key 'skip)
- (otherwise t))))
-
-
-(defun org-pos-in-regexp (pos regexp &optional nlines)
- (save-excursion
- (goto-char pos)
- (org-in-regexp regexp nlines)))
-
-
-(defun org-drill-hide-region (beg end &optional text)
- "Hide the buffer region between BEG and END with an 'invisible text'
-visual overlay, or with the string TEXT if it is supplied."
- (let ((ovl (make-overlay beg end)))
- (overlay-put ovl 'category
- 'org-drill-hidden-text-overlay)
- (overlay-put ovl 'priority 9999)
- (when (stringp text)
- (overlay-put ovl 'invisible nil)
- (overlay-put ovl 'face 'default)
- (overlay-put ovl 'display text))))
-
-
-(defun org-drill-hide-heading-at-point (&optional text)
- (unless (org-at-heading-p)
- (error "Point is not on a heading."))
- (save-excursion
- (let ((beg (point)))
- (end-of-line)
- (org-drill-hide-region beg (point) text))))
-
-
-(defun org-drill-hide-comments ()
- (save-excursion
- (while (re-search-forward "^#.*$" nil t)
- (org-drill-hide-region (match-beginning 0) (match-end 0)))))
-
-
-(defun org-drill-unhide-text ()
- ;; This will also unhide the item's heading.
- (save-excursion
- (dolist (ovl (overlays-in (point-min) (point-max)))
- (when (eql 'org-drill-hidden-text-overlay (overlay-get ovl 'category))
- (delete-overlay ovl)))))
-
-
-(defun org-drill-hide-clozed-text ()
- (save-excursion
- (while (re-search-forward org-drill-cloze-regexp nil t)
- ;; Don't hide:
- ;; - org links, partly because they might contain inline
- ;; images which we want to keep visible.
- ;; - LaTeX math fragments
- ;; - the contents of SRC blocks
- (unless (save-match-data
- (or (org-pos-in-regexp (match-beginning 0)
- org-bracket-link-regexp 1)
- (org-in-src-block-p)
- (org-inside-LaTeX-fragment-p)))
- (org-drill-hide-matched-cloze-text)))))
-
-
-(defun org-drill-hide-matched-cloze-text ()
- "Hide the current match with a 'cloze' visual overlay."
- (let ((ovl (make-overlay (match-beginning 0) (match-end 0)))
- (hint-sep-pos (string-match-p (regexp-quote org-drill-hint-separator)
- (match-string 0))))
- (overlay-put ovl 'category
- 'org-drill-cloze-overlay-defaults)
- (overlay-put ovl 'priority 9999)
- (when (and hint-sep-pos
- (> hint-sep-pos 1))
- (let ((hint (substring-no-properties
- (match-string 0)
- (+ hint-sep-pos (length org-drill-hint-separator))
- (1- (length (match-string 0))))))
- (overlay-put
- ovl 'display
- ;; If hint is like `X...' then display [X...]
- ;; otherwise display [...X]
- (format (if (string-match-p (regexp-quote "...") hint) "[%s]" "[%s...]")
- hint))))))
-
-
-(defun org-drill-hide-cloze-hints ()
- (save-excursion
- (while (re-search-forward org-drill-cloze-regexp nil t)
- (unless (or (save-match-data
- (org-pos-in-regexp (match-beginning 0)
- org-bracket-link-regexp 1))
- (null (match-beginning 2))) ; hint subexpression matched
- (org-drill-hide-region (match-beginning 2) (match-end 2))))))
-
-
-(defmacro with-replaced-entry-text (text &rest body)
- "During the execution of BODY, the entire text of the current entry is
-concealed by an overlay that displays the string TEXT."
- `(progn
- (org-drill-replace-entry-text ,text)
- (unwind-protect
- (progn
- ,@body)
- (org-drill-unreplace-entry-text))))
-
-
-(defmacro with-replaced-entry-text-multi (replacements &rest body)
- "During the execution of BODY, the entire text of the current entry is
-concealed by an overlay that displays the overlays in REPLACEMENTS."
- `(progn
- (org-drill-replace-entry-text ,replacements t)
- (unwind-protect
- (progn
- ,@body)
- (org-drill-unreplace-entry-text))))
-
-
-(defun org-drill-replace-entry-text (text &optional multi-p)
- "Make an overlay that conceals the entire text of the item, not
-including properties or the contents of subheadings. The overlay shows
-the string TEXT.
-If MULTI-P is non-nil, TEXT must be a list of values which are legal
-for the `display' text property. The text of the item will be temporarily
-replaced by all of these items, in the order in which they appear in
-the list.
-Note: does not actually alter the item."
- (cond
- ((and multi-p
- (listp text))
- (org-drill-replace-entry-text-multi text))
- (t
- (let ((ovl (make-overlay (point-min)
- (save-excursion
- (outline-next-heading)
- (point)))))
- (overlay-put ovl 'priority 9999)
- (overlay-put ovl 'category
- 'org-drill-replaced-text-overlay)
- (overlay-put ovl 'display text)))))
-
-
-(defun org-drill-unreplace-entry-text ()
- (save-excursion
- (dolist (ovl (overlays-in (point-min) (point-max)))
- (when (eql 'org-drill-replaced-text-overlay (overlay-get ovl 'category))
- (delete-overlay ovl)))))
-
-
-(defun org-drill-replace-entry-text-multi (replacements)
- "Make overlays that conceal the entire text of the item, not
-including properties or the contents of subheadings. The overlay shows
-the string TEXT.
-Note: does not actually alter the item."
- (let ((ovl nil)
- (p-min (point-min))
- (p-max (save-excursion
- (outline-next-heading)
- (point))))
- (assert (>= (- p-max p-min) (length replacements)))
- (dotimes (i (length replacements))
- (setq ovl (make-overlay (+ p-min (* 2 i))
- (if (= i (1- (length replacements)))
- p-max
- (+ p-min (* 2 i) 1))))
- (overlay-put ovl 'priority 9999)
- (overlay-put ovl 'category
- 'org-drill-replaced-text-overlay)
- (overlay-put ovl 'display (nth i replacements)))))
-
-
-(defmacro with-replaced-entry-heading (heading &rest body)
- `(progn
- (org-drill-replace-entry-heading ,heading)
- (unwind-protect
- (progn
- ,@body)
- (org-drill-unhide-text))))
-
-
-(defun org-drill-replace-entry-heading (heading)
- "Make an overlay that conceals the heading of the item. The overlay shows
-the string TEXT.
-Note: does not actually alter the item."
- (org-drill-hide-heading-at-point heading))
-
-
-(defun org-drill-unhide-clozed-text ()
- (save-excursion
- (dolist (ovl (overlays-in (point-min) (point-max)))
- (when (eql 'org-drill-cloze-overlay-defaults (overlay-get ovl 'category))
- (delete-overlay ovl)))))
-
-
-(defun org-drill-get-entry-text (&optional keep-properties-p)
- (let ((text (org-agenda-get-some-entry-text (point-marker) 100)))
- (if keep-properties-p
- text
- (substring-no-properties text))))
-
-
-;; (defun org-entry-empty-p ()
-;; (zerop (length (org-drill-get-entry-text))))
-
-;; This version is about 5x faster than the old version, above.
-(defun org-entry-empty-p ()
- (save-excursion
- (org-back-to-heading t)
- (let ((lim (save-excursion
- (outline-next-heading) (point))))
- (if (fboundp 'org-end-of-meta-data-and-drawers)
- (org-end-of-meta-data-and-drawers) ; function removed Feb 2015
- (org-end-of-meta-data t))
- (or (>= (point) lim)
- (null (re-search-forward "[[:graph:]]" lim t))))))
-
-(defun org-drill-entry-empty-p () (org-entry-empty-p))
-
-
-;;; Presentation functions ====================================================
-;;
-;; Each of these is called with point on topic heading. Each needs to show the
-;; topic in the form of a 'question' or with some information 'hidden', as
-;; appropriate for the card type. The user should then be prompted to press a
-;; key. The function should then reveal either the 'answer' or the entire
-;; topic, and should return t if the user chose to see the answer and rate their
-;; recall, nil if they chose to quit.
-
-
-(defun org-drill-present-simple-card ()
- (with-hidden-comments
- (with-hidden-cloze-hints
- (with-hidden-cloze-text
- (org-drill-hide-all-subheadings-except nil)
- (org-drill--show-latex-fragments) ; overlay all LaTeX fragments with images
- (ignore-errors
- (org-display-inline-images t))
- (org-cycle-hide-drawers 'all)
- (prog1 (org-drill-presentation-prompt)
- (org-drill-hide-subheadings-if 'org-drill-entry-p))))))
-
-
-(defun org-drill-present-default-answer (reschedule-fn)
- (cond
- (drill-answer
- (with-replaced-entry-text
- (format "\nAnswer:\n\n %s\n" drill-answer)
- (prog1
- (funcall reschedule-fn)
- (setq drill-answer nil))))
- (t
- (org-drill-hide-subheadings-if 'org-drill-entry-p)
- (org-drill-unhide-clozed-text)
- (org-drill--show-latex-fragments)
- (ignore-errors
- (org-display-inline-images t))
- (org-cycle-hide-drawers 'all)
- (with-hidden-cloze-hints
- (funcall reschedule-fn)))))
-
-
-(defun org-drill--show-latex-fragments ()
- (org-remove-latex-fragment-image-overlays)
- (if (fboundp 'org-toggle-latex-fragment)
- (org-toggle-latex-fragment '(4))
- (org-preview-latex-fragment '(4))))
-
-
-(defun org-drill-present-two-sided-card ()
- (with-hidden-comments
- (with-hidden-cloze-hints
- (with-hidden-cloze-text
- (let ((drill-sections (org-drill-hide-all-subheadings-except nil)))
- (when drill-sections
- (save-excursion
- (goto-char (nth (random* (min 2 (length drill-sections)))
- drill-sections))
- (org-show-subtree)))
- (org-drill--show-latex-fragments)
- (ignore-errors
- (org-display-inline-images t))
- (org-cycle-hide-drawers 'all)
- (prog1 (org-drill-presentation-prompt)
- (org-drill-hide-subheadings-if 'org-drill-entry-p)))))))
-
-
-
-(defun org-drill-present-multi-sided-card ()
- (with-hidden-comments
- (with-hidden-cloze-hints
- (with-hidden-cloze-text
- (let ((drill-sections (org-drill-hide-all-subheadings-except nil)))
- (when drill-sections
- (save-excursion
- (goto-char (nth (random* (length drill-sections)) drill-sections))
- (org-show-subtree)))
- (org-drill--show-latex-fragments)
- (ignore-errors
- (org-display-inline-images t))
- (org-cycle-hide-drawers 'all)
- (prog1 (org-drill-presentation-prompt)
- (org-drill-hide-subheadings-if 'org-drill-entry-p)))))))
-
-
-(defun org-drill-present-multicloze-hide-n (number-to-hide
- &optional
- force-show-first
- force-show-last
- force-hide-first)
- "Hides NUMBER-TO-HIDE pieces of text that are marked for cloze deletion,
-chosen at random.
-If NUMBER-TO-HIDE is negative, show only (ABS NUMBER-TO-HIDE) pieces,
-hiding all the rest.
-If FORCE-HIDE-FIRST is non-nil, force the first piece of text to be one of
-the hidden items.
-If FORCE-SHOW-FIRST is non-nil, never hide the first piece of text.
-If FORCE-SHOW-LAST is non-nil, never hide the last piece of text.
-If the number of text pieces in the item is less than
-NUMBER-TO-HIDE, then all text pieces will be hidden (except the first or last
-items if FORCE-SHOW-FIRST or FORCE-SHOW-LAST is non-nil)."
- (with-hidden-comments
- (with-hidden-cloze-hints
- (let ((item-end nil)
- (match-count 0)
- (body-start (or (cdr (org-get-property-block))
- (point))))
- (if (and force-hide-first force-show-first)
- (error "FORCE-HIDE-FIRST and FORCE-SHOW-FIRST are mutually exclusive"))
- (org-drill-hide-all-subheadings-except nil)
- (save-excursion
- (outline-next-heading)
- (setq item-end (point)))
- (save-excursion
- (goto-char body-start)
- (while (re-search-forward org-drill-cloze-regexp item-end t)
- (let ((in-regexp? (save-match-data
- (org-pos-in-regexp (match-beginning 0)
- org-bracket-link-regexp 1))))
- (unless (or in-regexp?
- (org-inside-LaTeX-fragment-p))
- (incf match-count)))))
- (if (minusp number-to-hide)
- (setq number-to-hide (+ match-count number-to-hide)))
- (when (plusp match-count)
- (let* ((positions (shuffle-list (loop for i from 1
- to match-count
- collect i)))
- (match-nums nil)
- (cnt nil))
- (if force-hide-first
- ;; Force '1' to be in the list, and to be the first item
- ;; in the list.
- (setq positions (cons 1 (remove 1 positions))))
- (if force-show-first
- (setq positions (remove 1 positions)))
- (if force-show-last
- (setq positions (remove match-count positions)))
- (setq match-nums
- (subseq positions
- 0 (min number-to-hide (length positions))))
- ;; (dolist (pos-to-hide match-nums)
- (save-excursion
- (goto-char body-start)
- (setq cnt 0)
- (while (re-search-forward org-drill-cloze-regexp item-end t)
- (unless (save-match-data
- (or (org-pos-in-regexp (match-beginning 0)
- org-bracket-link-regexp 1)
- (org-inside-LaTeX-fragment-p)))
- (incf cnt)
- (if (memq cnt match-nums)
- (org-drill-hide-matched-cloze-text)))))))
- ;; (loop
- ;; do (re-search-forward org-drill-cloze-regexp
- ;; item-end t pos-to-hide)
- ;; while (org-pos-in-regexp (match-beginning 0)
- ;; org-bracket-link-regexp 1))
- ;; (org-drill-hide-matched-cloze-text)))))
- (org-drill--show-latex-fragments)
- (ignore-errors
- (org-display-inline-images t))
- (org-cycle-hide-drawers 'all)
- (prog1 (org-drill-presentation-prompt)
- (org-drill-hide-subheadings-if 'org-drill-entry-p)
- (org-drill-unhide-clozed-text))))))
-
-
-(defun org-drill-present-multicloze-hide-nth (to-hide)
- "Hide the TO-HIDE'th piece of clozed text. 1 is the first piece. If
-TO-HIDE is negative, count backwards, so -1 means the last item, -2
-the second to last, etc."
- (with-hidden-comments
- (with-hidden-cloze-hints
- (let ((item-end nil)
- (match-count 0)
- (body-start (or (cdr (org-get-property-block))
- (point)))
- (cnt 0))
- (org-drill-hide-all-subheadings-except nil)
- (save-excursion
- (outline-next-heading)
- (setq item-end (point)))
- (save-excursion
- (goto-char body-start)
- (while (re-search-forward org-drill-cloze-regexp item-end t)
- (let ((in-regexp? (save-match-data
- (org-pos-in-regexp (match-beginning 0)
- org-bracket-link-regexp 1))))
- (unless (or in-regexp?
- (org-inside-LaTeX-fragment-p))
- (incf match-count)))))
- (if (minusp to-hide)
- (setq to-hide (+ 1 to-hide match-count)))
- (cond
- ((or (not (plusp match-count))
- (> to-hide match-count))
- nil)
- (t
- (save-excursion
- (goto-char body-start)
- (setq cnt 0)
- (while (re-search-forward org-drill-cloze-regexp item-end t)
- (unless (save-match-data
- ;; Don't consider this a cloze region if it is part of an
- ;; org link, or if it occurs inside a LaTeX math
- ;; fragment
- (or (org-pos-in-regexp (match-beginning 0)
- org-bracket-link-regexp 1)
- (org-inside-LaTeX-fragment-p)))
- (incf cnt)
- (if (= cnt to-hide)
- (org-drill-hide-matched-cloze-text)))))))
- (org-drill--show-latex-fragments)
- (ignore-errors
- (org-display-inline-images t))
- (org-cycle-hide-drawers 'all)
- (prog1 (org-drill-presentation-prompt)
- (org-drill-hide-subheadings-if 'org-drill-entry-p)
- (org-drill-unhide-clozed-text))))))
-
-
-(defun org-drill-present-multicloze-hide1 ()
- "Hides one of the pieces of text that are marked for cloze deletion,
-chosen at random."
- (org-drill-present-multicloze-hide-n 1))
-
-
-(defun org-drill-present-multicloze-hide2 ()
- "Hides two of the pieces of text that are marked for cloze deletion,
-chosen at random."
- (org-drill-present-multicloze-hide-n 2))
-
-
-(defun org-drill-present-multicloze-hide-first ()
- "Hides the first piece of text that is marked for cloze deletion."
- (org-drill-present-multicloze-hide-nth 1))
-
-
-(defun org-drill-present-multicloze-hide-last ()
- "Hides the last piece of text that is marked for cloze deletion."
- (org-drill-present-multicloze-hide-nth -1))
-
-
-(defun org-drill-present-multicloze-hide1-firstmore ()
- "Commonly, hides the FIRST piece of text that is marked for
-cloze deletion. Uncommonly, hide one of the other pieces of text,
-chosen at random.
-
-The definitions of 'commonly' and 'uncommonly' are determined by
-the value of `org-drill-cloze-text-weight'."
- ;; The 'firstmore' and 'lastmore' functions used to randomly choose whether
- ;; to hide the 'favoured' piece of text. However even when the chance of
- ;; hiding it was set quite high (80%), the outcome was too unpredictable over
- ;; the small number of repetitions where most learning takes place for each
- ;; item. In other words, the actual frequency during the first 10 repetitions
- ;; was often very different from 80%. Hence we use modulo instead.
- (cond
- ((null org-drill-cloze-text-weight)
- ;; Behave as hide1cloze
- (org-drill-present-multicloze-hide1))
- ((not (and (integerp org-drill-cloze-text-weight)
- (plusp org-drill-cloze-text-weight)))
- (error "Illegal value for org-drill-cloze-text-weight: %S"
- org-drill-cloze-text-weight))
- ((zerop (mod (1+ (org-drill-entry-total-repeats 0))
- org-drill-cloze-text-weight))
- ;; Uncommonly, hide any item except the first
- (org-drill-present-multicloze-hide-n 1 t))
- (t
- ;; Commonly, hide first item
- (org-drill-present-multicloze-hide-first))))
-
-
-(defun org-drill-present-multicloze-show1-lastmore ()
- "Commonly, hides all pieces except the last. Uncommonly, shows
-any random piece. The effect is similar to 'show1cloze' except
-that the last item is much less likely to be the item that is
-visible.
-
-The definitions of 'commonly' and 'uncommonly' are determined by
-the value of `org-drill-cloze-text-weight'."
- (cond
- ((null org-drill-cloze-text-weight)
- ;; Behave as show1cloze
- (org-drill-present-multicloze-show1))
- ((not (and (integerp org-drill-cloze-text-weight)
- (plusp org-drill-cloze-text-weight)))
- (error "Illegal value for org-drill-cloze-text-weight: %S"
- org-drill-cloze-text-weight))
- ((zerop (mod (1+ (org-drill-entry-total-repeats 0))
- org-drill-cloze-text-weight))
- ;; Uncommonly, show any item except the last
- (org-drill-present-multicloze-hide-n -1 nil nil t))
- (t
- ;; Commonly, show the LAST item
- (org-drill-present-multicloze-hide-n -1 nil t))))
-
-
-(defun org-drill-present-multicloze-show1-firstless ()
- "Commonly, hides all pieces except one, where the shown piece
-is guaranteed NOT to be the first piece. Uncommonly, shows any
-random piece. The effect is similar to 'show1cloze' except that
-the first item is much less likely to be the item that is
-visible.
-
-The definitions of 'commonly' and 'uncommonly' are determined by
-the value of `org-drill-cloze-text-weight'."
- (cond
- ((null org-drill-cloze-text-weight)
- ;; Behave as show1cloze
- (org-drill-present-multicloze-show1))
- ((not (and (integerp org-drill-cloze-text-weight)
- (plusp org-drill-cloze-text-weight)))
- (error "Illegal value for org-drill-cloze-text-weight: %S"
- org-drill-cloze-text-weight))
- ((zerop (mod (1+ (org-drill-entry-total-repeats 0))
- org-drill-cloze-text-weight))
- ;; Uncommonly, show the first item
- (org-drill-present-multicloze-hide-n -1 t))
- (t
- ;; Commonly, show any item, except the first
- (org-drill-present-multicloze-hide-n -1 nil nil t))))
-
-
-(defun org-drill-present-multicloze-show1 ()
- "Similar to `org-drill-present-multicloze-hide1', but hides all
-the pieces of text that are marked for cloze deletion, except for one
-piece which is chosen at random."
- (org-drill-present-multicloze-hide-n -1))
-
-
-(defun org-drill-present-multicloze-show2 ()
- "Similar to `org-drill-present-multicloze-show1', but reveals two
-pieces rather than one."
- (org-drill-present-multicloze-hide-n -2))
-
-
-(defun org-drill-present-card-using-text (question &optional answer)
- "Present the string QUESTION as the only visible content of the card.
-If ANSWER is supplied, set the global variable `drill-answer' to its value."
- (if answer (setq drill-answer answer))
- (with-hidden-comments
- (with-replaced-entry-text
- (concat "\n" question)
- (org-drill-hide-all-subheadings-except nil)
- (org-cycle-hide-drawers 'all)
- (ignore-errors
- (org-display-inline-images t))
- (prog1 (org-drill-presentation-prompt)
- (org-drill-hide-subheadings-if 'org-drill-entry-p)))))
-
-
-(defun org-drill-present-card-using-multiple-overlays (replacements &optional answer)
- "TEXTS is a list of valid values for the 'display' text property.
-Present these overlays, in sequence, as the only
-visible content of the card.
-If ANSWER is supplied, set the global variable `drill-answer' to its value."
- (if answer (setq drill-answer answer))
- (with-hidden-comments
- (with-replaced-entry-text-multi
- replacements
- (org-drill-hide-all-subheadings-except nil)
- (org-cycle-hide-drawers 'all)
- (ignore-errors
- (org-display-inline-images t))
- (prog1 (org-drill-presentation-prompt)
- (org-drill-hide-subheadings-if 'org-drill-entry-p)))))
-
-(defun org-drill-pronounce-word ()
- "Pronounce word after querying."
- (interactive)
- (start-process-shell-command
- "org-drill pronounce"
- nil
- (concat org-drill-pronounce-command
- " " org-drill-pronounce-command-args " "
- (shell-quote-argument
- (substring-no-properties (org-get-heading t t t t))))))
-
-(defun org-drill-entry ()
- "Present the current topic for interactive review, as in `org-drill'.
-Review will occur regardless of whether the topic is due for review or whether
-it meets the definition of a 'review topic' used by `org-drill'.
-
-Returns a quality rating from 0 to 5, or nil if the user quit, or the symbol
-EDIT if the user chose to exit the drill and edit the current item. Choosing
-the latter option leaves the drill session suspended; it can be resumed
-later using `org-drill-resume'.
-
-See `org-drill' for more details."
- (interactive)
- (org-drill-goto-drill-entry-heading)
- ;;(unless (org-part-of-drill-entry-p)
- ;; (error "Point is not inside a drill entry"))
- ;;(unless (org-at-heading-p)
- ;; (org-back-to-heading))
- (let ((card-type (org-entry-get (point) "DRILL_CARD_TYPE" t))
- (answer-fn 'org-drill-present-default-answer)
- (present-empty-cards nil)
- (cont nil)
- ;; fontification functions in `outline-view-change-hook' can cause big
- ;; slowdowns, so we temporarily bind this variable to nil here.
- (outline-view-change-hook nil))
- (setq drill-answer nil)
- (org-save-outline-visibility t
- (save-restriction
- (org-narrow-to-subtree)
- (org-show-subtree)
- (org-cycle-hide-drawers 'all)
-
- (let ((presentation-fn
- (cdr (assoc card-type org-drill-card-type-alist))))
- (if (listp presentation-fn)
- (psetq answer-fn (or (second presentation-fn)
- 'org-drill-present-default-answer)
- present-empty-cards (third presentation-fn)
- presentation-fn (first presentation-fn)))
- (when org-drill-auto-pronounce (org-drill-pronounce-word))
- (run-hook-with-args 'org-drill-entry-before-hook)
- (prog1
- (cond
- ((null presentation-fn)
- (message "%s:%d: Unrecognised card type '%s', skipping..."
- (buffer-name) (point) card-type)
- (sit-for 0.5)
- 'skip)
- (t
- (setq cont (funcall presentation-fn))
- (cond
- ((not cont)
- (message "Quit")
- nil)
- ((eql cont 'edit)
- 'edit)
- ((eql cont 'skip)
- 'skip)
- (t
- (save-excursion
- (funcall answer-fn
- (lambda () (org-drill-reschedule))))))))
- (run-hook-with-args 'org-drill-entry-after-hook)
- (org-remove-latex-fragment-image-overlays)))))))
-
-
-(defun org-drill-entries-pending-p ()
- (or *org-drill-again-entries*
- *org-drill-current-item*
- (and (not (org-drill-maximum-item-count-reached-p))
- (not (org-drill-maximum-duration-reached-p))
- (or *org-drill-new-entries*
- *org-drill-failed-entries*
- *org-drill-young-mature-entries*
- *org-drill-old-mature-entries*
- *org-drill-overdue-entries*
- *org-drill-again-entries*))))
-
-
-(defun org-drill-pending-entry-count ()
- (+ (if (markerp *org-drill-current-item*) 1 0)
- (length *org-drill-new-entries*)
- (length *org-drill-failed-entries*)
- (length *org-drill-young-mature-entries*)
- (length *org-drill-old-mature-entries*)
- (length *org-drill-overdue-entries*)
- (length *org-drill-again-entries*)))
-
-
-(defun org-drill-maximum-duration-reached-p ()
- "Returns true if the current drill session has continued past its
-maximum duration."
- (and org-drill-maximum-duration
- (not *org-drill-cram-mode*)
- *org-drill-start-time*
- (> (- (float-time (current-time)) *org-drill-start-time*)
- (* org-drill-maximum-duration 60))))
-
-
-(defun org-drill-maximum-item-count-reached-p ()
- "Returns true if the current drill session has reached the
-maximum number of items."
- (and org-drill-maximum-items-per-session
- (not *org-drill-cram-mode*)
- (>= (length *org-drill-done-entries*)
- org-drill-maximum-items-per-session)))
-
-
-(defun org-drill-pop-next-pending-entry ()
- (block org-drill-pop-next-pending-entry
- (let ((m nil))
- (while (or (null m)
- (not (org-drill-entry-p m)))
- (setq
- m
- (cond
- ;; First priority is items we failed in a prior session.
- ((and *org-drill-failed-entries*
- (not (org-drill-maximum-item-count-reached-p))
- (not (org-drill-maximum-duration-reached-p)))
- (pop-random *org-drill-failed-entries*))
- ;; Next priority is overdue items.
- ((and *org-drill-overdue-entries*
- (not (org-drill-maximum-item-count-reached-p))
- (not (org-drill-maximum-duration-reached-p)))
- ;; We use `pop', not `pop-random', because we have already
- ;; sorted overdue items into a random order which takes
- ;; number of days overdue into account.
- (pop *org-drill-overdue-entries*))
- ;; Next priority is 'young' items.
- ((and *org-drill-young-mature-entries*
- (not (org-drill-maximum-item-count-reached-p))
- (not (org-drill-maximum-duration-reached-p)))
- (pop-random *org-drill-young-mature-entries*))
- ;; Next priority is newly added items, and older entries.
- ;; We pool these into a single group.
- ((and (or *org-drill-new-entries*
- *org-drill-old-mature-entries*)
- (not (org-drill-maximum-item-count-reached-p))
- (not (org-drill-maximum-duration-reached-p)))
- (cond
- ((< (random* (+ (length *org-drill-new-entries*)
- (length *org-drill-old-mature-entries*)))
- (length *org-drill-new-entries*))
- (pop-random *org-drill-new-entries*))
- (t
- (pop-random *org-drill-old-mature-entries*))))
- ;; After all the above are done, last priority is items
- ;; that were failed earlier THIS SESSION.
- (*org-drill-again-entries*
- (pop *org-drill-again-entries*))
- (t ; nothing left -- return nil
- (return-from org-drill-pop-next-pending-entry nil)))))
- m)))
-
-
-(defun org-drill-entries (&optional resuming-p)
- "Returns nil, t, or a list of markers representing entries that were
-'failed' and need to be presented again before the session ends.
-
-RESUMING-P is true if we are resuming a suspended drill session."
- (block org-drill-entries
- (while (org-drill-entries-pending-p)
- (let ((m (cond
- ((or (not resuming-p)
- (null *org-drill-current-item*)
- (not (org-drill-entry-p *org-drill-current-item*)))
- (org-drill-pop-next-pending-entry))
- (t ; resuming a suspended session.
- (setq resuming-p nil)
- *org-drill-current-item*))))
- (setq *org-drill-current-item* m)
- (unless m
- (error "Unexpectedly ran out of pending drill items"))
- (save-excursion
- (org-drill-goto-entry m)
- (cond
- ((not (org-drill-entry-due-p))
- ;; The entry is not due anymore. This could arise if the user
- ;; suspends a drill session, then drills an individual entry,
- ;; then resumes the session.
- (message "Entry no longer due, skipping...")
- (sit-for 0.3)
- nil)
- (t
- (setq result (org-drill-entry))
- (cond
- ((null result)
- (message "Quit")
- (setq end-pos :quit)
- (return-from org-drill-entries nil))
- ((eql result 'edit)
- (setq end-pos (point-marker))
- (return-from org-drill-entries nil))
- ((eql result 'skip)
- (setq *org-drill-current-item* nil)
- nil) ; skip this item
- (t
- (cond
- ((<= result org-drill-failure-quality)
- (if *org-drill-again-entries*
- (setq *org-drill-again-entries*
- (shuffle-list *org-drill-again-entries*)))
- (push-end m *org-drill-again-entries*))
- (t
- (push m *org-drill-done-entries*)))
- (setq *org-drill-current-item* nil))))))))))
-
-
-
-(defun org-drill-final-report ()
- (let ((pass-percent
- (round (* 100 (count-if (lambda (qual)
- (> qual org-drill-failure-quality))
- *org-drill-session-qualities*))
- (max 1 (length *org-drill-session-qualities*))))
- (prompt nil)
- (max-mini-window-height 0.6))
- (setq prompt
- (format
- "%d items reviewed. Session duration %s.
-Recall of reviewed items:
- Excellent (5): %3d%% | Near miss (2): %3d%%
- Good (4): %3d%% | Failure (1): %3d%%
- Hard (3): %3d%% | Abject failure (0): %3d%%
-
-You successfully recalled %d%% of reviewed items (quality > %s)
-%d/%d items still await review (%s, %s, %s, %s, %s).
-Tomorrow, %d more items will become due for review.
-Session finished. Press a key to continue..."
- (length *org-drill-done-entries*)
- (format-seconds "%h:%.2m:%.2s"
- (- (float-time (current-time)) *org-drill-start-time*))
- (round (* 100 (count 5 *org-drill-session-qualities*))
- (max 1 (length *org-drill-session-qualities*)))
- (round (* 100 (count 2 *org-drill-session-qualities*))
- (max 1 (length *org-drill-session-qualities*)))
- (round (* 100 (count 4 *org-drill-session-qualities*))
- (max 1 (length *org-drill-session-qualities*)))
- (round (* 100 (count 1 *org-drill-session-qualities*))
- (max 1 (length *org-drill-session-qualities*)))
- (round (* 100 (count 3 *org-drill-session-qualities*))
- (max 1 (length *org-drill-session-qualities*)))
- (round (* 100 (count 0 *org-drill-session-qualities*))
- (max 1 (length *org-drill-session-qualities*)))
- pass-percent
- org-drill-failure-quality
- (org-drill-pending-entry-count)
- (+ (org-drill-pending-entry-count)
- *org-drill-dormant-entry-count*)
- (propertize
- (format "%d failed"
- (+ (length *org-drill-failed-entries*)
- (length *org-drill-again-entries*)))
- 'face `(:foreground ,org-drill-failed-count-color))
- (propertize
- (format "%d overdue"
- (length *org-drill-overdue-entries*))
- 'face `(:foreground ,org-drill-failed-count-color))
- (propertize
- (format "%d new"
- (length *org-drill-new-entries*))
- 'face `(:foreground ,org-drill-new-count-color))
- (propertize
- (format "%d young"
- (length *org-drill-young-mature-entries*))
- 'face `(:foreground ,org-drill-mature-count-color))
- (propertize
- (format "%d old"
- (length *org-drill-old-mature-entries*))
- 'face `(:foreground ,org-drill-mature-count-color))
- *org-drill-due-tomorrow-count*
- ))
-
- (while (not (input-pending-p))
- (message "%s" prompt)
- (sit-for 0.5))
- (read-char-exclusive)
-
- (if (and *org-drill-session-qualities*
- (< pass-percent (- 100 org-drill-forgetting-index)))
- (read-char-exclusive
- (format
- "%s
-You failed %d%% of the items you reviewed during this session.
-%d (%d%%) of all items scanned were overdue.
-
-Are you keeping up with your items, and reviewing them
-when they are scheduled? If so, you may want to consider
-lowering the value of `org-drill-learn-fraction' slightly in
-order to make items appear more frequently over time."
- (propertize "WARNING!" 'face 'org-warning)
- (- 100 pass-percent)
- *org-drill-overdue-entry-count*
- (round (* 100 *org-drill-overdue-entry-count*)
- (+ *org-drill-dormant-entry-count*
- *org-drill-due-entry-count*)))
- ))))
-
-
-
-(defun org-drill-free-markers (markers)
- "MARKERS is a list of markers, all of which will be freed (set to
-point nowhere). Alternatively, MARKERS can be 't', in which case
-all the markers used by Org-Drill will be freed."
- (dolist (m (if (eql t markers)
- (append *org-drill-done-entries*
- *org-drill-new-entries*
- *org-drill-failed-entries*
- *org-drill-again-entries*
- *org-drill-overdue-entries*
- *org-drill-young-mature-entries*
- *org-drill-old-mature-entries*)
- markers))
- (free-marker m)))
-
-
-;;; overdue-data is a list of entries, each entry has the form (POS DUE AGE)
-;;; where POS is a marker pointing to the start of the entry, and
-;;; DUE is a number indicating how many days ago the entry was due.
-;;; AGE is the number of days elapsed since item creation (nil if unknown).
-;;; if age > lapse threshold (default 90), sort by age (oldest first)
-;;; if age < lapse threshold, sort by due (biggest first)
-
-
-(defun org-drill-order-overdue-entries (overdue-data)
- (let* ((lapsed-days (if org-drill--lapse-very-overdue-entries-p
- 90 most-positive-fixnum))
- (not-lapsed (remove-if (lambda (a) (> (or (second a) 0) lapsed-days))
- overdue-data))
- (lapsed (remove-if-not (lambda (a) (> (or (second a) 0)
- lapsed-days)) overdue-data)))
- (setq *org-drill-overdue-entries*
- (mapcar 'first
- (append
- (sort (shuffle-list not-lapsed)
- (lambda (a b) (> (second a) (second b))))
- (sort lapsed
- (lambda (a b) (> (third a) (third b)))))))))
-
-
-(defun org-drill--entry-lapsed-p ()
- (let ((lapsed-days 90))
- (and org-drill--lapse-very-overdue-entries-p
- (> (or (org-drill-entry-days-overdue) 0) lapsed-days))))
-
-
-
-
-(defun org-drill-entry-days-since-creation (&optional use-last-interval-p)
- "If USE-LAST-INTERVAL-P is non-nil, and DATE_ADDED is missing, use the
-value of DRILL_LAST_INTERVAL instead (as the item's age must be at least
-that many days)."
- (let ((timestamp (org-entry-get (point) "DATE_ADDED")))
- (cond
- (timestamp
- (- (org-time-stamp-to-now timestamp)))
- (use-last-interval-p
- (+ (or (org-drill-entry-days-overdue) 0)
- (read (or (org-entry-get (point) "DRILL_LAST_INTERVAL") "0"))))
- (t nil))))
-
-
-(defun org-drill-entry-status ()
- "Returns a list (STATUS DUE AGE) where DUE is the number of days overdue,
-zero being due today, -1 being scheduled 1 day in the future.
-AGE is the number of days elapsed since the item was created (nil if unknown).
-STATUS is one of the following values:
-- nil, if the item is not a drill entry, or has an empty body
-- :unscheduled
-- :future
-- :new
-- :failed
-- :overdue
-- :young
-- :old
-"
- (save-excursion
- (unless (org-at-heading-p)
- (org-back-to-heading))
- (let ((due (org-drill-entry-days-overdue))
- (age (org-drill-entry-days-since-creation t))
- (last-int (org-drill-entry-last-interval 1)))
- (list
- (cond
- ((not (org-drill-entry-p))
- nil)
- ((and (org-entry-empty-p)
- (let* ((card-type (org-entry-get (point) "DRILL_CARD_TYPE" nil))
- (dat (cdr (assoc card-type org-drill-card-type-alist))))
- (or (null card-type)
- (not (third dat)))))
- ;; body is empty, and this is not a card type where empty bodies are
- ;; meaningful, so skip it.
- nil)
- ((null due) ; unscheduled - usually a skipped leech
- :unscheduled)
- ;; ((eql -1 due)
- ;; :tomorrow)
- ((minusp due) ; scheduled in the future
- :future)
- ;; The rest of the stati all denote 'due' items ==========================
- ((<= (org-drill-entry-last-quality 9999)
- org-drill-failure-quality)
- ;; Mature entries that were failed last time are
- ;; FAILED, regardless of how young, old or overdue
- ;; they are.
- :failed)
- ((org-drill-entry-new-p)
- :new)
- ((org-drill-entry-overdue-p due last-int)
- ;; Overdue status overrides young versus old
- ;; distinction.
- ;; Store marker + due, for sorting of overdue entries
- :overdue)
- ((<= (org-drill-entry-last-interval 9999)
- org-drill-days-before-old)
- :young)
- (t
- :old))
- due age))))
-
-
-(defun org-drill-progress-message (collected scanned)
- (when (zerop (% scanned 50))
- (let* ((meter-width 40)
- (sym1 (if (oddp (floor scanned (* 50 meter-width))) ?| ?.))
- (sym2 (if (eql sym1 ?.) ?| ?.)))
- (message "Collecting due drill items:%4d %s%s"
- collected
- (make-string (% (ceiling scanned 50) meter-width)
- sym2)
- (make-string (- meter-width (% (ceiling scanned 50) meter-width))
- sym1)))))
-
-
-(defun org-map-drill-entry-function ()
- (org-drill-progress-message
- (+ (length *org-drill-new-entries*)
- (length *org-drill-overdue-entries*)
- (length *org-drill-young-mature-entries*)
- (length *org-drill-old-mature-entries*)
- (length *org-drill-failed-entries*))
- (incf cnt))
- (cond
- ((not (org-drill-entry-p))
- nil) ; skip
- (t
- (when (and (not warned-about-id-creation)
- (null (org-id-get)))
- (message (concat "Creating unique IDs for items "
- "(slow, but only happens once)"))
- (sit-for 0.5)
- (setq warned-about-id-creation t))
- (org-id-get-create) ; ensure drill entry has unique ID
- (destructuring-bind (status due age)
- (org-drill-entry-status)
- (case status
- (:unscheduled
- (incf *org-drill-dormant-entry-count*))
- ;; (:tomorrow
- ;; (incf *org-drill-dormant-entry-count*)
- ;; (incf *org-drill-due-tomorrow-count*))
- (:future
- (incf *org-drill-dormant-entry-count*)
- (if (eq -1 due)
- (incf *org-drill-due-tomorrow-count*)))
- (:new
- (push (point-marker) *org-drill-new-entries*))
- (:failed
- (push (point-marker) *org-drill-failed-entries*))
- (:young
- (push (point-marker) *org-drill-young-mature-entries*))
- (:overdue
- (push (list (point-marker) due age) overdue-data))
- (:old
- (push (point-marker) *org-drill-old-mature-entries*))
- )))))
-
-
-(defun org-drill (&optional scope drill-match resume-p)
- "Begin an interactive 'drill session'. The user is asked to
-review a series of topics (headers). Each topic is initially
-presented as a 'question', often with part of the topic content
-hidden. The user attempts to recall the hidden information or
-answer the question, then presses a key to reveal the answer. The
-user then rates his or her recall or performance on that
-topic. This rating information is used to reschedule the topic
-for future review.
-
-Org-drill proceeds by:
-
-- Finding all topics (headings) in SCOPE which have either been
- used and rescheduled before, or which have a tag that matches
- `org-drill-question-tag'.
-
-- All matching topics which are either unscheduled, or are
- scheduled for the current date or a date in the past, are
- considered to be candidates for the drill session.
-
-- If `org-drill-maximum-items-per-session' is set, a random
- subset of these topics is presented. Otherwise, all of the
- eligible topics will be presented.
-
-SCOPE determines the scope in which to search for
-questions. It accepts the same values as `org-drill-scope',
-which see.
-
-DRILL-MATCH, if supplied, is a string specifying a tags/property/
-todo query. Only items matching the query will be considered.
-It accepts the same values as `org-drill-match', which see.
-
-If RESUME-P is non-nil, resume a suspended drill session rather
-than starting a new one."
-
- (interactive)
- ;; Check org version. Org 7.9.3f introduced a backwards-incompatible change
- ;; to the arguments accepted by `org-schedule'. At the time of writing there
- ;; are still lots of people using versions of org older than this.
- (let ((majorv (first (mapcar 'string-to-number (split-string (org-release) "[.]")))))
- (if (and (< majorv 8)
- (not (string-match-p "universal prefix argument" (documentation 'org-schedule))))
- (read-char-exclusive
- (format "Warning: org-drill requires org mode 7.9.3f or newer. Scheduling of failed cards will not
-work correctly with older versions of org mode. Your org mode version (%s) appears to be older than
-7.9.3f. Please consider installing a more recent version of org mode." (org-release)))))
- (let ((end-pos nil)
- (overdue-data nil)
- (cnt 0))
- (block org-drill
- (unless resume-p
- (org-drill-free-markers t)
- (setq *org-drill-current-item* nil
- *org-drill-done-entries* nil
- *org-drill-dormant-entry-count* 0
- *org-drill-due-entry-count* 0
- *org-drill-due-tomorrow-count* 0
- *org-drill-overdue-entry-count* 0
- *org-drill-new-entries* nil
- *org-drill-overdue-entries* nil
- *org-drill-young-mature-entries* nil
- *org-drill-old-mature-entries* nil
- *org-drill-failed-entries* nil
- *org-drill-again-entries* nil)
- (setq *org-drill-session-qualities* nil)
- (setq *org-drill-start-time* (float-time (current-time))))
- (setq *random-state* (make-random-state t)) ; reseed RNG
- (unwind-protect
- (save-excursion
- (unless resume-p
- (let ((org-trust-scanner-tags t)
- (warned-about-id-creation nil))
- (org-map-drill-entries
- 'org-map-drill-entry-function
- scope drill-match)
- (org-drill-order-overdue-entries overdue-data)
- (setq *org-drill-overdue-entry-count*
- (length *org-drill-overdue-entries*))))
- (setq *org-drill-due-entry-count* (org-drill-pending-entry-count))
- (cond
- ((and (null *org-drill-current-item*)
- (null *org-drill-new-entries*)
- (null *org-drill-failed-entries*)
- (null *org-drill-overdue-entries*)
- (null *org-drill-young-mature-entries*)
- (null *org-drill-old-mature-entries*))
- (message "I did not find any pending drill items."))
- (t
- (org-drill-entries resume-p)
- (message "Drill session finished!"))))
- (progn
- (unless end-pos
- (setq *org-drill-cram-mode* nil)
- (org-drill-free-markers *org-drill-done-entries*)))))
- (cond
- (end-pos
- (when (markerp end-pos)
- (org-drill-goto-entry end-pos)
- (org-reveal)
- (org-show-entry))
- (let ((keystr (command-keybinding-to-string 'org-drill-resume)))
- (message
- "You can continue the drill session with the command `org-drill-resume'.%s"
- (if keystr (format "\nYou can run this command by pressing %s." keystr)
- ""))))
- (t
- (org-drill-final-report)
- (if (eql 'sm5 org-drill-spaced-repetition-algorithm)
- (org-drill-save-optimal-factor-matrix))
- (if org-drill-save-buffers-after-drill-sessions-p
- (save-some-buffers))
- (message "Drill session finished!")
- ))))
-
-
-(defun org-drill-save-optimal-factor-matrix ()
- (savehist-autosave))
-
-
-(defun org-drill-cram (&optional scope drill-match)
- "Run an interactive drill session in 'cram mode'. In cram mode,
-all drill items are considered to be due for review, unless they
-have been reviewed within the last `org-drill-cram-hours'
-hours."
- (interactive)
- (setq *org-drill-cram-mode* t)
- (org-drill scope drill-match))
-
-
-(defun org-drill-tree ()
- "Run an interactive drill session using drill items within the
-subtree at point."
- (interactive)
- (org-drill 'tree))
-
-
-(defun org-drill-directory ()
- "Run an interactive drill session using drill items from all org
-files in the same directory as the current file."
- (interactive)
- (org-drill 'directory))
-
-
-(defun org-drill-again (&optional scope drill-match)
- "Run a new drill session, but try to use leftover due items that
-were not reviewed during the last session, rather than scanning for
-unreviewed items. If there are no leftover items in memory, a full
-scan will be performed."
- (interactive)
- (setq *org-drill-cram-mode* nil)
- (cond
- ((plusp (org-drill-pending-entry-count))
- (org-drill-free-markers *org-drill-done-entries*)
- (if (markerp *org-drill-current-item*)
- (free-marker *org-drill-current-item*))
- (setq *org-drill-start-time* (float-time (current-time))
- *org-drill-done-entries* nil
- *org-drill-current-item* nil)
- (org-drill scope drill-match t))
- (t
- (org-drill scope drill-match))))
-
-
-
-(defun org-drill-resume ()
- "Resume a suspended drill session. Sessions are suspended by
-exiting them with the `edit' or `quit' options."
- (interactive)
- (cond
- ((org-drill-entries-pending-p)
- (org-drill nil nil t))
- ((and (plusp (org-drill-pending-entry-count))
- ;; Current drill session is finished, but there are still
- ;; more items which need to be reviewed.
- (y-or-n-p (format
- "You have finished the drill session. However, %d items still
-need reviewing. Start a new drill session? "
- (org-drill-pending-entry-count))))
- (org-drill-again))
- (t
- (message "You have finished the drill session."))))
-
-
-(defun org-drill-relearn-item ()
- "Make the current item due for revision, and set its last interval to 0.
-Makes the item behave as if it has been failed, without actually recording a
-failure. This command can be used to 'reset' repetitions for an item."
- (interactive)
- (org-drill-smart-reschedule 4 0))
-
-
-(defun org-drill-strip-entry-data ()
- (dolist (prop org-drill-scheduling-properties)
- (org-delete-property prop))
- (org-schedule '(4)))
-
-
-(defun org-drill-strip-all-data (&optional scope)
- "Delete scheduling data from every drill entry in scope. This
-function may be useful if you want to give your collection of
-entries to someone else. Scope defaults to the current buffer,
-and is specified by the argument SCOPE, which accepts the same
-values as `org-drill-scope'."
- (interactive)
- (when (yes-or-no-p
- "Delete scheduling data from ALL items in scope: are you sure?")
- (cond
- ((null scope)
- ;; Scope is the current buffer. This means we can use
- ;; `org-delete-property-globally', which is faster.
- (dolist (prop org-drill-scheduling-properties)
- (org-delete-property-globally prop))
- (org-map-drill-entries (lambda () (org-schedule '(4))) scope))
- (t
- (org-map-drill-entries 'org-drill-strip-entry-data scope)))
- (message "Done.")))
-
-
-(defun org-drill-add-cloze-fontification ()
- ;; Compute local versions of the regexp for cloze deletions, in case
- ;; the left and right delimiters are redefined locally.
- (setq-local org-drill-cloze-regexp (org-drill--compute-cloze-regexp))
- (setq-local org-drill-cloze-keywords (org-drill--compute-cloze-keywords))
- (when org-drill-use-visible-cloze-face-p
- (add-to-list 'org-font-lock-extra-keywords
- (first org-drill-cloze-keywords))))
-
-
-;; Can't add to org-mode-hook, because local variables won't have been loaded
-;; yet.
-
-;; (defun org-drill-add-cloze-fontification ()
-;; (when (eql major-mode 'org-mode)
-;; ;; Compute local versions of the regexp for cloze deletions, in case
-;; ;; the left and right delimiters are redefined locally.
-;; (setq-local org-drill-cloze-regexp (org-drill--compute-cloze-regexp))
-;; (setq-local org-drill-cloze-keywords (org-drill--compute-cloze-keywords))
-;; (when org-drill-use-visible-cloze-face-p
-;; (font-lock-add-keywords nil ;'org-mode
-;; org-drill-cloze-keywords
-;; nil))))
-
-;; XXX
-;; (add-hook 'hack-local-variables-hook
-;; 'org-drill-add-cloze-fontification)
-;;
-;; (org-drill-add-cloze-fontification)
-
-
-;;; Synching card collections =================================================
-
-
-(defvar *org-drill-dest-id-table* (make-hash-table :test 'equal))
-
-
-(defun org-drill-copy-entry-to-other-buffer (dest &optional path)
- "Copy the subtree at point to the buffer DEST. The copy will receive
-the tag 'imported'."
- (block org-drill-copy-entry-to-other-buffer
- (save-excursion
- (let ((src (current-buffer))
- (m nil))
- (cl-flet ((paste-tree-here (&optional level)
- (org-paste-subtree level)
- (org-drill-strip-entry-data)
- (org-toggle-tag "imported" 'on)
- (org-map-drill-entries
- (lambda ()
- (let ((id (org-id-get)))
- (org-drill-strip-entry-data)
- (unless (gethash id *org-drill-dest-id-table*)
- (puthash id (point-marker)
- *org-drill-dest-id-table*))))
- 'tree)))
- (unless path
- (setq path (org-get-outline-path)))
- (org-copy-subtree)
- (switch-to-buffer dest)
- (setq m
- (condition-case nil
- (org-find-olp path t)
- (error ; path does not exist in DEST
- (return-from org-drill-copy-entry-to-other-buffer
- (cond
- ((cdr path)
- (org-drill-copy-entry-to-other-buffer
- dest (butlast path)))
- (t
- ;; We've looked all the way up the path
- ;; Default to appending to the end of DEST
- (goto-char (point-max))
- (newline)
- (paste-tree-here)))))))
- (goto-char m)
- (outline-next-heading)
- (newline)
- (forward-line -1)
- (paste-tree-here (1+ (or (org-current-level) 0)))
- )))))
-
-
-
-(defun org-drill-merge-buffers (src &optional dest ignore-new-items-p)
- "SRC and DEST are two org mode buffers containing drill items.
-For each drill item in DEST that shares an ID with an item in SRC,
-overwrite scheduling data in DEST with data taken from the item in SRC.
-This is intended for use when two people are sharing a set of drill items,
-one person has made some updates to the item set, and the other person
-wants to migrate to the updated set without losing their scheduling data.
-
-By default, any drill items in SRC which do not exist in DEST are
-copied into DEST. We attempt to place the copied item in the
-equivalent location in DEST to its location in SRC, by matching
-the heading hierarchy. However if IGNORE-NEW-ITEMS-P is non-nil,
-we simply ignore any items that do not exist in DEST, and do not
-copy them across."
- (interactive "bImport scheduling info from which buffer?")
- (unless dest
- (setq dest (current-buffer)))
- (setq src (get-buffer src)
- dest (get-buffer dest))
- (when (yes-or-no-p
- (format
- (concat "About to overwrite all scheduling data for drill items in `%s' "
- "with information taken from matching items in `%s'. Proceed? ")
- (buffer-name dest) (buffer-name src)))
- ;; Compile list of all IDs in the destination buffer.
- (clrhash *org-drill-dest-id-table*)
- (with-current-buffer dest
- (org-map-drill-entries
- (lambda ()
- (let ((this-id (org-id-get)))
- (when this-id
- (puthash this-id (point-marker) *org-drill-dest-id-table*))))
- 'file))
- ;; Look through all entries in source buffer.
- (with-current-buffer src
- (org-map-drill-entries
- (lambda ()
- (let ((id (org-id-get))
- (last-quality nil) (last-reviewed nil)
- (scheduled-time nil))
- (cond
- ((or (null id)
- (not (org-drill-entry-p)))
- nil)
- ((gethash id *org-drill-dest-id-table*)
- ;; This entry matches an entry in dest. Retrieve all its
- ;; scheduling data, then go to the matching location in dest
- ;; and write the data.
- (let ((marker (gethash id *org-drill-dest-id-table*)))
- (destructuring-bind (last-interval repetitions failures
- total-repeats meanq ease)
- (org-drill-get-item-data)
- (setq last-reviewed (org-entry-get (point) "DRILL_LAST_REVIEWED")
- last-quality (org-entry-get (point) "DRILL_LAST_QUALITY")
- scheduled-time (org-get-scheduled-time (point)))
- (save-excursion
- ;; go to matching entry in destination buffer
- (switch-to-buffer (marker-buffer marker))
- (goto-char marker)
- (org-drill-strip-entry-data)
- (unless (zerop total-repeats)
- (org-drill-store-item-data last-interval repetitions failures
- total-repeats meanq ease)
- (if last-quality
- (org-set-property "LAST_QUALITY" last-quality)
- (org-delete-property "LAST_QUALITY"))
- (if last-reviewed
- (org-set-property "LAST_REVIEWED" last-reviewed)
- (org-delete-property "LAST_REVIEWED"))
- (if scheduled-time
- (org-schedule nil scheduled-time)))))
- (remhash id *org-drill-dest-id-table*)
- (free-marker marker)))
- (t
- ;; item in SRC has ID, but no matching ID in DEST.
- ;; It must be a new item that does not exist in DEST.
- ;; Copy the entire item to the *end* of DEST.
- (unless ignore-new-items-p
- (org-drill-copy-entry-to-other-buffer dest))))))
- 'file))
- ;; Finally: there may be some items in DEST which are not in SRC, and
- ;; which have been scheduled by another user of DEST. Clear out the
- ;; scheduling info from all the unmatched items in DEST.
- (with-current-buffer dest
- (maphash (lambda (id m)
- (goto-char m)
- (org-drill-strip-entry-data)
- (free-marker m))
- *org-drill-dest-id-table*))))
-
-
-
-;;; Card types for learning languages =========================================
-
-;;; Get spell-number.el from:
-;;; http://www.emacswiki.org/emacs/spell-number.el
-(autoload 'spelln-integer-in-words "spell-number")
-
-
-;;; `conjugate' card type =====================================================
-;;; See spanish.org for usage
-
-(defvar org-drill-verb-tense-alist
- '(("present" "tomato")
- ("simple present" "tomato")
- ("present indicative" "tomato")
- ;; past tenses
- ("past" "purple")
- ("simple past" "purple")
- ("preterite" "purple")
- ("imperfect" "darkturquoise")
- ("present perfect" "royalblue")
- ;; future tenses
- ("future" "green")
- ;; moods (backgrounds).
- ("indicative" nil) ; default
- ("subjunctive" "medium blue")
- ("conditional" "grey30")
- ("negative imperative" "red4")
- ("positive imperative" "darkgreen")
- )
- "Alist where each entry has the form (TENSE COLOUR), where
-TENSE is a string naming a tense in which verbs can be
-conjugated, and COLOUR is a string specifying a foreground colour
-which will be used by `org-drill-present-verb-conjugation' and
-`org-drill-show-answer-verb-conjugation' to fontify the verb and
-the name of the tense.")
-
-
-(defun org-drill-get-verb-conjugation-info ()
- "Auxiliary function used by `org-drill-present-verb-conjugation' and
-`org-drill-show-answer-verb-conjugation'."
- (let ((infinitive (org-entry-get (point) "VERB_INFINITIVE" t))
- (inf-hint (org-entry-get (point) "VERB_INFINITIVE_HINT" t))
- (translation (org-entry-get (point) "VERB_TRANSLATION" t))
- (tense (org-entry-get (point) "VERB_TENSE" nil))
- (mood (org-entry-get (point) "VERB_MOOD" nil))
- (highlight-face nil))
- (unless (and infinitive translation (or tense mood))
- (error "Missing information for verb conjugation card (%s, %s, %s, %s) at %s"
- infinitive translation tense mood (point)))
- (setq tense (if tense (downcase (car (read-from-string tense))))
- mood (if mood (downcase (car (read-from-string mood))))
- infinitive (car (read-from-string infinitive))
- inf-hint (if inf-hint (car (read-from-string inf-hint)))
- translation (car (read-from-string translation)))
- (setq highlight-face
- (list :foreground
- (or (second (assoc-string tense org-drill-verb-tense-alist t))
- "hotpink")
- :background
- (second (assoc-string mood org-drill-verb-tense-alist t))))
- (setq infinitive (propertize infinitive 'face highlight-face))
- (setq translation (propertize translation 'face highlight-face))
- (if tense (setq tense (propertize tense 'face highlight-face)))
- (if mood (setq mood (propertize mood 'face highlight-face)))
- (list infinitive inf-hint translation tense mood)))
-
-
-(defun org-drill-present-verb-conjugation ()
- "Present a drill entry whose card type is 'conjugate'."
- (cl-flet ((tense-and-mood-to-string
- (tense mood)
- (cond
- ((and tense mood)
- (format "%s tense, %s mood" tense mood))
- (tense
- (format "%s tense" tense))
- (mood
- (format "%s mood" mood)))))
- (destructuring-bind (infinitive inf-hint translation tense mood)
- (org-drill-get-verb-conjugation-info)
- (org-drill-present-card-using-text
- (cond
- ((zerop (random* 2))
- (format "\nTranslate the verb\n\n%s\n\nand conjugate for the %s.\n\n"
- infinitive (tense-and-mood-to-string tense mood)))
-
- (t
- (format "\nGive the verb that means\n\n%s %s\n
-and conjugate for the %s.\n\n"
- translation
- (if inf-hint (format " [HINT: %s]" inf-hint) "")
- (tense-and-mood-to-string tense mood))))))))
-
-
-(defun org-drill-show-answer-verb-conjugation (reschedule-fn)
- "Show the answer for a drill item whose card type is 'conjugate'.
-RESCHEDULE-FN must be a function that calls `org-drill-reschedule' and
-returns its return value."
- (destructuring-bind (infinitive inf-hint translation tense mood)
- (org-drill-get-verb-conjugation-info)
- (with-replaced-entry-heading
- (format "%s of %s ==> %s\n\n"
- (capitalize
- (cond
- ((and tense mood)
- (format "%s tense, %s mood" tense mood))
- (tense
- (format "%s tense" tense))
- (mood
- (format "%s mood" mood))))
- infinitive translation)
- (org-cycle-hide-drawers 'all)
- (funcall reschedule-fn))))
-
-
-;;; `decline_noun' card type ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-
-(defvar org-drill-noun-gender-alist
- '(("masculine" "dodgerblue")
- ("masc" "dodgerblue")
- ("male" "dodgerblue")
- ("m" "dodgerblue")
- ("feminine" "orchid")
- ("fem" "orchid")
- ("female" "orchid")
- ("f" "orchid")
- ("neuter" "green")
- ("neutral" "green")
- ("neut" "green")
- ("n" "green")
- ))
-
-
-(defun org-drill-get-noun-info ()
- "Auxiliary function used by `org-drill-present-noun-declension' and
-`org-drill-show-answer-noun-declension'."
- (let ((noun (org-entry-get (point) "NOUN" t))
- (noun-hint (org-entry-get (point) "NOUN_HINT" t))
- (noun-root (org-entry-get (point) "NOUN_ROOT" t))
- (noun-gender (org-entry-get (point) "NOUN_GENDER" t))
- (translation (org-entry-get (point) "NOUN_TRANSLATION" t))
- (highlight-face nil))
- (unless (and noun translation)
- (error "Missing information for `decline_noun' card (%s, %s, %s, %s) at %s"
- noun translation noun-hint noun-root (point)))
- (setq noun-root (if noun-root (car (read-from-string noun-root)))
- noun (car (read-from-string noun))
- noun-gender (downcase (car (read-from-string noun-gender)))
- noun-hint (if noun-hint (car (read-from-string noun-hint)))
- translation (car (read-from-string translation)))
- (setq highlight-face
- (list :foreground
- (or (second (assoc-string noun-gender
- org-drill-noun-gender-alist t))
- "red")))
- (setq noun (propertize noun 'face highlight-face))
- (setq translation (propertize translation 'face highlight-face))
- (list noun noun-root noun-gender noun-hint translation)))
-
-
-(defun org-drill-present-noun-declension ()
- "Present a drill entry whose card type is 'decline_noun'."
- (destructuring-bind (noun noun-root noun-gender noun-hint translation)
- (org-drill-get-noun-info)
- (let* ((props (org-entry-properties (point)))
- (definite
- (cond
- ((assoc "DECLINE_DEFINITE" props)
- (propertize (if (org-entry-get (point) "DECLINE_DEFINITE")
- "definite" "indefinite")
- 'face 'warning))
- (t nil)))
- (plural
- (cond
- ((assoc "DECLINE_PLURAL" props)
- (propertize (if (org-entry-get (point) "DECLINE_PLURAL")
- "plural" "singular")
- 'face 'warning))
- (t nil))))
- (org-drill-present-card-using-text
- (cond
- ((zerop (random* 2))
- (format "\nTranslate the noun\n\n%s (%s)\n\nand list its declensions%s.\n\n"
- noun noun-gender
- (if (or plural definite)
- (format " for the %s %s form" definite plural)
- "")))
- (t
- (format "\nGive the noun that means\n\n%s %s\n
-and list its declensions%s.\n\n"
- translation
- (if noun-hint (format " [HINT: %s]" noun-hint) "")
- (if (or plural definite)
- (format " for the %s %s form" definite plural)
- ""))))))))
-
-
-(defun org-drill-show-answer-noun-declension (reschedule-fn)
- "Show the answer for a drill item whose card type is 'decline_noun'.
-RESCHEDULE-FN must be a function that calls `org-drill-reschedule' and
-returns its return value."
- (destructuring-bind (noun noun-root noun-gender noun-hint translation)
- (org-drill-get-noun-info)
- (with-replaced-entry-heading
- (format "Declensions of %s (%s) ==> %s\n\n"
- noun noun-gender translation)
- (org-cycle-hide-drawers 'all)
- (funcall reschedule-fn))))
-
-
-;;; `translate_number' card type ==============================================
-;;; See spanish.org for usage
-
-
-(defun spelln-integer-in-language (n lang)
- (let ((spelln-language lang))
- (spelln-integer-in-words n)))
-
-(defun org-drill-present-translate-number ()
- (let ((num-min (read (org-entry-get (point) "DRILL_NUMBER_MIN")))
- (num-max (read (org-entry-get (point) "DRILL_NUMBER_MAX")))
- (language (read (org-entry-get (point) "DRILL_LANGUAGE" t)))
- (drilled-number 0)
- (drilled-number-direction 'to-english)
- (highlight-face 'font-lock-warning-face))
- (cond
- ((not (fboundp 'spelln-integer-in-words))
- (message "`spell-number.el' not loaded, skipping 'translate_number' card...")
- (sit-for 0.5)
- 'skip)
- ((not (and (numberp num-min) (numberp num-max) language))
- (error "Missing language or minimum or maximum numbers for number card"))
- (t
- (if (> num-min num-max)
- (psetf num-min num-max
- num-max num-min))
- (setq drilled-number
- (+ num-min (random* (abs (1+ (- num-max num-min))))))
- (setq drilled-number-direction
- (if (zerop (random* 2)) 'from-english 'to-english))
- (cond
- ((eql 'to-english drilled-number-direction)
- (org-drill-present-card-using-text
- (format "\nTranslate into English:\n\n%s\n"
- (propertize
- (spelln-integer-in-language drilled-number language)
- 'face highlight-face))
- (spelln-integer-in-language drilled-number 'english-gb)))
- (t
- (org-drill-present-card-using-text
- (format "\nTranslate into %s:\n\n%s\n"
- (capitalize (format "%s" language))
- (propertize
- (spelln-integer-in-language drilled-number 'english-gb)
- 'face highlight-face))
- (spelln-integer-in-language drilled-number language))))))))
-
-
-;; (defun org-drill-show-answer-translate-number (reschedule-fn)
-;; (let* ((language (read (org-entry-get (point) "DRILL_LANGUAGE" t)))
-;; (highlight-face 'font-lock-warning-face)
-;; (non-english
-;; (let ((spelln-language language))
-;; (propertize (spelln-integer-in-words *drilled-number*)
-;; 'face highlight-face)))
-;; (english
-;; (let ((spelln-language 'english-gb))
-;; (propertize (spelln-integer-in-words *drilled-number*)
-;; 'face 'highlight-face))))
-;; (with-replaced-entry-text
-;; (cond
-;; ((eql 'to-english *drilled-number-direction*)
-;; (format "\nThe English translation of %s is:\n\n%s\n"
-;; non-english english))
-;; (t
-;; (format "\nThe %s translation of %s is:\n\n%s\n"
-;; (capitalize (format "%s" language))
-;; english non-english)))
-;; (funcall reschedule-fn))))
-
-
-;;; `spanish_verb' card type ==================================================
-;;; Not very interesting, but included to demonstrate how a presentation
-;;; function can manipulate which subheading are hidden versus shown.
-
-
-(defun org-drill-present-spanish-verb ()
- (let ((prompt nil)
- (reveal-headings nil))
- (with-hidden-comments
- (with-hidden-cloze-hints
- (with-hidden-cloze-text
- (case (random* 6)
- (0
- (org-drill-hide-all-subheadings-except '("Infinitive"))
- (setq prompt
- (concat "Translate this Spanish verb, and conjugate it "
- "for the *present* tense.")
- reveal-headings '("English" "Present Tense" "Notes")))
- (1
- (org-drill-hide-all-subheadings-except '("English"))
- (setq prompt (concat "For the *present* tense, conjugate the "
- "Spanish translation of this English verb.")
- reveal-headings '("Infinitive" "Present Tense" "Notes")))
- (2
- (org-drill-hide-all-subheadings-except '("Infinitive"))
- (setq prompt (concat "Translate this Spanish verb, and "
- "conjugate it for the *past* tense.")
- reveal-headings '("English" "Past Tense" "Notes")))
- (3
- (org-drill-hide-all-subheadings-except '("English"))
- (setq prompt (concat "For the *past* tense, conjugate the "
- "Spanish translation of this English verb.")
- reveal-headings '("Infinitive" "Past Tense" "Notes")))
- (4
- (org-drill-hide-all-subheadings-except '("Infinitive"))
- (setq prompt (concat "Translate this Spanish verb, and "
- "conjugate it for the *future perfect* tense.")
- reveal-headings '("English" "Future Perfect Tense" "Notes")))
- (5
- (org-drill-hide-all-subheadings-except '("English"))
- (setq prompt (concat "For the *future perfect* tense, conjugate the "
- "Spanish translation of this English verb.")
- reveal-headings '("Infinitive" "Future Perfect Tense" "Notes"))))
- (org-cycle-hide-drawers 'all)
- (prog1 (org-drill-presentation-prompt)
- (org-drill-hide-subheadings-if 'org-drill-entry-p)))))))
-
-
-(provide 'org-drill)
diff --git a/contrib/lisp/org-eldoc.el b/contrib/lisp/org-eldoc.el
index 556b945..4003c12 100644
--- a/contrib/lisp/org-eldoc.el
+++ b/contrib/lisp/org-eldoc.el
@@ -110,7 +110,7 @@
(defun org-eldoc-get-mode-local-documentation-function (lang)
"Check if LANG-mode sets eldoc-documentation-function and return its value."
(let ((cached-func (gethash lang org-eldoc-local-functions-cache 'empty))
- (mode-func (intern-soft (format "%s-mode" lang)))
+ (mode-func (org-src-get-lang-mode lang))
doc-func)
(if (eq 'empty cached-func)
(when (fboundp mode-func)
diff --git a/contrib/lisp/org-expiry.el b/contrib/lisp/org-expiry.el
index 5304d57..a7ee023 100644
--- a/contrib/lisp/org-expiry.el
+++ b/contrib/lisp/org-expiry.el
@@ -52,7 +52,7 @@
;; This entry will expire on the 14th, january 2008, one week after its
;; creation date.
;;
-;; What happen when an entry is expired? Nothing until you explicitely
+;; What happen when an entry is expired? Nothing until you explicitly
;; M-x org-expiry-process-entries When doing this, org-expiry will check
;; for expired entries and request permission to process them.
;;
diff --git a/contrib/lisp/org-link-edit.el b/contrib/lisp/org-link-edit.el
index 9059df0..b046a77 100644
--- a/contrib/lisp/org-link-edit.el
+++ b/contrib/lisp/org-link-edit.el
@@ -95,9 +95,7 @@ The list includes
(match-end 0)
(save-match-data
(org-link-unescape (match-string-no-properties 1)))
- (or (and (match-end 3)
- (match-string-no-properties 3))
- "")))
+ (or (match-string-no-properties 2) "")))
((looking-at org-plain-link-re)
(list (match-beginning 0)
(match-end 0)
diff --git a/contrib/lisp/org-mac-link.el b/contrib/lisp/org-mac-link.el
index 6bd6dc5..7952b35 100644
--- a/contrib/lisp/org-mac-link.el
+++ b/contrib/lisp/org-mac-link.el
@@ -514,7 +514,7 @@ The links are of the form <link>::split::<name>."
;;;###autoload
(defun org-mac-together-get-selected ()
(interactive)
- (message "Applescript: Getting Togther items...")
+ (message "Applescript: Getting Together items...")
(org-mac-paste-applescript-links (as-get-selected-together-items)))
;;;###autoload
diff --git a/contrib/lisp/org-passwords.el b/contrib/lisp/org-passwords.el
index 1f32f9b..4bdd804 100644
--- a/contrib/lisp/org-passwords.el
+++ b/contrib/lisp/org-passwords.el
@@ -348,7 +348,7 @@ separated SEPARATOR."
separator)))
(defun org-passwords-substitute (string-to-change list-of-substitutions)
- "Substitutes each appearence in STRING-TO-CHANGE of the `car' of
+ "Substitutes each appearance in STRING-TO-CHANGE of the `car' of
each element of LIST-OF-SUBSTITUTIONS by the `cdr' of that
element. For example:
(org-passwords-substitute \"ab\" \'((\"a\" . \"b\") (\"b\" . \"c\")))
diff --git a/contrib/lisp/org-screenshot.el b/contrib/lisp/org-screenshot.el
index abac4a1..58ebaa4 100644
--- a/contrib/lisp/org-screenshot.el
+++ b/contrib/lisp/org-screenshot.el
@@ -86,7 +86,7 @@
(defcustom org-screenshot-image-directory "./images/"
"Directory in which screenshot image files will be stored, it
-be automatically created if it does't already exist."
+be automatically created if it doesn't already exist."
:type 'string
:group 'org-screenshot)
@@ -290,7 +290,7 @@ screenshot is done, any more `C-u' after that increases delay by
(setq num (* num 4)
cnt (+ cnt (if (< cnt 3) 1 2))))
cnt))
- (t (error "Invald delay"))))
+ (t (error "Invalid delay"))))
(when (and org-screenshot-process
(member (process-status org-screenshot-process)
'(run stop)))
@@ -331,7 +331,7 @@ screenshot is done, any more `C-u' after that increases delay by
(make-variable-buffer-local 'org-screenshot-rotation-index)
(defun org-screenshot-rotation-init (lastfile)
- "Initialize variable `org-screenshot-file-list' variabel with
+ "Initialize variable `org-screenshot-file-list' variable with
the list of PNG files in `org-screenshot-image-directory' sorted
by most recent first"
(setq
diff --git a/contrib/lisp/org-sudoku.el b/contrib/lisp/org-sudoku.el
index 9537c0c..67665ff 100644
--- a/contrib/lisp/org-sudoku.el
+++ b/contrib/lisp/org-sudoku.el
@@ -1,4 +1,4 @@
-;;; org-sudoku.el --- Greate and solve SUDOKU games in Org tables
+;;; org-sudoku.el --- Create and solve SUDOKU games in Org tables
;; Copyright (C) 2012-2018 Free Software Foundation, Inc.
;;
diff --git a/contrib/lisp/org-toc.el b/contrib/lisp/org-toc.el
index 3a05c4a..08cc9e9 100644
--- a/contrib/lisp/org-toc.el
+++ b/contrib/lisp/org-toc.el
@@ -90,7 +90,7 @@ This variable is only used when `org-toc-recenter-mode' is set to
(defcustom org-toc-info-exclude '("ALLTAGS")
"A list of excluded properties when displaying info in the
-echo-area. The COLUMNS property is always exluded."
+echo-area. The COLUMNS property is always excluded."
:group 'org-toc
:type 'lits)
diff --git a/contrib/lisp/orgtbl-sqlinsert.el b/contrib/lisp/orgtbl-sqlinsert.el
index 759c464..49a4558 100644
--- a/contrib/lisp/orgtbl-sqlinsert.el
+++ b/contrib/lisp/orgtbl-sqlinsert.el
@@ -36,7 +36,7 @@ PARAMS is a property list of parameters that can influence the conversion.
Names and strings are modified slightly by default. Single-ticks
are doubled as per SQL's standard mechanism. Backslashes and
dollar signs are deleted. And tildes are changed to spaces.
-These modifications were chosed for use with TeX. See
+These modifications were chosen for use with TeX. See
ORGTBL-SQL-STRIP-AND-QUOTE.
Supports all parameters from ORGTBL-TO-GENERIC. New to this function
diff --git a/contrib/lisp/ox-deck.el b/contrib/lisp/ox-deck.el
index 427c7d7..3b911e1 100644
--- a/contrib/lisp/ox-deck.el
+++ b/contrib/lisp/ox-deck.el
@@ -32,7 +32,7 @@
;;
;; Add the path to the extracted code to the variable
;; `org-deck-directories' There are a number of customization in the
-;; org-export-deck group, most of which can be overrriden with buffer
+;; org-export-deck group, most of which can be overridden with buffer
;; local customization (starting with DECK_.)
;; See ox.el and ox-html.el for more details on how this exporter
@@ -137,7 +137,7 @@ transitions (with full paths) to a temporary buffer."
(defcustom org-deck-include-extensions nil
"If non-nil, list of extensions to include instead of all available.
-Can be overriden or set with the DECK_INCLUDE_EXTENSIONS property.
+Can be overridden or set with the DECK_INCLUDE_EXTENSIONS property.
During output generation, the extensions found by
`org-deck--find-extensions' are searched for the appropriate
files (scripts and/or stylesheets) to include in the generated
@@ -147,12 +147,12 @@ html. The href/src attributes are created relative to `org-deck-base-url'."
(defcustom org-deck-exclude-extensions nil
"If non-nil, list of extensions to exclude.
-Can be overriden or set with the DECK_EXCLUDE_EXTENSIONS property."
+Can be overridden or set with the DECK_EXCLUDE_EXTENSIONS property."
:group 'org-export-deck
:type '(repeat (string :tag "Extension")))
(defcustom org-deck-theme "swiss.css"
- "deck.js theme. Can be overriden with the DECK_THEME property.
+ "deck.js theme. Can be overridden with the DECK_THEME property.
If this value contains a path component (\"/\"), it is used as a
literal path (url). Otherwise it is prepended with
`org-deck-base-url'/themes/style/."
@@ -160,7 +160,7 @@ literal path (url). Otherwise it is prepended with
:type 'string)
(defcustom org-deck-transition "fade.css"
- "deck.js transition theme. Can be overriden with the
+ "deck.js transition theme. Can be overridden with the
DECK_TRANSITION property.
If this value contains a path component (\"/\"), it is used as a
literal path (url). Otherwise it is prepended with
@@ -171,7 +171,7 @@ literal path (url). Otherwise it is prepended with
(defcustom org-deck-base-url "deck.js"
"Url prefix to deck.js base directory containing the core, extensions
and themes directories.
-Can be overriden with the DECK_BASE_URL property."
+Can be overridden with the DECK_BASE_URL property."
:group 'org-export-deck
:type 'string)
@@ -180,7 +180,7 @@ Can be overriden with the DECK_BASE_URL property."
(preamble "position: absolute; top: 10px;")
(postamble ""))
"Alist of css styles for the preamble, postamble and both respectively.
-Can be overriden in `org-deck-styles'. See also `org-html-divs'.")
+Can be overridden in `org-deck-styles'. See also `org-html-divs'.")
(defcustom org-deck-postamble "<h1>%a - %t</h1>"
"Non-nil means insert a postamble in HTML export.
@@ -239,7 +239,7 @@ precedence over this variable."
"#table-of-contents ul {margin-bottom: 0;}"
"#table-of-contents li {padding: 0;}") "\n")
"Default css styles used for formatting a table of contents slide.
-Can be overriden in `org-deck-styles'.
+Can be overridden in `org-deck-styles'.
Note that when the headline numbering option is true, a \"list-style: none\"
is automatically added to avoid both numbers and bullets on the toc entries.")
diff --git a/contrib/lisp/ox-groff.el b/contrib/lisp/ox-groff.el
index 85e24a5..97d307a 100644
--- a/contrib/lisp/ox-groff.el
+++ b/contrib/lisp/ox-groff.el
@@ -429,7 +429,7 @@ language.")
is replace on the value of the CDR. "
:group 'org-export-groff
:type '(list
- (cons :tag "Character Subtitute"
+ (cons :tag "Character Substitute"
(string :tag "Original Character Group")
(string :tag "Replacement Character"))))
diff --git a/contrib/lisp/ox-koma-letter.el b/contrib/lisp/ox-koma-letter.el
index abc0c28..f3a27a3 100644
--- a/contrib/lisp/ox-koma-letter.el
+++ b/contrib/lisp/ox-koma-letter.el
@@ -921,7 +921,7 @@ contents of hidden elements.
When optional argument BODY-ONLY is non-nil, only write code
between \"\\begin{letter}\" and \"\\end{letter}\".
-EXT-PLIST, when provided, is a proeprty list with external
+EXT-PLIST, when provided, is a property list with external
parameters overriding Org default settings, but still inferior to
file-local settings.
diff --git a/contrib/lisp/ox-s5.el b/contrib/lisp/ox-s5.el
index 0496aae..2433325 100644
--- a/contrib/lisp/ox-s5.el
+++ b/contrib/lisp/ox-s5.el
@@ -98,7 +98,7 @@ Can be overridden with S5_VERSION."
:type 'string)
(defcustom org-s5-theme-file nil
-"Url to S5 theme (slides.css) file. Can be overriden with the
+"Url to S5 theme (slides.css) file. Can be overridden with the
S5_THEME_FILE property. If nil, defaults to
`org-s5-ui-url'/default/slides.css. If it starts with anything but
\"http\" or \"/\", it is used as-is. Otherwise the link in generated
@@ -111,7 +111,7 @@ generated relative to `org-s5-ui-url'/default."
(defcustom org-s5-ui-url "ui"
"Base url to directory containing S5 \"default\" subdirectory
and the \"s5-notes.html\" file.
-Can be overriden with the S5_UI_URL property."
+Can be overridden with the S5_UI_URL property."
:group 'org-export-s5
:type 'string)
diff --git a/contrib/scripts/StartOzServer.oz b/contrib/scripts/StartOzServer.oz
index df3ebe6..79b86a8 100644
--- a/contrib/scripts/StartOzServer.oz
+++ b/contrib/scripts/StartOzServer.oz
@@ -74,10 +74,10 @@ MyCompiler = Emacs.condSend.compiler
%% !! catching some exceptions does not work??
-%% exception is not catched
+%% exception is not caught
try {Bla} catch E then {Error.printException E} {Browse nil} end
-%% exception is catched
+%% exception is caught
try {Browse 1 div 0} catch E then {Error.printException E} {Browse nil} end
{Browse ok}
diff --git a/doc/.aspell.org.conf b/doc/.aspell.org.conf
index facdc49..dd8601d 100644
--- a/doc/.aspell.org.conf
+++ b/doc/.aspell.org.conf
@@ -68,7 +68,7 @@ suggest true
# Miscellaneous
#
# Org documentation uses a lot of compound words. Try and ignore them
-# rather than including them in a specfic word list.
+# rather than including them in a specific word list.
run-together-limit 2
run-together-min 2
diff --git a/doc/Makefile b/doc/Makefile
index 14dea7e..96fda14 100644
--- a/doc/Makefile
+++ b/doc/Makefile
@@ -7,7 +7,7 @@ endif
all: $(ORG_MAKE_DOC)
-info: org
+info: org orgguide
html: org.html
@@ -27,7 +27,7 @@ guide:: orgguide.texi org-version.inc
../mk/guidesplit.pl $@/*
endif
-org.texi: org-manual.org
+org.texi orgguide.texi: org-manual.org org-guide.org
$(BATCH) \
--eval '(add-to-list '"'"'load-path "../lisp")' \
--eval '(load "../mk/org-fixup.el")' \
@@ -46,21 +46,24 @@ org-version.tex: orgcard.tex
@printf "\def\\\\versionyear{$(YEAR)}\n" >> org-version.tex
@printf "\def\year{$(YEAR)}\n" >> org-version.tex
-install: org
+install: org orgguide
if [ ! -d $(DESTDIR)$(infodir) ]; then $(MKDIR) $(DESTDIR)$(infodir); else true; fi ;
$(CP) org $(DESTDIR)$(infodir)
+ $(CP) orgguide $(DESTDIR)$(infodir)
$(INSTALL_INFO) --infodir=$(DESTDIR)$(infodir) org
+ $(INSTALL_INFO) --infodir=$(DESTDIR)$(infodir) orgguide
clean:
- $(RM) org *.pdf *.html *_letter.tex org-version.inc org-version.tex \
- *.aux *.cp *.cps *.dvi *.fn *.fns *.ky *.kys *.pg *.pgs \
- *.toc *.tp *.tps *.vr *.vrs *.log *.html *.ps
+ $(RM) org orgguide *.pdf *.html *_letter.tex org-version.inc \
+ org-version.tex *.aux *.cp *.cps *.dvi *.fn *.fns *.ky *.kys \
+ *.pg *.pgs *.toc *.tp *.tps *.vr *.vrs *.log *.html *.ps
cleanall: clean
$(RMR) guide manual
clean-install:
$(RM) $(DESTDIR)$(infodir)/org*
$(INSTALL_INFO) --infodir=$(DESTDIR)$(infodir) --remove org
+ $(INSTALL_INFO) --infodir=$(DESTDIR)$(infodir) --remove orgguide
.SUFFIXES: .texi .tex .txt _letter.tex
diff --git a/doc/dir b/doc/dir
index 9610c40..6c75b5d 100644
--- a/doc/dir
+++ b/doc/dir
@@ -15,4 +15,5 @@ File: dir, Node: Top This is the top of the INFO tree
* Menu:
Emacs
-* Org Mode: (org). Outline-based notes management and organizer
+* Org Mode: (org). Outline-based notes management and organizer.
+* Org Guide: (orgguide). Abbreviated Org mode manual.
diff --git a/doc/doc-setup.org b/doc/doc-setup.org
new file mode 100644
index 0000000..b0eef09
--- /dev/null
+++ b/doc/doc-setup.org
@@ -0,0 +1,36 @@
+# SETUPFILE for manuals
+
+# XXX: We cannot use TODO keyword as a node starts with "TODO".
+#+todo: REVIEW FIXME | DONE
+#+property: header-args :eval no
+#+startup: overview nologdone
+
+# Use proper quote and backtick for code sections in PDF output
+# Cf. Texinfo manual 14.2
+#+texinfo_header: @set txicodequoteundirected
+#+texinfo_header: @set txicodequotebacktick
+
+# Contact Info
+#+texinfo_header: @set MAINTAINERSITE @uref{https://orgmode.org,maintainers webpage}
+#+texinfo_header: @set MAINTAINER Carsten Dominik
+#+texinfo_header: @set MAINTAINEREMAIL @email{carsten at orgmode dot org}
+#+texinfo_header: @set MAINTAINERCONTACT @uref{mailto:carsten at orgmode dot org,contact the maintainer}
+
+#+options: H:4 num:t toc:t author:t \n:nil ::t |:t ^:nil -:t f:t *:t <:t e:t ':t
+#+options: d:nil todo:nil pri:nil tags:not-in-toc stat:nil broken-links:mark
+#+select_tags: export
+#+exclude_tags: noexport
+
+#+macro: cite @@texinfo:@cite{@@$1@@texinfo:}@@
+#+macro: var @@texinfo:@var{@@$1@@texinfo:}@@
+
+# The "version" macro extracts "Version" keyword from "org.el". It
+# returns major.minor version number. This is sufficient since bugfix
+# releases are not expected to add features and therefore imply manual
+# modifications.
+#+macro: version (eval (with-current-buffer (find-file-noselect "../lisp/org.el") (org-with-point-at 1 (if (re-search-forward "Version: +\\([0-9.]+\\)" nil t) (mapconcat #'identity (cl-subseq (split-string (match-string-no-properties 1) "\\.") 0 2) ".") (error "Missing \"Version\" keyword in \"org.el\"")))))
+
+# The "kbd" macro turns KBD into @kbd{KBD}. Additionally, it
+# encloses case-sensitive special keys (SPC, RET...) within @key{...}.
+#+macro: kbd (eval (let ((case-fold-search nil) (regexp (regexp-opt '("SPC" "RET" "LFD" "TAB" "BS" "ESC" "DELETE" "SHIFT" "Ctrl" "Meta" "Alt" "Cmd" "Super" "UP" "LEFT" "RIGHT" "DOWN") 'words))) (format "@@texinfo:@kbd{@@%s@@texinfo:}@@" (replace-regexp-in-string regexp "@@texinfo:@key{@@\\&@@texinfo:}@@" $1 t))))
+
diff --git a/doc/doclicense.texi b/doc/doclicense.texi
deleted file mode 100644
index 483ecdc..0000000
--- a/doc/doclicense.texi
+++ /dev/null
@@ -1,505 +0,0 @@
-@c The GNU Free Documentation License.
-@center Version 1.3, 3 November 2008
-
-@c This file is intended to be included within another document,
-@c hence no sectioning command or @node.
-
-@display
-Copyright @copyright{} 2000, 2001, 2002, 2007, 2008, 2013, 2014, 2018 Free Software Foundation, Inc.
-@uref{http://fsf.org/}
-
-Everyone is permitted to copy and distribute verbatim copies
-of this license document, but changing it is not allowed.
-@end display
-
-@enumerate 0
-@item
-PREAMBLE
-
-The purpose of this License is to make a manual, textbook, or other
-functional and useful document @dfn{free} in the sense of freedom: to
-assure everyone the effective freedom to copy and redistribute it,
-with or without modifying it, either commercially or noncommercially.
-Secondarily, this License preserves for the author and publisher a way
-to get credit for their work, while not being considered responsible
-for modifications made by others.
-
-This License is a kind of ``copyleft'', which means that derivative
-works of the document must themselves be free in the same sense. It
-complements the GNU General Public License, which is a copyleft
-license designed for free software.
-
-We have designed this License in order to use it for manuals for free
-software, because free software needs free documentation: a free
-program should come with manuals providing the same freedoms that the
-software does. But this License is not limited to software manuals;
-it can be used for any textual work, regardless of subject matter or
-whether it is published as a printed book. We recommend this License
-principally for works whose purpose is instruction or reference.
-
-@item
-APPLICABILITY AND DEFINITIONS
-
-This License applies to any manual or other work, in any medium, that
-contains a notice placed by the copyright holder saying it can be
-distributed under the terms of this License. Such a notice grants a
-world-wide, royalty-free license, unlimited in duration, to use that
-work under the conditions stated herein. The ``Document'', below,
-refers to any such manual or work. Any member of the public is a
-licensee, and is addressed as ``you''. You accept the license if you
-copy, modify or distribute the work in a way requiring permission
-under copyright law.
-
-A ``Modified Version'' of the Document means any work containing the
-Document or a portion of it, either copied verbatim, or with
-modifications and/or translated into another language.
-
-A ``Secondary Section'' is a named appendix or a front-matter section
-of the Document that deals exclusively with the relationship of the
-publishers or authors of the Document to the Document's overall
-subject (or to related matters) and contains nothing that could fall
-directly within that overall subject. (Thus, if the Document is in
-part a textbook of mathematics, a Secondary Section may not explain
-any mathematics.) The relationship could be a matter of historical
-connection with the subject or with related matters, or of legal,
-commercial, philosophical, ethical or political position regarding
-them.
-
-The ``Invariant Sections'' are certain Secondary Sections whose titles
-are designated, as being those of Invariant Sections, in the notice
-that says that the Document is released under this License. If a
-section does not fit the above definition of Secondary then it is not
-allowed to be designated as Invariant. The Document may contain zero
-Invariant Sections. If the Document does not identify any Invariant
-Sections then there are none.
-
-The ``Cover Texts'' are certain short passages of text that are listed,
-as Front-Cover Texts or Back-Cover Texts, in the notice that says that
-the Document is released under this License. A Front-Cover Text may
-be at most 5 words, and a Back-Cover Text may be at most 25 words.
-
-A ``Transparent'' copy of the Document means a machine-readable copy,
-represented in a format whose specification is available to the
-general public, that is suitable for revising the document
-straightforwardly with generic text editors or (for images composed of
-pixels) generic paint programs or (for drawings) some widely available
-drawing editor, and that is suitable for input to text formatters or
-for automatic translation to a variety of formats suitable for input
-to text formatters. A copy made in an otherwise Transparent file
-format whose markup, or absence of markup, has been arranged to thwart
-or discourage subsequent modification by readers is not Transparent.
-An image format is not Transparent if used for any substantial amount
-of text. A copy that is not ``Transparent'' is called ``Opaque''.
-
-Examples of suitable formats for Transparent copies include plain
-ASCII without markup, Texinfo input format, La@TeX{} input
-format, SGML or XML using a publicly available
-DTD, and standard-conforming simple HTML,
-PostScript or PDF designed for human modification. Examples
-of transparent image formats include PNG, XCF and
-JPG@. Opaque formats include proprietary formats that can be
-read and edited only by proprietary word processors, SGML or
-XML for which the DTD and/or processing tools are
-not generally available, and the machine-generated HTML,
-PostScript or PDF produced by some word processors for
-output purposes only.
-
-The ``Title Page'' means, for a printed book, the title page itself,
-plus such following pages as are needed to hold, legibly, the material
-this License requires to appear in the title page. For works in
-formats which do not have any title page as such, ``Title Page'' means
-the text near the most prominent appearance of the work's title,
-preceding the beginning of the body of the text.
-
-The ``publisher'' means any person or entity that distributes copies
-of the Document to the public.
-
-A section ``Entitled XYZ'' means a named subunit of the Document whose
-title either is precisely XYZ or contains XYZ in parentheses following
-text that translates XYZ in another language. (Here XYZ stands for a
-specific section name mentioned below, such as ``Acknowledgements'',
-``Dedications'', ``Endorsements'', or ``History''.) To ``Preserve the Title''
-of such a section when you modify the Document means that it remains a
-section ``Entitled XYZ'' according to this definition.
-
-The Document may include Warranty Disclaimers next to the notice which
-states that this License applies to the Document. These Warranty
-Disclaimers are considered to be included by reference in this
-License, but only as regards disclaiming warranties: any other
-implication that these Warranty Disclaimers may have is void and has
-no effect on the meaning of this License.
-
-@item
-VERBATIM COPYING
-
-You may copy and distribute the Document in any medium, either
-commercially or noncommercially, provided that this License, the
-copyright notices, and the license notice saying this License applies
-to the Document are reproduced in all copies, and that you add no other
-conditions whatsoever to those of this License. You may not use
-technical measures to obstruct or control the reading or further
-copying of the copies you make or distribute. However, you may accept
-compensation in exchange for copies. If you distribute a large enough
-number of copies you must also follow the conditions in section 3.
-
-You may also lend copies, under the same conditions stated above, and
-you may publicly display copies.
-
-@item
-COPYING IN QUANTITY
-
-If you publish printed copies (or copies in media that commonly have
-printed covers) of the Document, numbering more than 100, and the
-Document's license notice requires Cover Texts, you must enclose the
-copies in covers that carry, clearly and legibly, all these Cover
-Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on
-the back cover. Both covers must also clearly and legibly identify
-you as the publisher of these copies. The front cover must present
-the full title with all words of the title equally prominent and
-visible. You may add other material on the covers in addition.
-Copying with changes limited to the covers, as long as they preserve
-the title of the Document and satisfy these conditions, can be treated
-as verbatim copying in other respects.
-
-If the required texts for either cover are too voluminous to fit
-legibly, you should put the first ones listed (as many as fit
-reasonably) on the actual cover, and continue the rest onto adjacent
-pages.
-
-If you publish or distribute Opaque copies of the Document numbering
-more than 100, you must either include a machine-readable Transparent
-copy along with each Opaque copy, or state in or with each Opaque copy
-a computer-network location from which the general network-using
-public has access to download using public-standard network protocols
-a complete Transparent copy of the Document, free of added material.
-If you use the latter option, you must take reasonably prudent steps,
-when you begin distribution of Opaque copies in quantity, to ensure
-that this Transparent copy will remain thus accessible at the stated
-location until at least one year after the last time you distribute an
-Opaque copy (directly or through your agents or retailers) of that
-edition to the public.
-
-It is requested, but not required, that you contact the authors of the
-Document well before redistributing any large number of copies, to give
-them a chance to provide you with an updated version of the Document.
-
-@item
-MODIFICATIONS
-
-You may copy and distribute a Modified Version of the Document under
-the conditions of sections 2 and 3 above, provided that you release
-the Modified Version under precisely this License, with the Modified
-Version filling the role of the Document, thus licensing distribution
-and modification of the Modified Version to whoever possesses a copy
-of it. In addition, you must do these things in the Modified Version:
-
-@enumerate A
-@item
-Use in the Title Page (and on the covers, if any) a title distinct
-from that of the Document, and from those of previous versions
-(which should, if there were any, be listed in the History section
-of the Document). You may use the same title as a previous version
-if the original publisher of that version gives permission.
-
-@item
-List on the Title Page, as authors, one or more persons or entities
-responsible for authorship of the modifications in the Modified
-Version, together with at least five of the principal authors of the
-Document (all of its principal authors, if it has fewer than five),
-unless they release you from this requirement.
-
-@item
-State on the Title page the name of the publisher of the
-Modified Version, as the publisher.
-
-@item
-Preserve all the copyright notices of the Document.
-
-@item
-Add an appropriate copyright notice for your modifications
-adjacent to the other copyright notices.
-
-@item
-Include, immediately after the copyright notices, a license notice
-giving the public permission to use the Modified Version under the
-terms of this License, in the form shown in the Addendum below.
-
-@item
-Preserve in that license notice the full lists of Invariant Sections
-and required Cover Texts given in the Document's license notice.
-
-@item
-Include an unaltered copy of this License.
-
-@item
-Preserve the section Entitled ``History'', Preserve its Title, and add
-to it an item stating at least the title, year, new authors, and
-publisher of the Modified Version as given on the Title Page. If
-there is no section Entitled ``History'' in the Document, create one
-stating the title, year, authors, and publisher of the Document as
-given on its Title Page, then add an item describing the Modified
-Version as stated in the previous sentence.
-
-@item
-Preserve the network location, if any, given in the Document for
-public access to a Transparent copy of the Document, and likewise
-the network locations given in the Document for previous versions
-it was based on. These may be placed in the ``History'' section.
-You may omit a network location for a work that was published at
-least four years before the Document itself, or if the original
-publisher of the version it refers to gives permission.
-
-@item
-For any section Entitled ``Acknowledgements'' or ``Dedications'', Preserve
-the Title of the section, and preserve in the section all the
-substance and tone of each of the contributor acknowledgements and/or
-dedications given therein.
-
-@item
-Preserve all the Invariant Sections of the Document,
-unaltered in their text and in their titles. Section numbers
-or the equivalent are not considered part of the section titles.
-
-@item
-Delete any section Entitled ``Endorsements''. Such a section
-may not be included in the Modified Version.
-
-@item
-Do not retitle any existing section to be Entitled ``Endorsements'' or
-to conflict in title with any Invariant Section.
-
-@item
-Preserve any Warranty Disclaimers.
-@end enumerate
-
-If the Modified Version includes new front-matter sections or
-appendices that qualify as Secondary Sections and contain no material
-copied from the Document, you may at your option designate some or all
-of these sections as invariant. To do this, add their titles to the
-list of Invariant Sections in the Modified Version's license notice.
-These titles must be distinct from any other section titles.
-
-You may add a section Entitled ``Endorsements'', provided it contains
-nothing but endorsements of your Modified Version by various
-parties---for example, statements of peer review or that the text has
-been approved by an organization as the authoritative definition of a
-standard.
-
-You may add a passage of up to five words as a Front-Cover Text, and a
-passage of up to 25 words as a Back-Cover Text, to the end of the list
-of Cover Texts in the Modified Version. Only one passage of
-Front-Cover Text and one of Back-Cover Text may be added by (or
-through arrangements made by) any one entity. If the Document already
-includes a cover text for the same cover, previously added by you or
-by arrangement made by the same entity you are acting on behalf of,
-you may not add another; but you may replace the old one, on explicit
-permission from the previous publisher that added the old one.
-
-The author(s) and publisher(s) of the Document do not by this License
-give permission to use their names for publicity for or to assert or
-imply endorsement of any Modified Version.
-
-@item
-COMBINING DOCUMENTS
-
-You may combine the Document with other documents released under this
-License, under the terms defined in section 4 above for modified
-versions, provided that you include in the combination all of the
-Invariant Sections of all of the original documents, unmodified, and
-list them all as Invariant Sections of your combined work in its
-license notice, and that you preserve all their Warranty Disclaimers.
-
-The combined work need only contain one copy of this License, and
-multiple identical Invariant Sections may be replaced with a single
-copy. If there are multiple Invariant Sections with the same name but
-different contents, make the title of each such section unique by
-adding at the end of it, in parentheses, the name of the original
-author or publisher of that section if known, or else a unique number.
-Make the same adjustment to the section titles in the list of
-Invariant Sections in the license notice of the combined work.
-
-In the combination, you must combine any sections Entitled ``History''
-in the various original documents, forming one section Entitled
-``History''; likewise combine any sections Entitled ``Acknowledgements'',
-and any sections Entitled ``Dedications''. You must delete all
-sections Entitled ``Endorsements.''
-
-@item
-COLLECTIONS OF DOCUMENTS
-
-You may make a collection consisting of the Document and other documents
-released under this License, and replace the individual copies of this
-License in the various documents with a single copy that is included in
-the collection, provided that you follow the rules of this License for
-verbatim copying of each of the documents in all other respects.
-
-You may extract a single document from such a collection, and distribute
-it individually under this License, provided you insert a copy of this
-License into the extracted document, and follow this License in all
-other respects regarding verbatim copying of that document.
-
-@item
-AGGREGATION WITH INDEPENDENT WORKS
-
-A compilation of the Document or its derivatives with other separate
-and independent documents or works, in or on a volume of a storage or
-distribution medium, is called an ``aggregate'' if the copyright
-resulting from the compilation is not used to limit the legal rights
-of the compilation's users beyond what the individual works permit.
-When the Document is included in an aggregate, this License does not
-apply to the other works in the aggregate which are not themselves
-derivative works of the Document.
-
-If the Cover Text requirement of section 3 is applicable to these
-copies of the Document, then if the Document is less than one half of
-the entire aggregate, the Document's Cover Texts may be placed on
-covers that bracket the Document within the aggregate, or the
-electronic equivalent of covers if the Document is in electronic form.
-Otherwise they must appear on printed covers that bracket the whole
-aggregate.
-
-@item
-TRANSLATION
-
-Translation is considered a kind of modification, so you may
-distribute translations of the Document under the terms of section 4.
-Replacing Invariant Sections with translations requires special
-permission from their copyright holders, but you may include
-translations of some or all Invariant Sections in addition to the
-original versions of these Invariant Sections. You may include a
-translation of this License, and all the license notices in the
-Document, and any Warranty Disclaimers, provided that you also include
-the original English version of this License and the original versions
-of those notices and disclaimers. In case of a disagreement between
-the translation and the original version of this License or a notice
-or disclaimer, the original version will prevail.
-
-If a section in the Document is Entitled ``Acknowledgements'',
-``Dedications'', or ``History'', the requirement (section 4) to Preserve
-its Title (section 1) will typically require changing the actual
-title.
-
-@item
-TERMINATION
-
-You may not copy, modify, sublicense, or distribute the Document
-except as expressly provided under this License. Any attempt
-otherwise to copy, modify, sublicense, or distribute it is void, and
-will automatically terminate your rights under this License.
-
-However, if you cease all violation of this License, then your license
-from a particular copyright holder is reinstated (a) provisionally,
-unless and until the copyright holder explicitly and finally
-terminates your license, and (b) permanently, if the copyright holder
-fails to notify you of the violation by some reasonable means prior to
-60 days after the cessation.
-
-Moreover, your license from a particular copyright holder is
-reinstated permanently if the copyright holder notifies you of the
-violation by some reasonable means, this is the first time you have
-received notice of violation of this License (for any work) from that
-copyright holder, and you cure the violation prior to 30 days after
-your receipt of the notice.
-
-Termination of your rights under this section does not terminate the
-licenses of parties who have received copies or rights from you under
-this License. If your rights have been terminated and not permanently
-reinstated, receipt of a copy of some or all of the same material does
-not give you any rights to use it.
-
-@item
-FUTURE REVISIONS OF THIS LICENSE
-
-The Free Software Foundation may publish new, revised versions
-of the GNU Free Documentation License from time to time. Such new
-versions will be similar in spirit to the present version, but may
-differ in detail to address new problems or concerns. See
-@uref{http://www.gnu.org/copyleft/}.
-
-Each version of the License is given a distinguishing version number.
-If the Document specifies that a particular numbered version of this
-License ``or any later version'' applies to it, you have the option of
-following the terms and conditions either of that specified version or
-of any later version that has been published (not as a draft) by the
-Free Software Foundation. If the Document does not specify a version
-number of this License, you may choose any version ever published (not
-as a draft) by the Free Software Foundation. If the Document
-specifies that a proxy can decide which future versions of this
-License can be used, that proxy's public statement of acceptance of a
-version permanently authorizes you to choose that version for the
-Document.
-
-@item
-RELICENSING
-
-``Massive Multiauthor Collaboration Site'' (or ``MMC Site'') means any
-World Wide Web server that publishes copyrightable works and also
-provides prominent facilities for anybody to edit those works. A
-public wiki that anybody can edit is an example of such a server. A
-``Massive Multiauthor Collaboration'' (or ``MMC'') contained in the
-site means any set of copyrightable works thus published on the MMC
-site.
-
-``CC-BY-SA'' means the Creative Commons Attribution-Share Alike 3.0
-license published by Creative Commons Corporation, a not-for-profit
-corporation with a principal place of business in San Francisco,
-California, as well as future copyleft versions of that license
-published by that same organization.
-
-``Incorporate'' means to publish or republish a Document, in whole or
-in part, as part of another Document.
-
-An MMC is ``eligible for relicensing'' if it is licensed under this
-License, and if all works that were first published under this License
-somewhere other than this MMC, and subsequently incorporated in whole
-or in part into the MMC, (1) had no cover texts or invariant sections,
-and (2) were thus incorporated prior to November 1, 2008.
-
-The operator of an MMC Site may republish an MMC contained in the site
-under CC-BY-SA on the same site at any time before August 1, 2009,
-provided the MMC is eligible for relicensing.
-
-@end enumerate
-
-@page
-@heading ADDENDUM: How to use this License for your documents
-
-To use this License in a document you have written, include a copy of
-the License in the document and put the following copyright and
-license notices just after the title page:
-
-@smallexample
-@group
- Copyright (C) @var{year} @var{your name}.
- Permission is granted to copy, distribute and/or modify this document
- under the terms of the GNU Free Documentation License, Version 1.3
- or any later version published by the Free Software Foundation;
- with no Invariant Sections, no Front-Cover Texts, and no Back-Cover
- Texts. A copy of the license is included in the section entitled ``GNU
- Free Documentation License''.
-@end group
-@end smallexample
-
-If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts,
-replace the ``with@dots{}Texts.''@: line with this:
-
-@smallexample
-@group
- with the Invariant Sections being @var{list their titles}, with
- the Front-Cover Texts being @var{list}, and with the Back-Cover Texts
- being @var{list}.
-@end group
-@end smallexample
-
-If you have Invariant Sections without Cover Texts, or some other
-combination of the three, merge those two alternatives to suit the
-situation.
-
-If your document contains nontrivial examples of program code, we
-recommend releasing these examples in parallel under your choice of
-free software license, such as the GNU General Public License,
-to permit their use in free software.
-
-@c Local Variables:
-@c ispell-local-pdict: "ispell-dict"
-@c End:
diff --git a/doc/docstyle.texi b/doc/docstyle.texi
deleted file mode 100644
index dfd1430..0000000
--- a/doc/docstyle.texi
+++ /dev/null
@@ -1,10 +0,0 @@
-@c Emacs documentation style settings
-@documentencoding UTF-8
-@c These two require Texinfo 5.0 or later, so we use the older
-@c equivalent @set variables supported in 4.11 and hence
-@ignore
-@codequotebacktick on
-@codequoteundirected on
-@end ignore
-@set txicodequoteundirected
-@set txicodequotebacktick
diff --git a/doc/fdl.org b/doc/fdl.org
new file mode 100644
index 0000000..30c7d93
--- /dev/null
+++ b/doc/fdl.org
@@ -0,0 +1,490 @@
+# The GNU Free Documentation License.
+#+begin_center
+Version 1.3, 3 November 2008
+#+end_center
+
+# This file is intended to be included within another document.
+
+#+begin_verse
+Copyright \copy{} 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc.
+http://fsf.org/
+
+Everyone is permitted to copy and distribute verbatim copies
+of this license document, but changing it is not allowed.
+#+end_verse
+
+0. [@0] PREAMBLE
+
+ The purpose of this License is to make a manual, textbook, or other
+ functional and useful document @@texinfo:@dfn{@@free@@texinfo:}@@
+ in the sense of freedom: to assure everyone the effective freedom
+ to copy and redistribute it, with or without modifying it, either
+ commercially or noncommercially. Secondarily, this License
+ preserves for the author and publisher a way to get credit for
+ their work, while not being considered responsible for
+ modifications made by others.
+
+ This License is a kind of "copyleft", which means that derivative
+ works of the document must themselves be free in the same sense.
+ It complements the GNU General Public License, which is a copyleft
+ license designed for free software.
+
+ We have designed this License in order to use it for manuals for
+ free software, because free software needs free documentation:
+ a free program should come with manuals providing the same freedoms
+ that the software does. But this License is not limited to
+ software manuals; it can be used for any textual work, regardless
+ of subject matter or whether it is published as a printed book. We
+ recommend this License principally for works whose purpose is
+ instruction or reference.
+
+1. APPLICABILITY AND DEFINITIONS
+
+ This License applies to any manual or other work, in any medium,
+ that contains a notice placed by the copyright holder saying it can
+ be distributed under the terms of this License. Such a notice
+ grants a world-wide, royalty-free license, unlimited in duration,
+ to use that work under the conditions stated herein. The
+ "Document", below, refers to any such manual or work. Any member
+ of the public is a licensee, and is addressed as "you". You accept
+ the license if you copy, modify or distribute the work in a way
+ requiring permission under copyright law.
+
+ A "Modified Version" of the Document means any work containing the
+ Document or a portion of it, either copied verbatim, or with
+ modifications and/or translated into another language.
+
+ A "Secondary Section" is a named appendix or a front-matter section
+ of the Document that deals exclusively with the relationship of the
+ publishers or authors of the Document to the Document's overall
+ subject (or to related matters) and contains nothing that could
+ fall directly within that overall subject. (Thus, if the Document
+ is in part a textbook of mathematics, a Secondary Section may not
+ explain any mathematics.) The relationship could be a matter of
+ historical connection with the subject or with related matters, or
+ of legal, commercial, philosophical, ethical or political position
+ regarding them.
+
+ The "Invariant Sections" are certain Secondary Sections whose
+ titles are designated, as being those of Invariant Sections, in the
+ notice that says that the Document is released under this License.
+ If a section does not fit the above definition of Secondary then it
+ is not allowed to be designated as Invariant. The Document may
+ contain zero Invariant Sections. If the Document does not identify
+ any Invariant Sections then there are none.
+
+ The "Cover Texts" are certain short passages of text that are
+ listed, as Front-Cover Texts or Back-Cover Texts, in the notice
+ that says that the Document is released under this License.
+ A Front-Cover Text may be at most 5 words, and a Back-Cover Text
+ may be at most 25 words.
+
+ A "Transparent" copy of the Document means a machine-readable copy,
+ represented in a format whose specification is available to the
+ general public, that is suitable for revising the document
+ straightforwardly with generic text editors or (for images composed
+ of pixels) generic paint programs or (for drawings) some widely
+ available drawing editor, and that is suitable for input to text
+ formatters or for automatic translation to a variety of formats
+ suitable for input to text formatters. A copy made in an otherwise
+ Transparent file format whose markup, or absence of markup, has
+ been arranged to thwart or discourage subsequent modification by
+ readers is not Transparent. An image format is not Transparent if
+ used for any substantial amount of text. A copy that is not
+ "Transparent" is called "Opaque".
+
+ Examples of suitable formats for Transparent copies include plain
+ ASCII without markup, Texinfo input format, LaTeX input format,
+ SGML or XML using a publicly available DTD, and standard-conforming
+ simple HTML, PostScript or PDF designed for human modification.
+ Examples of transparent image formats include PNG, XCF and JPG.
+ Opaque formats include proprietary formats that can be read and
+ edited only by proprietary word processors, SGML or XML for which
+ the DTD and/or processing tools are not generally available, and
+ the machine-generated HTML, PostScript or PDF produced by some word
+ processors for output purposes only.
+
+ The "Title Page" means, for a printed book, the title page itself,
+ plus such following pages as are needed to hold, legibly, the
+ material this License requires to appear in the title page. For
+ works in formats which do not have any title page as such, "Title
+ Page" means the text near the most prominent appearance of the
+ work's title, preceding the beginning of the body of the text.
+
+ The "publisher" means any person or entity that distributes copies
+ of the Document to the public.
+
+ A section "Entitled XYZ" means a named subunit of the Document
+ whose title either is precisely XYZ or contains XYZ in parentheses
+ following text that translates XYZ in another language. (Here XYZ
+ stands for a specific section name mentioned below, such as
+ "Acknowledgements", "Dedications", "Endorsements", or "History".)
+ To "Preserve the Title" of such a section when you modify the
+ Document means that it remains a section "Entitled XYZ" according
+ to this definition.
+
+ The Document may include Warranty Disclaimers next to the notice
+ which states that this License applies to the Document. These
+ Warranty Disclaimers are considered to be included by reference in
+ this License, but only as regards disclaiming warranties: any other
+ implication that these Warranty Disclaimers may have is void and
+ has no effect on the meaning of this License.
+
+2. VERBATIM COPYING
+
+ You may copy and distribute the Document in any medium, either
+ commercially or noncommercially, provided that this License, the
+ copyright notices, and the license notice saying this License
+ applies to the Document are reproduced in all copies, and that you
+ add no other conditions whatsoever to those of this License. You
+ may not use technical measures to obstruct or control the reading
+ or further copying of the copies you make or distribute. However,
+ you may accept compensation in exchange for copies. If you
+ distribute a large enough number of copies you must also follow the
+ conditions in section 3.
+
+ You may also lend copies, under the same conditions stated above,
+ and you may publicly display copies.
+
+3. COPYING IN QUANTITY
+
+ If you publish printed copies (or copies in media that commonly
+ have printed covers) of the Document, numbering more than 100, and
+ the Document's license notice requires Cover Texts, you must
+ enclose the copies in covers that carry, clearly and legibly, all
+ these Cover Texts: Front-Cover Texts on the front cover, and
+ Back-Cover Texts on the back cover. Both covers must also clearly
+ and legibly identify you as the publisher of these copies. The
+ front cover must present the full title with all words of the title
+ equally prominent and visible. You may add other material on the
+ covers in addition. Copying with changes limited to the covers, as
+ long as they preserve the title of the Document and satisfy these
+ conditions, can be treated as verbatim copying in other respects.
+
+ If the required texts for either cover are too voluminous to fit
+ legibly, you should put the first ones listed (as many as fit
+ reasonably) on the actual cover, and continue the rest onto
+ adjacent pages.
+
+ If you publish or distribute Opaque copies of the Document
+ numbering more than 100, you must either include a machine-readable
+ Transparent copy along with each Opaque copy, or state in or with
+ each Opaque copy a computer-network location from which the general
+ network-using public has access to download using public-standard
+ network protocols a complete Transparent copy of the Document, free
+ of added material. If you use the latter option, you must take
+ reasonably prudent steps, when you begin distribution of Opaque
+ copies in quantity, to ensure that this Transparent copy will
+ remain thus accessible at the stated location until at least one
+ year after the last time you distribute an Opaque copy (directly or
+ through your agents or retailers) of that edition to the public.
+
+ It is requested, but not required, that you contact the authors of
+ the Document well before redistributing any large number of copies,
+ to give them a chance to provide you with an updated version of the
+ Document.
+
+4. MODIFICATIONS
+
+ You may copy and distribute a Modified Version of the Document
+ under the conditions of sections 2 and 3 above, provided that you
+ release the Modified Version under precisely this License, with the
+ Modified Version filling the role of the Document, thus licensing
+ distribution and modification of the Modified Version to whoever
+ possesses a copy of it. In addition, you must do these things in
+ the Modified Version:
+
+ #+attr_texinfo: :enum A
+ 1. Use in the Title Page (and on the covers, if any) a title
+ distinct from that of the Document, and from those of previous
+ versions (which should, if there were any, be listed in the
+ History section of the Document). You may use the same title as
+ a previous version if the original publisher of that version
+ gives permission.
+
+ 2. List on the Title Page, as authors, one or more persons or
+ entities responsible for authorship of the modifications in the
+ Modified Version, together with at least five of the principal
+ authors of the Document (all of its principal authors, if it has
+ fewer than five), unless they release you from this requirement.
+
+ 3. State on the Title page the name of the publisher of the
+ Modified Version, as the publisher.
+
+ 4. Preserve all the copyright notices of the Document.
+
+ 5. Add an appropriate copyright notice for your modifications
+ adjacent to the other copyright notices.
+
+ 6. Include, immediately after the copyright notices, a license
+ notice giving the public permission to use the Modified Version
+ under the terms of this License, in the form shown in the
+ Addendum below.
+
+ 7. Preserve in that license notice the full lists of Invariant
+ Sections and required Cover Texts given in the Document's
+ license notice.
+
+ 8. Include an unaltered copy of this License.
+
+ 9. Preserve the section Entitled "History", Preserve its Title, and
+ add to it an item stating at least the title, year, new authors,
+ and publisher of the Modified Version as given on the Title
+ Page. If there is no section Entitled "History" in the Document,
+ create one stating the title, year, authors, and publisher of
+ the Document as given on its Title Page, then add an item
+ describing the Modified Version as stated in the previous
+ sentence.
+
+ 10. Preserve the network location, if any, given in the Document
+ for public access to a Transparent copy of the Document, and
+ likewise the network locations given in the Document for
+ previous versions it was based on. These may be placed in the
+ "History" section. You may omit a network location for a work
+ that was published at least four years before the Document
+ itself, or if the original publisher of the version it refers
+ to gives permission.
+
+ 11. For any section Entitled "Acknowledgements" or "Dedications",
+ Preserve the Title of the section, and preserve in the section
+ all the substance and tone of each of the contributor
+ acknowledgements and/or dedications given therein.
+
+ 12. Preserve all the Invariant Sections of the Document, unaltered
+ in their text and in their titles. Section numbers or the
+ equivalent are not considered part of the section titles.
+
+ 13. Delete any section Entitled "Endorsements". Such a section may
+ not be included in the Modified Version.
+
+ 14. Do not retitle any existing section to be Entitled
+ "Endorsements" or to conflict in title with any Invariant
+ Section.
+
+ 15. Preserve any Warranty Disclaimers.
+
+ If the Modified Version includes new front-matter sections or
+ appendices that qualify as Secondary Sections and contain no material
+ copied from the Document, you may at your option designate some or all
+ of these sections as invariant. To do this, add their titles to the
+ list of Invariant Sections in the Modified Version's license notice.
+ These titles must be distinct from any other section titles.
+
+ You may add a section Entitled "Endorsements", provided it contains
+ nothing but endorsements of your Modified Version by various
+ parties---for example, statements of peer review or that the text has
+ been approved by an organization as the authoritative definition of a
+ standard.
+
+ You may add a passage of up to five words as a Front-Cover Text, and a
+ passage of up to 25 words as a Back-Cover Text, to the end of the list
+ of Cover Texts in the Modified Version. Only one passage of
+ Front-Cover Text and one of Back-Cover Text may be added by (or
+ through arrangements made by) any one entity. If the Document already
+ includes a cover text for the same cover, previously added by you or
+ by arrangement made by the same entity you are acting on behalf of,
+ you may not add another; but you may replace the old one, on explicit
+ permission from the previous publisher that added the old one.
+
+ The author(s) and publisher(s) of the Document do not by this License
+ give permission to use their names for publicity for or to assert or
+ imply endorsement of any Modified Version.
+
+5. COMBINING DOCUMENTS
+
+ You may combine the Document with other documents released under
+ this License, under the terms defined in section 4 above for
+ modified versions, provided that you include in the combination all
+ of the Invariant Sections of all of the original documents,
+ unmodified, and list them all as Invariant Sections of your
+ combined work in its license notice, and that you preserve all
+ their Warranty Disclaimers.
+
+ The combined work need only contain one copy of this License, and
+ multiple identical Invariant Sections may be replaced with a single
+ copy. If there are multiple Invariant Sections with the same name
+ but different contents, make the title of each such section unique
+ by adding at the end of it, in parentheses, the name of the
+ original author or publisher of that section if known, or else
+ a unique number. Make the same adjustment to the section titles in
+ the list of Invariant Sections in the license notice of the
+ combined work.
+
+ In the combination, you must combine any sections Entitled
+ "History" in the various original documents, forming one section
+ Entitled "History"; likewise combine any sections Entitled
+ "Acknowledgements", and any sections Entitled "Dedications". You
+ must delete all sections Entitled "Endorsements."
+
+6. COLLECTIONS OF DOCUMENTS
+
+ You may make a collection consisting of the Document and other
+ documents released under this License, and replace the individual
+ copies of this License in the various documents with a single copy
+ that is included in the collection, provided that you follow the
+ rules of this License for verbatim copying of each of the documents
+ in all other respects.
+
+ You may extract a single document from such a collection, and
+ distribute it individually under this License, provided you insert
+ a copy of this License into the extracted document, and follow this
+ License in all other respects regarding verbatim copying of that
+ document.
+
+7. AGGREGATION WITH INDEPENDENT WORKS
+
+ A compilation of the Document or its derivatives with other
+ separate and independent documents or works, in or on a volume of
+ a storage or distribution medium, is called an "aggregate" if the
+ copyright resulting from the compilation is not used to limit the
+ legal rights of the compilation's users beyond what the individual
+ works permit. When the Document is included in an aggregate, this
+ License does not apply to the other works in the aggregate which
+ are not themselves derivative works of the Document.
+
+ If the Cover Text requirement of section 3 is applicable to these
+ copies of the Document, then if the Document is less than one half
+ of the entire aggregate, the Document's Cover Texts may be placed
+ on covers that bracket the Document within the aggregate, or the
+ electronic equivalent of covers if the Document is in electronic
+ form. Otherwise they must appear on printed covers that bracket
+ the whole aggregate.
+
+8. TRANSLATION
+
+ Translation is considered a kind of modification, so you may
+ distribute translations of the Document under the terms of
+ section 4. Replacing Invariant Sections with translations requires
+ special permission from their copyright holders, but you may
+ include translations of some or all Invariant Sections in addition
+ to the original versions of these Invariant Sections. You may
+ include a translation of this License, and all the license notices
+ in the Document, and any Warranty Disclaimers, provided that you
+ also include the original English version of this License and the
+ original versions of those notices and disclaimers. In case of
+ a disagreement between the translation and the original version of
+ this License or a notice or disclaimer, the original version will
+ prevail.
+
+ If a section in the Document is Entitled "Acknowledgements",
+ "Dedications", or "History", the requirement (section 4) to
+ Preserve its Title (section 1) will typically require changing the
+ actual title.
+
+9. TERMINATION
+
+ You may not copy, modify, sublicense, or distribute the Document
+ except as expressly provided under this License. Any attempt
+ otherwise to copy, modify, sublicense, or distribute it is void,
+ and will automatically terminate your rights under this License.
+
+ However, if you cease all violation of this License, then your
+ license from a particular copyright holder is reinstated (a)
+ provisionally, unless and until the copyright holder explicitly and
+ finally terminates your license, and (b) permanently, if the
+ copyright holder fails to notify you of the violation by some
+ reasonable means prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+ reinstated permanently if the copyright holder notifies you of the
+ violation by some reasonable means, this is the first time you have
+ received notice of violation of this License (for any work) from
+ that copyright holder, and you cure the violation prior to 30 days
+ after your receipt of the notice.
+
+ Termination of your rights under this section does not terminate
+ the licenses of parties who have received copies or rights from you
+ under this License. If your rights have been terminated and not
+ permanently reinstated, receipt of a copy of some or all of the
+ same material does not give you any rights to use it.
+
+10. FUTURE REVISIONS OF THIS LICENSE
+
+ The Free Software Foundation may publish new, revised versions of
+ the GNU Free Documentation License from time to time. Such new
+ versions will be similar in spirit to the present version, but may
+ differ in detail to address new problems or concerns. See
+ http://www.gnu.org/copyleft/.
+
+ Each version of the License is given a distinguishing version
+ number. If the Document specifies that a particular numbered
+ version of this License "or any later version" applies to it, you
+ have the option of following the terms and conditions either of
+ that specified version or of any later version that has been
+ published (not as a draft) by the Free Software Foundation. If
+ the Document does not specify a version number of this License,
+ you may choose any version ever published (not as a draft) by the
+ Free Software Foundation. If the Document specifies that a proxy
+ can decide which future versions of this License can be used, that
+ proxy's public statement of acceptance of a version permanently
+ authorizes you to choose that version for the Document.
+
+11. RELICENSING
+
+ "Massive Multiauthor Collaboration Site" (or "MMC Site") means any
+ World Wide Web server that publishes copyrightable works and also
+ provides prominent facilities for anybody to edit those works.
+ A public wiki that anybody can edit is an example of such
+ a server. A "Massive Multiauthor Collaboration" (or "MMC")
+ contained in the site means any set of copyrightable works thus
+ published on the MMC site.
+
+ "CC-BY-SA" means the Creative Commons Attribution-Share Alike 3.0
+ license published by Creative Commons Corporation,
+ a not-for-profit corporation with a principal place of business in
+ San Francisco, California, as well as future copyleft versions of
+ that license published by that same organization.
+
+ "Incorporate" means to publish or republish a Document, in whole
+ or in part, as part of another Document.
+
+ An MMC is "eligible for relicensing" if it is licensed under this
+ License, and if all works that were first published under this
+ License somewhere other than this MMC, and subsequently
+ incorporated in whole or in part into the MMC, (1) had no cover
+ texts or invariant sections, and (2) were thus incorporated prior
+ to November 1, 2008.
+
+ The operator of an MMC Site may republish an MMC contained in the
+ site under CC-BY-SA on the same site at any time before August 1,
+ 2009, provided the MMC is eligible for relicensing.
+
+#+texinfo: @page
+
+* ADDENDUM: How to use this License for your documents
+:PROPERTIES:
+:UNNUMBERED: notoc
+:END:
+
+To use this License in a document you have written, include a copy of
+the License in the document and put the following copyright and
+license notices just after the title page:
+
+#+begin_example
+ Copyright (C) YEAR YOUR NAME.
+ Permission is granted to copy, distribute and/or modify this document
+ under the terms of the GNU Free Documentation License, Version 1.3
+ or any later version published by the Free Software Foundation;
+ with no Invariant Sections, no Front-Cover Texts, and no Back-Cover
+ Texts. A copy of the license is included in the section entitled ``GNU
+ Free Documentation License''.
+#+end_example
+
+If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts,
+replace the "with...Texts."\nbsp{}line with this:
+
+#+begin_example
+ with the Invariant Sections being LIST THEIR TITLES, with
+ the Front-Cover Texts being LIST, and with the Back-Cover Texts
+ being LIST.
+#+end_example
+
+If you have Invariant Sections without Cover Texts, or some other
+combination of the three, merge those two alternatives to suit the
+situation.
+
+If your document contains nontrivial examples of program code, we
+recommend releasing these examples in parallel under your choice of
+free software license, such as the GNU General Public License, to
+permit their use in free software.
+
diff --git a/doc/org-guide.org b/doc/org-guide.org
new file mode 100644
index 0000000..9e76e5a
--- /dev/null
+++ b/doc/org-guide.org
@@ -0,0 +1,2656 @@
+#+title: Org Mode Compact Guide
+#+subtitle: Release {{{version}}}
+#+author: The Org Mode Developers
+#+language: en
+
+#+texinfo: @insertcopying
+
+* Copying
+:PROPERTIES:
+:copying: t
+:END:
+
+Copyright \copy 2004--2019 Free Software Foundation, Inc.
+
+#+begin_quote
+Permission is granted to copy, distribute and/or modify this document
+under the terms of the GNU Free Documentation License, Version 1.3 or
+any later version published by the Free Software Foundation; with no
+Invariant Sections, with the Front-Cover Texts being "A GNU Manual,"
+and with the Back-Cover Texts as in (a) below. A copy of the license
+is included in the section entitled "GNU Free Documentation License."
+in the full Org manual, which is distributed together with this
+compact guide.
+
+(a) The FSF's Back-Cover Text is: "You have the freedom to copy and
+modify this GNU manual."
+#+end_quote
+
+* Introduction
+:PROPERTIES:
+:DESCRIPTION: Welcome!
+:END:
+
+Org is a mode for keeping notes, maintaining TODO lists, and doing
+project planning with a fast and effective plain-text system. It is
+also an authoring and publishing system, and it supports working with
+source code for literal programming and reproducible research.
+
+This document is a much compressed derivative of the [[info:org][comprehensive Org
+mode manual]]. It contains all basic features and commands, along with
+important hints for customization. It is intended for beginners who
+would shy back from a 200 pages manual because of sheer size.
+
+** Installation
+:PROPERTIES:
+:UNNUMBERED: notoc
+:END:
+
+#+attr_texinfo: :tag Important
+#+begin_quote
+If you are using a version of Org that is part of the Emacs
+distribution, please skip this section and go directly to [[*Activation]].
+#+end_quote
+
+If you have downloaded Org from the web, either as a distribution
+=.zip= or =.tar= file, or as a Git archive, it is best to run it
+directly from the distribution directory. You need to add the =lisp/=
+subdirectories to the Emacs load path. To do this, add the following
+line to your Emacs init file:
+
+: (add-to-list 'load-path "~/path/to/orgdir/lisp")
+: (add-to-list 'load-path "~/path/to/orgdir/contrib/lisp" t)
+
+#+texinfo: @noindent
+If you have been using git or a tar ball to get Org, you need to run
+the following command to generate autoload information.
+
+: make autoloads
+
+** Activation
+:PROPERTIES:
+:UNNUMBERED: notoc
+:END:
+
+Add the following lines to your Emacs init file. The last four lines
+define /global/ keys for some commands---please choose suitable keys
+yourself.
+
+#+begin_src emacs-lisp
+;; The following lines are always needed. Choose your own keys.
+(global-set-key (kbd "C-l") 'org-store-link)
+(global-set-key (kbd "C-a") 'org-agenda)
+(global-set-key (kbd "C-c") 'org-capture)
+(global-set-key (kbd "C-b") 'org-switchb)
+#+end_src
+
+Files with extension =.org= will be put into Org mode automatically.
+
+** Feedback
+:PROPERTIES:
+:UNNUMBERED: notoc
+:END:
+
+If you find problems with Org, or if you have questions, remarks, or
+ideas about it, please mail to the Org mailing list
+mailto:emacs-orgmode@gnu.org. For information on how to submit bug
+reports, see the main manual.
+
+* Document Structure
+:PROPERTIES:
+:DESCRIPTION: A tree works like your brain.
+:END:
+
+Org is an outliner. Outlines allow a document to be organized in
+a hierarchical structure, which, least for me, is the best
+representation of notes and thoughts. An overview of this structure
+is achieved by folding, i.e., hiding large parts of the document to
+show only the general document structure and the parts currently being
+worked on. Org greatly simplifies the use of outlines by compressing
+the entire show and hide functionalities into a single command,
+~org-cycle~, which is bound to the {{{kbd(TAB)}}} key.
+
+** Headlines
+:PROPERTIES:
+:DESCRIPTION: How to typeset Org tree nodes.
+:END:
+
+Headlines define the structure of an outline tree. The headlines in
+Org start with one or more stars, on the left margin[fn:1]. For
+example:
+
+#+begin_example
+,* Top level headline
+,** Second level
+,*** Third level
+ some text
+,*** Third level
+ more text
+,* Another top level headline
+#+end_example
+
+Note that a headline named after ~org-footnote-section~, which
+defaults to =Footnotes=, is considered as special. A subtree with
+this headline will be silently ignored by exporting functions.
+
+Some people find the many stars too noisy and would prefer an outline
+that has whitespace followed by a single star as headline starters.
+See [[*Miscellaneous]] for a setup to realize this.
+
+** Visibility Cycling
+:PROPERTIES:
+:DESCRIPTION: Show and hide, much simplified.
+:END:
+
+Outlines make it possible to hide parts of the text in the buffer.
+Org uses just two commands, bound to {{{kbd(TAB)}}} and
+{{{kbd{S-TAB)}}} to change the visibility in the buffer.
+
+#+attr_texinfo: :sep ,
+- {{{kbd(TAB)}}} ::
+
+ /Subtree cycling/: Rotate current subtree among the states
+
+ : ,-> FOLDED -> CHILDREN -> SUBTREE --.
+ : '-----------------------------------'
+
+ When called with a prefix argument ({{{kbd(C-u TAB)}}}), or with the
+ Shift key, global cycling is invoked.
+
+- {{{kbd(S-TAB)}}}, {{{kbd(C-u TAB)}}} ::
+
+ /Global cycling/: Rotate the entire buffer among the states
+
+ : ,-> OVERVIEW -> CONTENTS -> SHOW ALL --.
+ : '--------------------------------------'
+
+- {{{kbd(C-u C-u C-u TAB)}}} ::
+
+ Show all, including drawers.
+
+When Emacs first visits an Org file, the global state is set to
+OVERVIEW, i.e., only the top level headlines are visible. This can be
+configured through the variable ~org-startup-folded~, or on a per-file
+basis by adding a =STARTUP= keyword to =overview=, =content=, or
+=showall=, like this:
+
+: #+STARTUP: content
+
+** Motion
+:PROPERTIES:
+:DESCRIPTION: Jumping to other headlines.
+:END:
+
+The following commands jump to other headlines in the buffer.
+
+- {{{kbd(C-c C-n)}}} :: Next heading.
+
+- {{{kbd(C-c C-p)}}} :: Previous heading.
+
+- {{{kbd(C-c C-f)}}} :: Next heading same level.
+
+- {{{kbd(C-c C-b)}}} :: Previous heading same level.
+
+- {{{kbd(C-c C-u)}}} :: Backward to higher level heading.
+
+** Structure Editing
+:PROPERTIES:
+:DESCRIPTION: Changing sequence and level of headlines.
+:END:
+
+#+attr_texinfo: :sep ,
+- {{{kbd(M-RET)}}} ::
+
+ Insert new heading with same level as current. If point is in
+ a plain list item, a new item is created (see [[Plain Lists]]). When
+ this command is used in the middle of a line, the line is split and
+ the rest of the line becomes the new headline[fn:2].
+
+- {{{kbd(M-S-RET)}}} ::
+
+ Insert new TODO entry with same level as current heading.
+
+- {{{kbd(TAB)}}} in new, empty entry ::
+
+ In a new entry with no text yet, {{{kbd(TAB)}}} cycles through
+ reasonable levels.
+
+- {{{kbd(M-LEFT)}}}, {{{kbd(M-RIGHT)}}} ::
+
+ Promote or demote current heading by one level.
+
+- {{{kbd(M-UP)}}}, {{{kbd(M-DOWN)}}} ::
+
+ Move subtree up or down, i.e., swap with previous or next subtree of
+ same level.
+
+- {{{kbd(C-c C-w)}}} ::
+
+ Refile entry or region to a different location. See [[*Refile and
+ Copy]].
+
+- {{{kbd(C-x n s)}}}, {{{kbd(C-x n w)}}} ::
+
+ Narrow buffer to current subtree and widen it again.
+
+When there is an active region (Transient Mark mode), promotion and
+demotion work on all headlines in the region.
+
+** Sparse Trees
+:PROPERTIES:
+:DESCRIPTION: Matches embedded in context.
+:END:
+
+An important feature of Org mode is the ability to construct /sparse
+trees/ for selected information in an outline tree, so that the entire
+document is folded as much as possible, but the selected information
+is made visible along with the headline structure above it[fn:3].
+Just try it out and you will see immediately how it works.
+
+Org mode contains several commands creating such trees, all these
+commands can be accessed through a dispatcher:
+
+- {{{kbd(C-c /)}}} ::
+
+ This prompts for an extra key to select a sparse-tree creating
+ command.
+
+- {{{kbd(C-c / r)}}} ::
+
+ Occur. Prompts for a regexp and shows a sparse tree with all
+ matches. Each match is also highlighted; the highlights disappear
+ by pressing {{{kbd(C-c C-c)}}}.
+
+ The other sparse tree commands select headings based on TODO
+ keywords, tags, or properties and will be discussed later in this
+ manual.
+
+** Plain Lists
+:PROPERTIES:
+:DESCRIPTION: Additional structure within an entry.
+:END:
+
+Within an entry of the outline tree, hand-formatted lists can provide
+additional structure. They also provide a way to create lists of
+checkboxes (see [[*Checkboxes]]). Org supports editing such lists, and
+every exporter (see [[*Exporting]]) can parse and format them.
+
+Org knows ordered lists, unordered lists, and description lists.
+
+#+attr_texinfo: :indic @bullet
+- /Unordered/ list items start with =-=, =+=, or =*= as bullets.
+
+- /Ordered/ list items start with =1.=, or =1)=.
+
+- /Description/ list use =::= to separate the /term/ from the
+ description.
+
+Items belonging to the same list must have the same indentation on the
+first line. An item ends before the next line that is indented like
+its bullet/number, or less. A list ends when all items are closed, or
+before two blank lines. An example:
+
+#+begin_example
+,* Lord of the Rings
+ My favorite scenes are (in this order)
+ 1. The attack of the Rohirrim
+ 2. Eowyn's fight with the witch king
+ + this was already my favorite scene in the book
+ + I really like Miranda Otto.
+ Important actors in this film are:
+ - Elijah Wood :: He plays Frodo
+ - Sean Astin :: He plays Sam, Frodo's friend.
+#+end_example
+
+The following commands act on items when point is in the first line of
+an item (the line with the bullet or number).
+
+#+attr_texinfo: :sep ,
+- {{{kbd(TAB)}}} ::
+
+ Items can be folded just like headline levels.
+
+- {{{kbd(M-RET)}}} ::
+
+ Insert new item at current level. With a prefix argument, force
+ a new heading (see [[*Structure Editing]]).
+
+- {{{kbd(M-S-RET)}}} ::
+
+ Insert a new item with a checkbox (see [[*Checkboxes]]).
+
+- {{{kbd(M-S-UP)}}}, {{{kbd(M-S-DOWN)}}} ::
+
+ Move the item including subitems up/down (swap with previous/next
+ item of same indentation). If the list is ordered, renumbering is
+ automatic.
+
+- {{{kbd(M-LEFT)}}}, {{{kbd(M-RIGHT)}}} ::
+
+ Decrease/increase the indentation of an item, leaving children
+ alone.
+
+- {{{kbd(M-S-LEFT)}}}, {{{kbd(M-S-RIGHT)}}} ::
+
+ Decrease/increase the indentation of the item, including subitems.
+
+- {{{kbd(C-c C-c)}}} ::
+
+ If there is a checkbox (see [[*Checkboxes]]) in the item line, toggle
+ the state of the checkbox. Also verify bullets and indentation
+ consistency in the whole list.
+
+- {{{kbd(C-c -)}}} ::
+
+ Cycle the entire list level through the different itemize/enumerate
+ bullets (=-=, =+=, =*=, =1.=, =1)=).
+
+* Tables
+:PROPERTIES:
+:DESCRIPTION: Pure magic for quick formatting.
+:END:
+
+Org comes with a fast and intuitive table editor. Spreadsheet-like
+calculations are supported in connection with the Emacs Calc package
+(see [[info:calc][GNU Emacs Calculator Manual]]).
+
+Org makes it easy to format tables in plain ASCII. Any line with =|=
+as the first non-whitespace character is considered part of a table.
+=|= is also the column separator. A table might look like this:
+
+#+begin_example
+| Name | Phone | Age |
+|-------+-------+-----|
+| Peter | 1234 | 17 |
+| Anna | 4321 | 25 |
+#+end_example
+
+A table is re-aligned automatically each time you press {{{kbd(TAB)}}}
+or {{{kbd(RET)}}} or {{{kbd(C-c C-c)}}} inside the table.
+{{{kbd(TAB)}}} also moves to the next field ({{{kbd(RET)}}} to the
+next row) and creates new table rows at the end of the table or before
+horizontal lines. The indentation of the table is set by the first
+line. Any line starting with =|-= is considered as a horizontal
+separator line and will be expanded on the next re-align to span the
+whole table width. So, to create the above table, you would only type
+
+: |Name|Phone|Age|
+: |-
+
+#+texinfo: @noindent
+and then press {{{kbd(TAB)}}} to align the table and start filling in
+fields. Even faster would be to type =|Name|Phone|Age= followed by
+{{{kbd(C-c RET)}}}.
+
+When typing text into a field, Org treats {{{kbd(DEL)}}},
+{{{kbd(Backspace)}}}, and all character keys in a special way, so that
+inserting and deleting avoids shifting other fields. Also, when
+typing /immediately after point was moved into a new field with
+{{{kbd(TAB)}}}, {{{kbd(S-TAB)}}} or {{{kbd(RET)}}}/, the field is
+automatically made blank.
+
+** Creation and conversion
+:PROPERTIES:
+:UNNUMBERED: notoc
+:END:
+
+- {{{kbd(C-c |)}}} ::
+
+ Convert the active region to table. If every line contains at least
+ one {{{kbd(TAB)}}} character, the function assumes that the material
+ is tab separated. If every line contains a comma, comma-separated
+ values (CSV) are assumed. If not, lines are split at whitespace
+ into fields.
+
+ If there is no active region, this command creates an empty Org
+ table. But it is easier just to start typing, like {{{kbd(|
+ N a m e | P h o n e | A g e RET | - TAB)}}}.
+
+** Re-aligning and field motion
+:PROPERTIES:
+:UNNUMBERED: notoc
+:END:
+
+#+attr_texinfo: :sep ,
+- {{{kbd(C-c C-c)}}} ::
+
+ Re-align the table without moving point.
+
+- {{{kbd(TAB)}}} ::
+
+ Re-align the table, move to the next field. Creates a new row if
+ necessary.
+
+- {{{kbd(S-TAB)}}} ::
+
+ Re-align, move to previous field.
+
+- {{{kbd(RET)}}} ::
+
+ Re-align the table and move down to next row. Creates a new row if
+ necessary.
+
+- {{{kbd(S-UP)}}}, {{{kbd(S-DOWN)}}}, {{{kbd(S-LEFT)}}}, {{{kbd(S-RIGHT)}}} ::
+
+ Move a cell up, down, left, and right by swapping with adjacent
+ cell.
+
+** Column and row editing
+:PROPERTIES:
+:UNNUMBERED: notoc
+:END:
+
+- {{{kbd(M-LEFT)}}}, {{{kbd(M-RIGHT)}}} ::
+
+ Move the current column left/right.
+
+- {{{kbd(M-S-LEFT)}}} ::
+
+ Kill the current column.
+
+- {{{kbd(M-S-RIGHT)}}} ::
+
+ Insert a new column to the left of point position.
+
+- {{{kbd(M-UP)}}}, {{{kbd(M-DOWN)}}} ::
+
+ Move the current row up/down.
+
+- {{{kbd(M-S-UP)}}} ::
+
+ Kill the current row or horizontal line.
+
+- {{{kbd(M-S-DOWN)}}} ::
+
+ Insert a new row above the current row. With a prefix argument, the
+ line is created below the current one.
+
+- {{{kbd(C-c -)}}} ::
+
+ Insert a horizontal line below current row. With a prefix argument,
+ the line is created above the current line.
+
+- {{{kbd(C-c RET)}}} ::
+
+ Insert a horizontal line below current row, and move the point into
+ the row below that line.
+
+- {{{kbd(C-c ^)}}} ::
+
+ Sort the table lines in the region. The position of point indicates
+ the column to be used for sorting, and the range of lines is the
+ range between the nearest horizontal separator lines, or the entire
+ table.
+
+* Hyperlinks
+:PROPERTIES:
+:DESCRIPTION: Notes in context.
+:END:
+
+Like HTML, Org provides links inside a file, external links to other
+files, Usenet articles, emails, and much more.
+
+Org recognizes plain URIs, possibly wrapped within angle brackets, and
+activate them as clickable links. The general link format, however,
+looks like this:
+
+: [[LINK][DESCRIPTION]]
+
+#+texinfo: @noindent
+or alternatively
+
+: [[LINK]]
+
+Once a link in the buffer is complete, with all brackets present, Org
+changes the display so that =DESCRIPTION= is displayed instead of
+=[[LINK][DESCRIPTION]]= and =LINK= is displayed instead of =[[LINK]]=.
+To edit the invisible {{{var(LINK)}}} part, use {{{kbd(C-c C-l)}}}
+with the point on the link.
+
+** Internal links
+:PROPERTIES:
+:UNNUMBERED: notoc
+:END:
+
+If the link does not look like a URL, it is considered to be internal
+in the current file. The most important case is a link like
+=[[#my-custom-id]]= which links to the entry with the =CUSTOM_ID= property
+=my-custom-id=.
+
+Links such as =[[My Target]]= or =[[My Target][Find my target]]= lead
+to a text search in the current file for the corresponding target,
+which looks like =<<My Target>>=.
+
+** External Links
+:PROPERTIES:
+:UNNUMBERED: notoc
+:END:
+
+Org supports links to files, websites, Usenet and email messages, BBDB
+database entries and links to both IRC conversations and their logs.
+External links are URL-like locators. They start with a short
+identifying string followed by a colon. There can be no space after
+the colon. Here are some examples:
+
+| =http://www.astro.uva.nl/=dominik= | on the web |
+| =file:/home/dominik/images/jupiter.jpg= | file, absolute path |
+| =/home/dominik/images/jupiter.jpg= | same as above |
+| =file:papers/last.pdf= | file, relative path |
+| =./papers/last.pdf= | same as above |
+| =file:projects.org= | another Org file |
+| =docview:papers/last.pdf::NNN= | open in DocView mode at page {{{var(NNN)}}} |
+| =id:B7423F4D-2E8A-471B-8810-C40F074717E9= | link to heading by ID |
+| =news:comp.emacs= | Usenet link |
+| =mailto:adent@galaxy.net= | mail link |
+| =mhe:folder#id= | MH-E message link |
+| =rmail:folder#id= | Rmail message link |
+| =gnus:group#id= | Gnus article link |
+| =bbdb:R.*Stallman= | BBDB link (with regexp) |
+| =irc:/irc.com/#emacs/bob= | IRC link |
+| =info:org#Hyperlinks= | Info node link |
+
+File links can contain additional information to make Emacs jump to
+a particular location in the file when following a link. This can be
+a line number or a search option after a double colon. Here are a few
+examples,, together with an explanation:
+
+| =file:~/code/main.c::255= | Find line 255 |
+| =file:~/xx.org::My Target= | Find =<<My Target>>= |
+| =[[file:~/xx.org::#my-custom-id]]= | Find entry with a custom ID |
+
+** Handling Links
+:PROPERTIES:
+:UNNUMBERED: notoc
+:END:
+
+Org provides methods to create a link in the correct syntax, to insert
+it into an Org file, and to follow the link.
+
+The main function is ~org-store-link~, called with {{{kbd(M-x
+org-store-link)}}}. Because of its importance, we suggest to bind it
+to a widely available key (see [[*Activation]]). It stores a link to the
+current location. The link is stored for later insertion into an Org
+buffer---see below.
+
+From an Org buffer, the following commands create, navigate or, more
+generally, act on links.
+
+#+attr_texinfo: :sep ,
+- {{{kbd(C-c C-l)}}} ::
+
+ Insert a link. This prompts for a link to be inserted into the
+ buffer. You can just type a link, or use history keys {{{kbd(UP)}}}
+ and {{{kbd(DOWN)}}} to access stored links. You will be prompted
+ for the description part of the link.
+
+ When called with a {{{kbd(C-u)}}} prefix argument, file name
+ completion is used to link to a file.
+
+- {{{kbd(C-c C-l)}}} (with point on existing link) ::
+
+ When point is on an existing link, {{{kbd(C-c C-l)}}} allows you to
+ edit the link and description parts of the link.
+
+- {{{kbd(C-c C-o)}}} ::
+
+ Open link at point.
+
+- {{{kbd(C-c &)}}} ::
+
+ Jump back to a recorded position. A position is recorded by the
+ commands following internal links, and by {{{kbd(C-c %)}}}. Using
+ this command several times in direct succession moves through a ring
+ of previously recorded positions.
+
+* TODO Items
+:PROPERTIES:
+:DESCRIPTION: Every tree branch can be a TODO item.
+:END:
+
+Org mode does not require TODO lists to live in separate documents.
+Instead, TODO items are part of a notes file, because TODO items
+usually come up while taking notes! With Org mode, simply mark any
+entry in a tree as being a TODO item. In this way, information is not
+duplicated, and TODO items remain in the context from which they
+emerged.
+
+Org mode provides methods to give you an overview of all the things
+that you have to do, collected from many files.
+
+** Basic TODO Functionality
+:PROPERTIES:
+:DESCRIPTION: Marking and displaying TODO entries.
+:ALT_TITLE: TODO Basics
+:END:
+
+Any headline becomes a TODO item when it starts with the word =TODO=,
+for example:
+
+: *** TODO Write letter to Sam Fortune
+
+The most important commands to work with TODO entries are:
+
+#+attr_texinfo: :sep ,
+- {{{kbd(C-c C-t)}}} ::
+
+ Rotate the TODO state of the current item among
+
+ : ,-> (unmarked) -> TODO -> DONE --.
+ : '--------------------------------'
+
+ The same rotation can also be done "remotely" from the agenda buffer
+ with the {{{kbd(t)}}} command key (see [[*Commands in the Agenda
+ Buffer]]).
+
+- {{{kbd(S-RIGHT)}}}, {{{kbd(S-LEFT)}}} ::
+
+ Select the following/preceding TODO state, similar to cycling.
+
+- {{{kbd(C-c / t)}}} ::
+
+ View TODO items in a /sparse tree/ (see [[*Sparse Trees]]). Folds the
+ entire buffer, but shows all TODO items---with not-DONE state---and
+ the headings hierarchy above them.
+
+- {{{kbd(M-x org-agenda t)}}} ::
+
+ Show the global TODO list. Collects the TODO items (with not-DONE
+ states) from all agenda files (see [[*Agenda Views]]) into a single
+ buffer. See [[*The Global TODO List]], for more information.
+
+- {{{kbd(S-M-RET)}}} ::
+
+ Insert a new TODO entry below the current one.
+
+Changing a TODO state can also trigger tag changes. See the docstring
+of the option ~org-todo-state-tags-triggers~ for details.
+
+** Multi-state Workflow
+:PROPERTIES:
+:DESCRIPTION: More than just on/off.
+:END:
+
+You can use TODO keywords to indicate @emph{sequential} working progress
+states:
+
+#+begin_src emacs-lisp
+(setq org-todo-keywords
+ '((sequence "TODO" "FEEDBACK" "VERIFY" "|" "DONE" "DELEGATED")))
+#+end_src
+
+#+texinfo: @noindent
+The vertical bar separates the =TODO= keywords (states that /need
+action/) from the =DONE= states (which need /no further action/). If
+you do not provide the separator bar, the last state is used as the
+=DONE= state. With this setup, the command {{{kbd(C-c C-t)}}} cycles
+an entry from =TODO= to =FEEDBACK=, then to =VERIFY=, and finally to
+=DONE= and =DELEGATED=.
+
+Sometimes you may want to use different sets of TODO keywords in
+parallel. For example, you may want to have the basic =TODO=/=DONE=,
+but also a workflow for bug fixing. Your setup would then look like
+this:
+
+#+begin_src emacs-lisp
+(setq org-todo-keywords
+ '((sequence "TODO(t)" "|" "DONE(d)")
+ (sequence "REPORT(r)" "BUG(b)" "KNOWNCAUSE(k)" "|" "FIXED(f)")))
+#+end_src
+
+#+texinfo: @noindent
+The keywords should all be different, this helps Org mode to keep
+track of which subsequence should be used for a given entry. The
+example also shows how to define keys for fast access of a particular
+state, by adding a letter in parenthesis after each keyword---you will
+be prompted for the key after {{{kbd(C-c C-t)}}}.
+
+To define TODO keywords that are valid only in a single file, use the
+following text anywhere in the file.
+
+#+begin_example
+,#+TODO: TODO(t) | DONE(d)
+,#+TODO: REPORT(r) BUG(b) KNOWNCAUSE(k) | FIXED(f)
+,#+TODO: | CANCELED(c)
+#+end_example
+
+After changing one of these lines, use {{{kbd(C-c C-c)}}} with the
+cursor still in the line to make the changes known to Org mode.
+
+** Progress Logging
+:PROPERTIES:
+:DESCRIPTION: Dates and notes for progress.
+:END:
+
+To record a timestamp and a note when changing a TODO state, call the
+command ~org-todo~ with a prefix argument.
+
+#+attr_texinfo: :sep ,
+- {{{kbd(C-u C-c C-t)}}} ::
+ Prompt for a note and record a the time of the TODO state change.
+
+Org mode can also automatically record a timestamp and optionally a
+note when you mark a TODO item as DONE, or even each time you change
+the state of a TODO item. This system is highly configurable,
+settings can be on a per-keyword basis and can be localized to a file
+or even a subtree. For information on how to clock working time for a
+task, see [[*Clocking Work Time]].
+
+*** Closing items
+:PROPERTIES:
+:UNNUMBERED: notoc
+:END:
+
+The most basic logging is to keep track of /when/ a certain TODO item
+was marked as done. This can be achieved with[fn:4]
+
+#+begin_src emacs-lisp
+(setq org-log-done 'time)
+#+end_src
+
+#+texinfo: @noindent
+Then each time you turn an entry from a TODO (not-done) state into any
+of the DONE states, a line =CLOSED: [timestamp]= is inserted just
+after the headline.
+
+If you want to record a note along with the timestamp, use[fn:5]
+
+#+begin_src emacs-lisp
+(setq org-log-done 'note)
+#+end_src
+
+#+texinfo: @noindent
+You are then be prompted for a note, and that note is stored below the
+entry with a =Closing Note= heading.
+
+*** Tracking TODO state changes
+:PROPERTIES:
+:UNNUMBERED: notoc
+:END:
+
+You might want to keep track of TODO state changes. You can either
+record just a timestamp, or a time-stamped note for a change. These
+records are inserted after the headline as an itemized list. When
+taking a lot of notes, you might want to get the notes out of the way
+into a drawer. Customize the variable ~org-log-into-drawer~ to get
+this behavior.
+
+For state logging, Org mode expects configuration on a per-keyword
+basis. This is achieved by adding special markers =!= (for
+a timestamp) and =@= (for a note) in parentheses after each keyword.
+For example:
+
+: #+TODO: TODO(t) WAIT(w@/!) | DONE(d!) CANCELED(c@)
+
+#+texinfo: @noindent
+defines TODO keywords and fast access keys, and also request that
+a time is recorded when the entry is set to =DONE=, and that a note is
+recorded when switching to =WAIT= or =CANCELED=. The same syntax
+works also when setting ~org-todo-keywords~.
+
+** Priorities
+:PROPERTIES:
+:DESCRIPTION: Some things are more important than others.
+:END:
+
+If you use Org mode extensively, you may end up with enough TODO items
+that it starts to make sense to prioritize them. Prioritizing can be
+done by placing a /priority cookie/ into the headline of a TODO item,
+like this
+
+: *** TODO [#A] Write letter to Sam Fortune
+
+Org mode supports three priorities: =A=, =B=, and =C=. =A= is the
+highest, =B= the default if none is given. Priorities make
+a difference only in the agenda.
+
+#+attr_texinfo: :sep ;
+- {{{kbd(C-c \,)}}} ::
+
+ Set the priority of the current headline. Press {{{kbd(A)}}},
+ {{{kbd(B)}}} or {{{kbd(C)}}} to select a priority, or {{{kbd(SPC)}}}
+ to remove the cookie.
+
+- {{{kbd(S-UP)}}} (~org-priority-up~); {{{kbd(S-DOWN)}}} (~org-priority-down~) ::
+
+ Increase/decrease the priority of the current headline.
+
+** Breaking Tasks Down into Subtasks
+:PROPERTIES:
+:DESCRIPTION: Splitting a task into manageable pieces.
+:ALT_TITLE: Breaking Down Tasks
+:END:
+
+It is often advisable to break down large tasks into smaller,
+manageable subtasks. You can do this by creating an outline tree
+below a TODO item, with detailed subtasks on the tree. To keep an
+overview of the fraction of subtasks that have already been marked
+as done, insert either =[/]= or =[%]= anywhere in the headline. These
+cookies are updated each time the TODO status of a child changes, or
+when pressing {{{kbd(C-c C-c)}}} on the cookie. For example:
+
+#+begin_example
+,* Organize Party [33%]
+,** TODO Call people [1/2]
+,*** TODO Peter
+,*** DONE Sarah
+,** TODO Buy food
+,** DONE Talk to neighbor
+#+end_example
+
+** Checkboxes
+:PROPERTIES:
+:DESCRIPTION: Tick-off lists.
+:END:
+
+Every item in a plain list (see [[*Plain Lists]]) can be made into
+a checkbox by starting it with the string =[ ]=. Checkboxes are not
+included into the global TODO list, so they are often great to split
+a task into a number of simple steps.
+
+Here is an example of a checkbox list.
+
+#+begin_example
+,* TODO Organize party [2/4]
+ - [-] call people [1/2]
+ - [ ] Peter
+ - [X] Sarah
+ - [X] order food
+#+end_example
+
+Checkboxes work hierarchically, so if a checkbox item has children
+that are checkboxes, toggling one of the children checkboxes makes the
+parent checkbox reflect if none, some, or all of the children are
+checked.
+
+The following commands work with checkboxes:
+
+- {{{kbd(C-c C-c)}}} ::
+
+ Toggle checkbox status or---with prefix argument---checkbox presence
+ at point.
+
+- {{{kbd(M-S-RET)}}} ::
+
+ Insert a new item with a checkbox. This works only if point is
+ already in a plain list item (see [[*Plain Lists]]).
+
+* Tags
+:PROPERTIES:
+:DESCRIPTION: Tagging headlines and matching sets of tags.
+:END:
+
+An excellent way to implement labels and contexts for
+cross-correlating information is to assign /tags/ to headlines. Org
+mode has extensive support for tags.
+
+Every headline can contain a list of tags; they occur at the end of
+the headline. Tags are normal words containing letters, numbers, =_=,
+and =@=. Tags must be preceded and followed by a single colon, e.g.,
+=:work:=. Several tags can be specified, as in =:work:urgent:=. Tags
+by default are in bold face with the same color as the headline.
+
+** Tag inheritance
+:PROPERTIES:
+:UNNUMBERED: notoc
+:END:
+
+Tags make use of the hierarchical structure of outline trees. If
+a heading has a certain tag, all subheadings inherit the tag as well.
+For example, in the list
+
+#+begin_example
+,* Meeting with the French group :work:
+,** Summary by Frank :boss:notes:
+,*** TODO Prepare slides for him :action:
+#+end_example
+
+#+texinfo: @noindent
+the final heading has the tags =work=, =boss=, =notes=, and =action=
+even though the final heading is not explicitly marked with those
+tags.
+
+You can also set tags that all entries in a file should inherit just
+as if these tags were defined in a hypothetical level zero that
+surrounds the entire file. Use a line like this[fn:6]:
+
+: #+FILETAGS: :Peter:Boss:Secret:
+
+** Setting tags
+:PROPERTIES:
+:UNNUMBERED: notoc
+:END:
+
+Tags can simply be typed into the buffer at the end of a headline.
+After a colon, {{{kbd(M-TAB)}}} offers completion on tags. There is
+also a special command for inserting tags:
+
+- {{{kbd(C-c C-q)}}} ::
+
+ Enter new tags for the current headline. Org mode either offers
+ completion or a special single-key interface for setting tags, see
+ below.
+
+- {{{kbd(C-c C-c)}}} ::
+
+ When point is in a headline, this does the same as {{{kbd(C-c
+ C-q)}}}.
+
+Org supports tag insertion based on a /list of tags/. By default this
+list is constructed dynamically, containing all tags currently used in
+the buffer. You may also globally specify a hard list of tags with
+the variable ~org-tag-alist~. Finally you can set the default tags
+for a given file using the =TAGS= keyword, like
+
+: #+TAGS: @work @home @tennisclub
+: #+TAGS: laptop car pc sailboat
+
+By default Org mode uses the standard minibuffer completion facilities
+for entering tags. However, it also implements another, quicker, tag
+selection method called /fast tag selection/. This allows you to
+select and deselect tags with just a single key press. For this to
+work well you should assign unique letters to most of your commonly
+used tags. You can do this globally by configuring the variable
+~org-tag-alist~ in your Emacs init file. For example, you may find
+the need to tag many items in different files with =@home=. In this
+case you can set something like:
+
+#+begin_src emacs-lisp
+(setq org-tag-alist '(("@work" . ?w) ("@home" . ?h) ("laptop" . ?l)))
+#+end_src
+
+If the tag is only relevant to the file you are working on, then you
+can instead set the =TAGS= keyword as:
+
+: #+TAGS: @work(w) @home(h) @tennisclub(t) laptop(l) pc(p)
+
+** Tag groups
+:PROPERTIES:
+:UNNUMBERED: notoc
+:END:
+
+A tag can be defined as a /group tag/ for a set of other tags. The
+group tag can be seen as the "broader term" for its set of tags.
+
+You can set group tags by using brackets and inserting a colon between
+the group tag and its related tags:
+
+: #+TAGS: [ GTD : Control Persp ]
+
+#+texinfo: @noindent
+or, if tags in the group should be mutually exclusive:
+
+: #+TAGS: { Context : @Home @Work }
+
+When you search for a group tag, it return matches for all members in
+the group and its subgroups. In an agenda view, filtering by a group
+tag displays or hide headlines tagged with at least one of the members
+of the group or any of its subgroups.
+
+If you want to ignore group tags temporarily, toggle group tags
+support with ~org-toggle-tags-groups~, bound to {{{kbd(C-c C-x q)}}}.
+
+** Tag searches
+:PROPERTIES:
+:UNNUMBERED: notoc
+:END:
+
+- {{{kbd(C-c / m)}}} or {{{kbd(C-c \)}}} ::
+
+ Create a sparse tree with all headlines matching a tags search.
+ With a {{{kbd(C-u)}}} prefix argument, ignore headlines that are not
+ a TODO line.
+
+- {{{kbd(M-x org-agenda m)}}} ::
+
+ Create a global list of tag matches from all agenda files. See
+ [[*Matching Tags and Properties]].
+
+- {{{kbd(M-x org-agenda M)}}} ::
+
+ Create a global list of tag matches from all agenda files, but check
+ only TODO items and force checking subitems (see the option
+ ~org-tags-match-list-sublevels~).
+
+These commands all prompt for a match string which allows basic
+Boolean logic like =+boss+urgent-project1=, to find entries with tags
+=boss= and =urgent=, but not =project1=, or =Kathy|Sally= to find
+entries which are tagged, like =Kathy= or =Sally=. The full syntax of
+the search string is rich and allows also matching against TODO
+keywords, entry levels and properties. For a more detailed description
+with many examples, see [[*Matching Tags and Properties]].
+
+* Properties
+:PROPERTIES:
+:DESCRIPTION: Storing information about an entry.
+:END:
+
+Properties are key-value pairs associated with an entry. They live in
+a special drawer with the name =PROPERTIES=. Each property is
+specified on a single line, with the key (surrounded by colons) first,
+and the value after it:
+
+#+begin_example
+,* CD collection
+,** Classic
+,*** Goldberg Variations
+ :PROPERTIES:
+ :Title: Goldberg Variations
+ :Composer: J.S. Bach
+ :Publisher: Deutsche Grammophon
+ :NDisks: 1
+ :END:
+#+end_example
+
+You may define the allowed values for a particular property =Xyz= by
+setting a property =Xyz_ALL=. This special property is /inherited/,
+so if you set it in a level 1 entry, it applies to the entire tree.
+When allowed values are defined, setting the corresponding property
+becomes easier and is less prone to typing errors. For the example
+with the CD collection, we can pre-define publishers and the number of
+disks in a box like this:
+
+#+begin_example
+,* CD collection
+ :PROPERTIES:
+ :NDisks_ALL: 1 2 3 4
+ :Publisher_ALL: "Deutsche Grammophon" Philips EMI
+ :END:
+#+end_example
+
+If you want to set properties that can be inherited by any entry in
+a file, use a line like:
+
+: #+PROPERTY: NDisks_ALL 1 2 3 4
+
+The following commands help to work with properties:
+
+- {{{kbd(C-c C-x p)}}} ::
+
+ Set a property. This prompts for a property name and a value.
+
+- {{{kbd(C-c C-c d)}}} ::
+
+ Remove a property from the current entry.
+
+To create sparse trees and special lists with selection based on
+properties, the same commands are used as for tag searches (see
+[[*Tags]]). The syntax for the search string is described in [[*Matching
+Tags and Properties]].
+
+* Dates and Times
+:PROPERTIES:
+:DESCRIPTION: Making items useful for planning.
+:END:
+
+To assist project planning, TODO items can be labeled with a date
+and/or a time. The specially formatted string carrying the date and
+time information is called a /timestamp/ in Org mode.
+
+** Timestamps
+:PROPERTIES:
+:DESCRIPTION: Assigning a time to a tree entry.
+:END:
+
+A timestamp is a specification of a date---possibly with a time or
+a range of times---in a special format, either =<2003-09-16 Tue>= or
+=<2003-09-16 Tue 09:39>= or =<2003-09-16 Tue 12:00-12:30>=.
+A timestamp can appear anywhere in the headline or body of an Org tree
+entry. Its presence causes entries to be shown on specific dates in
+the agenda (see [[*The Weekly/daily Agenda]]). We distinguish:
+
+- Plain timestamp; Event; Appointment ::
+
+ A simple timestamp just assigns a date/time to an item. This is
+ just like writing down an appointment or event in a paper agenda.
+
+ #+begin_example
+ ,* Meet Peter at the movies
+ <2006-11-01 Wed 19:15>
+ ,* Discussion on climate change
+ <2006-11-02 Thu 20:00-22:00>
+ #+end_example
+
+- Timestamp with repeater interval ::
+
+ A timestamp may contain a /repeater interval/, indicating that it
+ applies not only on the given date, but again and again after
+ a certain interval of N days (d), weeks (w), months (m), or years
+ (y). The following shows up in the agenda every Wednesday:
+
+ #+begin_example
+ ,* Pick up Sam at school
+ <2007-05-16 Wed 12:30 +1w>
+ #+end_example
+
+- Diary-style expression entries ::
+
+ #+cindex: diary style timestamps
+ #+cindex: sexp timestamps
+ For more complex date specifications, Org mode supports using the
+ special expression diary entries implemented in the Emacs Calendar
+ package. For example, with optional time:
+
+ #+begin_example
+ ,* 22:00-23:00 The nerd meeting on every 2nd Thursday of the month
+ <%%(diary-float t 4 2)>
+ #+end_example
+
+- Time/Date range ::
+
+ Two timestamps connected by =--= denote a range.
+
+ #+begin_example
+ ,** Meeting in Amsterdam
+ <2004-08-23 Mon>--<2004-08-26 Thu>
+ #+end_example
+
+- Inactive timestamp ::
+
+ Just like a plain timestamp, but with square brackets instead of
+ angular ones. These timestamps are inactive in the sense that they
+ do /not/ trigger an entry to show up in the agenda.
+
+ #+begin_example
+ ,* Gillian comes late for the fifth time
+ [2006-11-01 Wed]
+ #+end_example
+
+** Creating Timestamps
+:PROPERTIES:
+:DESCRIPTION: Commands that insert timestamps.
+:END:
+
+For Org mode to recognize timestamps, they need to be in the specific
+format. All commands listed below produce timestamps in the correct
+format.
+
+#+attr_texinfo: :sep ,
+- {{{kbd(C-c .)}}} ::
+
+ Prompt for a date and insert a corresponding timestamp. When point
+ is at an existing timestamp in the buffer, the command is used to
+ modify this timestamp instead of inserting a new one. When this
+ command is used twice in succession, a time range is inserted. With
+ a prefix argument, it also adds the current time.
+
+- {{{kbd(C-c !)}}} ::
+
+ Like {{{kbd(C-c .)}}}, but insert an inactive timestamp that does
+ not cause an agenda entry.
+
+- {{{kbd(S-LEFT)}}}, {{{kbd(S-RIGHT)}}} ::
+
+ Change date at point by one day.
+
+- {{{kbd(S-UP)}}}, {{{kbd(S-DOWN)}}} ::
+
+ On the beginning or enclosing bracket of a timestamp, change its
+ type. Within a timestamp, change the item under point. Point can
+ be on a year, month, day, hour or minute. When the timestamp
+ contains a time range like =15:30-16:30=, modifying the first time
+ also shifts the second, shifting the time block with constant
+ length. To change the length, modify the second time.
+
+
+When Org mode prompts for a date/time, it accepts any string
+containing some date and/or time information, and intelligently
+interprets the string, deriving defaults for unspecified information
+from the current date and time. You can also select a date in the
+pop-up calendar. See the manual for more information on how exactly
+the date/time prompt works.
+
+** Deadlines and Scheduling
+:PROPERTIES:
+:DESCRIPTION: Planning your work.
+:END:
+
+A timestamp may be preceded by special keywords to facilitate
+planning:
+
+- {{{kbd(C-c C-d)}}} ::
+
+ Insert =DEADLINE= keyword along with a time stamp, in the line
+ following the headline.
+
+ Meaning: the task---most likely a TODO item, though not
+ necessarily---is supposed to be finished on that date.
+
+ On the deadline date, the task is listed in the agenda. In
+ addition, the agenda for /today/ carries a warning about the
+ approaching or missed deadline, starting ~org-deadline-warning-days~
+ before the due date, and continuing until the entry is marked as
+ done. An example:
+
+ #+begin_example
+ ,*** TODO write article about the Earth for the Guide
+ DEADLINE: <2004-02-29 Sun>
+ The editor in charge is [[bbdb:Ford Prefect]]
+ #+end_example
+
+- {{{kbd(C-c C-s)}}} ::
+
+ Insert =SCHEDULED= keyword along with a stamp, in the line following
+ the headline.
+
+ Meaning: you are planning to start working on that task on the given
+ date[fn:7].
+
+ The headline is listed under the given date[fn:8]. In addition,
+ a reminder that the scheduled date has passed is present in the
+ compilation for /today/, until the entry is marked as done, i.e.,
+ the task is automatically forwarded until completed.
+
+ #+begin_example
+ ,*** TODO Call Trillian for a date on New Years Eve.
+ SCHEDULED: <2004-12-25 Sat>
+ #+end_example
+
+Some tasks need to be repeated again and again. Org mode helps to
+organize such tasks using a so-called repeater in a =DEADLINE=,
+=SCHEDULED=, or plain timestamps. In the following example:
+
+#+begin_example
+,** TODO Pay the rent
+ DEADLINE: <2005-10-01 Sat +1m>
+#+end_example
+
+#+texinfo: @noindent
+the =+1m= is a repeater; the intended interpretation is that the task
+has a deadline on =<2005-10-01>= and repeats itself every (one) month
+starting from that time.
+
+** Clocking Work Time
+:PROPERTIES:
+:DESCRIPTION: Tracking how long you spent on a task.
+:END:
+
+Org mode allows you to clock the time you spend on specific tasks in
+a project.
+
+#+attr_texinfo: :sep ,
+- {{{kbd(C-c C-x C-i)}}} ::
+
+ Start the clock on the current item (clock-in). This inserts the
+ =CLOCK= keyword together with a timestamp. When called with
+ a {{{kbd(C-u)}}} prefix argument, select the task from a list of
+ recently clocked tasks.
+
+- {{{kbd(C-c C-x C-o)}}} ::
+
+ Stop the clock (clock-out). This inserts another timestamp at the
+ same location where the clock was last started. It also directly
+ computes the resulting time in inserts it after the time range as
+ ==>HH:MM=.
+
+- {{{kbd(C-c C-x C-e)}}} ::
+
+ Update the effort estimate for the current clock task.
+
+- {{{kbd(C-c C-x C-q)}}} ::
+
+ Cancel the current clock. This is useful if a clock was started by
+ mistake, or if you ended up working on something else.
+
+- {{{kbd(C-c C-x C-j)}}} ::
+
+ Jump to the headline of the currently clocked in task. With
+ a {{{kbd(C-u)}}} prefix argument, select the target task from a list
+ of recently clocked tasks.
+
+The {{{kbd(l)}}} key may be used in the agenda (see [[*The Weekly/daily
+Agenda]]) to show which tasks have been worked on or closed during
+a day.
+
+* Capture, Refile, Archive
+:PROPERTIES:
+:DESCRIPTION: The ins and outs for projects.
+:END:
+
+An important part of any organization system is the ability to quickly
+capture new ideas and tasks, and to associate reference material with
+them. Org does this using a process called /capture/. It also can
+store files related to a task (/attachments/) in a special directory.
+Once in the system, tasks and projects need to be moved around.
+Moving completed project trees to an archive file keeps the system
+compact and fast.
+
+** Capture
+:PROPERTIES:
+:DESCRIPTION: Capturing new stuff.
+:END:
+
+Capture lets you quickly store notes with little interruption of your
+work flow. You can define templates for new entries and associate
+them with different targets for storing notes.
+
+*** Setting up capture
+:PROPERTIES:
+:UNNUMBERED: notoc
+:END:
+
+The following customization sets a default target[fn:9] file for notes.
+
+#+begin_src emacs-lisp
+(setq org-default-notes-file (concat org-directory "/notes.org"))
+#+end_src
+
+You may also define a global key for capturing new material (see
+[[*Activation]]).
+
+*** Using capture
+:PROPERTIES:
+:UNNUMBERED: notoc
+:END:
+
+- {{{kbd(M-x org-capture)}}} ::
+
+ Start a capture process, placing you into a narrowed indirect buffer
+ to edit.
+
+- {{{kbd(C-c C-c)}}} ::
+
+ Once you have finished entering information into the capture buffer,
+ {{{kbd(C-c C-c)}}} returns you to the window configuration before
+ the capture process, so that you can resume your work without
+ further distraction.
+
+- {{{kbd(C-c C-w)}}} ::
+
+ Finalize the capture process by refiling the note to a different
+ place (see [[*Refile and Copy]]).
+
+- {{{kbd(C-c C-k)}}} ::
+
+ Abort the capture process and return to the previous state.
+
+*** Capture templates
+:PROPERTIES:
+:UNNUMBERED: notoc
+:END:
+
+You can use templates for different types of capture items, and for
+different target locations. Say you would like to use one template to
+create general TODO entries, and you want to put these entries under
+the heading =Tasks= in your file =~/org/gtd.org=. Also, a date tree
+in the file =journal.org= should capture journal entries. A possible
+configuration would look like:
+
+#+begin_src emacs-lisp
+(setq org-capture-templates
+ '(("t" "Todo" entry (file+headline "~/org/gtd.org" "Tasks")
+ "* TODO %?\n %i\n %a")
+ ("j" "Journal" entry (file+datetree "~/org/journal.org")
+ "* %?\nEntered on %U\n %i\n %a")))
+#+end_src
+
+If you then press {{{kbd(t)}}} from the capture menu, Org will prepare
+the template for you like this:
+
+: * TODO
+: [[file:LINK TO WHERE YOU INITIATED CAPTURE]]
+
+#+texinfo: @noindent
+During expansion of the template, special %-escapes[fn:10] allow
+dynamic insertion of content. Here is a small selection of the
+possibilities, consult the manual for more.
+
+| =%a= | annotation, normally the link created with ~org-store-link~ |
+| =%i= | initial content, the region when capture is called with {{{kbd(C-u)}}} |
+| =%t=, =%T= | timestamp, date only, or date and time |
+| =%u=, =%U= | like above, but inactive timestamps |
+| =%?= | after completing the template, position point here |
+
+** Refile and Copy
+:PROPERTIES:
+:DESCRIPTION: Moving/copying a tree from one place to another.
+:END:
+
+When reviewing the captured data, you may want to refile or to copy
+some of the entries into a different list, for example into a project.
+Cutting, finding the right location, and then pasting the note is
+cumbersome. To simplify this process, you can use the following
+special command:
+
+- {{{kbd(C-c C-w)}}} ::
+
+ Refile the entry or region at point. This command offers possible
+ locations for refiling the entry and lets you select one with
+ completion. The item (or all items in the region) is filed below
+ the target heading as a subitem.
+
+ By default, all level 1 headlines in the current buffer are
+ considered to be targets, but you can have more complex definitions
+ across a number of files. See the variable ~org-refile-targets~ for
+ details.
+
+- {{{kbd(C-u C-c C-w)}}} ::
+
+ Use the refile interface to jump to a heading.
+
+- {{{kbd(C-u C-u C-c C-w)}}} ::
+
+ Jump to the location where ~org-refile~ last moved a tree to.
+
+- {{{kbd(C-c M-w)}}} ::
+
+ Copying works like refiling, except that the original note is not
+ deleted.
+
+** Archiving
+:PROPERTIES:
+:DESCRIPTION: What to do with finished products.
+:END:
+
+When a project represented by a (sub)tree is finished, you may want to
+move the tree out of the way and to stop it from contributing to the
+agenda. Archiving is important to keep your working files compact and
+global searches like the construction of agenda views fast.
+
+The most common archiving action is to move a project tree to another
+file, the archive file.
+
+- {{{kbd(C-c C-x C-a)}}} ::
+
+ Archive the current entry using the command specified in the
+ variable ~org-archive-default-command~.
+
+- {{{kbd(C-c C-x C-s)}}} or short {{{kbd(C-c $)}}} ::
+
+ Archive the subtree starting at point position to the location given
+ by ~org-archive-location~.
+
+The default archive location is a file in the same directory as the
+current file, with the name derived by appending =_archive= to the
+current file name. You can also choose what heading to file archived
+items under, with the possibility to add them to a datetree in a file.
+For information and examples on how to specify the file and the
+heading, see the documentation string of the variable
+~org-archive-location~.
+
+There is also an in-buffer option for setting this variable, for
+example:
+
+: #+ARCHIVE: %s_done::
+
+* Agenda Views
+:PROPERTIES:
+:DESCRIPTION: Collecting information into views.
+:END:
+
+Due to the way Org works, TODO items, time-stamped items, and tagged
+headlines can be scattered throughout a file or even a number of
+files. To get an overview of open action items, or of events that are
+important for a particular date, this information must be collected,
+sorted and displayed in an organized way.
+
+The extracted information is displayed in a special /agenda buffer/.
+This buffer is read-only, but provides commands to visit the
+corresponding locations in the original Org files, and even to edit
+these files remotely. Remote editing from the agenda buffer means,
+for example, that you can change the dates of deadlines and
+appointments from the agenda buffer. For commands available in the
+Agenda buffer, see [[*Commands in the Agenda Buffer]].
+
+** Agenda Files
+:PROPERTIES:
+:DESCRIPTION: Files being searched for agenda information.
+:END:
+
+The information to be shown is normally collected from all /agenda
+files/, the files listed in the variable ~org-agenda-files~.
+
+#+attr_texinfo: :sep or
+- {{{kbd(C-c [)}}} ::
+
+ Add current file to the list of agenda files. The file is added to
+ the front of the list. If it was already in the list, it is moved
+ to the front. With a prefix argument, file is added/moved to the
+ end.
+
+- {{{kbd(C-c ])}}} ::
+
+ Remove current file from the list of agenda files.
+
+- {{{kbd(C-')}}} or {{{kbd(C-\,)}}} ::
+
+ Cycle through agenda file list, visiting one file after the other.
+
+** The Agenda Dispatcher
+:PROPERTIES:
+:DESCRIPTION: Keyboard access to agenda views.
+:ALT_TITLE: Agenda Dispatcher
+:END:
+
+The views are created through a dispatcher, accessible with {{{kbd(M-x
+org-agenda)}}}, or, better, bound to a global key (see [[*Activation]]).
+It displays a menu from which an additional letter is required to
+execute a command. The dispatcher offers the following default
+commands:
+
+#+attr_texinfo: :sep ,
+- {{{kbd(a)}}} ::
+
+ Create the calendar-like agenda (see [[*The Weekly/daily Agenda]]).
+
+- {{{kbd(t)}}}, {{{kbd(T)}}} ::
+
+ Create a list of all TODO items (see [[*The Global TODO List]]).
+
+- {{{kbd(m)}}}, {{{kbd(M)}}} ::
+
+ Create a list of headlines matching a given expression (see
+ [[*Matching Tags and Properties]]).
+
+- {{{kbd(s)}}} ::
+
+ #+kindex: s @r{(Agenda dispatcher)}
+ Create a list of entries selected by a boolean expression of
+ keywords and/or regular expressions that must or must not occur in
+ the entry.
+
+** The Weekly/Daily Agenda
+:PROPERTIES:
+:DESCRIPTION: What is available out of the box?
+:ALT_TITLE: Built-in Agenda Views
+:END:
+
+The purpose of the weekly/daily /agenda/ is to act like a page of
+a paper agenda, showing all the tasks for the current week or day.
+
+- {{{kbd(M-x org-agenda a)}}} ::
+
+ Compile an agenda for the current week from a list of Org files.
+ The agenda shows the entries for each day.
+
+Org mode understands the syntax of the diary and allows you to use
+diary expression entries directly in Org files:
+
+#+begin_example
+,* Holidays
+ :PROPERTIES:
+ :CATEGORY: Holiday
+ :END:
+%%(org-calendar-holiday) ; special function for holiday names
+
+,* Birthdays
+ :PROPERTIES:
+ :CATEGORY: Ann
+ :END:
+%%(org-anniversary 1956 5 14) Arthur Dent is %d years old
+%%(org-anniversary 1869 10 2) Mahatma Gandhi would be %d years old
+#+end_example
+
+Org can interact with Emacs appointments notification facility. To
+add the appointments of your agenda files, use the command
+~org-agenda-to-appt~.
+
+** The Global TODO List
+:PROPERTIES:
+:DESCRIPTION: All unfinished action items.
+:ALT_TITLE: Global TODO List
+:END:
+
+The global TODO list contains all unfinished TODO items formatted and
+collected into a single place. Remote editing of TODO items lets you
+can change the state of a TODO entry with a single key press. For
+commands available in the TODO list, see [[*Commands in the Agenda
+Buffer]].
+
+- {{{kbd(M-x org-agenda t)}}} ::
+
+ Show the global TODO list. This collects the TODO items from all
+ agenda files (see [[*Agenda Views]]) into a single buffer.
+
+- {{{kbd(M-x org-agenda T)}}} ::
+
+ Like the above, but allows selection of a specific TODO keyword.
+
+** Matching Tags and Properties
+:PROPERTIES:
+:DESCRIPTION: Structured information with fine-tuned search.
+:END:
+
+If headlines in the agenda files are marked with /tags/ (see [[*Tags]]),
+or have properties (see [[*Properties]]), you can select headlines based
+on this metadata and collect them into an agenda buffer. The match
+syntax described here also applies when creating sparse trees with
+{{{kbd(C-c / m)}}}.
+
+- {{{kbd(M-x org-agenda m)}}} ::
+
+ Produce a list of all headlines that match a given set of tags. The
+ command prompts for a selection criterion, which is a boolean logic
+ expression with tags, like =+work+urgent-withboss= or =work|home=
+ (see [[*Tags]]). If you often need a specific search, define a custom
+ command for it (see [[*The Agenda Dispatcher]]).
+
+- {{{kbd(M-x org-agenda M)}}} ::
+
+ Like {{{kbd(m)}}}, but only select headlines that are also TODO
+ items.
+
+A search string can use Boolean operators =&= for AND and =|= for OR.
+=&= binds more strongly than =|=. Parentheses are currently not
+implemented. Each element in the search is either a tag, a regular
+expression matching tags, or an expression like =PROPERTY OPERATOR
+VALUE= with a comparison operator, accessing a property value. Each
+element may be preceded by =-= to select against it, and =+= is
+syntactic sugar for positive selection. The AND operator =&= is
+optional when =+= or =-= is present. Here are some examples, using
+only tags.
+
+- =+work-boss= ::
+
+ Select headlines tagged =work=, but discard those also tagged
+ =boss=.
+
+- =work|laptop= ::
+
+ Selects lines tagged =work= or =laptop=.
+
+- =work|laptop+night= ::
+
+ Like before, but require the =laptop= lines to be tagged also
+ =night=.
+
+You may also test for properties at the same time as matching tags,
+see the manual for more information.
+
+** Search View
+:PROPERTIES:
+:DESCRIPTION: Find entries by searching for text.
+:END:
+
+This agenda view is a general text search facility for Org mode
+entries. It is particularly useful to find notes.
+
+- {{{kbd(M-x org-agenda s)}}} (~org-search-view~) ::
+
+ #+kindex: s @r{(Agenda dispatcher)}
+ #+findex: org-search-view
+ This is a special search that lets you select entries by matching
+ a substring or specific words using a boolean logic.
+
+For example, the search string =computer equipment= matches entries
+that contain =computer equipment= as a substring.
+
+Search view can also search for specific keywords in the entry, using
+Boolean logic. The search string =+computer
++wifi -ethernet -{8\.11[bg]}= matches note entries that contain the
+keywords =computer= and =wifi=, but not the keyword =ethernet=, and
+which are also not matched by the regular expression =8\.11[bg]=,
+meaning to exclude both =8.11b= and =8.11g=.
+
+Note that in addition to the agenda files, this command also searches
+the files listed in ~org-agenda-text-search-extra-files~.
+
+** Commands in the Agenda Buffer
+:PROPERTIES:
+:DESCRIPTION: Remote editing of Org trees.
+:ALT_TITLE: Agenda Commands
+:END:
+
+Entries in the agenda buffer are linked back to the Org file or diary
+file where they originate. You are not allowed to edit the agenda
+buffer itself, but commands are provided to show and jump to the
+original entry location, and to edit the Org files "remotely" from the
+agenda buffer. This is just a selection of the many commands, explore
+the agenda menu and the manual for a complete list.
+
+*** Motion
+:PROPERTIES:
+:UNNUMBERED: notoc
+:END:
+
+- {{{kbd(n)}}} ::
+
+ Next line (same as {{{kbd(DOWN)}}} and {{{kbd(C-n)}}}).
+
+- {{{kbd(p)}}} ::
+
+ Previous line (same as {{{kbd(UP)}}} and {{{kbd(C-p)}}}).
+
+*** View/Go to Org file
+:PROPERTIES:
+:UNNUMBERED: notoc
+:END:
+
+- {{{kbd(SPC)}}} ::
+
+ Display the original location of the item in another window.
+ With a prefix argument, make sure that drawers stay folded.
+
+- {{{kbd(TAB)}}} ::
+
+ Go to the original location of the item in another window.
+
+- {{{kbd(RET)}}} ::
+
+ Go to the original location of the item and delete other windows.
+
+*** Change display
+:PROPERTIES:
+:UNNUMBERED: notoc
+:END:
+#+attr_texinfo: :sep ,
+- {{{kbd(o)}}} ::
+
+ Delete other windows.
+
+- {{{kbd(v d)}}} or short {{{kbd(d)}}} ::
+
+ Switch to day view.
+
+- {{{kbd(v w)}}} or short {{{kbd(w)}}} ::
+
+ Switch to week view.
+
+- {{{kbd(f)}}} ::
+
+ Go forward in time to display the span following the current one.
+ For example, if the display covers a week, switch to the following
+ week.
+
+- {{{kbd(b)}}} ::
+
+ Go backward in time to display earlier dates.
+
+- {{{kbd(.)}}} ::
+
+ Go to today.
+
+- {{{kbd(j)}}} ::
+
+ Prompt for a date and go there.
+
+- {{{kbd(v l)}}} or {{{kbd(v L)}}} or short {{{kbd(l)}}} ::
+
+ Toggle Logbook mode. In Logbook mode, entries that were marked as
+ done while logging was on (see the variable ~org-log-done~) are
+ shown in the agenda, as are entries that have been clocked on that
+ day. When called with a {{{kbd(C-u)}}} prefix argument, show all
+ possible logbook entries, including state changes.
+
+- {{{kbd(r)}}}, {{{kbd(g)}}} ::
+
+ Recreate the agenda buffer, for example to reflect the changes after
+ modification of the timestamps of items.
+
+- {{{kbd(s)}}} ::
+
+ #+kindex: C-x C-s
+ #+findex: org-save-all-org-buffers
+ #+kindex: s
+ Save all Org buffers in the current Emacs session, and also the
+ locations of IDs.
+
+*** Remote editing
+:PROPERTIES:
+:UNNUMBERED: notoc
+:END:
+
+- {{{kbd(0--9)}}} ::
+
+ Digit argument.
+
+- {{{kbd(t)}}} ::
+
+ Change the TODO state of the item, both in the agenda and in the
+ original Org file.
+
+- {{{kbd(C-k)}}} ::
+
+ Delete the current agenda item along with the entire subtree
+ belonging to it in the original Org file.
+
+- {{{kbd(C-c C-w)}}} ::
+
+ Refile the entry at point.
+
+- {{{kbd(a)}}} ::
+
+ Archive the subtree corresponding to the entry at point using the
+ default archiving command set in ~org-archive-default-command~.
+
+- {{{kbd($)}}} ::
+
+ Archive the subtree corresponding to the current headline.
+
+- {{{kbd(C-c C-s)}}} ::
+
+ Schedule this item. With a prefix argument, remove the
+ scheduling timestamp
+
+- {{{kbd(C-c C-d)}}} ::
+
+ Set a deadline for this item. With a prefix argument, remove the
+ deadline.
+
+- {{{kbd(S-RIGHT)}}} ::
+
+ Change the timestamp associated with the current line by one day
+ into the future.
+
+- {{{kbd(S-LEFT)}}} ::
+
+ Change the timestamp associated with the current line by one day
+ into the past.
+
+- {{{kbd(I)}}} ::
+
+ Start the clock on the current item.
+
+- {{{kbd(O)}}} ::
+
+ Stop the previously started clock.
+
+- {{{kbd(X)}}} ::
+
+ Cancel the currently running clock.
+
+- {{{kbd(J)}}} ::
+
+ Jump to the running clock in another window.
+
+*** Quit and exit
+:PROPERTIES:
+:UNNUMBERED: notoc
+:END:
+
+- {{{kbd(q)}}} ::
+
+ Quit agenda, remove the agenda buffer.
+
+- {{{kbd(x)}}} ::
+
+ Exit agenda, remove the agenda buffer and all buffers loaded by
+ Emacs for the compilation of the agenda.
+
+** Custom Agenda Views
+:PROPERTIES:
+:DESCRIPTION: Defining special searches and views.
+:END:
+
+The first application of custom searches is the definition of keyboard
+shortcuts for frequently used searches, either creating an agenda
+buffer, or a sparse tree (the latter covering of course only the
+current buffer).
+
+Custom commands are configured in the variable
+~org-agenda-custom-commands~. You can customize this variable, for
+example by pressing {{{kbd(C)}}} from the agenda dispatcher (see [[*The
+Agenda Dispatcher]]). You can also directly set it with Emacs Lisp in
+the Emacs init file. The following example contains all valid agenda
+views:
+
+#+begin_src emacs-lisp
+(setq org-agenda-custom-commands
+ '(("w" todo "WAITING")
+ ("u" tags "+boss-urgent")
+ ("v" tags-todo "+boss-urgent")))
+#+end_src
+
+The initial string in each entry defines the keys you have to press
+after the dispatcher command in order to access the command. Usually
+this is just a single character. The second parameter is the search
+type, followed by the string or regular expression to be used for the
+matching. The example above will therefore define:
+
+- {{{kbd(w)}}} ::
+
+ as a global search for TODO entries with =WAITING= as the TODO
+ keyword.
+
+- {{{kbd(u)}}} ::
+
+ as a global tags search for headlines tagged =boss= but not
+ =urgent=.
+
+- {{{kbd(v)}}} ::
+
+ The same search, but limiting it to headlines that are also TODO
+ items.
+
+* Markup for Rich Contents
+:PROPERTIES:
+:DESCRIPTION: Compose beautiful documents.
+:ALT_TITLE: Markup
+:END:
+
+Org is primarily about organizing and searching through your
+plain-text notes. However, it also provides a lightweight yet robust
+markup language for rich text formatting and more. Used in
+conjunction with the export framework (see [[*Exporting]]), you can author
+beautiful documents in Org.
+
+** Paragraphs
+:PROPERTIES:
+:DESCRIPTION: The basic unit of text.
+:END:
+
+Paragraphs are separated by at least one empty line. If you need to
+enforce a line break within a paragraph, use =\\= at the end of
+a line.
+
+To preserve the line breaks, indentation and blank lines in a region,
+but otherwise use normal formatting, you can use this construct, which
+can also be used to format poetry.
+
+#+begin_example
+,#+BEGIN_VERSE
+ Great clouds overhead
+ Tiny black birds rise and fall
+ Snow covers Emacs
+
+ ---AlexSchroeder
+,#+END_VERSE
+#+end_example
+
+When quoting a passage from another document, it is customary to
+format this as a paragraph that is indented on both the left and the
+right margin. You can include quotations in Org documents like this:
+
+#+begin_example
+,#+BEGIN_QUOTE
+Everything should be made as simple as possible,
+but not any simpler ---Albert Einstein
+,#+END_QUOTE
+#+end_example
+
+If you would like to center some text, do it like this:
+
+#+begin_example
+,#+BEGIN_CENTER
+Everything should be made as simple as possible, \\
+but not any simpler
+,#+END_CENTER
+#+end_example
+
+** Emphasis and Monospace
+:PROPERTIES:
+:DESCRIPTION: Bold, italic, etc.
+:END:
+
+You can make words =*bold*=, =/italic/=, =_underlined_=, ==verbatim==
+and =~code~=, and, if you must, =+strike-through+=. Text in the code
+and verbatim string is not processed for Org specific syntax; it is
+exported verbatim.
+
+** Embedded LaTeX
+:PROPERTIES:
+:DESCRIPTION: LaTeX can be freely used inside Org documents.
+:END:
+
+For scientific notes which need to be able to contain mathematical
+symbols and the occasional formula, Org mode supports embedding LaTeX
+code into its files. You can directly use TeX-like syntax for special
+symbols, enter formulas and entire LaTeX environments.
+
+#+begin_example
+The radius of the sun is R_sun = 6.96 x 10^8 m. On the other hand,
+the radius of Alpha Centauri is R_{Alpha Centauri} = 1.28 x R_{sun}.
+
+\begin{equation} % arbitrary environments,
+x=\sqrt{b} % even tables, figures
+\end{equation} % etc
+
+If $a^2=b$ and \( b=2 \), then the solution must be
+either $$ a=+\sqrt{2} $$ or \[ a=-\sqrt{2} \].
+#+end_example
+
+** Literal examples
+:PROPERTIES:
+:DESCRIPTION: Source code examples with special formatting.
+:END:
+
+You can include literal examples that should not be subjected to
+markup. Such examples are typeset in monospace, so this is well
+suited for source code and similar examples.
+
+#+begin_example
+,#+BEGIN_EXAMPLE
+ Some example from a text file.
+,#+END_EXAMPLE
+#+end_example
+
+For simplicity when using small examples, you can also start the
+example lines with a colon followed by a space. There may also be
+additional whitespace before the colon:
+
+#+begin_example
+Here is an example
+ : Some example from a text file.
+#+end_example
+
+If the example is source code from a programming language, or any
+other text that can be marked up by Font Lock in Emacs, you can ask
+for the example to look like the fontified Emacs buffer.
+
+#+begin_example
+,#+BEGIN_SRC emacs-lisp
+ (defun org-xor (a b)
+ "Exclusive or."
+ (if a (not b) b))
+ ,#+END_SRC
+#+end_example
+
+To edit the example in a special buffer supporting this language, use
+{{{kbd(C-c ')}}} to both enter and leave the editing buffer.
+
+** Images
+:PROPERTIES:
+:DESCRIPTION: Display an image.
+:END:
+
+An image is a link to an image file that does not have a description
+part, for example
+
+: ./img/cat.jpg
+
+If you wish to define a caption for the image and maybe a label for
+internal cross references (see [[*Hyperlinks]]), make sure that the
+link is on a line by itself and precede it with =CAPTION= and =NAME=
+keywords as follows:
+
+#+begin_example
+,#+CAPTION: This is the caption for the next figure link (or table)
+,#+NAME: fig:SED-HR4049
+[[./img/a.jpg]]
+#+end_example
+
+** Creating Footnotes
+:PROPERTIES:
+:DESCRIPTION: Edit and read footnotes.
+:END:
+
+A footnote is defined in a paragraph that is started by a footnote
+marker in square brackets in column 0, no indentation allowed. The
+footnote reference is simply the marker in square brackets, inside
+text. For example:
+
+#+begin_example
+The Org homepage[fn:1] now looks a lot better than it used to.
+...
+[fn:1] The link is: https://orgmode.org
+#+end_example
+
+The following commands handle footnotes:
+
+- {{{kbd(C-c C-x f)}}} ::
+
+ The footnote action command. When point is on a footnote reference,
+ jump to the definition. When it is at a definition, jump to the
+ (first) reference. Otherwise, create a new footnote. When this
+ command is called with a prefix argument, a menu of additional
+ options including renumbering is offered.
+
+- {{{kbd(C-c C-c)}}} ::
+
+ Jump between definition and reference.
+
+* Exporting
+:PROPERTIES:
+:DESCRIPTION: Sharing and publishing notes.
+:END:
+
+Org can convert and export documents to a variety of other formats
+while retaining as much structure (see [[*Document Structure]]) and markup
+(see [[*Markup for Rich Contents]]) as possible.
+
+** The Export Dispatcher
+:PROPERTIES:
+:DESCRIPTION: The main interface.
+:END:
+
+The export dispatcher is the main interface for Org's exports.
+A hierarchical menu presents the currently configured export formats.
+Options are shown as easy toggle switches on the same screen.
+
+- {{{kbd(C-c C-e)}}} ::
+
+ Invokes the export dispatcher interface.
+
+Org exports the entire buffer by default. If the Org buffer has an
+active region, then Org exports just that region.
+
+** Export Settings
+:PROPERTIES:
+:DESCRIPTION: Common export settings.
+:END:
+
+The exporter recognizes special lines in the buffer which provide
+additional information. These lines may be put anywhere in the file:
+
+: #+TITLE: I'm in the Mood for Org
+
+Most proeminent export options include:
+
+| =TITLE= | the title to be shown |
+| =AUTHOR= | the author (default taken from ~user-full-name~) |
+| =DATE= | a date, fixed, or an Org timestamp |
+| =EMAIL= | email address (default from ~user-mail-address~) |
+| =LANGUAGE= | language code, e.g., =en= |
+
+Option keyword sets can be inserted from the export dispatcher (see
+[[*The Export Dispatcher]]) using the =Insert template= command by
+pressing {{{kbd(#)}}}.
+
+** Table of Contents
+:PROPERTIES:
+:DESCRIPTION: The if and where of the table of contents.
+:END:
+
+The table of contents includes all headlines in the document. Its
+depth is therefore the same as the headline levels in the file. If
+you need to use a different depth, or turn it off entirely, set the
+~org-export-with-toc~ variable accordingly. You can achieve the same
+on a per file basis, using the following =toc= item in =OPTIONS=
+keyword:
+
+#+begin_example
+,#+OPTIONS: toc:2 (only include two levels in TOC)
+,#+OPTIONS: toc:nil (no default TOC at all)
+#+end_example
+
+Org normally inserts the table of contents directly before the first
+headline of the file.
+
+** Include Files
+:PROPERTIES:
+:DESCRIPTION: Include additional files into a document.
+:END:
+
+During export, you can include the content of another file. For
+example, to include your =.emacs= file, you could use:
+
+: #+INCLUDE: "~/.emacs" src emacs-lisp
+
+#+texinfo: @noindent
+The first parameter is the file name to include. The optional second
+parameter specifies the block type: =example=, =export= or =src=. The
+optional third parameter specifies the source code language to use for
+formatting the contents. This is relevant to both =export= and =src=
+block types.
+
+You can visit the included file with {{{kbd(C-c ')}}}.
+
+** Comment Lines
+:PROPERTIES:
+:DESCRIPTION: What will not be exported.
+:END:
+
+Lines starting with zero or more whitespace characters followed by one
+=#= and a whitespace are treated as comments and, as such, are not
+exported.
+
+Likewise, regions surrounded by =#+BEGIN_COMMENT= ... =#+END_COMMENT=
+are not exported.
+
+Finally, a =COMMENT= keyword at the beginning of an entry, but after
+any other keyword or priority cookie, comments out the entire subtree.
+The command below helps changing the comment status of a headline.
+
+- {{{kbd(C-c ;)}}} ::
+
+ Toggle the =COMMENT= keyword at the beginning of an entry.
+
+** ASCII/UTF-8 Export
+:PROPERTIES:
+:DESCRIPTION: Exporting to flat files with encoding.
+:END:
+
+ASCII export produces an output file containing only plain ASCII
+characters. This is the simplest and most direct text output. It
+does not contain any Org markup. UTF-8 export uses additional
+characters and symbols available in this encoding standards.
+
+#+attr_texinfo: :sep ,
+- {{{kbd(C-c C-e t a)}}}, {{{kbd(C-c C-e t u)}}} ::
+
+ Export as an ASCII file with a =.txt= extension. For =myfile.org=,
+ Org exports to =myfile.txt=, overwriting without warning. For
+ =myfile.txt=, Org exports to =myfile.txt.txt= in order to prevent
+ data loss.
+
+** HTML Export
+:PROPERTIES:
+:DESCRIPTION: Exporting to HTML.
+:END:
+
+Org mode contains an HTML exporter with extensive HTML formatting
+compatible with XHTML 1.0 strict standard.
+
+- {{{kbd(C-c C-e h h)}}} ::
+
+ Export as HTML file with a =.html= extension. For =myfile.org=, Org
+ exports to =myfile.html=, overwriting without warning. {{{kbd{C-c
+ C-e h o)}}} exports to HTML and opens it in a web browser.
+
+The HTML export back-end transforms =<= and =>= to =&lt;= and =&gt;=.
+To include raw HTML code in the Org file so the HTML export back-end
+can insert that HTML code in the output, use this inline syntax:
+=@@html:...@@=. For example:
+
+: @@html:<b>@@bold text@@html:</b>@@
+
+For larger raw HTML code blocks, use these HTML export code blocks:
+
+#+begin_example
+,#+HTML: Literal HTML code for export
+
+,#+BEGIN_EXPORT html
+ All lines between these markers are exported literally
+,#+END_EXPORT
+#+end_example
+
+** LaTeX Export
+:PROPERTIES:
+:DESCRIPTION: Exporting to @LaTeX{} and processing to PDF.
+:END:
+
+The LaTeX export back-end can handle complex documents, incorporate
+standard or custom LaTeX document classes, generate documents using
+alternate LaTeX engines, and produce fully linked PDF files with
+indexes, bibliographies, and tables of contents, destined for
+interactive online viewing or high-quality print publication.
+
+By default, the LaTeX output uses the /article/ class. You can change
+this by adding an option like =#+LATEX_CLASS: myclass= in your file.
+The class must be listed in ~org-latex-classes~.
+
+- {{{kbd(C-c C-e l l)}}} ::
+
+ Export to a LaTeX file with a =.tex= extension. For =myfile.org=,
+ Org exports to =myfile.tex=, overwriting without warning.
+
+- {{{kbd(C-c C-e l p)}}} ::
+
+ Export as LaTeX file and convert it to PDF file.
+
+- {{{kbd(C-c C-e l o)}}} ::
+
+ Export as LaTeX file and convert it to PDF, then open the PDF using
+ the default viewer.
+
+The LaTeX export back-end can insert any arbitrary LaTeX code, see
+[[*Embedded LaTeX]]. There are three ways to embed such code in the Org
+file and they all use different quoting syntax.
+
+Inserting in-line quoted with @ symbols:
+
+: Code embedded in-line @@latex:any arbitrary LaTeX code@@ in a paragraph.
+
+Inserting as one or more keyword lines in the Org file:
+
+: #+LATEX: any arbitrary LaTeX code
+
+Inserting as an export block in the Org file, where the back-end
+exports any code between begin and end markers:
+
+#+begin_example
+,#+BEGIN_EXPORT latex
+ any arbitrary LaTeX code
+,#+END_EXPORT
+#+end_example
+
+** iCalendar Export
+:PROPERTIES:
+:DESCRIPTION: Exporting to iCalendar.
+:END:
+
+A large part of Org mode's interoperability success is its ability to
+easily export to or import from external applications. The iCalendar
+export back-end takes calendar data from Org files and exports to the
+standard iCalendar format.
+
+- {{{kbd(C-c C-e c f)}}} ::
+
+ Create iCalendar entries from the current Org buffer and store them
+ in the same directory, using a file extension =.ics=.
+
+- {{{kbd(C-c C-e c c)}}} ::
+
+ Create a combined iCalendar file from Org files in
+ ~org-agenda-files~ and write it to
+ ~org-icalendar-combined-agenda-file~ file name.
+
+* Publishing
+:PROPERTIES:
+:DESCRIPTION: Create a web site of linked Org files.
+:END:
+
+Org includes a publishing management system that allows you to
+configure automatic HTML conversion of /projects/ composed of
+interlinked Org files. You can also configure Org to automatically
+upload your exported HTML pages and related attachments, such as
+images and source code files, to a web server.
+
+You can also use Org to convert files into PDF, or even combine HTML
+and PDF conversion so that files are available in both formats on the
+server.
+
+For detailed instructions about setup, see the manual. Here is an
+example:
+
+#+begin_src emacs-lisp
+(setq org-publish-project-alist
+ '(("org"
+ :base-directory "~/org/"
+ :publishing-directory "~/public_html"
+ :section-numbers nil
+ :table-of-contents nil
+ :style "<link rel=\"stylesheet\"
+ href=\"../other/mystyle.css\"
+ type=\"text/css\"/>")))
+#+end_src
+
+- {{{kbd(C-c C-e P x)}}} ::
+
+ Prompt for a specific project and publish all files that belong to
+ it.
+
+- {{{kbd(C-c C-e P p)}}} ::
+
+ Publish the project containing the current file.
+
+- {{{kbd(C-c C-e P f)}}} ::
+
+ Publish only the current file.
+
+- {{{kbd(C-c C-e P a)}}} ::
+
+ Publish every project.
+
+Org uses timestamps to track when a file has changed. The above
+functions normally only publish changed files. You can override this
+and force publishing of all files by giving a prefix argument to any
+of the commands above.
+
+* Working with Source Code
+:PROPERTIES:
+:DESCRIPTION: Export, evaluate, and tangle code blocks.
+:END:
+
+Org mode provides a number of features for working with source code,
+including editing of code blocks in their native major mode,
+evaluation of code blocks, tangling of code blocks, and exporting code
+blocks and their results in several formats.
+
+A source code block conforms to this structure:
+
+#+begin_example
+,#+NAME: <name>
+,#+BEGIN_SRC <language> <switches> <header arguments>
+ <body>
+,#+END_SRC
+#+end_example
+
+#+texinfo: @noindent
+where:
+
+- =<name>= is a string used to uniquely name the code block,
+
+- =<language>= specifies the language of the code block, e.g.,
+ =emacs-lisp=, =shell=, =R=, =python=, etc.,
+
+- =<switches>= can be used to control export of the code block,
+
+- =<header arguments>= can be used to control many aspects of code
+ block behavior as demonstrated below,
+
+- =<body>= contains the actual source code.
+
+Use {{{kbd(C-c ')}}} to edit the current code block. It opens a new
+major mode edit buffer containing the body of the source code block,
+ready for any edits. Use {{{kbd(C-c ')}}} again to close the buffer
+and return to the Org buffer.
+
+** Using header arguments
+:PROPERTIES:
+:UNNUMBERED: notoc
+:END:
+
+A header argument is specified with an initial colon followed by the
+argument's name in lowercase.
+
+Header arguments can be set in several ways; Org prioritizes them in
+case of overlaps or conflicts by giving local settings a higher
+priority.
+
+- System-wide header arguments ::
+
+ Those are specified by customizing ~org-babel-default-header-args~
+ variable, or, for a specific language {{{var(LANG)}}}
+ ~org-babel-default-header-args:LANG~.
+
+- Header arguments in properties ::
+
+ You can set them using =header-args= property (see [[*Properties]])---or
+ =header-args:LANG= for language {{{var(LANG)}}}. Header arguments
+ set through properties drawers apply at the sub-tree level on down.
+
+- Header arguments in code blocks ::
+
+ Header arguments are most commonly set at the source code block
+ level, on the =BEGIN_SRC= line:
+
+ #+begin_example
+ ,#+NAME: factorial
+ ,#+BEGIN_SRC haskell :results silent :exports code :var n=0
+ fac 0 = 1
+ fac n = n * fac (n-1)
+ ,#+END_SRC
+ #+end_example
+
+ Code block header arguments can span multiple lines using =HEADER=
+ keyword on each line.
+
+** Evaluating code blocks
+:PROPERTIES:
+:UNNUMBERED: notoc
+:END:
+
+Use {{{kbd(C-c C-c)}}} to evaluate the current code block and insert
+its results in the Org document. By default, evaluation is only
+turned on for =emacs-lisp= code blocks, however support exists for
+evaluating blocks in many languages. For a complete list of supported
+languages see the manual. The following shows a code block and its
+results.
+
+#+begin_example
+,#+BEGIN_SRC emacs-lisp
+ (+ 1 2 3 4)
+,#+END_SRC
+
+,#+RESULTS:
+: 10
+#+end_example
+
+The following syntax is used to pass arguments to code blocks using
+the =var= header argument.
+
+: :var NAME=ASSIGN
+
+#+texinfo: @noindent
+{{{var(NAME)}}} is the name of the variable bound in the code block
+body. {{{var(ASSIGN)}}} is a literal value, such as a string,
+a number, a reference to a table, a list, a literal example, another
+code block---with or without arguments---or the results of evaluating
+a code block.
+
+** Results of evaluation
+:PROPERTIES:
+:UNNUMBERED: notoc
+:END:
+
+How Org handles results of a code block execution depends on many
+header arguments working together. The primary determinant, however,
+is the =results= header argument. It controls the /collection/,
+/type/, /format/, and /handling/ of code block results.
+
+- Collection ::
+
+ How the results should be collected from the code block. You may
+ choose either =output= or =value= (the default).
+
+- Type ::
+
+ What result types to expect from the execution of the code block.
+ You may choose among =table=, =list=, =scalar=, and =file=. Org
+ tries to guess it if you do not provide it.
+
+- Format ::
+
+ How Org processes results. Some possible values are =code=,
+ =drawer=, =html=, =latex=, =link=, and =raw=.
+
+- Handling ::
+
+ How to insert the results once properly formatted. Allowed values
+ are =silent=, =replace= (the default), =append=, or =prepend=.
+
+Code blocks which output results to files---e.g.: graphs, diagrams and
+figures---can accept a =:file FILENAME= header argument, in which case
+the results are saved to the named file, and a link to the file is
+inserted into the buffer.
+
+** Exporting code blocks
+:PROPERTIES:
+:UNNUMBERED: notoc
+:END:
+
+It is possible to export the /code/ of code blocks, the /results/ of
+code block evaluation, /both/ the code and the results of code block
+evaluation, or /none/. Org defaults to exporting /code/ for most
+languages.
+
+The =exports= header argument is to specify if that part of the Org
+file is exported to, say, HTML or LaTeX formats. It can be set to
+either =code=, =results=, =both= or =none=.
+
+** Extracting source code
+:PROPERTIES:
+:UNNUMBERED: notoc
+:END:
+
+Use {{{kbd(C-c C-v t)}}} to create pure source code files by
+extracting code from source blocks in the current buffer. This is
+referred to as "tangling"---a term adopted from the literate
+programming community. During tangling of code blocks their bodies
+are expanded using ~org-babel-expand-src-block~, which can expand both
+variable and "Noweb" style references. In order to tangle a code
+block it must have a =tangle= header argument, see the manual for
+details.
+
+* Miscellaneous
+:PROPERTIES:
+:DESCRIPTION: All the rest which did not fit elsewhere.
+:END:
+
+** Completion
+:PROPERTIES:
+:UNNUMBERED: notoc
+:END:
+
+Org has in-buffer completions with {{{kbd(M-TAB)}}}. No minibuffer is
+involved. Type one or more letters and invoke the hot key to complete
+the text in-place.
+
+For example, this command will complete TeX symbols after =\=, TODO
+keywords at the beginning of a headline, and tags after =:= in
+a headline.
+
+
+** Structure Templates
+:PROPERTIES:
+:UNNUMBERED: notoc
+:END:
+
+To quickly insert empty structural blocks, such as =#+BEGIN_SRC=
+... =#+END_SRC=, or to wrap existing text in such a block, use
+
+- {{{kbd(C-c C-\,)}}} ::
+
+ Prompt for a type of block structure, and insert the block at point.
+ If the region is active, it is wrapped in the block.
+
+** Clean view
+:PROPERTIES:
+:UNNUMBERED: notoc
+:END:
+
+Org's default outline with stars and no indents can become too
+cluttered for short documents. For /book-like/ long documents, the
+effect is not as noticeable. Org provides an alternate stars and
+indentation scheme, as shown on the right in the following table. It
+uses only one star and indents text to line with the heading:
+
+#+begin_example
+,* Top level headline | * Top level headline
+,** Second level | * Second level
+,*** Third level | * Third level
+ some text | some text
+,*** Third level | * Third level
+ more text | more text
+,* Another top level headline | * Another top level headline
+#+end_example
+
+This kind of view can be achieved dynamically at display time using
+Org Indent mode ({{{kbd(M-x org-indent-mode RET)}}}), which prepends
+intangible space to each line. You can turn on Org Indent mode for
+all files by customizing the variable ~org-startup-indented~, or you
+can turn it on for individual files using
+
+: #+STARTUP: indent
+
+If you want the indentation to be hard space characters so that the
+plain text file looks as similar as possible to the Emacs display, Org
+supports you by helping to indent (with {{{kbd(TAB)}}}) text below
+each headline, by hiding leading stars, and by only using levels 1, 3,
+etc to get two characters indentation for each level. To get this
+support in a file, use
+
+: #+STARTUP: hidestars odd
+
+* Export Setup :noexport:
+
+#+setupfile: doc-setup.org
+
+#+export_file_name: orgguide.texi
+
+#+texinfo_dir_category: Emacs
+#+texinfo_dir_title: Org Guide: (orgguide)
+#+texinfo_dir_desc: Abbreviated Org mode manual
+
+* Footnotes
+
+[fn:1] See the variable ~org-special-ctrl-a/e~ to configure special
+behavior of {{{kbd(C-a)}}} and {{{kbd(C-e)}}} in headlines.
+
+[fn:2] If you do not want the line to be split, customize the variable
+~org-M-RET-may-split-line~.
+
+[fn:3] See also the variable ~org-show-context-detail~ to decide how
+much context is shown around each match.
+
+[fn:4] The corresponding in-buffer setting is =#+STARTUP: logdone=.
+
+[fn:5] The corresponding in-buffer setting is =#+STARTUP:
+logenotedone=.
+
+[fn:6] As with all these in-buffer settings, pressing {{{kbd(C-c
+C-c)}}} activates any changes in the line.
+
+[fn:7] This is quite different from what is normally understood by
+/scheduling a meeting/, which is done in Org by just inserting a time
+stamp without keyword.
+
+[fn:8] It will still be listed on that date after it has been marked
+as done. If you do not like this, set the variable
+~org-agenda-skip-scheduled-if-done~.
+
+[fn:9] Using capture templates, you get finer control over capture
+locations. See [[*Capture templates]].
+
+[fn:10] If you need one of these sequences literally, escape the =%=
+with a backslash.
diff --git a/doc/org-manual.org b/doc/org-manual.org
index d4b1aa9..6476126 100644
--- a/doc/org-manual.org
+++ b/doc/org-manual.org
@@ -1,4 +1,9 @@
#+title: The Org Manual
+#+subtitle: Release {{{version}}}
+#+author: The Org Mode Developers
+#+date: {{{modification-time}}}
+#+language: en
+
#+texinfo: @insertcopying
@@ -142,7 +147,7 @@ $ cd org-mode/
$ make autoloads
#+end_example
-Note that in this case, ~make autoloads~ is mandatory: it defines
+Note that in this case, =make autoloads= is mandatory: it defines
Org's version in =org-version.el= and Org's autoloads in
=org-loaddefs.el=.
@@ -181,8 +186,8 @@ For a better experience, the three Org commands ~org-store-link~,
~org-capture~ and ~org-agenda~ ought to be accessible anywhere in
Emacs, not just in Org buffers. To that effect, you need to bind them
to globally available keys, like the ones reserved for users (see
-[[info:elisp::Key%20Binding%20Conventions]]). Here are suggested
-bindings, please modify the keys to your own liking.
+[[info:elisp::Key Binding Conventions]]). Here are suggested bindings,
+please modify the keys to your own liking.
#+begin_src emacs-lisp
(global-set-key (kbd "C-c l") 'org-store-link)
@@ -203,10 +208,10 @@ which selects Org mode for this buffer no matter what the file's name
is. See also the variable ~org-insert-mode-line-in-empty-file~.
Many commands in Org work on the region if the region is /active/. To
-make use of this, you need to have ~transient-mark-mode~ turned on,
-which is the default. If you do not like ~transient-mark-mode~, you
-can create an active region by using the mouse to select a region, or
-pressing {{{kbd(C-SPC)}}} twice before moving point.
+make use of this, you need to have Transient Mark mode turned on,
+which is the default. If you do not like it, you can create an active
+region by using the mouse to select a region, or pressing
+{{{kbd(C-SPC)}}} twice before moving point.
** Feedback
:PROPERTIES:
@@ -333,24 +338,24 @@ conventions:
#+attr_texinfo: :sep ,
- =TODO=, =WAITING= ::
- TODO keywords are written with all capitals, even if they are
- user-defined.
+ TODO keywords are written with all capitals, even if they are
+ user-defined.
- =boss=, =ARCHIVE= ::
- Tags are case-sensitive. User-defined tags are written in
- lowercase; built-in tags with special meaning are written as they
- should appear in the document, usually with all capitals.
+ Tags are case-sensitive. User-defined tags are written in
+ lowercase; built-in tags with special meaning are written as they
+ should appear in the document, usually with all capitals.
- =Release=, =PRIORITY= ::
- User-defined properties are capitalized; built-in properties with
- special meaning are written with all capitals.
+ User-defined properties are capitalized; built-in properties with
+ special meaning are written with all capitals.
- =TITLE=, =BEGIN= ... =END= ::
- Keywords and blocks are written in uppercase to enhance their
- readability, but you can use lowercase in your Org files.
+ Keywords and blocks are written in uppercase to enhance their
+ readability, but you can use lowercase in your Org files.
*** Key bindings and commands
:PROPERTIES:
@@ -413,7 +418,11 @@ as a title for your own headings.
Some people find the many stars too noisy and would prefer an outline
that has whitespace followed by a single star as headline starters.
-See [[*A Cleaner Outline View]].
+This can be achieved using a Org Indent minor mode. See [[*A Cleaner
+Outline View]] for more information.
+
+Headlines are not numbered. However, you may want to dynamically
+number some, or all, of them. See [[*Dynamic Headline Numbering]].
#+vindex: org-cycle-separator-lines
An empty line after the end of a subtree is considered part of it and
@@ -449,104 +458,104 @@ Org uses just two commands, bound to {{{kbd(TAB)}}} and
#+attr_texinfo: :sep ,
- {{{kbd(TAB)}}} (~org-cycle~) ::
- #+kindex: TAB
- #+findex: org-cycle
- /Subtree cycling/: Rotate current subtree among the states
+ #+kindex: TAB
+ #+findex: org-cycle
+ /Subtree cycling/: Rotate current subtree among the states
- #+begin_example
- ,-> FOLDED -> CHILDREN -> SUBTREE --.
- '-----------------------------------'
- #+end_example
+ #+begin_example
+ ,-> FOLDED -> CHILDREN -> SUBTREE --.
+ '-----------------------------------'
+ #+end_example
- #+vindex: org-cycle-emulate-tab
- Point must be on a headline for this to work[fn:4].
+ #+vindex: org-cycle-emulate-tab
+ Point must be on a headline for this to work[fn:4].
- {{{kbd(S-TAB)}}} (~org-global-cycle~), {{{kbd(C-u TAB)}}} ::
- #+cindex: global visibility states
- #+cindex: global cycling
- #+cindex: overview, global visibility state
- #+cindex: contents, global visibility state
- #+cindex: show all, global visibility state
- #+kindex: C-u TAB
- #+kindex: S-TAB
- #+findex: org-global-cycle
- /Global cycling/: Rotate the entire buffer among the states
-
- #+begin_example
- ,-> OVERVIEW -> CONTENTS -> SHOW ALL --.
- '--------------------------------------'
- #+end_example
-
- When {{{kbd(S-TAB)}}} is called with a numeric prefix argument N,
- the CONTENTS view up to headlines of level N are shown. Note
- that inside tables (see [[*Tables]]), {{{kbd(S-TAB)}}} jumps to the
- previous field instead.
-
- #+vindex: org-cycle-global-at-bob
- You can run global cycling using {{{kbd(TAB)}}} only if point is
- at the very beginning of the buffer, but not on a headline, and
- ~org-cycle-global-at-bob~ is set to a non-~nil~ value.
+ #+cindex: global visibility states
+ #+cindex: global cycling
+ #+cindex: overview, global visibility state
+ #+cindex: contents, global visibility state
+ #+cindex: show all, global visibility state
+ #+kindex: C-u TAB
+ #+kindex: S-TAB
+ #+findex: org-global-cycle
+ /Global cycling/: Rotate the entire buffer among the states
+
+ #+begin_example
+ ,-> OVERVIEW -> CONTENTS -> SHOW ALL --.
+ '--------------------------------------'
+ #+end_example
+
+ When {{{kbd(S-TAB)}}} is called with a numeric prefix argument N,
+ the CONTENTS view up to headlines of level N are shown. Note that
+ inside tables (see [[*Tables]]), {{{kbd(S-TAB)}}} jumps to the previous
+ field instead.
+
+ #+vindex: org-cycle-global-at-bob
+ You can run global cycling using {{{kbd(TAB)}}} only if point is at
+ the very beginning of the buffer, but not on a headline, and
+ ~org-cycle-global-at-bob~ is set to a non-~nil~ value.
- {{{kbd(C-u C-u TAB)}}} (~org-set-startup-visibility~) ::
- #+cindex: startup visibility
- #+kindex: C-u C-u TAB
- #+findex: org-set-startup-visibility
- Switch back to the startup visibility of the buffer (see [[*Initial
- visibility]]).
+ #+cindex: startup visibility
+ #+kindex: C-u C-u TAB
+ #+findex: org-set-startup-visibility
+ Switch back to the startup visibility of the buffer (see [[*Initial
+ visibility]]).
- {{{kbd(C-u C-u C-u TAB)}}} (~outline-show-all~) ::
- #+cindex: show all, command
- #+kindex: C-u C-u C-u TAB
- #+findex: outline-show-all
- Show all, including drawers.
+ #+cindex: show all, command
+ #+kindex: C-u C-u C-u TAB
+ #+findex: outline-show-all
+ Show all, including drawers.
- {{{kbd(C-c C-r)}}} (~org-reveal~) ::
- #+cindex: revealing context
- #+kindex: C-c C-r
- #+findex: org-reveal
- Reveal context around point, showing the current entry, the
- following heading and the hierarchy above. Useful for working
- near a location that has been exposed by a sparse tree command
- (see [[*Sparse Trees]]) or an agenda command (see [[*Commands in the
- Agenda Buffer]]). With a prefix argument show, on each level, all
- sibling headings. With a double prefix argument, also show the
- entire subtree of the parent.
+ #+cindex: revealing context
+ #+kindex: C-c C-r
+ #+findex: org-reveal
+ Reveal context around point, showing the current entry, the
+ following heading and the hierarchy above. Useful for working near
+ a location that has been exposed by a sparse tree command (see
+ [[*Sparse Trees]]) or an agenda command (see [[*Commands in the Agenda
+ Buffer]]). With a prefix argument show, on each level, all sibling
+ headings. With a double prefix argument, also show the entire
+ subtree of the parent.
- {{{kbd(C-c C-k)}}} (~outline-show-branches~) ::
- #+cindex: show branches, command
- #+kindex: C-c C-k
- #+findex: outline-show-branches
- Expose all the headings of the subtree, CONTENTS view for just
- one subtree.
+ #+cindex: show branches, command
+ #+kindex: C-c C-k
+ #+findex: outline-show-branches
+ Expose all the headings of the subtree, CONTENTS view for just one
+ subtree.
- {{{kbd(C-c TAB)}}} (~outline-show-children~) ::
- #+cindex: show children, command
- #+kindex: C-c TAB
- #+findex: outline-show-children
- Expose all direct children of the subtree. With a numeric prefix
- argument N, expose all children down to level N.
+ #+cindex: show children, command
+ #+kindex: C-c TAB
+ #+findex: outline-show-children
+ Expose all direct children of the subtree. With a numeric prefix
+ argument N, expose all children down to level N.
- {{{kbd(C-c C-x b)}}} (~org-tree-to-indirect-buffer~) ::
- #+kindex: C-c C-x b
- #+findex: org-tree-to-indirect-buffer
- Show the current subtree in an indirect buffer[fn:5]. With
- a numeric prefix argument, N, go up to level N and then take that
- tree. If N is negative then go up that many levels. With
- a {{{kbd(C-u)}}} prefix, do not remove the previously used
- indirect buffer.
+ #+kindex: C-c C-x b
+ #+findex: org-tree-to-indirect-buffer
+ Show the current subtree in an indirect buffer[fn:5]. With
+ a numeric prefix argument, N, go up to level N and then take that
+ tree. If N is negative then go up that many levels. With
+ a {{{kbd(C-u)}}} prefix, do not remove the previously used indirect
+ buffer.
- {{{kbd(C-c C-x v)}}} (~org-copy-visible~) ::
- #+kindex: C-c C-x v
- #+findex: org-copy-visible
- Copy the /visible/ text in the region into the kill ring.
+ #+kindex: C-c C-x v
+ #+findex: org-copy-visible
+ Copy the /visible/ text in the region into the kill ring.
*** Initial visibility
:PROPERTIES:
@@ -575,11 +584,11 @@ for this property are =folded=, =children=, =content=, and =all=.
- {{{kbd(C-u C-u TAB)}}} (~org-set-startup-visibility~) ::
- #+kindex: C-u C-u TAB
- #+findex: org-set-startup-visibility
- Switch back to the startup visibility of the buffer, i.e.,
- whatever is requested by startup options and =VISIBILITY=
- properties in individual entries.
+ #+kindex: C-u C-u TAB
+ #+findex: org-set-startup-visibility
+ Switch back to the startup visibility of the buffer, i.e., whatever
+ is requested by startup options and =VISIBILITY= properties in
+ individual entries.
*** Catching invisible edits
:PROPERTIES:
@@ -606,62 +615,62 @@ The following commands jump to other headlines in the buffer.
- {{{kbd(C-c C-n)}}} (~org-next-visible-heading~) ::
- #+kindex: C-c C-n
- #+findex: org-next-visible-heading
- Next heading.
+ #+kindex: C-c C-n
+ #+findex: org-next-visible-heading
+ Next heading.
- {{{kbd(C-c C-p)}}} (~org-previous-visible-heading~) ::
- #+kindex: C-c C-p
- #+findex: org-previous-visible-heading
- Previous heading.
+ #+kindex: C-c C-p
+ #+findex: org-previous-visible-heading
+ Previous heading.
- {{{kbd(C-c C-f)}}} (~org-forward-heading-same-level~) ::
- #+kindex: C-c C-f
- #+findex: org-forward-heading-same-level
- Next heading same level.
+ #+kindex: C-c C-f
+ #+findex: org-forward-heading-same-level
+ Next heading same level.
- {{{kbd(C-c C-b)}}} (~org-backward-heading-same-level~) ::
- #+kindex: C-c C-b
- #+findex: org-backward-heading-same-level
- Previous heading same level.
+ #+kindex: C-c C-b
+ #+findex: org-backward-heading-same-level
+ Previous heading same level.
- {{{kbd(C-c C-u)}}} (~outline-up-heading~) ::
- #+kindex: C-c C-u
- #+findex: outline-up-heading
- Backward to higher level heading.
+ #+kindex: C-c C-u
+ #+findex: outline-up-heading
+ Backward to higher level heading.
- {{{kbd(C-c C-j)}}} (~org-goto~) ::
- #+kindex: C-c C-j
- #+findex: org-goto
- #+vindex: org-goto-auto-isearch
- Jump to a different place without changing the current outline
- visibility. Shows the document structure in a temporary buffer,
- where you can use the following keys to find your destination:
-
- #+attr_texinfo: :columns 0.3 0.7
- | {{{kbd(TAB)}}} | Cycle visibility. |
- | {{{kbd(DOWN)}}} / {{{kbd(UP)}}} | Next/previous visible headline. |
- | {{{kbd(RET)}}} | Select this location. |
- | {{{kbd(/)}}} | Do a Sparse-tree search |
-
- #+texinfo: @noindent
- The following keys work if you turn off ~org-goto-auto-isearch~
-
- #+attr_texinfo: :columns 0.3 0.7
- | {{{kbd(n)}}} / {{{kbd(p)}}} | Next/previous visible headline. |
- | {{{kbd(f)}}} / {{{kbd(b)}}} | Next/previous headline same level. |
- | {{{kbd(u)}}} | One level up. |
- | {{{kbd(0)}}} ... {{{kbd(9)}}} | Digit argument. |
- | {{{kbd(q)}}} | Quit. |
-
- #+vindex: org-goto-interface
- #+texinfo: @noindent
- See also the variable ~org-goto-interface~.
+ #+kindex: C-c C-j
+ #+findex: org-goto
+ #+vindex: org-goto-auto-isearch
+ Jump to a different place without changing the current outline
+ visibility. Shows the document structure in a temporary buffer,
+ where you can use the following keys to find your destination:
+
+ #+attr_texinfo: :columns 0.3 0.7
+ | {{{kbd(TAB)}}} | Cycle visibility. |
+ | {{{kbd(DOWN)}}} / {{{kbd(UP)}}} | Next/previous visible headline. |
+ | {{{kbd(RET)}}} | Select this location. |
+ | {{{kbd(/)}}} | Do a Sparse-tree search |
+
+ #+texinfo: @noindent
+ The following keys work if you turn off ~org-goto-auto-isearch~
+
+ #+attr_texinfo: :columns 0.3 0.7
+ | {{{kbd(n)}}} / {{{kbd(p)}}} | Next/previous visible headline. |
+ | {{{kbd(f)}}} / {{{kbd(b)}}} | Next/previous headline same level. |
+ | {{{kbd(u)}}} | One level up. |
+ | {{{kbd(0)}}} ... {{{kbd(9)}}} | Digit argument. |
+ | {{{kbd(q)}}} | Quit. |
+
+ #+vindex: org-goto-interface
+ #+texinfo: @noindent
+ See also the variable ~org-goto-interface~.
** Structure Editing
:PROPERTIES:
@@ -680,208 +689,203 @@ The following commands jump to other headlines in the buffer.
- {{{kbd(M-RET)}}} (~org-meta-return~) ::
- #+kindex: M-RET
- #+findex: org-meta-return
- #+vindex: org-M-RET-may-split-line
- Insert a new heading, item or row.
+ #+kindex: M-RET
+ #+findex: org-meta-return
+ #+vindex: org-M-RET-may-split-line
+ Insert a new heading, item or row.
- If the command is used at the /beginning/ of a line, and if there
- is a heading or a plain list item (see [[*Plain Lists]]) at point,
- the new heading/item is created /before/ the current line. When
- used at the beginning of a regular line of text, turn that line
- into a heading.
+ If the command is used at the /beginning/ of a line, and if there is
+ a heading or a plain list item (see [[*Plain Lists]]) at point, the new
+ heading/item is created /before/ the current line. When used at the
+ beginning of a regular line of text, turn that line into a heading.
- When this command is used in the middle of a line, the line is
- split and the rest of the line becomes the new item or headline.
- If you do not want the line to be split, customize
- ~org-M-RET-may-split-line~.
+ When this command is used in the middle of a line, the line is split
+ and the rest of the line becomes the new item or headline. If you
+ do not want the line to be split, customize
+ ~org-M-RET-may-split-line~.
- Calling the command with a {{{kbd(C-u)}}} prefix unconditionally
- inserts a new heading at the end of the current subtree, thus
- preserving its contents. With a double {{{kbd(C-u C-u)}}}
- prefix, the new heading is created at the end of the parent
- subtree instead.
+ Calling the command with a {{{kbd(C-u)}}} prefix unconditionally
+ inserts a new heading at the end of the current subtree, thus
+ preserving its contents. With a double {{{kbd(C-u C-u)}}} prefix,
+ the new heading is created at the end of the parent subtree instead.
- {{{kbd(C-RET)}}} (~org-insert-heading-respect-content~) ::
- #+kindex: C-RET
- #+findex: org-insert-heading-respect-content
- Insert a new heading at the end of the current subtree.
+ #+kindex: C-RET
+ #+findex: org-insert-heading-respect-content
+ Insert a new heading at the end of the current subtree.
- {{{kbd(M-S-RET)}}} (~org-insert-todo-heading~) ::
- #+kindex: M-S-RET
- #+findex: org-insert-todo-heading
- #+vindex: org-treat-insert-todo-heading-as-state-change
- Insert new TODO entry with same level as current heading. See
- also the variable
- ~org-treat-insert-todo-heading-as-state-change~.
+ #+kindex: M-S-RET
+ #+findex: org-insert-todo-heading
+ #+vindex: org-treat-insert-todo-heading-as-state-change
+ Insert new TODO entry with same level as current heading. See also
+ the variable ~org-treat-insert-todo-heading-as-state-change~.
- {{{kbd(C-S-RET)}}} (~org-insert-todo-heading-respect-content~) ::
- #+kindex: C-S-RET
- #+findex: org-insert-todo-heading-respect-content
- Insert new TODO entry with same level as current heading. Like
- {{{kbd(C-RET)}}}, the new headline is inserted after the current
- subtree.
+ #+kindex: C-S-RET
+ #+findex: org-insert-todo-heading-respect-content
+ Insert new TODO entry with same level as current heading. Like
+ {{{kbd(C-RET)}}}, the new headline is inserted after the current
+ subtree.
- {{{kbd(TAB)}}} (~org-cycle~) ::
- #+kindex: TAB
- #+findex: org-cycle
- In a new entry with no text yet, the first {{{kbd(TAB)}}} demotes
- the entry to become a child of the previous one. The next
- {{{kbd(TAB)}}} makes it a parent, and so on, all the way to top
- level. Yet another {{{kbd(TAB)}}}, and you are back to the
- initial level.
+ #+kindex: TAB
+ #+findex: org-cycle
+ In a new entry with no text yet, the first {{{kbd(TAB)}}} demotes
+ the entry to become a child of the previous one. The next
+ {{{kbd(TAB)}}} makes it a parent, and so on, all the way to top
+ level. Yet another {{{kbd(TAB)}}}, and you are back to the initial
+ level.
- {{{kbd(M-LEFT)}}} (~org-do-promote~) ::
- #+kindex: M-LEFT
- #+findex: org-do-promote
- Promote current heading by one level.
+ #+kindex: M-LEFT
+ #+findex: org-do-promote
+ Promote current heading by one level.
- {{{kbd(M-RIGHT)}}} (~org-do-demote~) ::
- #+kindex: M-RIGHT
- #+findex: org-do-demote
- Demote current heading by one level.
+ #+kindex: M-RIGHT
+ #+findex: org-do-demote
+ Demote current heading by one level.
- {{{kbd(M-S-LEFT)}}} (~org-promote-subtree~) ::
- #+kindex: M-S-LEFT
- #+findex: org-promote-subtree
- Promote the current subtree by one level.
+ #+kindex: M-S-LEFT
+ #+findex: org-promote-subtree
+ Promote the current subtree by one level.
- {{{kbd(M-S-RIGHT)}}} (~org-demote-subtree~) ::
- #+kindex: M-S-RIGHT
- #+findex: org-demote-subtree
- Demote the current subtree by one level.
+ #+kindex: M-S-RIGHT
+ #+findex: org-demote-subtree
+ Demote the current subtree by one level.
- {{{kbd(M-UP)}}} (~org-move-subtree-up~) ::
- #+kindex: M-UP
- #+findex: org-move-subtree-up
- Move subtree up, i.e., swap with previous subtree of same level.
+ #+kindex: M-UP
+ #+findex: org-move-subtree-up
+ Move subtree up, i.e., swap with previous subtree of same level.
- {{{kbd(M-DOWN)}}} (~org-move-subtree-down~) ::
- #+kindex: M-DOWN
- #+findex: org-move-subtree-down
- Move subtree down, i.e., swap with next subtree of same level.
+ #+kindex: M-DOWN
+ #+findex: org-move-subtree-down
+ Move subtree down, i.e., swap with next subtree of same level.
- {{{kbd(C-c @)}}} (~org-mark-subtree~) ::
- #+kindex: C-c @@
- #+findex: org-mark-subtree
- Mark the subtree at point. Hitting repeatedly marks subsequent
- subtrees of the same level as the marked subtree.
+ #+kindex: C-c @@
+ #+findex: org-mark-subtree
+ Mark the subtree at point. Hitting repeatedly marks subsequent
+ subtrees of the same level as the marked subtree.
- {{{kbd(C-c C-x C-w)}}} (~org-cut-subtree~) ::
- #+kindex: C-c C-x C-w
- #+findex: org-cut-subtree
- Kill subtree, i.e., remove it from buffer but save in kill ring.
- With a numeric prefix argument N, kill N sequential subtrees.
+ #+kindex: C-c C-x C-w
+ #+findex: org-cut-subtree
+ Kill subtree, i.e., remove it from buffer but save in kill ring.
+ With a numeric prefix argument N, kill N sequential subtrees.
- {{{kbd(C-c C-x M-w)}}} (~org-copy-subtree~) ::
- #+kindex: C-c C-x M-w
- #+findex: org-copy-subtree
- Copy subtree to kill ring. With a numeric prefix argument N,
- copy the N sequential subtrees.
+ #+kindex: C-c C-x M-w
+ #+findex: org-copy-subtree
+ Copy subtree to kill ring. With a numeric prefix argument N, copy
+ the N sequential subtrees.
- {{{kbd(C-c C-x C-y)}}} (~org-paste-subtree~) ::
- #+kindex: C-c C-x C-y
- #+findex: org-paste-subtree
- Yank subtree from kill ring. This does modify the level of the
- subtree to make sure the tree fits in nicely at the yank
- position. The yank level can also be specified with a numeric
- prefix argument, or by yanking after a headline marker like
- =****=.
+ #+kindex: C-c C-x C-y
+ #+findex: org-paste-subtree
+ Yank subtree from kill ring. This does modify the level of the
+ subtree to make sure the tree fits in nicely at the yank position.
+ The yank level can also be specified with a numeric prefix argument,
+ or by yanking after a headline marker like =****=.
- {{{kbd(C-y)}}} (~org-yank~) ::
- #+kindex: C-y
- #+findex: org-yank
- #+vindex: org-yank-adjusted-subtrees
- #+vindex: org-yank-folded-subtrees
- Depending on the variables ~org-yank-adjusted-subtrees~ and
- ~org-yank-folded-subtrees~, Org's internal ~yank~ command pastes
- subtrees folded and in a clever way, using the same command as
- {{{kbd(C-c C-x C-y)}}}. With the default settings, no level
- adjustment takes place, but the yanked tree is folded unless
- doing so would swallow text previously visible. Any prefix
- argument to this command forces a normal ~yank~ to be executed,
- with the prefix passed along. A good way to force a normal yank
- is {{{kbd(C-u C-y)}}}. If you use ~yank-pop~ after a yank, it
- yanks previous kill items plainly, without adjustment and
- folding.
+ #+kindex: C-y
+ #+findex: org-yank
+ #+vindex: org-yank-adjusted-subtrees
+ #+vindex: org-yank-folded-subtrees
+ Depending on the variables ~org-yank-adjusted-subtrees~ and
+ ~org-yank-folded-subtrees~, Org's internal ~yank~ command pastes
+ subtrees folded and in a clever way, using the same command as
+ {{{kbd(C-c C-x C-y)}}}. With the default settings, no level
+ adjustment takes place, but the yanked tree is folded unless doing
+ so would swallow text previously visible. Any prefix argument to
+ this command forces a normal ~yank~ to be executed, with the prefix
+ passed along. A good way to force a normal yank is {{{kbd(C-u
+ C-y)}}}. If you use ~yank-pop~ after a yank, it yanks previous kill
+ items plainly, without adjustment and folding.
- {{{kbd(C-c C-x c)}}} (~org-clone-subtree-with-time-shift~) ::
- #+kindex: C-c C-x c
- #+findex: org-clone-subtree-with-time-shift
- Clone a subtree by making a number of sibling copies of it. You
- are prompted for the number of copies to make, and you can also
- specify if any timestamps in the entry should be shifted. This
- can be useful, for example, to create a number of tasks related
- to a series of lectures to prepare. For more details, see the
- docstring of the command ~org-clone-subtree-with-time-shift~.
+ #+kindex: C-c C-x c
+ #+findex: org-clone-subtree-with-time-shift
+ Clone a subtree by making a number of sibling copies of it. You are
+ prompted for the number of copies to make, and you can also specify
+ if any timestamps in the entry should be shifted. This can be
+ useful, for example, to create a number of tasks related to a series
+ of lectures to prepare. For more details, see the docstring of the
+ command ~org-clone-subtree-with-time-shift~.
- {{{kbd(C-c C-w)}}} (~org-refile~) ::
- #+kindex: C-c C-w
- #+findex: org-refile
- Refile entry or region to a different location. See [[*Refile and
- Copy]].
+ #+kindex: C-c C-w
+ #+findex: org-refile
+ Refile entry or region to a different location. See [[*Refile and
+ Copy]].
- {{{kbd(C-c ^)}}} (~org-sort~) ::
- #+kindex: C-c ^
- #+findex: org-sort
- Sort same-level entries. When there is an active region, all
- entries in the region are sorted. Otherwise the children of the
- current headline are sorted. The command prompts for the sorting
- method, which can be alphabetically, numerically, by time---first
- timestamp with active preferred, creation time, scheduled time,
- deadline time---by priority, by TODO keyword---in the sequence
- the keywords have been defined in the setup---or by the value of
- a property. Reverse sorting is possible as well. You can also
- supply your own function to extract the sorting key. With
- a {{{kbd(C-u)}}} prefix, sorting is case-sensitive.
+ #+kindex: C-c ^
+ #+findex: org-sort
+ Sort same-level entries. When there is an active region, all
+ entries in the region are sorted. Otherwise the children of the
+ current headline are sorted. The command prompts for the sorting
+ method, which can be alphabetically, numerically, by time---first
+ timestamp with active preferred, creation time, scheduled time,
+ deadline time---by priority, by TODO keyword---in the sequence the
+ keywords have been defined in the setup---or by the value of
+ a property. Reverse sorting is possible as well. You can also
+ supply your own function to extract the sorting key. With
+ a {{{kbd(C-u)}}} prefix, sorting is case-sensitive.
- {{{kbd(C-x n s)}}} (~org-narrow-to-subtree~) ::
- #+kindex: C-x n s
- #+findex: org-narrow-to-subtree
- Narrow buffer to current subtree.
+ #+kindex: C-x n s
+ #+findex: org-narrow-to-subtree
+ Narrow buffer to current subtree.
- {{{kbd(C-x n b)}}} (~org-narrow-to-block~) ::
- #+kindex: C-x n b
- #+findex: org-narrow-to-block
- Narrow buffer to current block.
+ #+kindex: C-x n b
+ #+findex: org-narrow-to-block
+ Narrow buffer to current block.
- {{{kbd(C-x n w)}}} (~widen~) ::
- #+kindex: C-x n w
- #+findex: widen
- Widen buffer to remove narrowing.
+ #+kindex: C-x n w
+ #+findex: widen
+ Widen buffer to remove narrowing.
- {{{kbd(C-c *)}}} (~org-toggle-heading~) ::
- #+kindex: C-c *
- #+findex: org-toggle-heading
- Turn a normal line or plain list item into a headline---so that
- it becomes a subheading at its location. Also turn a headline
- into a normal line by removing the stars. If there is an active
- region, turn all lines in the region into headlines. If the
- first line in the region was an item, turn only the item lines
- into headlines. Finally, if the first line is a headline, remove
- the stars from all headlines in the region.
+ #+kindex: C-c *
+ #+findex: org-toggle-heading
+ Turn a normal line or plain list item into a headline---so that it
+ becomes a subheading at its location. Also turn a headline into
+ a normal line by removing the stars. If there is an active region,
+ turn all lines in the region into headlines. If the first line in
+ the region was an item, turn only the item lines into headlines.
+ Finally, if the first line is a headline, remove the stars from all
+ headlines in the region.
#+cindex: region, active
#+cindex: active region
@@ -915,41 +919,41 @@ commands can be accessed through a dispatcher:
- {{{kbd(C-c /)}}} (~org-sparse-tree~) ::
- #+kindex: C-c /
- #+findex: org-sparse-tree
- This prompts for an extra key to select a sparse-tree creating
- command.
+ #+kindex: C-c /
+ #+findex: org-sparse-tree
+ This prompts for an extra key to select a sparse-tree creating
+ command.
- {{{kbd(C-c / r)}}} or {{{kbd(C-c / /)}}} (~org-occur~) ::
- #+kindex: C-c / r
- #+kindex: C-c / /
- #+findex: org-occur
- #+vindex: org-remove-highlights-with-change
- Prompts for a regexp and shows a sparse tree with all matches.
- If the match is in a headline, the headline is made visible. If
- the match is in the body of an entry, headline and body are made
- visible. In order to provide minimal context, also the full
- hierarchy of headlines above the match is shown, as well as the
- headline following the match. Each match is also highlighted;
- the highlights disappear when the buffer is changed by an editing
- command, or by pressing {{{kbd(C-c C-c)}}}[fn:8]. When called
- with a {{{kbd(C-u)}}} prefix argument, previous highlights are
- kept, so several calls to this command can be stacked.
+ #+kindex: C-c / r
+ #+kindex: C-c / /
+ #+findex: org-occur
+ #+vindex: org-remove-highlights-with-change
+ Prompts for a regexp and shows a sparse tree with all matches. If
+ the match is in a headline, the headline is made visible. If the
+ match is in the body of an entry, headline and body are made
+ visible. In order to provide minimal context, also the full
+ hierarchy of headlines above the match is shown, as well as the
+ headline following the match. Each match is also highlighted; the
+ highlights disappear when the buffer is changed by an editing
+ command, or by pressing {{{kbd(C-c C-c)}}}[fn:8]. When called with
+ a {{{kbd(C-u)}}} prefix argument, previous highlights are kept, so
+ several calls to this command can be stacked.
- {{{kbd(M-g n)}}} or {{{kbd(M-g M-n)}}} (~next-error~) ::
- #+kindex: M-g n
- #+kindex: M-g M-n
- #+findex: next-error
- Jump to the next sparse tree match in this buffer.
+ #+kindex: M-g n
+ #+kindex: M-g M-n
+ #+findex: next-error
+ Jump to the next sparse tree match in this buffer.
- {{{kbd(M-g p)}}} or {{{kbd(M-g M-p)}}} (~previous-error~) ::
- #+kindex: M-g p
- #+kindex: M-g M-p
- #+findex: previous-error
- Jump to the previous sparse tree match in this buffer.
+ #+kindex: M-g p
+ #+kindex: M-g M-p
+ #+findex: previous-error
+ Jump to the previous sparse tree match in this buffer.
#+vindex: org-agenda-custom-commands
For frequently used sparse trees of specific search strings, you can
@@ -1064,134 +1068,133 @@ to disable them individually.
#+attr_texinfo: :sep ,
- {{{kbd(TAB)}}} (~org-cycle~) ::
- #+cindex: cycling, in plain lists
- #+kindex: TAB
- #+findex: org-cycle
- #+vindex: org-cycle-include-plain-lists
- Items can be folded just like headline levels. Normally this
- works only if point is on a plain list item. For more details,
- see the variable ~org-cycle-include-plain-lists~. If this
- variable is set to ~integrate~, plain list items are treated like
- low-level headlines. The level of an item is then given by the
- indentation of the bullet/number. Items are always subordinate
- to real headlines, however; the hierarchies remain completely
- separated. In a new item with no text yet, the first
- {{{kbd(TAB)}}} demotes the item to become a child of the previous
- one. Subsequent {{{kbd(TAB)}}}s move the item to meaningful
- levels in the list and eventually get it back to its initial
- position.
+ #+cindex: cycling, in plain lists
+ #+kindex: TAB
+ #+findex: org-cycle
+ #+vindex: org-cycle-include-plain-lists
+ Items can be folded just like headline levels. Normally this works
+ only if point is on a plain list item. For more details, see the
+ variable ~org-cycle-include-plain-lists~. If this variable is set
+ to ~integrate~, plain list items are treated like low-level
+ headlines. The level of an item is then given by the indentation of
+ the bullet/number. Items are always subordinate to real headlines,
+ however; the hierarchies remain completely separated. In a new item
+ with no text yet, the first {{{kbd(TAB)}}} demotes the item to
+ become a child of the previous one. Subsequent {{{kbd(TAB)}}}s move
+ the item to meaningful levels in the list and eventually get it back
+ to its initial position.
- {{{kbd(M-RET)}}} (~org-insert-heading~) ::
- #+kindex: M-RET
- #+findex: org-insert-heading
- #+vindex: org-M-RET-may-split-line
- Insert new item at current level. With a prefix argument, force
- a new heading (see [[*Structure Editing]]). If this command is used
- in the middle of an item, that item is /split/ in two, and the
- second part becomes the new item[fn:13]. If this command is
- executed /before item's body/, the new item is created /before/
- the current one.
+ #+kindex: M-RET
+ #+findex: org-insert-heading
+ #+vindex: org-M-RET-may-split-line
+ Insert new item at current level. With a prefix argument, force
+ a new heading (see [[*Structure Editing]]). If this command is used in
+ the middle of an item, that item is /split/ in two, and the second
+ part becomes the new item[fn:13]. If this command is executed
+ /before item's body/, the new item is created /before/ the current
+ one.
- {{{kbd(M-S-RET)}}} ::
- #+kindex: M-S-RET
- Insert a new item with a checkbox (see [[*Checkboxes]]).
+ #+kindex: M-S-RET
+ Insert a new item with a checkbox (see [[*Checkboxes]]).
- {{{kbd(S-UP)}}}, {{{kbd(S-DOWN)}}} ::
- #+kindex: S-UP
- #+kindex: S-DOWN
- #+cindex: shift-selection-mode
- #+vindex: org-support-shift-select
- #+vindex: org-list-use-circular-motion
- Jump to the previous/next item in the current list, but only if
- ~org-support-shift-select~ is off[fn:14]. If not, you can
- still use paragraph jumping commands like {{{kbd(C-UP)}}}
- and {{{kbd(C-DOWN)}}} to quite similar effect.
+ #+kindex: S-UP
+ #+kindex: S-DOWN
+ #+cindex: shift-selection-mode
+ #+vindex: org-support-shift-select
+ #+vindex: org-list-use-circular-motion
+ Jump to the previous/next item in the current list, but only if
+ ~org-support-shift-select~ is off[fn:14]. If not, you can still use
+ paragraph jumping commands like {{{kbd(C-UP)}}} and
+ {{{kbd(C-DOWN)}}} to quite similar effect.
- {{{kbd(M-UP)}}}, {{{kbd(M-DOWN)}}} ::
- #+kindex: M-UP
- #+kindex: M-DOWN
- Move the item including subitems up/down[fn:15], i.e., swap with
- previous/next item of same indentation. If the list is ordered,
- renumbering is automatic.
+ #+kindex: M-UP
+ #+kindex: M-DOWN
+ Move the item including subitems up/down[fn:15], i.e., swap with
+ previous/next item of same indentation. If the list is ordered,
+ renumbering is automatic.
- {{{kbd(M-LEFT)}}}, {{{kbd(M-RIGHT)}}} ::
- #+kindex: M-LEFT
- #+kindex: M-RIGHT
- Decrease/increase the indentation of an item, leaving children
- alone.
+ #+kindex: M-LEFT
+ #+kindex: M-RIGHT
+ Decrease/increase the indentation of an item, leaving children
+ alone.
- {{{kbd(M-S-LEFT)}}}, {{{kbd(M-S-RIGHT)}}} ::
- #+kindex: M-S-LEFT
- #+kindex: M-S-RIGHT
- Decrease/increase the indentation of the item, including
- subitems. Initially, the item tree is selected based on current
- indentation. When these commands are executed several times in
- direct succession, the initially selected region is used, even if
- the new indentation would imply a different hierarchy. To use
- the new hierarchy, break the command chain by moving point.
+ #+kindex: M-S-LEFT
+ #+kindex: M-S-RIGHT
+ Decrease/increase the indentation of the item, including subitems.
+ Initially, the item tree is selected based on current indentation.
+ When these commands are executed several times in direct succession,
+ the initially selected region is used, even if the new indentation
+ would imply a different hierarchy. To use the new hierarchy, break
+ the command chain by moving point.
- As a special case, using this command on the very first item of
- a list moves the whole list. This behavior can be disabled by
- configuring ~org-list-automatic-rules~. The global indentation
- of a list has no influence on the text /after/ the list.
+ As a special case, using this command on the very first item of
+ a list moves the whole list. This behavior can be disabled by
+ configuring ~org-list-automatic-rules~. The global indentation of
+ a list has no influence on the text /after/ the list.
- {{{kbd(C-c C-c)}}} ::
- #+kindex: C-c C-c
- If there is a checkbox (see [[*Checkboxes]]) in the item line, toggle
- the state of the checkbox. In any case, verify bullets and
- indentation consistency in the whole list.
+ #+kindex: C-c C-c
+ If there is a checkbox (see [[*Checkboxes]]) in the item line, toggle
+ the state of the checkbox. In any case, verify bullets and
+ indentation consistency in the whole list.
- {{{kbd(C-c -)}}} ::
- #+kindex: C-c -
- #+vindex: org-plain-list-ordered-item-terminator
- Cycle the entire list level through the different
- itemize/enumerate bullets (=-=, =+=, =*=, =1.=, =1)=) or a subset
- of them, depending on ~org-plain-list-ordered-item-terminator~,
- the type of list, and its indentation. With a numeric prefix
- argument N, select the Nth bullet from this list. If there is an
- active region when calling this, selected text is changed into an
- item. With a prefix argument, all lines are converted to list
- items. If the first line already was a list item, any item
- marker is removed from the list. Finally, even without an active
- region, a normal line is converted into a list item.
+ #+kindex: C-c -
+ #+vindex: org-plain-list-ordered-item-terminator
+ Cycle the entire list level through the different itemize/enumerate
+ bullets (=-=, =+=, =*=, =1.=, =1)=) or a subset of them, depending
+ on ~org-plain-list-ordered-item-terminator~, the type of list, and
+ its indentation. With a numeric prefix argument N, select the Nth
+ bullet from this list. If there is an active region when calling
+ this, selected text is changed into an item. With a prefix
+ argument, all lines are converted to list items. If the first line
+ already was a list item, any item marker is removed from the list.
+ Finally, even without an active region, a normal line is converted
+ into a list item.
- {{{kbd(C-c *)}}} ::
- #+kindex: C-c *
- Turn a plain list item into a headline---so that it becomes
- a subheading at its location. See [[*Structure Editing]], for
- a detailed explanation.
+ #+kindex: C-c *
+ Turn a plain list item into a headline---so that it becomes
+ a subheading at its location. See [[*Structure Editing]], for
+ a detailed explanation.
- {{{kbd(C-c C-*)}}} ::
- #+kindex: C-c C-*
- Turn the whole plain list into a subtree of the current heading.
- Checkboxes (see [[*Checkboxes]]) become TODO, respectively DONE,
- keywords when unchecked, respectively checked.
+ #+kindex: C-c C-*
+ Turn the whole plain list into a subtree of the current heading.
+ Checkboxes (see [[*Checkboxes]]) become =TODO=, respectively =DONE=,
+ keywords when unchecked, respectively checked.
- {{{kbd(S-LEFT)}}}, {{{kbd(S-RIGHT)}}} ::
- #+vindex: org-support-shift-select
- #+kindex: S-LEFT
- #+kindex: S-RIGHT
- This command also cycles bullet styles when point is in on the
- bullet or anywhere in an item line, details depending on
- ~org-support-shift-select~.
+ #+vindex: org-support-shift-select
+ #+kindex: S-LEFT
+ #+kindex: S-RIGHT
+ This command also cycles bullet styles when point is in on the
+ bullet or anywhere in an item line, details depending on
+ ~org-support-shift-select~.
- {{{kbd(C-c ^)}}} ::
- #+kindex: C-c ^
- #+cindex: sorting, of plain list
- Sort the plain list. Prompt for the sorting method: numerically,
- alphabetically, by time, or by custom function.
+ #+kindex: C-c ^
+ #+cindex: sorting, of plain list
+ Sort the plain list. Prompt for the sorting method: numerically,
+ alphabetically, by time, or by custom function.
** Drawers
:PROPERTIES:
@@ -1239,8 +1242,8 @@ a similar way to state changes, use
- {{{kbd(C-c C-z)}}} ::
- #+kindex: C-c C-z
- Add a time-stamped note to the =LOGBOOK= drawer.
+ #+kindex: C-c C-z
+ Add a time-stamped note to the =LOGBOOK= drawer.
** Blocks
:PROPERTIES:
@@ -1262,102 +1265,6 @@ the variable ~org-hide-block-startup~ or on a per-file basis by using
,#+STARTUP: nohideblocks
#+end_example
-** Creating Footnotes
-:PROPERTIES:
-:DESCRIPTION: How footnotes are defined in Org's syntax.
-:END:
-#+cindex: footnotes
-
-Org mode supports the creation of footnotes.
-
-A footnote is started by a footnote marker in square brackets in
-column 0, no indentation allowed. It ends at the next footnote
-definition, headline, or after two consecutive empty lines. The
-footnote reference is simply the marker in square brackets, inside
-text. Markers always start with =fn:=. For example:
-
-#+begin_example
-The Org homepage[fn:1] now looks a lot better than it used to.
-...
-[fn:1] The link is: https://orgmode.org
-#+end_example
-
-Org mode extends the number-based syntax to /named/ footnotes and
-optional inline definition. Here are the valid references:
-
-- =[fn:NAME]= ::
-
- A named footnote reference, where {{{var(NAME)}}} is a unique
- label word, or, for simplicity of automatic creation, a number.
-
-- =[fn:: This is the inline definition of this footnote]= ::
-
- A LaTeX-like anonymous footnote where the definition is given
- directly at the reference point.
-
-- =[fn:NAME: a definition]= ::
-
- An inline definition of a footnote, which also specifies a name
- for the note. Since Org allows multiple references to the same
- note, you can then use =[fn:NAME]= to create additional
- references.
-
-#+vindex: org-footnote-auto-label
-Footnote labels can be created automatically, or you can create names
-yourself. This is handled by the variable ~org-footnote-auto-label~
-and its corresponding =STARTUP= keywords. See the docstring of that
-variable for details.
-
-The following command handles footnotes:
-
-- {{{kbd(C-c C-x f)}}} ::
-
- The footnote action command.
-
- #+kindex: C-c C-x f
- When point is on a footnote reference, jump to the
- definition. When it is at a definition, jump to
- the---first---reference.
-
- #+vindex: org-footnote-define-inline
- #+vindex: org-footnote-section
- Otherwise, create a new footnote. Depending on the variable
- ~org-footnote-define-inline~[fn:17], the definition is placed
- right into the text as part of the reference, or separately into
- the location determined by the variable ~org-footnote-section~.
-
- When this command is called with a prefix argument, a menu of
- additional options is offered:
-
- #+attr_texinfo: :columns 0.1 0.9
- | {{{kbd(s)}}} | Sort the footnote definitions by reference sequence. |
- | {{{kbd(r)}}} | Renumber the simple =fn:N= footnotes. |
- | {{{kbd(S)}}} | Short for first {{{kbd(r)}}}, then {{{kbd(s)}}} action. |
- | {{{kbd(n)}}} | Rename all footnotes into a =fn:1= ... =fn:n= sequence. |
- | {{{kbd(d)}}} | Delete the footnote at point, including definition and references. |
-
- #+vindex: org-footnote-auto-adjust
- Depending on the variable ~org-footnote-auto-adjust~[fn:18],
- renumbering and sorting footnotes can be automatic after each
- insertion or deletion.
-
-- {{{kbd(C-c C-c)}}} ::
-
- #+kindex: C-c C-c
- If point is on a footnote reference, jump to the definition.
- If it is at the definition, jump back to the reference. When
- called at a footnote location with a prefix argument, offer the
- same menu as {{{kbd(C-c C-x f)}}}.
-
-- {{{kbd(C-c C-o)}}} or {{{kbd(mouse-1/2)}}} ::
-
- #+kindex: C-c C-o
- #+kindex: mouse-1
- #+kindex: mouse-2
- Footnote labels are also links to the corresponding definition or
- reference, and you can use the usual commands to follow these
- links.
-
* Tables
:PROPERTIES:
:DESCRIPTION: Pure magic for quick formatting.
@@ -1381,8 +1288,8 @@ Calculator Manual]]).
#+cindex: table syntax
Org makes it easy to format tables in plain ASCII. Any line with =|=
as the first non-whitespace character is considered part of a table.
-=|= is also the column separator[fn:19]. Moreover, a line starting
-with =|-= is a horizontal rule. It separates rows explicitely. Rows
+=|= is also the column separator[fn:17]. Moreover, a line starting
+with =|-= is a horizontal rule. It separates rows explicitly. Rows
before the first horizontal rule are header lines. A table might look
like this:
@@ -1427,22 +1334,22 @@ you, configure the option ~org-table-auto-blank-field~.
- {{{kbd(C-c |)}}} (~org-table-create-or-convert-from-region~) ::
- #+kindex: C-c |
- #+findex: org-table-create-or-convert-from-region
- Convert the active region to table. If every line contains at
- least one {{{kbd(TAB)}}} character, the function assumes that the
- material is tab separated. If every line contains a comma,
- comma-separated values (CSV) are assumed. If not, lines are
- split at whitespace into fields. You can use a prefix argument
- to force a specific separator: {{{kbd(C-u)}}} forces CSV,
- {{{kbd(C-u C-u)}}} forces {{{kbd(TAB)}}}, {{{kbd(C-u C-u C-u)}}}
- prompts for a regular expression to match the separator, and
- a numeric argument N indicates that at least N consecutive
- spaces, or alternatively a {{{kbd(TAB)}}} will be the separator.
-
- If there is no active region, this command creates an empty Org
- table. But it is easier just to start typing, like {{{kbd(|
- N a m e | P h o n e | A g e RET | - TAB)}}}.
+ #+kindex: C-c |
+ #+findex: org-table-create-or-convert-from-region
+ Convert the active region to table. If every line contains at least
+ one {{{kbd(TAB)}}} character, the function assumes that the material
+ is tab separated. If every line contains a comma, comma-separated
+ values (CSV) are assumed. If not, lines are split at whitespace
+ into fields. You can use a prefix argument to force a specific
+ separator: {{{kbd(C-u)}}} forces CSV, {{{kbd(C-u C-u)}}} forces
+ {{{kbd(TAB)}}}, {{{kbd(C-u C-u C-u)}}} prompts for a regular
+ expression to match the separator, and a numeric argument
+ N indicates that at least N consecutive spaces, or alternatively
+ a {{{kbd(TAB)}}} will be the separator.
+
+ If there is no active region, this command creates an empty Org
+ table. But it is easier just to start typing, like {{{kbd(|
+ N a m e | P h o n e | A g e RET | - TAB)}}}.
*** Re-aligning and field motion
:PROPERTIES:
@@ -1451,49 +1358,49 @@ you, configure the option ~org-table-auto-blank-field~.
- {{{kbd(C-c C-c)}}} (~org-table-align~) ::
- #+kindex: C-c C-c
- #+findex: org-table-align
- Re-align the table without moving point.
+ #+kindex: C-c C-c
+ #+findex: org-table-align
+ Re-align the table without moving point.
- {{{kbd(TAB)}}} (~org-table-next-field~) ::
- #+kindex: TAB
- #+findex: org-table-next-field
- Re-align the table, move to the next field. Creates a new row if
- necessary.
+ #+kindex: TAB
+ #+findex: org-table-next-field
+ Re-align the table, move to the next field. Creates a new row if
+ necessary.
- {{{kbd(C-c SPC)}}} (~org-table-blank-field~) ::
- #+kindex: C-c SPC
- #+findex: org-table-blank-field
- Blank the field at point.
+ #+kindex: C-c SPC
+ #+findex: org-table-blank-field
+ Blank the field at point.
- {{{kbd(S-TAB)}}} (~org-table-previous-field~) ::
- #+kindex: S-TAB
- #+findex: org-table-previous-field
- Re-align, move to previous field.
+ #+kindex: S-TAB
+ #+findex: org-table-previous-field
+ Re-align, move to previous field.
- {{{kbd(RET)}}} (~org-table-next-row~) ::
- #+kindex: RET
- #+findex: org-table-next-row
- Re-align the table and move down to next row. Creates a new row
- if necessary. At the beginning or end of a line, {{{kbd(RET)}}}
- still inserts a new line, so it can be used to split a table.
+ #+kindex: RET
+ #+findex: org-table-next-row
+ Re-align the table and move down to next row. Creates a new row if
+ necessary. At the beginning or end of a line, {{{kbd(RET)}}} still
+ inserts a new line, so it can be used to split a table.
- {{{kbd(M-a)}}} (~org-table-beginning-of-field~) ::
- #+kindex: M-a
- #+findex: org-table-beginning-of-field
- Move to beginning of the current table field, or on to the
- previous field.
+ #+kindex: M-a
+ #+findex: org-table-beginning-of-field
+ Move to beginning of the current table field, or on to the previous
+ field.
- {{{kbd(M-e)}}} (~org-table-end-of-field~) ::
- #+kindex: M-e
- #+findex: org-table-end-of-field
- Move to end of the current table field, or on to the next field.
+ #+kindex: M-e
+ #+findex: org-table-end-of-field
+ Move to end of the current table field, or on to the next field.
*** Column and row editing
:PROPERTIES:
@@ -1502,83 +1409,106 @@ you, configure the option ~org-table-auto-blank-field~.
- {{{kbd(M-LEFT)}}} (~org-table-move-column-left~) ::
- #+kindex: M-LEFT
- #+findex: org-table-move-column-left
- Move the current column left.
+ #+kindex: M-LEFT
+ #+findex: org-table-move-column-left
+ Move the current column left.
- {{{kbd(M-RIGHT)}}} (~org-table-move-column-right~) ::
- #+kindex: M-RIGHT
- #+findex: org-table-move-column-right
- Move the current column right.
+ #+kindex: M-RIGHT
+ #+findex: org-table-move-column-right
+ Move the current column right.
- {{{kbd(M-S-LEFT)}}} (~org-table-delete-column~) ::
- #+kindex: M-S-LEFT
- #+findex: org-table-delete-column
- Kill the current column.
+ #+kindex: M-S-LEFT
+ #+findex: org-table-delete-column
+ Kill the current column.
- {{{kbd(M-S-RIGHT)}}} (~org-table-insert-column~) ::
- #+kindex: M-S-RIGHT
- #+findex: org-table-insert-column
- Insert a new column to the left of point position.
+ #+kindex: M-S-RIGHT
+ #+findex: org-table-insert-column
+ Insert a new column to the left of point position.
- {{{kbd(M-UP)}}} (~org-table-move-row-up~) ::
- #+kindex: M-UP
- #+findex: org-table-move-row-up
- Move the current row up.
+ #+kindex: M-UP
+ #+findex: org-table-move-row-up
+ Move the current row up.
- {{{kbd(M-DOWN)}}} (~org-table-move-row-down~) ::
- #+kindex: M-DOWN
- #+findex: org-table-move-row-down
- Move the current row down.
+ #+kindex: M-DOWN
+ #+findex: org-table-move-row-down
+ Move the current row down.
- {{{kbd(M-S-UP)}}} (~org-table-kill-row~) ::
- #+kindex: M-S-UP
- #+findex: org-table-kill-row
- Kill the current row or horizontal line.
+ #+kindex: M-S-UP
+ #+findex: org-table-kill-row
+ Kill the current row or horizontal line.
+
+- {{{kbd(S-UP)}}} (~org-table-move-cell-up~) ::
+
+ #+kindex: S-UP
+ #+findex: org-table-move-cell-up
+ Move cell up by swapping with adjacent cell.
+
+- {{{kbd(S-DOWN)}}} (~org-table-move-cell-down~) ::
+
+ #+kindex: S-DOWN
+ #+findex: org-table-move-cell-down
+ Move cell down by swapping with adjacent cell.
+
+- {{{kbd(S-LEFT)}}} (~org-table-move-cell-left~) ::
+
+ #+kindex: S-LEFT
+ #+findex: org-table-move-cell-left
+ Move cell left by swapping with adjacent cell.
+
+- {{{kbd(S-RIGHT)}}} (~org-table-move-cell-right~) ::
+
+ #+kindex: S-RIGHT
+ #+findex: org-table-move-cell-right
+ Move cell right by swapping with adjacent cell.
- {{{kbd(M-S-DOWN)}}} (~org-table-insert-row~) ::
- #+kindex: M-S-DOWN
- #+findex: org-table-insert-row
- Insert a new row above the current row. With a prefix argument,
- the line is created below the current one.
+ #+kindex: M-S-DOWN
+ #+findex: org-table-insert-row
+ Insert a new row above the current row. With a prefix argument, the
+ line is created below the current one.
- {{{kbd(C-c -)}}} (~org-table-insert-hline~) ::
- #+kindex: C-c -
- #+findex: org-table-insert-hline
- Insert a horizontal line below current row. With a prefix
- argument, the line is created above the current line.
+ #+kindex: C-c -
+ #+findex: org-table-insert-hline
+ Insert a horizontal line below current row. With a prefix argument,
+ the line is created above the current line.
- {{{kbd(C-c RET)}}} (~org-table-hline-and-move~) ::
- #+kindex: C-c RET
- #+findex: org-table-hline-and-move
- Insert a horizontal line below current row, and move point
- into the row below that line.
+ #+kindex: C-c RET
+ #+findex: org-table-hline-and-move
+ Insert a horizontal line below current row, and move point into the
+ row below that line.
- {{{kbd(C-c ^)}}} (~org-table-sort-lines~) ::
- #+kindex: C-c ^
- #+findex: org-table-sort-lines
- Sort the table lines in the region. The position of point
- indicates the column to be used for sorting, and the range of
- lines is the range between the nearest horizontal separator
- lines, or the entire table. If point is before the first column,
- you are prompted for the sorting column. If there is an active
- region, the mark specifies the first line and the sorting column,
- while point should be in the last line to be included into the
- sorting. The command prompts for the sorting type,
- alphabetically, numerically, or by time. You can sort in normal
- or reverse order. You can also supply your own key extraction
- and comparison functions. When called with a prefix argument,
- alphabetic sorting is case-sensitive.
+ #+kindex: C-c ^
+ #+findex: org-table-sort-lines
+ Sort the table lines in the region. The position of point indicates
+ the column to be used for sorting, and the range of lines is the
+ range between the nearest horizontal separator lines, or the entire
+ table. If point is before the first column, you are prompted for
+ the sorting column. If there is an active region, the mark
+ specifies the first line and the sorting column, while point should
+ be in the last line to be included into the sorting. The command
+ prompts for the sorting type, alphabetically, numerically, or by
+ time. You can sort in normal or reverse order. You can also supply
+ your own key extraction and comparison functions. When called with
+ a prefix argument, alphabetic sorting is case-sensitive.
*** Regions
:PROPERTIES:
@@ -1587,43 +1517,40 @@ you, configure the option ~org-table-auto-blank-field~.
- {{{kbd(C-c C-x M-w)}}} (~org-table-copy-region~) ::
- #+kindex: C-c C-x M-w
- #+findex: org-table-copy-region
- Copy a rectangular region from a table to a special clipboard.
- Point and mark determine edge fields of the rectangle. If there
- is no active region, copy just the current field. The process
- ignores horizontal separator lines.
+ #+kindex: C-c C-x M-w
+ #+findex: org-table-copy-region
+ Copy a rectangular region from a table to a special clipboard.
+ Point and mark determine edge fields of the rectangle. If there is
+ no active region, copy just the current field. The process ignores
+ horizontal separator lines.
- {{{kbd(C-c C-x C-w)}}} (~org-table-cut-region~) ::
- #+kindex: C-c C-x C-w
- #+findex: org-table-cut-region
- Copy a rectangular region from a table to a special clipboard,
- and blank all fields in the rectangle. So this is the "cut"
- operation.
+ #+kindex: C-c C-x C-w
+ #+findex: org-table-cut-region
+ Copy a rectangular region from a table to a special clipboard, and
+ blank all fields in the rectangle. So this is the "cut" operation.
- {{{kbd(C-c C-x C-y)}}} (~org-table-paste-rectangle~) ::
- #+kindex: C-c C-x C-y
- #+findex: org-table-paste-rectangle
- Paste a rectangular region into a table. The upper left corner
- ends up in the current field. All involved fields are
- overwritten. If the rectangle does not fit into the present
- table, the table is enlarged as needed. The process ignores
- horizontal separator lines.
+ #+kindex: C-c C-x C-y
+ #+findex: org-table-paste-rectangle
+ Paste a rectangular region into a table. The upper left corner ends
+ up in the current field. All involved fields are overwritten. If
+ the rectangle does not fit into the present table, the table is
+ enlarged as needed. The process ignores horizontal separator lines.
- {{{kbd(M-RET)}}} (~org-table-wrap-region~) ::
- #+kindex: M-RET
- #+findex: org-table-wrap-region
- Split the current field at point position and move the rest
- to the line below. If there is an active region, and both point
- and mark are in the same column, the text in the column is
- wrapped to minimum width for the given number of lines.
- A numeric prefix argument may be used to change the number of
- desired lines. If there is no region, but you specify a prefix
- argument, the current field is made blank, and the content is
- appended to the field above.
+ #+kindex: M-RET
+ #+findex: org-table-wrap-region
+ Split the current field at point position and move the rest to the
+ line below. If there is an active region, and both point and mark
+ are in the same column, the text in the column is wrapped to minimum
+ width for the given number of lines. A numeric prefix argument may
+ be used to change the number of desired lines. If there is no
+ region, but you specify a prefix argument, the current field is made
+ blank, and the content is appended to the field above.
*** Calculations
:PROPERTIES:
@@ -1635,25 +1562,28 @@ you, configure the option ~org-table-auto-blank-field~.
- {{{kbd(C-c +)}}} (~org-table-sum~) ::
- #+kindex: C-c +
- #+findex: org-table-sum
- Sum the numbers in the current column, or in the rectangle
- defined by the active region. The result is shown in the echo
- area and can be inserted with {{{kbd(C-y)}}}.
+ #+kindex: C-c +
+ #+findex: org-table-sum
+ Sum the numbers in the current column, or in the rectangle defined
+ by the active region. The result is shown in the echo area and can
+ be inserted with {{{kbd(C-y)}}}.
- {{{kbd(S-RET)}}} (~org-table-copy-down~) ::
- #+kindex: S-RET
- #+findex: org-table-copy-down
- #+vindex: org-table-copy-increment
- When current field is empty, copy from first non-empty field
- above. When not empty, copy current field down to next row and
- move point along with it. Depending on the variable
- ~org-table-copy-increment~, integer field values can be
- incremented during copy. Integers that are too large are not
- incremented, however. Also, a ~0~ prefix argument temporarily
- disables the increment. This key is also used by shift-selection
- and related modes (see [[*Packages that conflict with Org mode]]).
+ #+kindex: S-RET
+ #+findex: org-table-copy-down
+ #+vindex: org-table-copy-increment
+ When current field is empty, copy from first non-empty field above.
+ When not empty, copy current field down to next row and move point
+ along with it.
+
+ Depending on the variable ~org-table-copy-increment~, integer and
+ time stamp field values, and fields prefixed or suffixed with
+ a whole number, can be incremented during copy. Also, a ~0~ prefix
+ argument temporarily disables the increment.
+
+ This key is also used by shift-selection and related modes (see
+ [[*Packages that conflict with Org mode]]).
*** Miscellaneous
:PROPERTIES:
@@ -1662,51 +1592,49 @@ you, configure the option ~org-table-auto-blank-field~.
- {{{kbd(C-c `)}}} (~org-table-edit-field~) ::
- #+kindex: C-c `
- #+findex: org-table-edit-field
- Edit the current field in a separate window. This is useful for
- fields that are not fully visible (see [[*Column Width and
- Alignment]]). When called with a {{{kbd(C-u)}}} prefix, just make
- the full field visible, so that it can be edited in place. When
- called with two {{{kbd(C-u)}}} prefixes, make the editor window
- follow point through the table and always show the current field.
- The follow mode exits automatically when point leaves the table,
- or when you repeat this command with {{{kbd(C-u C-u C-c `)}}}.
+ #+kindex: C-c `
+ #+findex: org-table-edit-field
+ Edit the current field in a separate window. This is useful for
+ fields that are not fully visible (see [[*Column Width and Alignment]]).
+ When called with a {{{kbd(C-u)}}} prefix, just make the full field
+ visible, so that it can be edited in place. When called with two
+ {{{kbd(C-u)}}} prefixes, make the editor window follow point through
+ the table and always show the current field. The follow mode exits
+ automatically when point leaves the table, or when you repeat this
+ command with {{{kbd(C-u C-u C-c `)}}}.
- {{{kbd(M-x org-table-import)}}} ::
- #+findex: org-table-import
- Import a file as a table. The table should be TAB or whitespace
- separated. Use, for example, to import a spreadsheet table or
- data from a database, because these programs generally can write
- TAB-separated text files. This command works by inserting the
- file into the buffer and then converting the region to a table.
- Any prefix argument is passed on to the converter, which uses it
- to determine the separator.
+ #+findex: org-table-import
+ Import a file as a table. The table should be TAB or whitespace
+ separated. Use, for example, to import a spreadsheet table or data
+ from a database, because these programs generally can write
+ TAB-separated text files. This command works by inserting the file
+ into the buffer and then converting the region to a table. Any
+ prefix argument is passed on to the converter, which uses it to
+ determine the separator.
- {{{kbd(C-c |)}}} (~org-table-create-or-convert-from-region~) ::
- #+kindex: C-c |
- #+findex: org-table-create-or-convert-from-region
- Tables can also be imported by pasting tabular text into the Org
- buffer, selecting the pasted text with {{{kbd(C-x C-x)}}} and
- then using the {{{kbd(C-c |)}}} command (see [[*Creation and
- conversion]]).
+ #+kindex: C-c |
+ #+findex: org-table-create-or-convert-from-region
+ Tables can also be imported by pasting tabular text into the Org
+ buffer, selecting the pasted text with {{{kbd(C-x C-x)}}} and then
+ using the {{{kbd(C-c |)}}} command (see [[*Creation and conversion]]).
- {{{kbd(M-x org-table-export)}}} ::
- #+findex: org-table-export
- #+vindex: org-table-export-default-format
- Export the table, by default as a TAB-separated file. Use for
- data exchange with, for example, spreadsheet or database
- programs. The format used to export the file can be configured
- in the variable ~org-table-export-default-format~. You may also
- use properties =TABLE_EXPORT_FILE= and =TABLE_EXPORT_FORMAT= to
- specify the file name and the format for table export in
- a subtree. Org supports quite general formats for exported
- tables. The exporter format is the same as the format used by
- Orgtbl radio tables, see [[*Translator functions]], for a detailed
- description.
+ #+findex: org-table-export
+ #+vindex: org-table-export-default-format
+ Export the table, by default as a TAB-separated file. Use for data
+ exchange with, for example, spreadsheet or database programs. The
+ format used to export the file can be configured in the variable
+ ~org-table-export-default-format~. You may also use properties
+ =TABLE_EXPORT_FILE= and =TABLE_EXPORT_FORMAT= to specify the file
+ name and the format for table export in a subtree. Org supports
+ quite general formats for exported tables. The exporter format is
+ the same as the format used by Orgtbl radio tables, see [[*Translator
+ functions]], for a detailed description.
** Column Width and Alignment
:PROPERTIES:
@@ -1728,9 +1656,9 @@ case, you can always align manually a table:
- {{{kbd(C-c C-c)}}} (~org-table-align~) ::
- #+kindex: C-c C-c
- #+findex: org-table-align
- Align the current table.
+ #+kindex: C-c C-c
+ #+findex: org-table-align
+ Align the current table.
#+vindex: org-startup-align-all-tables
Setting the option ~org-startup-align-all-tables~ re-aligns all tables
@@ -1763,28 +1691,28 @@ with the following tools:
- {{{kbd(C-c TAB)}}} (~org-table-toggle-column-width~) ::
- #+kindex: C-c TAB
- #+findex: org-table-toggle-column-width
- Shrink or expand current column.
+ #+kindex: C-c TAB
+ #+findex: org-table-toggle-column-width
+ Shrink or expand current column.
- If a width cookie specifies a width W for the column, shrinking
- it displays the first W visible characters only. Otherwise, the
- column is shrunk to a single character.
+ If a width cookie specifies a width W for the column, shrinking it
+ displays the first W visible characters only. Otherwise, the column
+ is shrunk to a single character.
- When called before the first column or after the last one, ask
- for a list of column ranges to operate on.
+ When called before the first column or after the last one, ask for
+ a list of column ranges to operate on.
- {{{kbd(C-u C-c TAB)}}} (~org-table-shrink~) ::
- #+kindex: C-u C-c TAB
- #+findex: org-table-shrink
- Shrink all columns with a column width. Expand the others.
+ #+kindex: C-u C-c TAB
+ #+findex: org-table-shrink
+ Shrink all columns with a column width. Expand the others.
- {{{kbd(C-u C-u C-c TAB)}}} (~org-table-expand~) ::
- #+kindex: C-u C-u C-c TAB
- #+findex: org-table-expand
- Expand all columns.
+ #+kindex: C-u C-u C-c TAB
+ #+findex: org-table-expand
+ Expand all columns.
To see the full text of a shrunk field, hold the mouse over it:
a tool-tip window then shows the full contents of the field.
@@ -1911,7 +1839,7 @@ Formulas can reference the value of another field in two ways. Like
in any other spreadsheet, you may reference fields with
a letter/number combination like =B3=, meaning the second field in the
third row. However, Org prefers to use another, more general
-representation that looks like this:[fn:20]
+representation that looks like this:[fn:18]
: @ROW$COLUMN
@@ -2002,23 +1930,22 @@ and ~org-table-current-column~. Examples:
- =if(@# % 2, $#, string(""))= ::
- Insert column number on odd rows, set field to empty on even
- rows.
+ Insert column number on odd rows, set field to empty on even rows.
- =$2 = '(identity remote(FOO, @@#$1))= ::
- Copy text or values of each row of column 1 of the table named
- {{{var(FOO)}}} into column 2 of the current table.
+ Copy text or values of each row of column 1 of the table named
+ {{{var(FOO)}}} into column 2 of the current table.
- =@3 = 2 * remote(FOO, @@1$$#)= ::
- Insert the doubled value of each column of row 1 of the table
- named {{{var(FOO)}}} into row 3 of the current table.
+ Insert the doubled value of each column of row 1 of the table
+ named {{{var(FOO)}}} into row 3 of the current table.
#+texinfo: @noindent
For the second and third examples, table {{{var(FOO)}}} must have at
least as many rows or columns as the current table. Note that this is
-inefficient[fn:21] for large number of rows.
+inefficient[fn:19] for large number of rows.
**** Named references
:PROPERTIES:
@@ -2046,7 +1973,7 @@ constants in table formulas: for a property =Xyz= use the name
entry and in the hierarchy above it. If you have the =constants.el=
package, it will also be used to resolve constants, including natural
constants like =$h= for Planck's constant, and units like =$km= for
-kilometers[fn:22]. Column names and parameters can be specified in
+kilometers[fn:20]. Column names and parameters can be specified in
special table lines. These are described below, see [[*Advanced
features]]. All names must start with a letter, and further consist
of letters and numbers.
@@ -2113,55 +2040,53 @@ variable ~org-calc-default-modes~.
- =p20= ::
- Set the internal Calc calculation precision to 20 digits.
+ Set the internal Calc calculation precision to 20 digits.
- =n3=, =s3=, =e2=, =f4= ::
- Normal, scientific, engineering or fixed format of the result of
- Calc passed back to Org. Calc formatting is unlimited in
- precision as long as the Calc calculation precision is greater.
+ Normal, scientific, engineering or fixed format of the result of
+ Calc passed back to Org. Calc formatting is unlimited in precision
+ as long as the Calc calculation precision is greater.
- =D=, =R= ::
- Degree and radian angle modes of Calc.
+ Degree and radian angle modes of Calc.
- =F=, =S= ::
- Fraction and symbolic modes of Calc.
+ Fraction and symbolic modes of Calc.
- =T=, =t=, =U= ::
- Duration computations in Calc or Lisp, [[*Durations and time
- values]].
+ Duration computations in Calc or Lisp, [[*Durations and time values]].
- =E= ::
- If and how to consider empty fields. Without =E= empty fields in
- range references are suppressed so that the Calc vector or Lisp
- list contains only the non-empty fields. With =E= the empty
- fields are kept. For empty fields in ranges or empty field
- references the value =nan= (not a number) is used in Calc
- formulas and the empty string is used for Lisp formulas. Add =N=
- to use 0 instead for both formula types. For the value of
- a field the mode =N= has higher precedence than =E=.
+ If and how to consider empty fields. Without =E= empty fields in
+ range references are suppressed so that the Calc vector or Lisp list
+ contains only the non-empty fields. With =E= the empty fields are
+ kept. For empty fields in ranges or empty field references the
+ value =nan= (not a number) is used in Calc formulas and the empty
+ string is used for Lisp formulas. Add =N= to use 0 instead for both
+ formula types. For the value of a field the mode =N= has higher
+ precedence than =E=.
- =N= ::
- Interpret all fields as numbers, use 0 for non-numbers. See the
- next section to see how this is essential for computations with
- Lisp formulas. In Calc formulas it is used only occasionally
- because there number strings are already interpreted as numbers
- without =N=.
+ Interpret all fields as numbers, use 0 for non-numbers. See the
+ next section to see how this is essential for computations with Lisp
+ formulas. In Calc formulas it is used only occasionally because
+ there number strings are already interpreted as numbers without =N=.
- =L= ::
- Literal, for Lisp formulas only. See the next section.
+ Literal, for Lisp formulas only. See the next section.
Unless you use large integer numbers or high-precision calculation and
display for floating point numbers you may alternatively provide
a ~printf~ format specifier to reformat the Calc result after it has
been passed back to Org instead of letting Calc already do the
-formatting[fn:23]. A few examples:
+formatting[fn:21]. A few examples:
| =$1+$2= | Sum of first and second field |
| =$1+$2;%.2f= | Same, format result to two decimals |
@@ -2175,44 +2100,42 @@ formatting[fn:23]. A few examples:
| =vmean($2..$7);EN= | Same, but treat empty fields as 0 |
| =taylor($3,x=7,2)= | Taylor series of $3, at x=7, second degree |
-Calc also contains a complete set of logical operations (see [[info:calc#Logical%20Operations][Logical
+Calc also contains a complete set of logical operations (see [[info:calc#Logical Operations][Logical
Operations]]). For example
- =if($1 < 20, teen, string(""))= ::
- ="teen"= if age =$1= is less than 20, else the Org table result
- field is set to empty with the empty string.
+ ="teen"= if age =$1= is less than 20, else the Org table result
+ field is set to empty with the empty string.
- =if("$1" =​= "nan" || "$2" =​= "nan", string(""), $1 + $2); E f-1= ::
- Sum of the first two columns. When at least one of the input
- fields is empty the Org table result field is set to empty. =E=
- is required to not convert empty fields to 0. =f-1= is an
- optional Calc format string similar to =%.1f= but leaves empty
- results empty.
+ Sum of the first two columns. When at least one of the input fields
+ is empty the Org table result field is set to empty. =E= is
+ required to not convert empty fields to 0. =f-1= is an optional
+ Calc format string similar to =%.1f= but leaves empty results empty.
- =if(typeof(vmean($1..$7)) =​= 12, string(""), vmean($1..$7); E= ::
- Mean value of a range unless there is any empty field. Every
- field in the range that is empty is replaced by =nan= which lets
- =vmean= result in =nan=. Then =typeof == 12= detects the =nan=
- from ~vmean~ and the Org table result field is set to empty. Use
- this when the sample set is expected to never have missing
- values.
+ Mean value of a range unless there is any empty field. Every field
+ in the range that is empty is replaced by =nan= which lets =vmean=
+ result in =nan=. Then =typeof == 12= detects the =nan= from ~vmean~
+ and the Org table result field is set to empty. Use this when the
+ sample set is expected to never have missing values.
- =if("$1..$7" =​= "[]", string(""), vmean($1..$7))= ::
- Mean value of a range with empty fields skipped. Every field in
- the range that is empty is skipped. When all fields in the range
- are empty the mean value is not defined and the Org table result
- field is set to empty. Use this when the sample set can have
- a variable size.
+ Mean value of a range with empty fields skipped. Every field in the
+ range that is empty is skipped. When all fields in the range are
+ empty the mean value is not defined and the Org table result field
+ is set to empty. Use this when the sample set can have a variable
+ size.
- =vmean($1..$7); EN= ::
- To complete the example before: Mean value of a range with empty
- fields counting as samples with value 0. Use this only when
- incomplete sample sets should be padded with 0 to the full size.
+ To complete the example before: Mean value of a range with empty
+ fields counting as samples with value 0. Use this only when
+ incomplete sample sets should be padded with 0 to the full size.
You can add your own Calc functions defined in Emacs Lisp with
~defmath~ and use them in formula syntax for Calc.
@@ -2251,15 +2174,15 @@ computations in Lisp:
- ='(concat (substring $1 1 2) (substring $1 0 1) (substring $1 2))= ::
- Swap the first two characters of the content of column 1.
+ Swap the first two characters of the content of column 1.
- ='(+ $1 $2);N= ::
- Add columns 1 and 2, equivalent to Calc's =$1+$2=.
+ Add columns 1 and 2, equivalent to Calc's =$1+$2=.
- ='(apply '+ '($1..$4));N= ::
- Compute the sum of columns 1 to 4, like Calc's =vsum($1..$4)=.
+ Compute the sum of columns 1 to 4, like Calc's =vsum($1..$4)=.
*** Durations and time values
:PROPERTIES:
@@ -2329,38 +2252,37 @@ following command
- {{{kbd(C-u C-c =)}}} (~org-table-eval-formula~) ::
- #+kindex: C-u C-c =
- #+findex: org-table-eval-formula
- Install a new formula for the current field. The command prompts
- for a formula with default taken from the =TBLFM= keyword,
- applies it to the current field, and stores it.
+ #+kindex: C-u C-c =
+ #+findex: org-table-eval-formula
+ Install a new formula for the current field. The command prompts
+ for a formula with default taken from the =TBLFM= keyword,
+ applies it to the current field, and stores it.
The left-hand side of a formula can also be a special expression in
order to assign the formula to a number of different fields. There is
no keyboard shortcut to enter such range formulas. To add them, use
-the formula editor (see [[*Editing and debugging formulas]]) or edit the
-=TBLFM= keyword directly.
+the formula editor (see [[*Editing and debugging formulas]]) or edit
+the =TBLFM= keyword directly.
- =$2== ::
- Column formula, valid for the entire column. This is so common
- that Org treats these formulas in a special way, see [[*Column
- formulas]].
+ Column formula, valid for the entire column. This is so common that
+ Org treats these formulas in a special way, see [[*Column formulas]].
- =@3== ::
- Row formula, applies to all fields in the specified row. =@>==
- means the last row.
+ Row formula, applies to all fields in the specified row. =@>==
+ means the last row.
- =@1$2..@4$3== ::
- Range formula, applies to all fields in the given rectangular
- range. This can also be used to assign a formula to some but not
- all fields in a row.
+ Range formula, applies to all fields in the given rectangular range.
+ This can also be used to assign a formula to some but not all fields
+ in a row.
- =$NAME== ::
- Named field, see [[*Advanced features]].
+ Named field, see [[*Advanced features]].
*** Column formulas
:PROPERTIES:
@@ -2397,14 +2319,14 @@ following command:
- {{{kbd(C-c =)}}} (~org-table-eval-formula~) ::
- #+kindex: C-c =
- #+findex: org-table-eval-formula
- Install a new formula for the current column and replace current
- field with the result of the formula. The command prompts for
- a formula, with default taken from the =TBLFM= keyword, applies
- it to the current field and stores it. With a numeric prefix
- argument, e.g., {{{kbd(C-5 C-c =)}}}, the command applies it to
- that many consecutive fields in the current column.
+ #+kindex: C-c =
+ #+findex: org-table-eval-formula
+ Install a new formula for the current column and replace current
+ field with the result of the formula. The command prompts for
+ a formula, with default taken from the =TBLFM= keyword, applies it
+ to the current field and stores it. With a numeric prefix argument,
+ e.g., {{{kbd(C-5 C-c =)}}}, the command applies it to that many
+ consecutive fields in the current column.
*** Lookup functions
:PROPERTIES:
@@ -2417,36 +2339,36 @@ Org has three predefined Emacs Lisp functions for lookups in tables.
- =(org-lookup-first VAL S-LIST R-LIST &optional PREDICATE)= ::
- #+findex: org-lookup-first
- Searches for the first element {{{var(S)}}} in list
- {{{var(S-LIST)}}} for which
- #+begin_src emacs-lisp
- (PREDICATE VAL S)
- #+end_src
- is non-~nil~; returns the value from the corresponding position
- in list {{{var(R-LIST)}}}. The default {{{var(PREDICATE)}}} is
- ~equal~. Note that the parameters {{{var(VAL)}}} and
- {{{var(S)}}} are passed to {{{var(PREDICATE)}}} in the same order
- as the corresponding parameters are in the call to
- ~org-lookup-first~, where {{{var(VAL)}}} precedes
- {{{var(S-LIST)}}}. If {{{var(R-LIST)}}} is ~nil~, the matching
- element {{{var(S)}}} of {{{var(S-LIST)}}} is returned.
+ #+findex: org-lookup-first
+ Searches for the first element {{{var(S)}}} in list
+ {{{var(S-LIST)}}} for which
+ #+begin_src emacs-lisp
+ (PREDICATE VAL S)
+ #+end_src
+ is non-~nil~; returns the value from the corresponding position in
+ list {{{var(R-LIST)}}}. The default {{{var(PREDICATE)}}} is
+ ~equal~. Note that the parameters {{{var(VAL)}}} and {{{var(S)}}}
+ are passed to {{{var(PREDICATE)}}} in the same order as the
+ corresponding parameters are in the call to ~org-lookup-first~,
+ where {{{var(VAL)}}} precedes {{{var(S-LIST)}}}. If
+ {{{var(R-LIST)}}} is ~nil~, the matching element {{{var(S)}}} of
+ {{{var(S-LIST)}}} is returned.
- =(org-lookup-last VAL S-LIST R-LIST &optional PREDICATE)= ::
- #+findex: org-lookup-last
- Similar to ~org-lookup-first~ above, but searches for the /last/
- element for which {{{var(PREDICATE)}}} is non-~nil~.
+ #+findex: org-lookup-last
+ Similar to ~org-lookup-first~ above, but searches for the /last/
+ element for which {{{var(PREDICATE)}}} is non-~nil~.
- =(org-lookup-all VAL S-LIST R-LIST &optional PREDICATE)= ::
- #+findex: org-lookup-all
- Similar to ~org-lookup-first~, but searches for /all/ elements
- for which {{{var(PREDICATE)}}} is non-~nil~, and returns /all/
- corresponding values. This function can not be used by itself in
- a formula, because it returns a list of values. However,
- powerful lookups can be built when this function is combined with
- other Emacs Lisp functions.
+ #+findex: org-lookup-all
+ Similar to ~org-lookup-first~, but searches for /all/ elements for
+ which {{{var(PREDICATE)}}} is non-~nil~, and returns /all/
+ corresponding values. This function can not be used by itself in
+ a formula, because it returns a list of values. However, powerful
+ lookups can be built when this function is combined with other Emacs
+ Lisp functions.
If the ranges used in these functions contain empty fields, the =E=
mode for the formula should usually be specified: otherwise empty
@@ -2476,136 +2398,134 @@ you prefer to only work with the internal format (like =@3$2= or
- {{{kbd(C-c =)}}} or {{{kbd(C-u C-c =)}}} (~org-table-eval-formula~) ::
- #+kindex: C-c =
- #+kindex: C-u C-c =
- #+findex: org-table-eval-formula
- Edit the formula associated with the current column/field in the
- minibuffer. See [[*Column formulas]], and [[*Field and range formulas]].
+ #+kindex: C-c =
+ #+kindex: C-u C-c =
+ #+findex: org-table-eval-formula
+ Edit the formula associated with the current column/field in the
+ minibuffer. See [[*Column formulas]], and [[*Field and range formulas]].
- {{{kbd(C-u C-u C-c =)}}} (~org-table-eval-formula~) ::
- #+kindex: C-u C-u C-c =
- #+findex: org-table-eval-formula
- Re-insert the active formula (either a field formula, or a column
- formula) into the current field, so that you can edit it directly
- in the field. The advantage over editing in the minibuffer is
- that you can use the command {{{kbd(C-c ?)}}}.
+ #+kindex: C-u C-u C-c =
+ #+findex: org-table-eval-formula
+ Re-insert the active formula (either a field formula, or a column
+ formula) into the current field, so that you can edit it directly in
+ the field. The advantage over editing in the minibuffer is that you
+ can use the command {{{kbd(C-c ?)}}}.
- {{{kbd(C-c ?)}}} (~org-table-field-info~) ::
- #+kindex: C-c ?
- #+findex: org-table-field-info
- While editing a formula in a table field, highlight the field(s)
- referenced by the reference at point position in the formula.
+ #+kindex: C-c ?
+ #+findex: org-table-field-info
+ While editing a formula in a table field, highlight the field(s)
+ referenced by the reference at point position in the formula.
- {{{kbd(C-c })}}} (~org-table-toggle-coordinate-overlays~) ::
- #+kindex: C-c @}
- #+findex: org-table-toggle-coordinate-overlays
- Toggle the display of row and column numbers for a table, using
- overlays. These are updated each time the table is aligned; you
- can force it with {{{kbd(C-c C-c)}}}.
+ #+kindex: C-c @}
+ #+findex: org-table-toggle-coordinate-overlays
+ Toggle the display of row and column numbers for a table, using
+ overlays. These are updated each time the table is aligned; you can
+ force it with {{{kbd(C-c C-c)}}}.
- {{{kbd(C-c {)}}} (~org-table-toggle-formula-debugger~) ::
- #+kindex: C-c @{
- #+findex: org-table-toggle-formula-debugger
- Toggle the formula debugger on and off. See below.
+ #+kindex: C-c @{
+ #+findex: org-table-toggle-formula-debugger
+ Toggle the formula debugger on and off. See below.
- {{{kbd(C-c ')}}} (~org-table-edit-formulas~) ::
- #+kindex: C-c '
- #+findex: org-table-edit-formulas
- Edit all formulas for the current table in a special buffer,
- where the formulas are displayed one per line. If the current
- field has an active formula, point in the formula editor marks
- it. While inside the special buffer, Org automatically
- highlights any field or range reference at point position. You
- may edit, remove and add formulas, and use the following
- commands:
+ #+kindex: C-c '
+ #+findex: org-table-edit-formulas
+ Edit all formulas for the current table in a special buffer, where
+ the formulas are displayed one per line. If the current field has
+ an active formula, point in the formula editor marks it. While
+ inside the special buffer, Org automatically highlights any field or
+ range reference at point position. You may edit, remove and add
+ formulas, and use the following commands:
- - {{{kbd(C-c C-c)}}} or {{{kbd(C-x C-s)}}} (~org-table-fedit-finish~) ::
+ - {{{kbd(C-c C-c)}}} or {{{kbd(C-x C-s)}}} (~org-table-fedit-finish~) ::
- #+kindex: C-x C-s
- #+kindex: C-c C-c
- #+findex: org-table-fedit-finish
- Exit the formula editor and store the modified formulas. With
- {{{kbd(C-u)}}} prefix, also apply the new formulas to the
- entire table.
+ #+kindex: C-x C-s
+ #+kindex: C-c C-c
+ #+findex: org-table-fedit-finish
+ Exit the formula editor and store the modified formulas. With
+ {{{kbd(C-u)}}} prefix, also apply the new formulas to the
+ entire table.
- - {{{kbd(C-c C-q)}}} (~org-table-fedit-abort~) ::
+ - {{{kbd(C-c C-q)}}} (~org-table-fedit-abort~) ::
- #+kindex: C-c C-q
- #+findex: org-table-fedit-abort
- Exit the formula editor without installing changes.
+ #+kindex: C-c C-q
+ #+findex: org-table-fedit-abort
+ Exit the formula editor without installing changes.
- - {{{kbd(C-c C-r)}}} (~org-table-fedit-toggle-ref-type~) ::
+ - {{{kbd(C-c C-r)}}} (~org-table-fedit-toggle-ref-type~) ::
- #+kindex: C-c C-r
- #+findex: org-table-fedit-toggle-ref-type
- Toggle all references in the formula editor between standard
- (like =B3=) and internal (like =@3$2=).
+ #+kindex: C-c C-r
+ #+findex: org-table-fedit-toggle-ref-type
+ Toggle all references in the formula editor between standard (like
+ =B3=) and internal (like =@3$2=).
- - {{{kbd(TAB)}}} (~org-table-fedit-lisp-indent~) ::
+ - {{{kbd(TAB)}}} (~org-table-fedit-lisp-indent~) ::
- #+kindex: TAB
- #+findex: org-table-fedit-lisp-indent
- Pretty-print or indent Lisp formula at point. When in a line
- containing a Lisp formula, format the formula according to
- Emacs Lisp rules. Another {{{kbd(TAB)}}} collapses the formula
- back again. In the open formula, {{{kbd(TAB)}}} re-indents
- just like in Emacs Lisp mode.
+ #+kindex: TAB
+ #+findex: org-table-fedit-lisp-indent
+ Pretty-print or indent Lisp formula at point. When in a line
+ containing a Lisp formula, format the formula according to Emacs
+ Lisp rules. Another {{{kbd(TAB)}}} collapses the formula back
+ again. In the open formula, {{{kbd(TAB)}}} re-indents just like
+ in Emacs Lisp mode.
- - {{{kbd(M-TAB)}}} (~lisp-complete-symbol~) ::
+ - {{{kbd(M-TAB)}}} (~lisp-complete-symbol~) ::
- #+kindex: M-TAB
- #+findex: lisp-complete-symbol
- Complete Lisp symbols, just like in Emacs Lisp mode.
+ #+kindex: M-TAB
+ #+findex: lisp-complete-symbol
+ Complete Lisp symbols, just like in Emacs Lisp mode.
- - {{{kbd(S-UP)}}}, {{{kbd(S-DOWN)}}}, {{{kbd(S-LEFT)}}}, {{{kbd(S-RIGHT)}}} ::
+ - {{{kbd(S-UP)}}}, {{{kbd(S-DOWN)}}}, {{{kbd(S-LEFT)}}}, {{{kbd(S-RIGHT)}}} ::
- #+kindex: S-UP
- #+kindex: S-DOWN
- #+kindex: S-LEFT
- #+kindex: S-RIGHT
- #+findex: org-table-fedit-ref-up
- #+findex: org-table-fedit-ref-down
- #+findex: org-table-fedit-ref-left
- #+findex: org-table-fedit-ref-right
- Shift the reference at point. For example, if the reference
- is =B3= and you press {{{kbd(S-RIGHT)}}}, it becomes =C3=.
- This also works for relative references and for hline
- references.
+ #+kindex: S-UP
+ #+kindex: S-DOWN
+ #+kindex: S-LEFT
+ #+kindex: S-RIGHT
+ #+findex: org-table-fedit-ref-up
+ #+findex: org-table-fedit-ref-down
+ #+findex: org-table-fedit-ref-left
+ #+findex: org-table-fedit-ref-right
+ Shift the reference at point. For example, if the reference is
+ =B3= and you press {{{kbd(S-RIGHT)}}}, it becomes =C3=. This also
+ works for relative references and for hline references.
- - {{{kbd(M-S-UP)}}} (~org-table-fedit-line-up~) ::
+ - {{{kbd(M-S-UP)}}} (~org-table-fedit-line-up~) ::
- #+kindex: M-S-UP
- #+findex: org-table-fedit-line-up
- Move the test line for column formulas up in the Org buffer.
+ #+kindex: M-S-UP
+ #+findex: org-table-fedit-line-up
+ Move the test line for column formulas up in the Org buffer.
- - {{{kbd(M-S-DOWN)}}} (~org-table-fedit-line-down~) ::
+ - {{{kbd(M-S-DOWN)}}} (~org-table-fedit-line-down~) ::
- #+kindex: M-S-DOWN
- #+findex: org-table-fedit-line-down
- Move the test line for column formulas down in the Org buffer.
+ #+kindex: M-S-DOWN
+ #+findex: org-table-fedit-line-down
+ Move the test line for column formulas down in the Org buffer.
- - {{{kbd(M-UP)}}} (~org-table-fedit-scroll-up~) ::
+ - {{{kbd(M-UP)}}} (~org-table-fedit-scroll-up~) ::
- #+kindex: M-UP
- #+findex: org-table-fedit-scroll-up
- Scroll up the window displaying the table.
+ #+kindex: M-UP
+ #+findex: org-table-fedit-scroll-up
+ Scroll up the window displaying the table.
- - {{{kbd(M-DOWN)}}} (~org-table-fedit-scroll-down~) ::
+ - {{{kbd(M-DOWN)}}} (~org-table-fedit-scroll-down~) ::
- #+kindex: M-DOWN
- #+findex: org-table-fedit-scroll-down
- Scroll down the window displaying the table.
+ #+kindex: M-DOWN
+ #+findex: org-table-fedit-scroll-down
+ Scroll down the window displaying the table.
- - {{{kbd(C-c })}}} ::
+ - {{{kbd(C-c })}}} ::
- #+kindex: C-c @}
- #+findex: org-table-toggle-coordinate-overlays
- Turn the coordinate grid in the table on and off.
+ #+kindex: C-c @}
+ #+findex: org-table-toggle-coordinate-overlays
+ Turn the coordinate grid in the table on and off.
Making a table field blank does not remove the formula associated with
the field, because that is stored in a different line---the =TBLFM=
@@ -2697,40 +2617,39 @@ following commands:
- {{{kbd(C-c *)}}} (~org-table-recalculate~) ::
- #+kindex: C-c *
- #+findex: org-table-recalculate
- Recalculate the current row by first applying the stored column
- formulas from left to right, and all field/range formulas in the
- current row.
+ #+kindex: C-c *
+ #+findex: org-table-recalculate
+ Recalculate the current row by first applying the stored column
+ formulas from left to right, and all field/range formulas in the
+ current row.
- {{{kbd(C-u C-c *)}}} or {{{kbd(C-u C-c C-c)}}} ::
- #+kindex: C-u C-c *
- #+kindex: C-u C-c C-c
- Recompute the entire table, line by line. Any lines before the
- first hline are left alone, assuming that these are part of the
- table header.
+ #+kindex: C-u C-c *
+ #+kindex: C-u C-c C-c
+ Recompute the entire table, line by line. Any lines before the
+ first hline are left alone, assuming that these are part of the
+ table header.
- {{{kbd(C-u C-u C-c *)}}} or {{{kbd(C-u C-u C-c C-c)}}} (~org-table-iterate~) ::
- #+kindex: C-u C-u C-c *
- #+kindex: C-u C-u C-c C-c
- #+findex: org-table-iterate
- Iterate the table by recomputing it until no further changes
- occur. This may be necessary if some computed fields use the
- value of other fields that are computed /later/ in the
- calculation sequence.
+ #+kindex: C-u C-u C-c *
+ #+kindex: C-u C-u C-c C-c
+ #+findex: org-table-iterate
+ Iterate the table by recomputing it until no further changes occur.
+ This may be necessary if some computed fields use the value of other
+ fields that are computed /later/ in the calculation sequence.
- {{{kbd(M-x org-table-recalculate-buffer-tables)}}} ::
- #+findex: org-table-recalculate-buffer-tables
- Recompute all tables in the current buffer.
+ #+findex: org-table-recalculate-buffer-tables
+ Recompute all tables in the current buffer.
- {{{kbd(M-x org-table-iterate-buffer-tables)}}} ::
- #+findex: org-table-iterate-buffer-tables
- Iterate all tables in the current buffer, in order to converge
- table-to-table dependencies.
+ #+findex: org-table-iterate-buffer-tables
+ Iterate all tables in the current buffer, in order to converge
+ table-to-table dependencies.
*** Advanced features
:PROPERTIES:
@@ -2738,17 +2657,17 @@ following commands:
:END:
If you want the recalculation of fields to happen automatically, or if
-you want to be able to assign /names/[fn:24] to fields and columns,
+you want to be able to assign /names/[fn:22] to fields and columns,
you need to reserve the first column of the table for special marking
characters.
- {{{kbd(C-#)}}} (~org-table-rotate-recalc-marks~) ::
- #+kindex: C-#
- #+findex: org-table-rotate-recalc-marks
- Rotate the calculation mark in first column through the states
- =#=, =*=, =!=, =$=. When there is an active region, change all
- marks in the region.
+ #+kindex: C-#
+ #+findex: org-table-rotate-recalc-marks
+ Rotate the calculation mark in first column through the states =#=,
+ =*=, =!=, =$=. When there is an active region, change all marks in
+ the region.
Here is an example of a table that collects exam results of students
and makes use of these features:
@@ -2784,47 +2703,46 @@ The marking characters have the following meaning:
- =!= ::
- The fields in this line define names for the columns, so that you
- may refer to a column as =$Tot= instead of =$6=.
+ The fields in this line define names for the columns, so that you
+ may refer to a column as =$Tot= instead of =$6=.
- =^= ::
- This row defines names for the fields /above/ the row. With such
- a definition, any formula in the table may use =$m1= to refer to
- the value =10=. Also, if you assign a formula to a names field,
- it is stored as =$name = ...=.
+ This row defines names for the fields /above/ the row. With such
+ a definition, any formula in the table may use =$m1= to refer to the
+ value =10=. Also, if you assign a formula to a names field, it is
+ stored as =$name = ...=.
- =_= ::
- Similar to =^=, but defines names for the fields in the row
- /below/.
+ Similar to =^=, but defines names for the fields in the row /below/.
- =$= ::
- Fields in this row can define /parameters/ for formulas. For
- example, if a field in a =$= row contains =max=50=, then formulas
- in this table can refer to the value 50 using =$max=. Parameters
- work exactly like constants, only that they can be defined on
- a per-table basis.
+ Fields in this row can define /parameters/ for formulas. For
+ example, if a field in a =$= row contains =max=50=, then formulas in
+ this table can refer to the value 50 using =$max=. Parameters work
+ exactly like constants, only that they can be defined on a per-table
+ basis.
- =#= ::
- Fields in this row are automatically recalculated when pressing
- {{{kbd(TAB)}}} or {{{kbd(RET)}}} or {{{kbd(S-TAB)}}} in this row.
- Also, this row is selected for a global recalculation with
- {{{kbd(C-u C-c *)}}}. Unmarked lines are left alone by this
- command.
+ Fields in this row are automatically recalculated when pressing
+ {{{kbd(TAB)}}} or {{{kbd(RET)}}} or {{{kbd(S-TAB)}}} in this row.
+ Also, this row is selected for a global recalculation with
+ {{{kbd(C-u C-c *)}}}. Unmarked lines are left alone by this
+ command.
- =*= ::
- Selects this line for global recalculation with {{{kbd(C-u C-c
- *)}}}, but not for automatic recalculation. Use this when
- automatic recalculation slows down editing too much.
+ Selects this line for global recalculation with {{{kbd(C-u C-c
+ *)}}}, but not for automatic recalculation. Use this when automatic
+ recalculation slows down editing too much.
- =/= ::
- Do not export this line. Useful for lines that contain the
- narrowing =<N>= markers or column group markers.
+ Do not export this line. Useful for lines that contain the
+ narrowing =<N>= markers or column group markers.
Finally, just to whet your appetite for what can be done with the
fantastic Calc package, here is a table that computes the Taylor
@@ -2890,65 +2808,65 @@ For more information and examples see the [[https://orgmode.org/worg/org-tutoria
- =set= ::
- Specify any Gnuplot option to be set when graphing.
+ Specify any Gnuplot option to be set when graphing.
- =title= ::
- Specify the title of the plot.
+ Specify the title of the plot.
- =ind= ::
- Specify which column of the table to use as the =x= axis.
+ Specify which column of the table to use as the =x= axis.
- =deps= ::
- Specify the columns to graph as a Lisp style list, surrounded by
- parentheses and separated by spaces for example =dep:(3 4)= to
- graph the third and fourth columns. Defaults to graphing all
- other columns aside from the =ind= column.
+ Specify the columns to graph as a Lisp style list, surrounded by
+ parentheses and separated by spaces for example =dep:(3 4)= to graph
+ the third and fourth columns. Defaults to graphing all other
+ columns aside from the =ind= column.
- =type= ::
- Specify whether the plot is =2d=, =3d=, or =grid=.
+ Specify whether the plot is =2d=, =3d=, or =grid=.
- =with= ::
- Specify a =with= option to be inserted for every column being
- plotted, e.g., =lines=, =points=, =boxes=, =impulses=. Defaults
- to =lines=.
+ Specify a =with= option to be inserted for every column being
+ plotted, e.g., =lines=, =points=, =boxes=, =impulses=. Defaults to
+ =lines=.
- =file= ::
- If you want to plot to a file, specify
- ="path/to/desired/output-file"=.
+ If you want to plot to a file, specify
+ ="path/to/desired/output-file"=.
- =labels= ::
- List of labels to be used for the =deps=. Defaults to the column
- headers if they exist.
+ List of labels to be used for the =deps=. Defaults to the column
+ headers if they exist.
- =line= ::
- Specify an entire line to be inserted in the Gnuplot script.
+ Specify an entire line to be inserted in the Gnuplot script.
- =map= ::
- When plotting =3d= or =grid= types, set this to =t= to graph
- a flat mapping rather than a =3d= slope.
+ When plotting =3d= or =grid= types, set this to =t= to graph a flat
+ mapping rather than a =3d= slope.
- =timefmt= ::
- Specify format of Org mode timestamps as they will be parsed by
- Gnuplot. Defaults to =%Y-%m-%d-%H:%M:%S=.
+ Specify format of Org mode timestamps as they will be parsed by
+ Gnuplot. Defaults to =%Y-%m-%d-%H:%M:%S=.
- =script= ::
- If you want total control, you can specify a script file---place
- the file name between double-quotes---which will be used to plot.
- Before plotting, every instance of =$datafile= in the specified
- script will be replaced with the path to the generated data file.
- Note: even if you set this option, you may still want to specify
- the plot type, as that can impact the content of the data file.
+ If you want total control, you can specify a script file---place the
+ file name between double-quotes---which will be used to plot.
+ Before plotting, every instance of =$datafile= in the specified
+ script will be replaced with the path to the generated data file.
+ Note: even if you set this option, you may still want to specify the
+ plot type, as that can impact the content of the data file.
*** ASCII bar plots
:PROPERTIES:
@@ -3008,7 +2926,7 @@ links to other files, Usenet articles, emails, and much more.
#+cindex: angle bracket links
#+cindex: plain links
Org recognizes plain URIs, possibly wrapped within angle
-brackets[fn:25], and activate them as clickable links.
+brackets[fn:23], and activate them as clickable links.
#+cindex: bracket links
The general link format, however, looks like this:
@@ -3020,18 +2938,25 @@ or alternatively
: [[LINK]]
-#+cindex: square brackets in links
#+cindex: escape syntax, for links
-The {{{var(LINK)}}} part cannot contain =[= and =]= characters. You
-can replace them with their percent-encoded counterparts, which are,
-respectively, =%5B= and =%5D=. You also need to encode =%= characters
-as =%25=. Optionally, it may also come handy to encode consecutive
-spaces as =%20=.
-
-Org takes for granted that such links are correctly escaped. Luckily,
-functions inserting links (see [[*Handling Links]]) take care of this.
-You really need to bother about it only when inserting manually a URI
-within square brackets.
+#+cindex: backslashes, in links
+Some =\= and =]= characters in the {{{var(LINK)}}} part need to be
+"escaped", i.e., preceded by another =\= character. More
+specifically, the following character categories, and only them, must
+be escaped, in order:
+
+1. all consecutive =\= characters at the end of the link,
+2. any =]= character at the very end of the link,
+3. all consecutive =\= characters preceding =][= or =]]= patterns,
+4. any =]= character followed by either =[= or =]=.
+
+#+findex: org-link-escape
+Org takes for granted that such links are correctly escaped.
+Functions inserting links (see [[*Handling Links]]) take care of this.
+You only need to bother about those rules when inserting directly, or
+yanking, a URI within square brackets. When in doubt, you may use the
+function ~org-link-escape~, which turns a link string into its
+properly escaped form.
Once a link in the buffer is complete, with all brackets present, Org
changes the display so that =DESCRIPTION= is displayed instead of
@@ -3047,7 +2972,7 @@ the {{{var(LINK)}}} part, if there is no description, or the
If you place point at the beginning or just behind the end of the
displayed text and press {{{kbd(BS)}}}, you remove
-the---invisible---bracket at that location[fn:26]. This makes the link
+the---invisible---bracket at that location[fn:24]. This makes the link
incomplete and the internals are again displayed as plain text.
Inserting the missing bracket hides the link internals again. To show
the internal structure of all links, use the menu: Org \rarr Hyperlinks \rarr
@@ -3092,12 +3017,12 @@ to, as in the following example
If none of the above succeeds, Org searches for a headline that is
exactly the link text but may also include a TODO keyword and
-tags[fn:27].
+tags[fn:25].
During export, internal links are used to mark objects and assign them
a number. Marked objects are then referenced by links pointing to
them. In particular, links without a description appear as the number
-assigned to the marked object[fn:28]. In the following excerpt from
+assigned to the marked object[fn:26]. In the following excerpt from
an Org buffer
#+begin_example
@@ -3142,54 +3067,137 @@ point on or at a target.
:END:
#+cindex: links, external
#+cindex: external links
-#+cindex: Gnus links
+#+cindex: attachment links
#+cindex: BBDB links
-#+cindex: irc links
-#+cindex: URL links
+#+cindex: Elisp links
#+cindex: file links
-#+cindex: Rmail links
+#+cindex: Gnus links
+#+cindex: Help links
+#+cindex: IRC links
+#+cindex: Info links
#+cindex: MH-E links
-#+cindex: Usenet links
+#+cindex: Rmail links
#+cindex: shell links
-#+cindex: Info links
-#+cindex: Elisp links
+#+cindex: URL links
+#+cindex: Usenet links
Org supports links to files, websites, Usenet and email messages, BBDB
database entries and links to both IRC conversations and their logs.
External links are URL-like locators. They start with a short
identifying string followed by a colon. There can be no space after
-the colon. The following list shows examples for each link type.
-
-| =http://www.astro.uva.nl/=dominik= | on the web |
-| =doi:10.1000/182= | DOI for an electronic resource |
-| =file:/home/dominik/images/jupiter.jpg= | file, absolute path |
-| =/home/dominik/images/jupiter.jpg= | same as above |
-| =file:papers/last.pdf= | file, relative path |
-| =./papers/last.pdf= | same as above |
-| =file:/ssh:me@some.where:papers/last.pdf= | file, path on remote machine |
-| =/ssh:me@some.where:papers/last.pdf= | same as above |
-| =file:sometextfile::NNN= | file, jump to line number |
-| =file:projects.org= | another Org file |
-| =file:projects.org::some words= | text search in Org file[fn:29] |
-| =file:projects.org::*task title= | heading search in Org file |
-| =file+sys:/path/to/file= | open via OS, like double-click |
-| =file+emacs:/path/to/file= | force opening by Emacs |
-| =docview:papers/last.pdf::NNN= | open in doc-view mode at page |
-| =id:B7423F4D-2E8A-471B-8810-C40F074717E9= | link to heading by ID |
-| =news:comp.emacs= | Usenet link |
-| =mailto:adent@galaxy.net= | mail link |
-| =mhe:folder= | MH-E folder link |
-| =mhe:folder#id= | MH-E message link |
-| =rmail:folder= | Rmail folder link |
-| =rmail:folder#id= | Rmail message link |
-| =gnus:group= | Gnus group link |
-| =gnus:group#id= | Gnus article link |
-| =bbdb:R.*Stallman= | BBDB link (with regexp) |
-| =irc:/irc.com/#emacs/bob= | IRC link |
-| =info:org#External links= | Info node link |
-| =shell:ls *.org= | shell command |
-| =elisp:org-agenda= | interactive Elisp command |
-| =elisp:(find-file "Elisp.org")= | Elisp form to evaluate |
+the colon.
+
+Here is the full set of built-in link types:
+
+- =file= ::
+
+ File links. File name may be remote, absolute, or relative.
+
+ Additionally, you can specify a line number, or a text search.
+ In Org files, you may link to a headline name, a custom ID, or a
+ code reference instead.
+
+ As a special case, "file" prefix may be omitted if the file name
+ is complete, e.g., it starts with =./=, or =/=.
+
+- =attachment= ::
+
+ Same as file links but for files and folders attached to the current
+ node (see [[*Attachments]]). Attachment links are intended to behave
+ exactly as file links but for files relative to the attachment
+ directory.
+
+- =bbdb= ::
+
+ Link to a BBDB record, with possible regexp completion.
+
+- =docview= ::
+
+ Link to a document opened with DocView mode. You may specify a page
+ number.
+
+- =doi= ::
+
+ Link to an electronic resource, through its handle.
+
+- =elisp= ::
+
+ Execute an Elisp command upon activation.
+
+- =gnus=, =rmail=, =mhe= ::
+
+ Link to messages or folders from a given Emacs' MUA.
+
+- =help= ::
+
+ Display documentation of a symbol in =*Help*= buffer.
+
+- =http=, =https= ::
+
+ Web links.
+
+- =id= ::
+
+ Link to a specific headline by its ID property, in an Org file.
+
+- =info= ::
+
+ Link to an Info manual, or to a specific node.
+
+- =irc= ::
+
+ Link to an IRC channel.
+
+- =mailto= ::
+
+ Link to message composition.
+
+- =news= ::
+
+ Usenet links.
+
+- =shell= ::
+
+ Execute a shell command upon activation.
+
+The following table illustrates the link types above, along with their
+options:
+
+| Link Type | Example |
+|------------+----------------------------------------------------------|
+| http | =http://staff.science.uva.nl/c.dominik/= |
+| https | =https://orgmode.org/= |
+| doi | =doi:10.1000/182= |
+| file | =file:/home/dominik/images/jupiter.jpg= |
+| | =/home/dominik/images/jupiter.jpg= (same as above) |
+| | =file:papers/last.pdf= |
+| | =./papers/last.pdf= (same as above) |
+| | =file:/ssh:me@some.where:papers/last.pdf= (remote) |
+| | =/ssh:me@some.where:papers/last.pdf= (same as above) |
+| | =file:sometextfile::NNN= (jump to line number) |
+| | =file:projects.org= |
+| | =file:projects.org::some words= (text search) [fn:27] |
+| | =file:projects.org::*task title= (headline search) |
+| | =file:projects.org::#custom-id= (headline search) |
+| attachment | =attachment:projects.org= |
+| | =attachment:projects.org::some words= (text search) |
+| docview | =docview:papers/last.pdf::NNN= |
+| id | =id:B7423F4D-2E8A-471B-8810-C40F074717E9= |
+| news | =news:comp.emacs= |
+| mailto | =mailto:adent@galaxy.net= |
+| mhe | =mhe:folder= (folder link) |
+| | =mhe:folder#id= (message link) |
+| rmail | =rmail:folder= (folder link) |
+| | =rmail:folder#id= (message link) |
+| gnus | =gnus:group= (group link) |
+| | =gnus:group#id= (article link) |
+| bbdb | =bbdb:R.*Stallman= (record with regexp) |
+| irc | =irc:/irc.com/#emacs/bob= |
+| help | =help:org-store-link= |
+| info | =info:org#External links= |
+| shell | =shell:ls *.org= |
+| elisp | =elisp:(find-file "Elisp.org")= (Elisp form to evaluate) |
+| | =elisp:org-agenda= (interactive Elisp command) |
#+cindex: VM links
#+cindex: Wanderlust links
@@ -3223,10 +3231,10 @@ image is inlined into the exported HTML file.
#+cindex: square brackets, around links
#+cindex: angular brackets, around links
#+cindex: plain text external links
-Org also finds external links in the normal text and activates them as
-links. If spaces must be part of the link (for example in
-=bbdb:Richard Stallman=), or if you need to remove ambiguities about
-the end of the link, enclose the link in square or angular brackets.
+Org also recognizes external links amid normal text and activates them
+as links. If spaces must be part of the link (for example in
+=bbdb:R.*Stallman=), or if you need to remove ambiguities about the
+end of the link, enclose the link in square or angular brackets.
** Handling Links
:PROPERTIES:
@@ -3248,64 +3256,64 @@ current buffer:
- /Org mode buffers/ ::
- For Org files, if there is a =<<target>>= at point, the link
- points to the target. Otherwise it points to the current
- headline, which is also the description[fn:30].
-
- #+vindex: org-id-link-to-org-use-id
- #+cindex: @samp{CUSTOM_ID}, property
- #+cindex: @samp{ID}, property
- If the headline has a =CUSTOM_ID= property, store a link to this
- custom ID. In addition or alternatively, depending on the value
- of ~org-id-link-to-org-use-id~, create and/or use a globally unique
- =ID= property for the link[fn:31]. So using this command in Org
- buffers potentially creates two links: a human-readable link from
- the custom ID, and one that is globally unique and works even if
- the entry is moved from file to file. Later, when inserting the
- link, you need to decide which one to use.
+ For Org files, if there is a =<<target>>= at point, the link points
+ to the target. Otherwise it points to the current headline, which
+ is also the description[fn:28].
+
+ #+vindex: org-id-link-to-org-use-id
+ #+cindex: @samp{CUSTOM_ID}, property
+ #+cindex: @samp{ID}, property
+ If the headline has a =CUSTOM_ID= property, store a link to this
+ custom ID. In addition or alternatively, depending on the value of
+ ~org-id-link-to-org-use-id~, create and/or use a globally unique
+ =ID= property for the link[fn:29]. So using this command in Org
+ buffers potentially creates two links: a human-readable link from
+ the custom ID, and one that is globally unique and works even if the
+ entry is moved from file to file. Later, when inserting the link,
+ you need to decide which one to use.
- /Email/News clients: VM, Rmail, Wanderlust, MH-E, Gnus/ ::
- #+vindex: org-email-link-description-format
- Pretty much all Emacs mail clients are supported. The link
- points to the current article, or, in some Gnus buffers, to the
- group. The description is constructed according to the variable
- ~org-email-link-description-format~. By default, it refers to
- the addressee and the subject, possibly truncated.
+ #+vindex: org-link-email-description-format
+ Pretty much all Emacs mail clients are supported. The link points
+ to the current article, or, in some Gnus buffers, to the group. The
+ description is constructed according to the variable
+ ~org-link-email-description-format~. By default, it refers to the
+ addressee and the subject.
- /Web browsers: W3, W3M and EWW/ ::
- Here the link is the current URL, with the page title as the
- description.
+ Here the link is the current URL, with the page title as the
+ description.
- /Contacts: BBDB/ ::
- Links created in a BBDB buffer point to the current entry.
+ Links created in a BBDB buffer point to the current entry.
- /Chat: IRC/ ::
- #+vindex: org-irc-links-to-logs
- For IRC links, if the variable ~org-irc-link-to-logs~ is
- non-~nil~, create a =file= style link to the relevant point in
- the logs for the current conversation. Otherwise store an =irc=
- style link to the user/channel/server under the point.
+ #+vindex: org-irc-links-to-logs
+ For IRC links, if the variable ~org-irc-link-to-logs~ is non-~nil~,
+ create a =file= style link to the relevant point in the logs for the
+ current conversation. Otherwise store an =irc= style link to the
+ user/channel/server under the point.
- /Other files/ ::
- For any other file, the link points to the file, with a search
- string (see [[*Search Options in File Links]]) pointing to the
- contents of the current line. If there is an active region, the
- selected words form the basis of the search string. You can write
- custom Lisp functions to select the search string and perform the
- search for particular file types (see [[*Custom Searches]]).
+ For any other file, the link points to the file, with a search
+ string (see [[*Search Options in File Links]]) pointing to the contents
+ of the current line. If there is an active region, the selected
+ words form the basis of the search string. You can write custom Lisp
+ functions to select the search string and perform the search for
+ particular file types (see [[*Custom Searches]]).
- You can also define dedicated links to other files. See [[*Adding
- Hyperlink Types]].
+ You can also define dedicated links to other files. See [[*Adding
+ Hyperlink Types]].
- /Agenda view/ ::
- When point is in an agenda view, the created link points to
- the entry referenced by the current line.
+ When point is in an agenda view, the created link points to the
+ entry referenced by the current line.
From an Org buffer, the following commands create, navigate or, more
generally, act on links.
@@ -3313,144 +3321,141 @@ generally, act on links.
#+attr_texinfo: :sep ,
- {{{kbd(C-c C-l)}}} (~org-insert-link~) ::
- #+kindex: C-c C-l
- #+findex: org-insert-link
- #+cindex: link completion
- #+cindex: completion, of links
- #+cindex: inserting links
- #+vindex: org-keep-stored-link-after-insertion
- Insert a link[fn:32]. This prompts for a link to be inserted
- into the buffer. You can just type a link, using text for an
- internal link, or one of the link type prefixes mentioned in the
- examples above. The link is inserted into the buffer, along with
- a descriptive text[fn:33]. If some text was selected at this
- time, it becomes the default description.
+ #+kindex: C-c C-l
+ #+findex: org-insert-link
+ #+cindex: link completion
+ #+cindex: completion, of links
+ #+cindex: inserting links
+ #+vindex: org-link-keep-stored-after-insertion
+ Insert a link[fn:30]. This prompts for a link to be inserted into
+ the buffer. You can just type a link, using text for an internal
+ link, or one of the link type prefixes mentioned in the examples
+ above. The link is inserted into the buffer, along with
+ a descriptive text[fn:31]. If some text was selected at this time,
+ it becomes the default description.
- /Inserting stored links/ ::
- All links stored during the current session are part of the
- history for this prompt, so you can access them with
- {{{kbd(UP)}}} and {{{kbd(DOWN)}}} (or {{{kbd(M-p)}}},
- {{{kbd(M-n)}}}).
+ All links stored during the current session are part of the
+ history for this prompt, so you can access them with {{{kbd(UP)}}}
+ and {{{kbd(DOWN)}}} (or {{{kbd(M-p)}}}, {{{kbd(M-n)}}}).
- /Completion support/ ::
- Completion with {{{kbd(TAB)}}} helps you to insert valid link
- prefixes like =http= or =ftp=, including the prefixes defined
- through link abbreviations (see [[*Link Abbreviations]]). If you
- press {{{kbd(RET)}}} after inserting only the prefix, Org
- offers specific completion support for some link types[fn:34].
- For example, if you type {{{kbd(f i l e RET)}}}---alternative
- access: {{{kbd(C-u C-c C-l)}}}, see below---Org offers file
- name completion, and after {{{kbd(b b d b RET)}}} you can
- complete contact names.
+ Completion with {{{kbd(TAB)}}} helps you to insert valid link
+ prefixes like =http= or =ftp=, including the prefixes defined
+ through link abbreviations (see [[*Link Abbreviations]]). If you
+ press {{{kbd(RET)}}} after inserting only the prefix, Org offers
+ specific completion support for some link types[fn:32]. For
+ example, if you type {{{kbd(f i l e RET)}}}---alternative access:
+ {{{kbd(C-u C-c C-l)}}}, see below---Org offers file name
+ completion, and after {{{kbd(b b d b RET)}}} you can complete
+ contact names.
- {{{kbd(C-u C-c C-l)}}} ::
- #+cindex: file name completion
- #+cindex: completion, of file names
- #+kindex: C-u C-c C-l
- When {{{kbd(C-c C-l)}}} is called with a {{{kbd(C-u)}}} prefix
- argument, insert a link to a file. You may use file name
- completion to select the name of the file. The path to the file
- is inserted relative to the directory of the current Org file, if
- the linked file is in the current directory or in a sub-directory
- of it, or if the path is written relative to the current
- directory using =../=. Otherwise an absolute path is used, if
- possible with =~/= for your home directory. You can force an
- absolute path with two {{{kbd(C-u)}}} prefixes.
+ #+cindex: file name completion
+ #+cindex: completion, of file names
+ #+kindex: C-u C-c C-l
+ When {{{kbd(C-c C-l)}}} is called with a {{{kbd(C-u)}}} prefix
+ argument, insert a link to a file. You may use file name completion
+ to select the name of the file. The path to the file is inserted
+ relative to the directory of the current Org file, if the linked
+ file is in the current directory or in a sub-directory of it, or if
+ the path is written relative to the current directory using =../=.
+ Otherwise an absolute path is used, if possible with =~/= for your
+ home directory. You can force an absolute path with two
+ {{{kbd(C-u)}}} prefixes.
- {{{kbd(C-c C-l)}}} (with point on existing link) ::
- #+cindex: following links
- When point is on an existing link, {{{kbd(C-c C-l)}}} allows
- you to edit the link and description parts of the link.
+ #+cindex: following links
+ When point is on an existing link, {{{kbd(C-c C-l)}}} allows you to
+ edit the link and description parts of the link.
- {{{kbd(C-c C-o)}}} (~org-open-at-point~) ::
- #+kindex: C-c C-o
- #+findex: org-open-at-point
- #+vindex: org-file-apps
- Open link at point. This launches a web browser for URL (using
- ~browse-url-at-point~), run VM/MH-E/Wanderlust/Rmail/Gnus/BBDB
- for the corresponding links, and execute the command in a shell
- link. When point is on an internal link, this command runs the
- corresponding search. When point is on the tags part of a
- headline, it creates the corresponding tags view (see [[*Matching
- tags and properties]]). If point is on a timestamp, it compiles
- the agenda for that date. Furthermore, it visits text and remote
- files in =file= links with Emacs and select a suitable
- application for local non-text files. Classification of files is
- based on file extension only. See option ~org-file-apps~. If
- you want to override the default application and visit the file
- with Emacs, use a {{{kbd(C-u)}}} prefix. If you want to avoid
- opening in Emacs, use a {{{kbd(C-u C-u)}}} prefix.
-
- #+vindex: org-link-frame-setup
- If point is on a headline, but not on a link, offer all links in
- the headline and entry text. If you want to setup the frame
- configuration for following links, customize
- ~org-link-frame-setup~.
+ #+kindex: C-c C-o
+ #+findex: org-open-at-point
+ #+vindex: org-file-apps
+ Open link at point. This launches a web browser for URL (using
+ ~browse-url-at-point~), run VM/MH-E/Wanderlust/Rmail/Gnus/BBDB for
+ the corresponding links, and execute the command in a shell link.
+ When point is on an internal link, this command runs the
+ corresponding search. When point is on the tags part of a headline,
+ it creates the corresponding tags view (see [[*Matching tags and
+ properties]]). If point is on a timestamp, it compiles the agenda for
+ that date. Furthermore, it visits text and remote files in =file=
+ links with Emacs and select a suitable application for local
+ non-text files. Classification of files is based on file extension
+ only. See option ~org-file-apps~. If you want to override the
+ default application and visit the file with Emacs, use
+ a {{{kbd(C-u)}}} prefix. If you want to avoid opening in Emacs, use
+ a {{{kbd(C-u C-u)}}} prefix.
+
+ #+vindex: org-link-frame-setup
+ If point is on a headline, but not on a link, offer all links in the
+ headline and entry text. If you want to setup the frame
+ configuration for following links, customize ~org-link-frame-setup~.
- {{{kbd(RET)}}} ::
- #+vindex: org-return-follows-link
- #+kindex: RET
- When ~org-return-follows-link~ is set, {{{kbd(RET)}}} also
- follows the link at point.
+ #+vindex: org-return-follows-link
+ #+kindex: RET
+ When ~org-return-follows-link~ is set, {{{kbd(RET)}}} also follows
+ the link at point.
- {{{kbd(mouse-2)}}} or {{{kbd(mouse-1)}}} ::
- #+kindex: mouse-2
- #+kindex: mouse-1
- On links, {{{kbd(mouse-1)}}} and {{{kbd(mouse-2)}}} opens the
- link just as {{{kbd(C-c C-o)}}} does.
+ #+kindex: mouse-2
+ #+kindex: mouse-1
+ On links, {{{kbd(mouse-1)}}} and {{{kbd(mouse-2)}}} opens the link
+ just as {{{kbd(C-c C-o)}}} does.
- {{{kbd(mouse-3)}}} ::
- #+vindex: org-display-internal-link-with-indirect-buffer
- #+kindex: mouse-3
- Like {{{kbd(mouse-2)}}}, but force file links to be opened with
- Emacs, and internal links to be displayed in another
- window[fn:35].
+ #+vindex: org-link-use-indirect-buffer-for-internals
+ #+kindex: mouse-3
+ Like {{{kbd(mouse-2)}}}, but force file links to be opened with
+ Emacs, and internal links to be displayed in another window[fn:33].
- {{{kbd(C-c %)}}} (~org-mark-ring-push~) ::
- #+kindex: C-c %
- #+findex: org-mark-ring-push
- #+cindex: mark ring
- Push the current position onto the Org mark ring, to be able to
- return easily. Commands following an internal link do this
- automatically.
+ #+kindex: C-c %
+ #+findex: org-mark-ring-push
+ #+cindex: mark ring
+ Push the current position onto the Org mark ring, to be able to
+ return easily. Commands following an internal link do this
+ automatically.
- {{{kbd(C-c &)}}} (~org-mark-ring-goto~) ::
- #+kindex: C-c &
- #+findex: org-mark-ring-goto
- #+cindex: links, returning to
- Jump back to a recorded position. A position is recorded by the
- commands following internal links, and by {{{kbd(C-c %)}}}.
- Using this command several times in direct succession moves
- through a ring of previously recorded positions.
+ #+kindex: C-c &
+ #+findex: org-mark-ring-goto
+ #+cindex: links, returning to
+ Jump back to a recorded position. A position is recorded by the
+ commands following internal links, and by {{{kbd(C-c %)}}}. Using
+ this command several times in direct succession moves through a ring
+ of previously recorded positions.
- {{{kbd(C-c C-x C-n)}}} (~org-next-link~), {{{kbd(C-c C-x C-p)}}} (~org-previous-link~) ::
- #+kindex: C-c C-x C-p
- #+findex: org-previous-link
- #+kindex: C-c C-x C-n
- #+findex: org-next-link
- #+cindex: links, finding next/previous
- Move forward/backward to the next link in the buffer. At the
- limit of the buffer, the search fails once, and then wraps
- around. The key bindings for this are really too long; you might
- want to bind this also to {{{kbd(M-n)}}} and {{{kbd(M-p)}}}.
-
- #+begin_src emacs-lisp
- (add-hook 'org-load-hook
- (lambda ()
- (define-key org-mode-map "\M-n" 'org-next-link)
- (define-key org-mode-map "\M-p" 'org-previous-link)))
- #+end_src
+ #+kindex: C-c C-x C-p
+ #+findex: org-previous-link
+ #+kindex: C-c C-x C-n
+ #+findex: org-next-link
+ #+cindex: links, finding next/previous
+ Move forward/backward to the next link in the buffer. At the limit
+ of the buffer, the search fails once, and then wraps around. The
+ key bindings for this are really too long; you might want to bind
+ this also to {{{kbd(M-n)}}} and {{{kbd(M-p)}}}.
+
+ #+begin_src emacs-lisp
+ (add-hook 'org-load-hook
+ (lambda ()
+ (define-key org-mode-map "\M-n" 'org-next-link)
+ (define-key org-mode-map "\M-p" 'org-previous-link)))
+ #+end_src
** Using Links Outside Org
:PROPERTIES:
@@ -3544,15 +3549,19 @@ the link completion function like this:
:END:
#+cindex: search option in file links
#+cindex: file links, searching
+#+cindex: attachment links, searching
-File links can contain additional information to make Emacs jump to
-a particular location in the file when following a link. This can be
-a line number or a search option after a double colon[fn:36]. For
+File links can contain additional information to make Emacs jump to a
+particular location in the file when following a link. This can be a
+line number or a search option after a double colon[fn:34]. For
example, when the command ~org-store-link~ creates a link (see
[[*Handling Links]]) to a file, it encodes the words in the current line
as a search string that can be used to find this line back later when
following the link with {{{kbd(C-c C-o)}}}.
+Note that all search options apply for Attachment links in the same
+way that they apply for File links.
+
Here is the syntax of the different ways to attach a search to a file
link, together with explanations for each:
@@ -3562,38 +3571,40 @@ link, together with explanations for each:
[[file:~/xx.org::*My Target]]
[[file:~/xx.org::#my-custom-id]]
[[file:~/xx.org::/regexp/]]
+[[attachment:main.c::255]]
#+end_example
- =255= ::
- Jump to line 255.
+ Jump to line 255.
- =My Target= ::
- Search for a link target =<<My Target>>=, or do a text search for
- =my target=, similar to the search in internal links, see
- [[*Internal Links]]. In HTML export (see [[*HTML Export]]), such a file
- link becomes a HTML reference to the corresponding named anchor
- in the linked file.
+ Search for a link target =<<My Target>>=, or do a text search for
+ =my target=, similar to the search in internal links, see [[*Internal
+ Links]]. In HTML export (see [[*HTML Export]]), such a file link becomes
+ a HTML reference to the corresponding named anchor in the linked
+ file.
- =*My Target= ::
- In an Org file, restrict search to headlines.
+ In an Org file, restrict search to headlines.
- =#my-custom-id= ::
- Link to a heading with a =CUSTOM_ID= property
+ Link to a heading with a =CUSTOM_ID= property
- =/REGEXP/= ::
- Do a regular expression search for {{{var(REGEXP)}}}. This uses
- the Emacs command ~occur~ to list all matches in a separate
- window. If the target file is in Org mode, ~org-occur~ is used
- to create a sparse tree with the matches.
+ Do a regular expression search for {{{var(REGEXP)}}}. This uses the
+ Emacs command ~occur~ to list all matches in a separate window. If
+ the target file is in Org mode, ~org-occur~ is used to create
+ a sparse tree with the matches.
As a degenerate case, a file link with an empty file name can be used
to search the current file. For example, =[[file:::find me]]= does
-a search for =find me= in the current file, just as =[[find me]]= would.
+a search for =find me= in the current file, just as =[[find me]]=
+would.
** Custom Searches
:PROPERTIES:
@@ -3618,7 +3629,7 @@ need to be added to the hook variables
~org-execute-file-search-functions~. See the docstring for these
variables for more information. Org actually uses this mechanism for
BibTeX database files, and you can use the corresponding code as an
-implementation example. See the file =org-bibtex.el=.
+implementation example. See the file =ol-bibtex.el=.
* TODO Items
:PROPERTIES:
@@ -3626,7 +3637,7 @@ implementation example. See the file =org-bibtex.el=.
:END:
#+cindex: TODO items
-Org mode does not maintain TODO lists as separate documents[fn:37].
+Org mode does not maintain TODO lists as separate documents[fn:35].
Instead, TODO items are an integral part of the notes file, because
TODO items usually come up while taking notes! With Org mode, simply
mark any entry in a tree as being a TODO item. In this way,
@@ -3653,76 +3664,67 @@ The most important commands to work with TODO entries are:
- {{{kbd(C-c C-t)}}} (~org-todo~) ::
- #+kindex: C-c C-t
- #+cindex: cycling, of TODO states
- Rotate the TODO state of the current item among
-
- #+begin_example
- ,-> (unmarked) -> TODO -> DONE --.
- '--------------------------------'
- #+end_example
+ #+kindex: C-c C-t
+ #+cindex: cycling, of TODO states
+ Rotate the TODO state of the current item among
- If TODO keywords have fast access keys (see [[*Fast access to
- TODO states]]), prompt for a TODO keyword through the fast
- selection interface; this is the default behavior when
- ~org-use-fast-todo-selection~ is non-~nil~.
+ #+begin_example
+ ,-> (unmarked) -> TODO -> DONE --.
+ '--------------------------------'
+ #+end_example
- The same rotation can also be done "remotely" from the agenda
- buffer with the {{{kbd(t)}}} command key (see [[*Commands in the
- Agenda Buffer]]).
+ If TODO keywords have fast access keys (see [[*Fast access to TODO
+ states]]), prompt for a TODO keyword through the fast selection
+ interface; this is the default behavior when
+ ~org-use-fast-todo-selection~ is non-~nil~.
-- {{{kbd(C-u C-c C-t)}}} ::
-
- #+kindex: C-u C-c C-t
- When TODO keywords have no selection keys, select a specific
- keyword using completion; otherwise force cycling through TODO
- states with no prompt. When ~org-use-fast-todo-selection~ is set
- to ~prefix~, use the fast selection interface.
+ The same state changing can also be done "remotely" from the agenda
+ buffer with the {{{kbd(t)}}} command key (see [[*Commands in the
+ Agenda Buffer]]).
- {{{kbd(S-RIGHT)}}} {{{kbd(S-LEFT)}}} ::
- #+kindex: S-RIGHT
- #+kindex: S-LEFT
- #+vindex: org-treat-S-cursor-todo-selection-as-state-change
- Select the following/preceding TODO state, similar to cycling.
- Useful mostly if more than two TODO states are possible (see
- [[*Extended Use of TODO Keywords]]). See also [[*Packages that
- conflict with Org mode]], for a discussion of the interaction with
- ~shift-selection-mode~. See also the variable
- ~org-treat-S-cursor-todo-selection-as-state-change~.
+ #+kindex: S-RIGHT
+ #+kindex: S-LEFT
+ #+vindex: org-treat-S-cursor-todo-selection-as-state-change
+ Select the following/preceding TODO state, similar to cycling.
+ Useful mostly if more than two TODO states are possible (see
+ [[*Extended Use of TODO Keywords]]). See also [[*Packages that conflict
+ with Org mode]], for a discussion of the interaction with
+ shift-selection. See also the variable
+ ~org-treat-S-cursor-todo-selection-as-state-change~.
- {{{kbd(C-c / t)}}} (~org-show-todo-tree~) ::
- #+kindex: C-c / t
- #+cindex: sparse tree, for TODO
- #+vindex: org-todo-keywords
- #+findex: org-show-todo-tree
- View TODO items in a /sparse tree/ (see [[*Sparse Trees]]). Folds
- the entire buffer, but shows all TODO items---with not-DONE
- state---and the headings hierarchy above them. With a prefix
- argument, or by using {{{kbd(C-c / T)}}}, search for a specific
- TODO. You are prompted for the keyword, and you can also give
- a list of keywords like =KWD1|KWD2|...= to list entries that
- match any one of these keywords. With a numeric prefix argument
- N, show the tree for the Nth keyword in the variable
- ~org-todo-keywords~. With two prefix arguments, find all TODO
- states, both un-done and done.
+ #+kindex: C-c / t
+ #+cindex: sparse tree, for TODO
+ #+vindex: org-todo-keywords
+ #+findex: org-show-todo-tree
+ View TODO items in a /sparse tree/ (see [[*Sparse Trees]]). Folds the
+ entire buffer, but shows all TODO items---with not-DONE state---and
+ the headings hierarchy above them. With a prefix argument, or by
+ using {{{kbd(C-c / T)}}}, search for a specific TODO. You are
+ prompted for the keyword, and you can also give a list of keywords
+ like =KWD1|KWD2|...= to list entries that match any one of these
+ keywords. With a numeric prefix argument N, show the tree for the
+ Nth keyword in the variable ~org-todo-keywords~. With two prefix
+ arguments, find all TODO states, both un-done and done.
- {{{kbd(M-x org-agenda t)}}} (~org-todo-list~) ::
- #+kindex: t @r{(Agenda dispatcher)}
- Show the global TODO list. Collects the TODO items (with
- not-DONE states) from all agenda files (see [[*Agenda Views]]) into
- a single buffer. The new buffer is in Org Agenda mode, which
- provides commands to examine and manipulate the TODO entries from
- the new buffer (see [[*Commands in the Agenda Buffer]]). See [[*The
- global TODO list]], for more information.
+ #+kindex: t @r{(Agenda dispatcher)}
+ Show the global TODO list. Collects the TODO items (with not-DONE
+ states) from all agenda files (see [[*Agenda Views]]) into a single
+ buffer. The new buffer is in Org Agenda mode, which provides
+ commands to examine and manipulate the TODO entries from the new
+ buffer (see [[*Commands in the Agenda Buffer]]). See [[*The global TODO
+ list]], for more information.
- {{{kbd(S-M-RET)}}} (~org-insert-todo-heading~) ::
- #+kindex: S-M-RET
- #+findex: org-insert-todo-heading
- Insert a new TODO entry below the current one.
+ #+kindex: S-M-RET
+ #+findex: org-insert-todo-heading
+ Insert a new TODO entry below the current one.
#+vindex: org-todo-state-tags-triggers
Changing a TODO state can also trigger tag changes. See the docstring
@@ -3753,8 +3755,8 @@ TODO items in particular (see [[*Tags]]).
#+cindex: TODO workflow
#+cindex: workflow states as TODO keywords
-You can use TODO keywords to indicate different /sequential/ states in
-the process of working on an item, for example[fn:38]:
+You can use TODO keywords to indicate different, possibly /sequential/
+states in the process of working on an item, for example[fn:36]:
#+begin_src emacs-lisp
(setq org-todo-keywords
@@ -3771,12 +3773,13 @@ With this setup, the command {{{kbd(C-c C-t)}}} cycles an entry from
=TODO= to =FEEDBACK=, then to =VERIFY=, and finally to =DONE= and
=DELEGATED=. You may also use a numeric prefix argument to quickly
select a specific state. For example {{{kbd(C-3 C-c C-t)}}} changes
-the state immediately to =VERIFY=. Or you can use {{{kbd(S-LEFT)}}}
-to go backward through the sequence. If you define many keywords, you
-can use in-buffer completion (see [[*Completion]]) or even a special
-one-key selection scheme (see [[*Fast access to TODO states]]) to insert
-these words into the buffer. Changing a TODO state can be logged with
-a timestamp, see [[*Tracking TODO state changes]], for more information.
+the state immediately to =VERIFY=. Or you can use {{{kbd(S-RIGHT)}}}
+and {{{kbd(S-LEFT)}}} to go forward and backward through the states.
+If you define many keywords, you can use in-buffer completion (see
+[[*Completion]]) or a special one-key selection scheme (see [[*Fast
+access to TODO states]]) to insert these words into the buffer.
+Changing a TODO state can be logged with a timestamp, see [[*Tracking
+TODO state changes]], for more information.
*** TODO keywords as types
:PROPERTIES:
@@ -3791,18 +3794,22 @@ The second possibility is to use TODO keywords to indicate different
/types/ of action items. For example, you might want to indicate that
items are for "work" or "home". Or, when you work with several people
on a single project, you might want to assign action items directly to
-persons, by using their names as TODO keywords. This would be set up
-like this:
+persons, by using their names as TODO keywords. This type of
+functionality is actually much better served by using tags (see
+[[*Tags]]), so the TODO implementation is kept just for backward
+compatibility.
+
+Using TODO types, it would be set up like this:
#+begin_src emacs-lisp
(setq org-todo-keywords '((type "Fred" "Sara" "Lucy" "|" "DONE")))
#+end_src
-In this case, different keywords do not indicate a sequence, but
+In this case, different keywords do not indicate states, but
rather different types. So the normal work flow would be to assign
a task to a person, and later to mark it DONE. Org mode supports this
style by adapting the workings of the command {{{kbd(C-c
-C-t)}}}[fn:39]. When used several times in succession, it still
+C-t)}}}[fn:37]. When used several times in succession, it still
cycles through all names, in order to first select the right type for
a task. But when you return to the item after some time and execute
{{{kbd(C-c C-t)}}} again, it will switch from any name directly to
@@ -3846,26 +3853,25 @@ correct sequence. In addition to typing a keyword or using completion
#+attr_texinfo: :sep ,
- {{{kbd(C-u C-u C-c C-t)}}}, {{{kbd(C-S-RIGHT)}}}, {{{kbd(C-S-LEFT)}}} ::
- #+kindex: C-S-RIGHT
- #+kindex: C-S-LEFT
- #+kindex: C-u C-u C-c C-t
- These keys jump from one TODO sub-sequence to the next. In the
- above example, {{{kbd(C-u C-u C-c C-t)}}} or {{{kbd(C-S-RIGHT)}}}
- would jump from =TODO= or =DONE= to =REPORT=, and any of the
- words in the second row to =CANCELED=. Note that the
- {{{kbd(C-S-)}}} key binding conflict with ~shift-selection-mode~
- (see [[*Packages that conflict with Org mode]]).
+ #+kindex: C-S-RIGHT
+ #+kindex: C-S-LEFT
+ #+kindex: C-u C-u C-c C-t
+ These keys jump from one TODO sub-sequence to the next. In the
+ above example, {{{kbd(C-u C-u C-c C-t)}}} or {{{kbd(C-S-RIGHT)}}}
+ would jump from =TODO= or =DONE= to =REPORT=, and any of the words
+ in the second row to =CANCELED=. Note that the {{{kbd(C-S-)}}} key
+ binding conflict with shift-selection (see [[*Packages that conflict
+ with Org mode]]).
- {{{kbd(S-RIGHT)}}}, {{{kbd(S-LEFT)}}} ::
- #+kindex: S-RIGHT
- #+kindex: S-LEFT
- {{{kbd(S-LEFT)}}} and {{{kbd(S-RIGHT)}}} walk through /all/
- keywords from all sub-sequences, so for example
- {{{kbd(S-RIGHT)}}} would switch from =DONE= to =REPORT= in the
- example above. For a discussion of the interaction with
- ~shift-selection-mode~, see [[*Packages that conflict with Org
- mode]].
+ #+kindex: S-RIGHT
+ #+kindex: S-LEFT
+ {{{kbd(S-LEFT)}}} and {{{kbd(S-RIGHT)}}} walk through /all/ keywords
+ from all sub-sequences, so for example {{{kbd(S-RIGHT)}}} would
+ switch from =DONE= to =REPORT= in the example above. For
+ a discussion of the interaction with shift-selection, see [[*Packages
+ that conflict with Org mode]].
*** Fast access to TODO states
:PROPERTIES:
@@ -3875,7 +3881,7 @@ correct sequence. In addition to typing a keyword or using completion
If you would like to quickly change an entry to an arbitrary TODO
state instead of cycling through the states, you can set up keys for
single-letter access to the states. This is done by adding the
-selection character after each keyword, in parentheses[fn:40]. For
+selection character after each keyword, in parentheses[fn:38]. For
example:
#+begin_src emacs-lisp
@@ -3888,7 +3894,7 @@ example:
#+vindex: org-fast-tag-selection-include-todo
If you then press {{{kbd(C-c C-t)}}} followed by the selection key,
the entry is switched to this state. {{{kbd(SPC)}}} can be used to
-remove any TODO keyword from an entry[fn:41].
+remove any TODO keyword from an entry[fn:39].
*** Setting up keywords for individual files
:PROPERTIES:
@@ -3933,7 +3939,7 @@ Remember that the keywords after the vertical bar---or the last
keyword if no bar is there---must always mean that the item is DONE,
although you may use a different word. After changing one of these
lines, use {{{kbd(C-c C-c)}}} with point still in the line to make the
-changes known to Org mode[fn:42].
+changes known to Org mode[fn:40].
*** Faces for TODO keywords
:PROPERTIES:
@@ -3976,15 +3982,15 @@ a background color.
#+cindex: @samp{ORDERED}, property
The structure of Org files---hierarchy and lists---makes it easy to
define TODO dependencies. Usually, a parent TODO task should not be
-marked DONE until all TODO subtasks, or children tasks, are marked as
-DONE. Sometimes there is a logical sequence to (sub)tasks, so that
+marked as done until all TODO subtasks, or children tasks, are marked
+as done. Sometimes there is a logical sequence to (sub)tasks, so that
one subtask cannot be acted upon before all siblings above it have
-been marked DONE. If you customize the variable
+been marked as done. If you customize the variable
~org-enforce-todo-dependencies~, Org blocks entries from changing
state to DONE while they have TODO children that are not DONE.
Furthermore, if an entry has a property =ORDERED=, each of its TODO
-children is blocked until all earlier siblings are marked DONE. Here
-is an example:
+children is blocked until all earlier siblings are marked as done.
+Here is an example:
#+begin_example
,* TODO Blocked until (two) is done
@@ -4014,25 +4020,25 @@ property (see [[*Properties and Columns]]):
- {{{kbd(C-c C-x o)}}} (~org-toggle-ordered-property~) ::
- #+kindex: C-c C-x o
- #+findex: org-toggle-ordered-property
- #+vindex: org-track-ordered-property-with-tag
- Toggle the =ORDERED= property of the current entry. A property
- is used for this behavior because this should be local to the
- current entry, not inherited from entries above like a tag (see
- [[*Tags]]). However, if you would like to /track/ the value of this
- property with a tag for better visibility, customize the variable
- ~org-track-ordered-property-with-tag~.
+ #+kindex: C-c C-x o
+ #+findex: org-toggle-ordered-property
+ #+vindex: org-track-ordered-property-with-tag
+ Toggle the =ORDERED= property of the current entry. A property is
+ used for this behavior because this should be local to the current
+ entry, not inherited from entries above like a tag (see [[*Tags]]).
+ However, if you would like to /track/ the value of this property
+ with a tag for better visibility, customize the variable
+ ~org-track-ordered-property-with-tag~.
- {{{kbd(C-u C-u C-u C-c C-t)}}} ::
- #+kindex: C-u C-u C-u C-c C-t
- Change TODO state, regardless of any state blocking.
+ #+kindex: C-u C-u C-u C-u C-c C-t
+ Change TODO state, regardless of any state blocking.
#+vindex: org-agenda-dim-blocked-tasks
If you set the variable ~org-agenda-dim-blocked-tasks~, TODO entries
-that cannot be marked DONE because of unmarked children are shown in a
-dimmed font or even made invisible in agenda views (see [[*Agenda
+that cannot be marked as done because of unmarked children are shown
+in a dimmed font or even made invisible in agenda views (see [[*Agenda
Views]]).
#+cindex: checkboxes and TODO dependencies
@@ -4053,20 +4059,30 @@ the contributed module =org-depend.el=.
#+cindex: progress logging
#+cindex: logging, of progress
-Org mode can automatically record a timestamp and optionally a note
-when you mark a TODO item as DONE, or even each time you change the
-state of a TODO item. This system is highly configurable, settings
-can be on a per-keyword basis and can be localized to a file or even a
-subtree. For information on how to clock working time for a task, see
-[[*Clocking Work Time]].
+To record a timestamp and a note when changing a TODO state, call the
+command ~org-todo~ with a prefix argument.
+
+- {{{kbd(C-u C-c C-t)}}} (~org-todo~) ::
+
+ #+kindex: C-u C-c C-t
+ Prompt for a note and record a the time of the TODO state change.
+ The note is inserted as a list item below the headline, but can also
+ be placed into a drawer, see [[*Tracking TODO state changes]].
+
+If you want to be more systematic, Org mode can automatically record a
+timestamp and optionally a note when you mark a TODO item as DONE, or
+even each time you change the state of a TODO item. This system is
+highly configurable, settings can be on a per-keyword basis and can be
+localized to a file or even a subtree. For information on how to
+clock working time for a task, see [[*Clocking Work Time]].
*** Closing items
:PROPERTIES:
-:DESCRIPTION: When was this entry marked DONE?
+:DESCRIPTION: When was this entry marked as done?
:END:
-The most basic logging is to keep track of /when/ a certain TODO item
-was marked DONE. This can be achieved with[fn:43]
+The most basic automatic logging is to keep track of /when/ a certain
+TODO item was marked as done. This can be achieved with[fn:41]
#+begin_src emacs-lisp
(setq org-log-done 'time)
@@ -4081,14 +4097,14 @@ through further state cycling, that line is removed again. If you
turn the entry back to a non-TODO state (by pressing {{{kbd(C-c C-t
SPC)}}} for example), that line is also removed, unless you set
~org-closed-keep-when-no-todo~ to non-~nil~. If you want to record
-a note along with the timestamp, use[fn:44]
+a note along with the timestamp, use[fn:42]
#+begin_src emacs-lisp
(setq org-log-done 'note)
#+end_src
#+texinfo: @noindent
-You are then be prompted for a note, and that note is stored below the
+You are then prompted for a note, and that note is stored below the
entry with a =Closing Note= heading.
*** Tracking TODO state changes
@@ -4100,16 +4116,16 @@ entry with a =Closing Note= heading.
#+vindex: org-log-states-order-reversed
#+vindex: org-log-into-drawer
#+cindex: @samp{LOG_INTO_DRAWER}, property
-When TODO keywords are used as workflow states (see [[*TODO keywords as workflow states][*Workflow states]]),
-you might want to keep track of when a state change occurred and maybe
-take a note about this change. You can either record just a
-timestamp, or a time-stamped note. These records are inserted after
-the headline as an itemized list, newest first[fn:45]. When taking a
-lot of notes, you might want to get the notes out of the way into a
-drawer (see [[*Drawers]]). Customize the variable ~org-log-into-drawer~
-to get this behavior---the recommended drawer for this is called
-=LOGBOOK=[fn:46]. You can also overrule the setting of this variable
-for a subtree by setting a =LOG_INTO_DRAWER= property.
+You might want to automatically keep track of when a state change
+occurred and maybe take a note about this change. You can either
+record just a timestamp, or a time-stamped note. These records are
+inserted after the headline as an itemized list, newest first[fn:43].
+When taking a lot of notes, you might want to get the notes out of the
+way into a drawer (see [[*Drawers]]). Customize the variable
+~org-log-into-drawer~ to get this behavior---the recommended drawer
+for this is called =LOGBOOK=[fn:44]. You can also overrule the
+setting of this variable for a subtree by setting a =LOG_INTO_DRAWER=
+property.
Since it is normally too much to record a note for every state, Org
mode expects configuration on a per-keyword basis for this. This is
@@ -4123,14 +4139,14 @@ example, with the setting
#+end_src
#+texinfo: @noindent
-to record a timestamp without a note for TODO keywords configured with
+To record a timestamp without a note for TODO keywords configured with
=@=, just type {{{kbd(C-c C-c)}}} to enter a blank note when prompted.
#+vindex: org-log-done
You not only define global TODO keywords and fast access keys, but
also request that a time is recorded when the entry is set to =DONE=,
and that a note is recorded when switching to =WAIT= or
-=CANCELED=[fn:47]. The setting for =WAIT= is even more special: the
+=CANCELED=[fn:45]. The setting for =WAIT= is even more special: the
=!= after the slash means that in addition to the note taken when
entering the state, a timestamp should be recorded when /leaving/ the
=WAIT= state, if and only if the /target/ state does not configure
@@ -4250,27 +4266,28 @@ the way habits are displayed in the agenda.
- ~org-habit-graph-column~ ::
- #+vindex: org-habit-graph-column
- The buffer column at which the consistency graph should be drawn.
- This overwrites any text in that column, so it is a good idea to
- keep your habits' titles brief and to the point.
+ #+vindex: org-habit-graph-column
+ The buffer column at which the consistency graph should be drawn.
+ This overwrites any text in that column, so it is a good idea to
+ keep your habits' titles brief and to the point.
- ~org-habit-preceding-days~ ::
- #+vindex: org-habit-preceding-days
- The amount of history, in days before today, to appear in
- consistency graphs.
+ #+vindex: org-habit-preceding-days
+ The amount of history, in days before today, to appear in
+ consistency graphs.
- ~org-habit-following-days~ ::
- #+vindex: org-habit-following-days
- The number of days after today that appear in consistency graphs.
+ #+vindex: org-habit-following-days
+ The number of days after today that appear in consistency graphs.
- ~org-habit-show-habits-only-for-today~ ::
- #+vindex: org-habit-show-habits-only-for-today
- If non-~nil~, only show habits in today's agenda view. The
- default value is ~t~.
+ #+vindex: org-habit-show-habits-only-for-today
+ If non-~nil~, only show habits in today's agenda view. The default
+ value is ~t~. Pressing {{{kbd(C-u K)}}} in the agenda toggles this
+ variable.
Lastly, pressing {{{kbd(K)}}} in the agenda buffer causes habits to
temporarily be disabled and do not appear at all. Press {{{kbd(K)}}}
@@ -4307,27 +4324,26 @@ TODO items.
#+attr_texinfo: :sep ;
- {{{kbd(C-c \,)}}} (~org-priority~) ::
- #+kindex: C-c ,
- #+findex: org-priority
- Set the priority of the current headline. The command prompts
- for a priority character =A=, =B= or =C=. When you press
- {{{kbd(SPC)}}} instead, the priority cookie, if one is set, is
- removed from the headline. The priorities can also be changed
- "remotely" from the agenda buffer with the {{{kbd(\,)}}} command
- (see [[*Commands in the Agenda Buffer]]).
+ #+kindex: C-c ,
+ #+findex: org-priority
+ Set the priority of the current headline. The command prompts for
+ a priority character =A=, =B= or =C=. When you press {{{kbd(SPC)}}}
+ instead, the priority cookie, if one is set, is removed from the
+ headline. The priorities can also be changed "remotely" from the
+ agenda buffer with the {{{kbd(\,)}}} command (see [[*Commands in the
+ Agenda Buffer]]).
- {{{kbd(S-UP)}}} (~org-priority-up~); {{{kbd(S-DOWN)}}} (~org-priority-down~) ::
- #+kindex: S-UP
- #+kindex: S-DOWN
- #+findex: org-priority-up
- #+findex: org-priority-down
- #+vindex: org-priority-start-cycle-with-default
- Increase/decrease the priority of the current headline[fn:48].
- Note that these keys are also used to modify timestamps (see
- [[*Creating Timestamps]]). See also [[*Packages that conflict with Org
- mode]], for a discussion of the interaction with
- ~shift-selection-mode~.
+ #+kindex: S-UP
+ #+kindex: S-DOWN
+ #+findex: org-priority-up
+ #+findex: org-priority-down
+ #+vindex: org-priority-start-cycle-with-default
+ Increase/decrease the priority of the current headline[fn:46]. Note
+ that these keys are also used to modify timestamps (see [[*Creating
+ Timestamps]]). See also [[*Packages that conflict with Org mode]], for
+ a discussion of the interaction with shift-selection.
#+vindex: org-highest-priority
#+vindex: org-lowest-priority
@@ -4352,9 +4368,9 @@ highest priority is earlier in the alphabet than the lowest priority):
#+vindex: org-agenda-todo-list-sublevels
It is often advisable to break down large tasks into smaller,
manageable subtasks. You can do this by creating an outline tree
-below a TODO item, with detailed subtasks on the tree[fn:49]. To keep
+below a TODO item, with detailed subtasks on the tree[fn:47]. To keep
an overview of the fraction of subtasks that have already been marked
-DONE, insert either =[/]= or =[%]= anywhere in the headline. These
+as done, insert either =[/]= or =[%]= anywhere in the headline. These
cookies are updated each time the TODO status of a child changes, or
when pressing {{{kbd(C-c C-c)}}} on the cookie. For example:
@@ -4408,14 +4424,12 @@ of) a large number of subtasks (see [[*Checkboxes]]).
#+cindex: checkboxes
#+vindex: org-list-automatic-rules
-Every item in a plain list[fn:50] (see [[*Plain Lists]]) can be made into
+Every item in a plain list[fn:48] (see [[*Plain Lists]]) can be made into
a checkbox by starting it with the string =[ ]=. This feature is
similar to TODO items (see [[*TODO Items]]), but is more lightweight.
Checkboxes are not included into the global TODO list, so they are
often great to split a task into a number of simple steps. Or you can
-use them in a shopping list. To toggle a checkbox, use {{{kbd(C-c
-C-c)}}}, or use the mouse (thanks to Piotr Zielinski's
-=org-mouse.el=).
+use them in a shopping list.
Here is an example of a checkbox list.
@@ -4446,7 +4460,7 @@ idea on how many checkboxes remain, even without opening a folded
entry. The cookies can be placed into a headline or into (the first
line of) a plain list item. Each cookie covers checkboxes of direct
children structurally below the headline/item on which the cookie
-appears[fn:51]. You have to insert the cookie yourself by typing
+appears[fn:49]. You have to insert the cookie yourself by typing
either =[/]= or =[%]=. With =[/]= you get an =n out of m= result, as
in the examples above. With =[%]= you get information about the
percentage of checkboxes checked (in the above example, this would be
@@ -4466,63 +4480,60 @@ The following commands work with checkboxes:
- {{{kbd(C-c C-c)}}} (~org-toggle-checkbox~) ::
- #+kindex: C-c C-c
- #+findex: org-toggle-checkbox
- Toggle checkbox status or---with prefix argument---checkbox
- presence at point. With a single prefix argument, add an empty
- checkbox or remove the current one[fn:52]. With a double prefix
- argument, set it to =[-]=, which is considered to be an
- intermediate state.
+ #+kindex: C-c C-c
+ #+findex: org-toggle-checkbox
+ Toggle checkbox status or---with prefix argument---checkbox presence
+ at point. With a single prefix argument, add an empty checkbox or
+ remove the current one[fn:50]. With a double prefix argument, set
+ it to =[-]=, which is considered to be an intermediate state.
- {{{kbd(C-c C-x C-b)}}} (~org-toggle-checkbox~) ::
- #+kindex: C-c C-x C-b
- Toggle checkbox status or---with prefix argument---checkbox
- presence at point. With double prefix argument, set it to =[-]=,
- which is considered to be an intermediate state.
+ #+kindex: C-c C-x C-b
+ Toggle checkbox status or---with prefix argument---checkbox presence
+ at point. With double prefix argument, set it to =[-]=, which is
+ considered to be an intermediate state.
- - If there is an active region, toggle the first checkbox in the
- region and set all remaining boxes to the same status as the
- first. With a prefix argument, add or remove the checkbox for
- all items in the region.
+ - If there is an active region, toggle the first checkbox in the
+ region and set all remaining boxes to the same status as the
+ first. With a prefix argument, add or remove the checkbox for all
+ items in the region.
- - If point is in a headline, toggle checkboxes in the region
- between this headline and the next---so /not/ the entire
- subtree.
+ - If point is in a headline, toggle checkboxes in the region between
+ this headline and the next---so /not/ the entire subtree.
- - If there is no active region, just toggle the checkbox at
- point.
+ - If there is no active region, just toggle the checkbox at point.
- {{{kbd(M-S-RET)}}} (~org-insert-todo-heading~) ::
- #+kindex: M-S-RET
- #+findex: org-insert-todo-heading
- Insert a new item with a checkbox. This works only if point
- is already in a plain list item (see [[*Plain Lists]]).
+ #+kindex: M-S-RET
+ #+findex: org-insert-todo-heading
+ Insert a new item with a checkbox. This works only if point is
+ already in a plain list item (see [[*Plain Lists]]).
- {{{kbd(C-c C-x o)}}} (~org-toggle-ordered-property~) ::
- #+kindex: C-c C-x o
- #+findex: org-toggle-ordered-property
- #+vindex: org-track-ordered-property-with-tag
- Toggle the =ORDERED= property of the entry, to toggle if
- checkboxes must be checked off in sequence. A property is used
- for this behavior because this should be local to the current
- entry, not inherited like a tag. However, if you would like to
- /track/ the value of this property with a tag for better
- visibility, customize ~org-track-ordered-property-with-tag~.
+ #+kindex: C-c C-x o
+ #+findex: org-toggle-ordered-property
+ #+vindex: org-track-ordered-property-with-tag
+ Toggle the =ORDERED= property of the entry, to toggle if checkboxes
+ must be checked off in sequence. A property is used for this
+ behavior because this should be local to the current entry, not
+ inherited like a tag. However, if you would like to /track/ the
+ value of this property with a tag for better visibility, customize
+ ~org-track-ordered-property-with-tag~.
- {{{kbd(C-c #)}}} (~org-update-statistics-cookies~) ::
- #+kindex: C-c #
- #+findex: org-update-statistics-cookies
- Update the statistics cookie in the current outline entry. When
- called with a {{{kbd(C-u)}}} prefix, update the entire file.
- Checkbox statistic cookies are updated automatically if you
- toggle checkboxes with {{{kbd(C-c C-c)}}} and make new ones with
- {{{kbd(M-S-RET)}}}. TODO statistics cookies update when changing
- TODO states. If you delete boxes/entries or add/change them by
- hand, use this command to get things back into sync.
+ #+kindex: C-c #
+ #+findex: org-update-statistics-cookies
+ Update the statistics cookie in the current outline entry. When
+ called with a {{{kbd(C-u)}}} prefix, update the entire file.
+ Checkbox statistic cookies are updated automatically if you toggle
+ checkboxes with {{{kbd(C-c C-c)}}} and make new ones with
+ {{{kbd(M-S-RET)}}}. TODO statistics cookies update when changing
+ TODO states. If you delete boxes/entries or add/change them by
+ hand, use this command to get things back into sync.
* Tags
:PROPERTIES:
@@ -4570,7 +4581,7 @@ the final heading has the tags =work=, =boss=, =notes=, and =action=
even though the final heading is not explicitly marked with those
tags. You can also set tags that all entries in a file should inherit
just as if these tags were defined in a hypothetical level zero that
-surrounds the entire file. Use a line like this[fn:53]
+surrounds the entire file. Use a line like this[fn:51]
#+cindex: @samp{FILETAGS}, keyword
: #+FILETAGS: :Peter:Boss:Secret:
@@ -4584,7 +4595,7 @@ use the variables ~org-use-tag-inheritance~ and
#+vindex: org-tags-match-list-sublevels
When a headline matches during a tags search while tag inheritance is
turned on, all the sublevels in the same tree---for a simple match
-form---match as well[fn:54]. The list of matches may then become
+form---match as well[fn:52]. The list of matches may then become
very long. If you only want to see the first tags match in a subtree,
configure the variable ~org-tags-match-list-sublevels~ (not
recommended).
@@ -4613,31 +4624,31 @@ also a special command for inserting tags:
- {{{kbd(C-c C-q)}}} (~org-set-tags-command~) ::
- #+kindex: C-c C-q
- #+findex: org-set-tags-command
- #+cindex: completion, of tags
- #+vindex: org-tags-column
- Enter new tags for the current headline. Org mode either offers
- completion or a special single-key interface for setting tags,
- see below. After pressing {{{kbd(RET)}}}, the tags are inserted
- and aligned to ~org-tags-column~. When called with
- a {{{kbd(C-u)}}} prefix, all tags in the current buffer are
- aligned to that column, just to make things look nice. Tags are
- automatically realigned after promotion, demotion, and TODO state
- changes (see [[*Basic TODO Functionality]]).
+ #+kindex: C-c C-q
+ #+findex: org-set-tags-command
+ #+cindex: completion, of tags
+ #+vindex: org-tags-column
+ Enter new tags for the current headline. Org mode either offers
+ completion or a special single-key interface for setting tags, see
+ below. After pressing {{{kbd(RET)}}}, the tags are inserted and
+ aligned to ~org-tags-column~. When called with a {{{kbd(C-u)}}}
+ prefix, all tags in the current buffer are aligned to that column,
+ just to make things look nice. Tags are automatically realigned
+ after promotion, demotion, and TODO state changes (see [[*Basic TODO
+ Functionality]]).
- {{{kbd(C-c C-c)}}} (~org-set-tags-command~) ::
- #+kindex: C-c C-c
- When point is in a headline, this does the same as {{{kbd(C-c
- C-q)}}}.
+ #+kindex: C-c C-c
+ When point is in a headline, this does the same as {{{kbd(C-c
+ C-q)}}}.
#+vindex: org-complete-tags-always-offer-all-agenda-tags
#+vindex: org-tag-alist
#+cindex: @samp{TAGS}, keyword
Org supports tag insertion based on a /list of tags/. By default this
list is constructed dynamically, containing all tags currently used in
-the buffer[fn:55]. You may also globally specify a hard list of tags
+the buffer[fn:53]. You may also globally specify a hard list of tags
with the variable ~org-tag-alist~. Finally you can set the default
tags for a given file using the =TAGS= keyword, like
@@ -4723,7 +4734,7 @@ by the following configuration:
If at least one tag has a selection key then pressing {{{kbd(C-c
C-c)}}} automatically presents you with a special interface, listing
inherited tags, the tags of the current headline, and a list of all
-valid tags with corresponding keys[fn:56].
+valid tags with corresponding keys[fn:54].
Pressing keys assigned to tags adds or removes them from the list of
tags in the current line. Selecting a tag in a group of mutually
@@ -4733,45 +4744,45 @@ In this interface, you can also use the following special keys:
- {{{kbd(TAB)}}} ::
- #+kindex: TAB
- Enter a tag in the minibuffer, even if the tag is not in the
- predefined list. You can complete on all tags present in the
- buffer. You can also add several tags: just separate them with
- a comma.
+ #+kindex: TAB
+ Enter a tag in the minibuffer, even if the tag is not in the
+ predefined list. You can complete on all tags present in the
+ buffer. You can also add several tags: just separate them with
+ a comma.
- {{{kbd(SPC)}}} ::
- #+kindex: SPC
- Clear all tags for this line.
+ #+kindex: SPC
+ Clear all tags for this line.
- {{{kbd(RET)}}} ::
- #+kindex: RET
- Accept the modified set.
+ #+kindex: RET
+ Accept the modified set.
- {{{kbd(C-g)}}} ::
- #+kindex: C-g
- Abort without installing changes.
+ #+kindex: C-g
+ Abort without installing changes.
- {{{kbd(q)}}} ::
- #+kindex: q
- If {{{kbd(q)}}} is not assigned to a tag, it aborts like
- {{{kbd(C-g)}}}.
+ #+kindex: q
+ If {{{kbd(q)}}} is not assigned to a tag, it aborts like
+ {{{kbd(C-g)}}}.
- {{{kbd(!)}}} ::
- #+kindex: !
- Turn off groups of mutually exclusive tags. Use this to (as an
- exception) assign several tags from such a group.
+ #+kindex: !
+ Turn off groups of mutually exclusive tags. Use this to (as an
+ exception) assign several tags from such a group.
- {{{kbd(C-c)}}} ::
- #+kindex: C-c C-c
- Toggle auto-exit after the next change (see below). If you are
- using expert mode, the first {{{kbd(C-c)}}} displays the
- selection window.
+ #+kindex: C-c C-c
+ Toggle auto-exit after the next change (see below). If you are
+ using expert mode, the first {{{kbd(C-c)}}} displays the selection
+ window.
This method lets you assign tags to a headline with very few keys.
With the above setup, you could clear the current tags and set
@@ -4908,27 +4919,27 @@ related information into special lists.
- {{{kbd(C-c / m)}}} or {{{kbd(C-c \)}}} (~org-match-sparse-tree~) ::
- #+kindex: C-c / m
- #+kindex: C-c \
- #+findex: org-match-sparse-tree
- Create a sparse tree with all headlines matching a tags search.
- With a {{{kbd(C-u)}}} prefix argument, ignore headlines that are
- not a TODO line.
+ #+kindex: C-c / m
+ #+kindex: C-c \
+ #+findex: org-match-sparse-tree
+ Create a sparse tree with all headlines matching a tags search.
+ With a {{{kbd(C-u)}}} prefix argument, ignore headlines that are not
+ a TODO line.
- {{{kbd(M-x org-agenda m)}}} (~org-tags-view~) ::
- #+kindex: m @r{(Agenda dispatcher)}
- #+findex: org-tags-view
- Create a global list of tag matches from all agenda files. See
- [[*Matching tags and properties]].
+ #+kindex: m @r{(Agenda dispatcher)}
+ #+findex: org-tags-view
+ Create a global list of tag matches from all agenda files. See
+ [[*Matching tags and properties]].
- {{{kbd(M-x org-agenda M)}}} (~org-tags-view~) ::
- #+kindex: M @r{(Agenda dispatcher)}
- #+vindex: org-tags-match-list-sublevels
- Create a global list of tag matches from all agenda files, but
- check only TODO items and force checking subitems (see the option
- ~org-tags-match-list-sublevels~).
+ #+kindex: M @r{(Agenda dispatcher)}
+ #+vindex: org-tags-match-list-sublevels
+ Create a global list of tag matches from all agenda files, but check
+ only TODO items and force checking subitems (see the option
+ ~org-tags-match-list-sublevels~).
These commands all prompt for a match string which allows basic
Boolean logic like =+boss+urgent-project1=, to find entries with tags
@@ -5059,63 +5070,62 @@ The following commands help to work with properties:
#+attr_texinfo: :sep ,
- {{{kbd(M-TAB)}}} (~pcomplete~) ::
- #+kindex: M-TAB
- #+findex: pcomplete
- After an initial colon in a line, complete property keys. All
- keys used in the current file are offered as possible
- completions.
+ #+kindex: M-TAB
+ #+findex: pcomplete
+ After an initial colon in a line, complete property keys. All keys
+ used in the current file are offered as possible completions.
- {{{kbd(C-c C-x p)}}} (~org-set-property~) ::
- #+kindex: C-c C-x p
- #+findex: org-set-property
- Set a property. This prompts for a property name and a value.
- If necessary, the property drawer is created as well.
+ #+kindex: C-c C-x p
+ #+findex: org-set-property
+ Set a property. This prompts for a property name and a value. If
+ necessary, the property drawer is created as well.
- {{{kbd(C-u M-x org-insert-drawer)}}} ::
- #+findex: org-insert-drawer
- Insert a property drawer into the current entry. The drawer is
- inserted early in the entry, but after the lines with planning
- information like deadlines.
+ #+findex: org-insert-drawer
+ Insert a property drawer into the current entry. The drawer is
+ inserted early in the entry, but after the lines with planning
+ information like deadlines.
- {{{kbd(C-c C-c)}}} (~org-property-action~) ::
- #+kindex: C-c C-c
- #+findex: org-property-action
- With point in a property drawer, this executes property commands.
+ #+kindex: C-c C-c
+ #+findex: org-property-action
+ With point in a property drawer, this executes property commands.
- {{{kbd(C-c C-c s)}}} (~org-set-property~) ::
- #+kindex: C-c C-c s
- #+findex: org-set-property
- Set a property in the current entry. Both the property and the value
- can be inserted using completion.
+ #+kindex: C-c C-c s
+ #+findex: org-set-property
+ Set a property in the current entry. Both the property and the
+ value can be inserted using completion.
- {{{kbd(S-RIGHT)}}} (~org-property-next-allowed-values~), {{{kbd(S-LEFT)}}} (~org-property-previous-allowed-value~) ::
- #+kindex: S-RIGHT
- #+kindex: S-LEFT
- Switch property at point to the next/previous allowed value.
+ #+kindex: S-RIGHT
+ #+kindex: S-LEFT
+ Switch property at point to the next/previous allowed value.
- {{{kbd(C-c C-c d)}}} (~org-delete-property~) ::
- #+kindex: C-c C-c d
- #+findex: org-delete-property
- Remove a property from the current entry.
+ #+kindex: C-c C-c d
+ #+findex: org-delete-property
+ Remove a property from the current entry.
- {{{kbd(C-c C-c D)}}} (~org-delete-property-globally~) ::
- #+kindex: C-c C-c D
- #+findex: org-delete-property-globally
- Globally remove a property, from all entries in the current file.
+ #+kindex: C-c C-c D
+ #+findex: org-delete-property-globally
+ Globally remove a property, from all entries in the current file.
- {{{kbd(C-c C-c c)}}} (~org-compute-property-at-point~) ::
- #+kindex: C-c C-c c
- #+findex: org-compute-property-at-point
- Compute the property at point, using the operator and scope from
- the nearest column format definition.
+ #+kindex: C-c C-c c
+ #+findex: org-compute-property-at-point
+ Compute the property at point, using the operator and scope from the
+ nearest column format definition.
** Special Properties
:PROPERTIES:
@@ -5176,27 +5186,26 @@ Searches]]).
- {{{kbd(C-c / m)}}} or {{{kbd(C-c \)}}} (~org-match-sparse-tree~) ::
- #+kindex: C-c / m
- #+kindex: C-c \
- #+findex: org-match-sparse-tree
- Create a sparse tree with all matching entries. With
- a {{{kbd(C-u)}}} prefix argument, ignore headlines that are not
- a TODO line.
+ #+kindex: C-c / m
+ #+kindex: C-c \
+ #+findex: org-match-sparse-tree
+ Create a sparse tree with all matching entries. With
+ a {{{kbd(C-u)}}} prefix argument, ignore headlines that are not
+ a TODO line.
- {{{kbd(M-x org-agenda m)}}}, ~org-tags-view~ ::
- #+kindex: m @r{(Agenda dispatcher)}
- #+findex: org-tags-view
- Create a global list of tag/property matches from all agenda
- files.
+ #+kindex: m @r{(Agenda dispatcher)}
+ #+findex: org-tags-view
+ Create a global list of tag/property matches from all agenda files.
- {{{kbd(M-x org-agenda M)}}} (~org-tags-view~) ::
- #+kindex: M @r{(Agenda dispatcher)}
- #+vindex: org-tags-match-list-sublevels
- Create a global list of tag matches from all agenda files, but
- check only TODO items and force checking of subitems (see the
- option ~org-tags-match-list-sublevels~).
+ #+kindex: M @r{(Agenda dispatcher)}
+ #+vindex: org-tags-match-list-sublevels
+ Create a global list of tag matches from all agenda files, but check
+ only TODO items and force checking of subitems (see the option
+ ~org-tags-match-list-sublevels~).
The syntax for the search string is described in [[*Matching tags and
properties]].
@@ -5206,13 +5215,13 @@ single property:
- {{{kbd(C-c / p)}}} ::
- #+kindex: C-c / p
- Create a sparse tree based on the value of a property. This
- first prompts for the name of a property, and then for a value.
- A sparse tree is created with all entries that define this
- property with the given value. If you enclose the value in curly
- braces, it is interpreted as a regular expression and matched
- against the property values.
+ #+kindex: C-c / p
+ Create a sparse tree based on the value of a property. This first
+ prompts for the name of a property, and then for a value. A sparse
+ tree is created with all entries that define this property with the
+ given value. If you enclose the value in curly braces, it is
+ interpreted as a regular expression and matched against the property
+ values.
** Property Inheritance
:PROPERTIES:
@@ -5240,31 +5249,31 @@ least for the special applications for which they are used:
- ~COLUMNS~ ::
- #+cindex: @samp{COLUMNS}, property
- The =COLUMNS= property defines the format of column view (see
- [[*Column View]]). It is inherited in the sense that the level where
- a =COLUMNS= property is defined is used as the starting point for
- a column view table, independently of the location in the subtree
- from where columns view is turned on.
+ #+cindex: @samp{COLUMNS}, property
+ The =COLUMNS= property defines the format of column view (see
+ [[*Column View]]). It is inherited in the sense that the level where
+ a =COLUMNS= property is defined is used as the starting point for
+ a column view table, independently of the location in the subtree
+ from where columns view is turned on.
- ~CATEGORY~ ::
- #+cindex: @samp{CATEGORY}, property
- For agenda view, a category set through a =CATEGORY= property
- applies to the entire subtree.
+ #+cindex: @samp{CATEGORY}, property
+ For agenda view, a category set through a =CATEGORY= property
+ applies to the entire subtree.
- ~ARCHIVE~ ::
- #+cindex: @samp{ARCHIVE}, property
- For archiving, the =ARCHIVE= property may define the archive
- location for the entire subtree (see [[*Moving a tree to an archive
- file]]).
+ #+cindex: @samp{ARCHIVE}, property
+ For archiving, the =ARCHIVE= property may define the archive
+ location for the entire subtree (see [[*Moving a tree to an archive
+ file]]).
- ~LOGGING~ ::
- #+cindex: @samp{LOGGING}, property
- The =LOGGING= property may define logging settings for an entry
- or a subtree (see [[*Tracking TODO state changes]]).
+ #+cindex: @samp{LOGGING}, property
+ The =LOGGING= property may define logging settings for an entry or
+ a subtree (see [[*Tracking TODO state changes]]).
** Column View
:PROPERTIES:
@@ -5339,48 +5348,48 @@ optional. The individual parts have the following meaning:
- {{{var(WIDTH)}}} ::
- An integer specifying the width of the column in characters. If
- omitted, the width is determined automatically.
+ An integer specifying the width of the column in characters. If
+ omitted, the width is determined automatically.
- {{{var(PROPERTY)}}} ::
- The property that should be edited in this column. Special
- properties representing meta data are allowed here as well (see
- [[*Special Properties]]).
+ The property that should be edited in this column. Special
+ properties representing meta data are allowed here as well (see
+ [[*Special Properties]]).
- {{{var(TITLE)}}} ::
- The header text for the column. If omitted, the property name is
- used.
+ The header text for the column. If omitted, the property name is
+ used.
- {{{var(SUMMARY-TYPE)}}} ::
- The summary type. If specified, the column values for parent
- nodes are computed from the children[fn:57].
-
- Supported summary types are:
-
- | =+= | Sum numbers in this column. |
- | =+;%.1f= | Like =+=, but format result with =%.1f=. |
- | =$= | Currency, short for =+;%.2f=. |
- | =min= | Smallest number in column. |
- | =max= | Largest number. |
- | =mean= | Arithmetic mean of numbers. |
- | =X= | Checkbox status, =[X]= if all children are =[X]=. |
- | =X/= | Checkbox status, =[n/m]=. |
- | =X%= | Checkbox status, =[n%]=. |
- | =:= | Sum times, HH:MM, plain numbers are hours. |
- | =:min= | Smallest time value in column. |
- | =:max= | Largest time value. |
- | =:mean= | Arithmetic mean of time values. |
- | =@min= | Minimum age[fn:58] (in days/hours/mins/seconds). |
- | =@max= | Maximum age (in days/hours/mins/seconds). |
- | =@mean= | Arithmetic mean of ages (in days/hours/mins/seconds). |
- | =est+= | Add low-high estimates. |
-
- #+vindex: org-columns-summary-types
- You can also define custom summary types by setting
- ~org-columns-summary-types~.
+ The summary type. If specified, the column values for parent nodes
+ are computed from the children[fn:55].
+
+ Supported summary types are:
+
+ | =+= | Sum numbers in this column. |
+ | =+;%.1f= | Like =+=, but format result with =%.1f=. |
+ | =$= | Currency, short for =+;%.2f=. |
+ | =min= | Smallest number in column. |
+ | =max= | Largest number. |
+ | =mean= | Arithmetic mean of numbers. |
+ | =X= | Checkbox status, =[X]= if all children are =[X]=. |
+ | =X/= | Checkbox status, =[n/m]=. |
+ | =X%= | Checkbox status, =[n%]=. |
+ | =:= | Sum times, HH:MM, plain numbers are minutes. |
+ | =:min= | Smallest time value in column. |
+ | =:max= | Largest time value. |
+ | =:mean= | Arithmetic mean of time values. |
+ | =@min= | Minimum age[fn:56] (in days/hours/mins/seconds). |
+ | =@max= | Maximum age (in days/hours/mins/seconds). |
+ | =@mean= | Arithmetic mean of ages (in days/hours/mins/seconds). |
+ | =est+= | Add low-high estimates. |
+
+ #+vindex: org-columns-summary-types
+ You can also define custom summary types by setting
+ ~org-columns-summary-types~.
The =est+= summary type requires further explanation. It is used for
combining estimates, expressed as low-high ranges. For example,
@@ -5401,7 +5410,7 @@ contrast, =est+= estimates the full job more realistically, at 10--15
days.
Here is an example for a complete columns definition, along with
-allowed values[fn:59].
+allowed values[fn:57].
#+begin_example
:COLUMNS: %25ITEM %9Approved(Approved?){X} %Owner %11Status \
@@ -5439,33 +5448,33 @@ either for all clocks or just for today.
- {{{kbd(C-c C-x C-c)}}} (~org-columns~) ::
- #+kindex: C-c C-x C-c
- #+vindex: org-columns
- #+vindex: org-columns-default-format
- Turn on column view. If point is before the first headline in
- the file, column view is turned on for the entire file, using the
- =#+COLUMNS= definition. If point is somewhere inside the
- outline, this command searches the hierarchy, up from point, for
- a =COLUMNS= property that defines a format. When one is found,
- the column view table is established for the tree starting at the
- entry that contains the =COLUMNS= property. If no such property
- is found, the format is taken from the =#+COLUMNS= line or from
- the variable ~org-columns-default-format~, and column view is
- established for the current entry and its subtree.
+ #+kindex: C-c C-x C-c
+ #+vindex: org-columns
+ #+vindex: org-columns-default-format
+ Turn on column view. If point is before the first headline in the
+ file, column view is turned on for the entire file, using the
+ =#+COLUMNS= definition. If point is somewhere inside the outline,
+ this command searches the hierarchy, up from point, for a =COLUMNS=
+ property that defines a format. When one is found, the column view
+ table is established for the tree starting at the entry that
+ contains the =COLUMNS= property. If no such property is found, the
+ format is taken from the =#+COLUMNS= line or from the variable
+ ~org-columns-default-format~, and column view is established for the
+ current entry and its subtree.
- {{{kbd(r)}}} or {{{kbd(g)}}} (~org-columns-redo~) ::
- #+kindex: r
- #+kindex: g
- #+findex: org-columns-redo
- Recreate the column view, to include recent changes made in the
- buffer.
+ #+kindex: r
+ #+kindex: g
+ #+findex: org-columns-redo
+ Recreate the column view, to include recent changes made in the
+ buffer.
- {{{kbd(q)}}} (~org-columns-quit~) ::
- #+kindex: q
- #+findex: org-columns-quit
- Exit column view.
+ #+kindex: q
+ #+findex: org-columns-quit
+ Exit column view.
**** Editing values
:PROPERTIES:
@@ -5475,55 +5484,55 @@ either for all clocks or just for today.
#+attr_texinfo: :sep and
- {{{kbd(LEFT)}}}, {{{kbd(RIGHT)}}}, {{{kbd(UP)}}}, {{{kbd(DOWN)}}} ::
- Move through the column view from field to field.
+ Move through the column view from field to field.
- {{{kbd(1..9\,0)}}} ::
- #+kindex: 1..9,0
- Directly select the Nth allowed value, {{{kbd(0)}}} selects the
- 10th value.
+ #+kindex: 1..9,0
+ Directly select the Nth allowed value, {{{kbd(0)}}} selects the
+ 10th value.
- {{{kbd(n)}}} or {{{kbd(S-RIGHT)}}} (~org-columns-next-allowed-value~) and {{{kbd(p)}}} or {{{kbd(S-LEFT)}}} (~org-columns-previous-allowed-value~) ::
- #+kindex: n
- #+kindex: S-RIGHT
- #+kindex: p
- #+kindex: S-LEFT
- #+findex: org-columns-next-allowed-value
- #+findex: org-columns-previous-allowed-value
- Switch to the next/previous allowed value of the field. For
- this, you have to have specified allowed values for a property.
+ #+kindex: n
+ #+kindex: S-RIGHT
+ #+kindex: p
+ #+kindex: S-LEFT
+ #+findex: org-columns-next-allowed-value
+ #+findex: org-columns-previous-allowed-value
+ Switch to the next/previous allowed value of the field. For this,
+ you have to have specified allowed values for a property.
- {{{kbd(e)}}} (~org-columns-edit-value~) ::
- #+kindex: e
- #+findex: org-columns-edit-value
- Edit the property at point. For the special properties, this
- invokes the same interface that you normally use to change that
- property. For example, the tag completion or fast selection
- interface pops up when editing a =TAGS= property.
+ #+kindex: e
+ #+findex: org-columns-edit-value
+ Edit the property at point. For the special properties, this
+ invokes the same interface that you normally use to change that
+ property. For example, the tag completion or fast selection
+ interface pops up when editing a =TAGS= property.
- {{{kbd(C-c C-c)}}} (~org-columns-set-tags-or-toggle~) ::
- #+kindex: C-c C-c
- #+findex: org-columns-set-tags-or-toggle
- When there is a checkbox at point, toggle it.
+ #+kindex: C-c C-c
+ #+findex: org-columns-set-tags-or-toggle
+ When there is a checkbox at point, toggle it.
- {{{kbd(v)}}} (~org-columns-show-value~) ::
- #+kindex: v
- #+findex: org-columns-show-value
- View the full value of this property. This is useful if the
- width of the column is smaller than that of the value.
+ #+kindex: v
+ #+findex: org-columns-show-value
+ View the full value of this property. This is useful if the width
+ of the column is smaller than that of the value.
- {{{kbd(a)}}} (~org-columns-edit-allowed~) ::
- #+kindex: a
- #+findex: org-columns-edit-allowed
- Edit the list of allowed values for this property. If the list
- is found in the hierarchy, the modified values is stored there.
- If no list is found, the new value is stored in the first entry
- that is part of the current column view.
+ #+kindex: a
+ #+findex: org-columns-edit-allowed
+ Edit the list of allowed values for this property. If the list is
+ found in the hierarchy, the modified values is stored there. If no
+ list is found, the new value is stored in the first entry that is
+ part of the current column view.
**** Modifying column view on-the-fly
:PROPERTIES:
@@ -5533,23 +5542,23 @@ either for all clocks or just for today.
#+attr_texinfo: :sep and
- {{{kbd(<)}}} (~org-columns-narrow~) and {{{kbd(>)}}} (~org-columns-widen~) ::
- #+kindex: <
- #+kindex: >
- #+findex: org-columns-narrow
- #+findex: org-columns-widen
- Make the column narrower/wider by one character.
+ #+kindex: <
+ #+kindex: >
+ #+findex: org-columns-narrow
+ #+findex: org-columns-widen
+ Make the column narrower/wider by one character.
- {{{kbd(S-M-RIGHT)}}} (~org-columns-new~) ::
- #+kindex: S-M-RIGHT
- #+findex: org-columns-new
- Insert a new column, to the left of the current column.
+ #+kindex: S-M-RIGHT
+ #+findex: org-columns-new
+ Insert a new column, to the left of the current column.
- {{{kbd(S-M-LEFT)}}} (~org-columns-delete~) ::
- #+kindex: S-M-LEFT
- #+findex: org-columns-delete
- Delete the current column.
+ #+kindex: S-M-LEFT
+ #+findex: org-columns-delete
+ Delete the current column.
*** Capturing column view
:PROPERTIES:
@@ -5573,81 +5582,86 @@ This dynamic block has the following parameters:
- =:id= ::
- This is the most important parameter. Column view is a feature
- that is often localized to a certain (sub)tree, and the capture
- block might be at a different location in the file. To identify
- the tree whose view to capture, you can use four values:
+ This is the most important parameter. Column view is a feature that
+ is often localized to a certain (sub)tree, and the capture block
+ might be at a different location in the file. To identify the tree
+ whose view to capture, you can use four values:
- - =local= ::
+ - =local= ::
- Use the tree in which the capture block is located.
+ Use the tree in which the capture block is located.
- - =global= ::
+ - =global= ::
- Make a global view, including all headings in the file.
+ Make a global view, including all headings in the file.
- - =file:FILENAME= ::
+ - =file:FILENAME= ::
- Run column view at the top of the {{{var(FILENAME)}}} file.
+ Run column view at the top of the {{{var(FILENAME)}}} file.
- - =LABEL= ::
+ - =LABEL= ::
- #+cindex: @samp{ID}, property
- Call column view in the tree that has an =ID= property with
- the value {{{var(LABEL)}}}. You can use {{{kbd(M-x
- org-id-copy)}}} to create a globally unique ID for the
- current entry and copy it to the kill-ring.
+ #+cindex: @samp{ID}, property
+ Call column view in the tree that has an =ID= property with the
+ value {{{var(LABEL)}}}. You can use {{{kbd(M-x org-id-copy)}}} to
+ create a globally unique ID for the current entry and copy it to
+ the kill-ring.
- =:hlines= ::
- When ~t~, insert an hline after every line. When a number N,
- insert an hline before each headline with level ~<= N~.
+ When ~t~, insert an hline after every line. When a number N, insert
+ an hline before each headline with level ~<= N~.
- =:vlines= ::
- When non-~nil~, force column groups to get vertical lines.
+ When non-~nil~, force column groups to get vertical lines.
- =:maxlevel= ::
- When set to a number, do not capture entries below this level.
+ When set to a number, do not capture entries below this level.
- =:skip-empty-rows= ::
- When non-~nil~, skip rows where the only non-empty specifier of
- the column view is =ITEM=.
+ When non-~nil~, skip rows where the only non-empty specifier of
+ the column view is =ITEM=.
+
+- =:exclude-tags= ::
+
+ List of tags to exclude from column view table: entries with these
+ tags will be excluded from the column view.
- =:indent= ::
- When non-~nil~, indent each =ITEM= field according to its level.
+ When non-~nil~, indent each =ITEM= field according to its level.
- =:format= ::
- Specify a column attribute (see [[*Column attributes]]) for the
- dynamic block.
+ Specify a column attribute (see [[*Column attributes]]) for the dynamic
+ block.
The following commands insert or update the dynamic block:
- {{{kbd(C-c C-x i)}}} (~org-insert-columns-dblock~) ::
- #+kindex: C-c C-x i
- #+findex: org-insert-columns-dblock
- Insert a dynamic block capturing a column view. Prompt for the
- scope or ID of the view.
+ #+kindex: C-c C-x i
+ #+findex: org-insert-columns-dblock
+ Insert a dynamic block capturing a column view. Prompt for the
+ scope or ID of the view.
- {{{kbd(C-c C-c)}}} {{{kbd(C-c C-x C-u)}}} (~org-dblock-update~) ::
- #+kindex: C-c C-c
- #+kindex: C-c C-x C-u
- #+findex: org-dblock-update
- Update dynamic block at point. point needs to be in the
- =#+BEGIN= line of the dynamic block.
+ #+kindex: C-c C-c
+ #+kindex: C-c C-x C-u
+ #+findex: org-dblock-update
+ Update dynamic block at point. point needs to be in the =#+BEGIN=
+ line of the dynamic block.
- {{{kbd(C-u C-c C-x C-u)}}} (~org-update-all-dblocks~) ::
- #+kindex: C-u C-c C-x C-u
- Update all dynamic blocks (see [[*Dynamic Blocks]]). This is useful
- if you have several clock table blocks, column-capturing blocks
- or other dynamic blocks in a buffer.
+ #+kindex: C-u C-c C-x C-u
+ Update all dynamic blocks (see [[*Dynamic Blocks]]). This is useful if
+ you have several clock table blocks, column-capturing blocks or
+ other dynamic blocks in a buffer.
You can add formulas to the column view table and you may add plotting
instructions in front of the table---these survive an update of the
@@ -5656,7 +5670,7 @@ recalculated automatically after an update.
An alternative way to capture and process property values into a table
is provided by Eric Schulte's =org-collector.el=, which is
-a contributed package[fn:60]. It provides a general API to collect
+a contributed package[fn:58]. It provides a general API to collect
properties from entries in a certain scope, and arbitrary Lisp
expressions to process these values before inserting them into a table
or a dynamic block.
@@ -5677,10 +5691,9 @@ a little confusing because timestamp is often used as indicating when
something was created or last changed. However, in Org mode this term
is used in a much wider sense.
-** Timestamps, Deadlines and Scheduling
+** Timestamps
:PROPERTIES:
:DESCRIPTION: Assigning a time to a tree entry.
-:ALT_TITLE: Timestamps
:END:
#+cindex: timestamps
#+cindex: ranges, time
@@ -5690,78 +5703,78 @@ is used in a much wider sense.
A timestamp is a specification of a date (possibly with a time or
a range of times) in a special format, either =<2003-09-16 Tue>= or
-=<2003-09-16 Tue 09:39>= or =<2003-09-16 Tue 12:00-12:30>=[fn:61].
+=<2003-09-16 Tue 09:39>= or =<2003-09-16 Tue 12:00-12:30>=[fn:59].
A timestamp can appear anywhere in the headline or body of an Org tree
entry. Its presence causes entries to be shown on specific dates in
the agenda (see [[*Weekly/daily agenda]]). We distinguish:
- Plain timestamp; Event; Appointment ::
- #+cindex: timestamp
- #+cindex: appointment
- A simple timestamp just assigns a date/time to an item. This is
- just like writing down an appointment or event in a paper agenda.
- In the agenda display, the headline of an entry associated with
- a plain timestamp is shown exactly on that date.
+ #+cindex: timestamp
+ #+cindex: appointment
+ A simple timestamp just assigns a date/time to an item. This is
+ just like writing down an appointment or event in a paper agenda.
+ In the agenda display, the headline of an entry associated with
+ a plain timestamp is shown exactly on that date.
- #+begin_example
- ,* Meet Peter at the movies
- <2006-11-01 Wed 19:15>
- ,* Discussion on climate change
- <2006-11-02 Thu 20:00-22:00>
- #+end_example
+ #+begin_example
+ ,* Meet Peter at the movies
+ <2006-11-01 Wed 19:15>
+ ,* Discussion on climate change
+ <2006-11-02 Thu 20:00-22:00>
+ #+end_example
- Timestamp with repeater interval ::
- #+cindex: timestamp, with repeater interval
- A timestamp may contain a /repeater interval/, indicating that it
- applies not only on the given date, but again and again after
- a certain interval of N days (d), weeks (w), months (m), or years
- (y). The following shows up in the agenda every Wednesday:
+ #+cindex: timestamp, with repeater interval
+ A timestamp may contain a /repeater interval/, indicating that it
+ applies not only on the given date, but again and again after
+ a certain interval of N days (d), weeks (w), months (m), or years
+ (y). The following shows up in the agenda every Wednesday:
- #+begin_example
- ,* Pick up Sam at school
- <2007-05-16 Wed 12:30 +1w>
- #+end_example
+ #+begin_example
+ ,* Pick up Sam at school
+ <2007-05-16 Wed 12:30 +1w>
+ #+end_example
-- Diary-style sexp entries ::
+- Diary-style expression entries ::
- #+cindex: diary style timestamps
- #+cindex: sexp timestamps
- For more complex date specifications, Org mode supports using the
- special sexp diary entries implemented in the Emacs
- calendar/diary package[fn:62]. For example, with optional time:
+ #+cindex: diary style timestamps
+ #+cindex: sexp timestamps
+ For more complex date specifications, Org mode supports using the
+ special expression diary entries implemented in the Emacs Calendar
+ package[fn:60]. For example, with optional time:
- #+begin_example
- ,* 22:00-23:00 The nerd meeting on every 2nd Thursday of the month
- <%%(diary-float t 4 2)>
- #+end_example
+ #+begin_example
+ ,* 22:00-23:00 The nerd meeting on every 2nd Thursday of the month
+ <%%(diary-float t 4 2)>
+ #+end_example
- Time/Date range ::
- #+cindex: timerange
- #+cindex: date range
- Two timestamps connected by =--= denote a range. The headline is
- shown on the first and last day of the range, and on any dates
- that are displayed and fall in the range. Here is an example:
+ #+cindex: timerange
+ #+cindex: date range
+ Two timestamps connected by =--= denote a range. The headline is
+ shown on the first and last day of the range, and on any dates that
+ are displayed and fall in the range. Here is an example:
- #+begin_example
- ,** Meeting in Amsterdam
- <2004-08-23 Mon>--<2004-08-26 Thu>
- #+end_example
+ #+begin_example
+ ,** Meeting in Amsterdam
+ <2004-08-23 Mon>--<2004-08-26 Thu>
+ #+end_example
- Inactive timestamp ::
- #+cindex: timestamp, inactive
- #+cindex: inactive timestamp
- Just like a plain timestamp, but with square brackets instead of
- angular ones. These timestamps are inactive in the sense that
- they do /not/ trigger an entry to show up in the agenda.
+ #+cindex: timestamp, inactive
+ #+cindex: inactive timestamp
+ Just like a plain timestamp, but with square brackets instead of
+ angular ones. These timestamps are inactive in the sense that they
+ do /not/ trigger an entry to show up in the agenda.
- #+begin_example
- ,* Gillian comes late for the fifth time
- [2006-11-01 Wed]
- #+end_example
+ #+begin_example
+ ,* Gillian comes late for the fifth time
+ [2006-11-01 Wed]
+ #+end_example
** Creating Timestamps
:PROPERTIES:
@@ -5775,93 +5788,92 @@ format.
#+attr_texinfo: :sep ,
- {{{kbd(C-c .)}}} (~org-time-stamp~) ::
- #+kindex: C-c .
- #+findex: org-time-stamp
- Prompt for a date and insert a corresponding timestamp. When
- point is at an existing timestamp in the buffer, the command is
- used to modify this timestamp instead of inserting a new one.
- When this command is used twice in succession, a time range is
- inserted.
-
- #+kindex: C-u C-c .
- #+vindex: org-time-stamp-rounding-minutes
- When called with a prefix argument, use the alternative format
- which contains date and time. The default time can be rounded to
- multiples of 5 minutes. See the option
- ~org-time-stamp-rounding-minutes~.
-
- #+kindex: C-u C-u C-c .
- With two prefix arguments, insert an active timestamp with the
- current time without prompting.
+ #+kindex: C-c .
+ #+findex: org-time-stamp
+ Prompt for a date and insert a corresponding timestamp. When point
+ is at an existing timestamp in the buffer, the command is used to
+ modify this timestamp instead of inserting a new one. When this
+ command is used twice in succession, a time range is inserted.
+
+ #+kindex: C-u C-c .
+ #+vindex: org-time-stamp-rounding-minutes
+ When called with a prefix argument, use the alternative format which
+ contains date and time. The default time can be rounded to
+ multiples of 5 minutes. See the option
+ ~org-time-stamp-rounding-minutes~.
+
+ #+kindex: C-u C-u C-c .
+ With two prefix arguments, insert an active timestamp with the
+ current time without prompting.
- {{{kbd(C-c !)}}} (~org-time-stamp-inactive~) ::
- #+kindex: C-c !
- #+kindex: C-u C-c !
- #+kindex: C-u C-u C-c !
- #+findex: org-time-stamp-inactive
- Like {{{kbd(C-c .)}}}, but insert an inactive timestamp that does
- not cause an agenda entry.
+ #+kindex: C-c !
+ #+kindex: C-u C-c !
+ #+kindex: C-u C-u C-c !
+ #+findex: org-time-stamp-inactive
+ Like {{{kbd(C-c .)}}}, but insert an inactive timestamp that does
+ not cause an agenda entry.
- {{{kbd(C-c C-c)}}} ::
- #+kindex: C-c C-c
- Normalize timestamp, insert or fix day name if missing or wrong.
+ #+kindex: C-c C-c
+ Normalize timestamp, insert or fix day name if missing or wrong.
- {{{kbd(C-c <)}}} (~org-date-from-calendar~) ::
- #+kindex: C-c <
- #+findex: org-date-from-calendar
- Insert a timestamp corresponding to point date in the calendar.
+ #+kindex: C-c <
+ #+findex: org-date-from-calendar
+ Insert a timestamp corresponding to point date in the calendar.
- {{{kbd(C-c >)}}} (~org-goto-calendar~) ::
- #+kindex: C-c >
- #+findex: org-goto-calendar
- Access the Emacs calendar for the current date. If there is
- a timestamp in the current line, go to the corresponding date
- instead.
+ #+kindex: C-c >
+ #+findex: org-goto-calendar
+ Access the Emacs calendar for the current date. If there is
+ a timestamp in the current line, go to the corresponding date
+ instead.
- {{{kbd(C-c C-o)}}} (~org-open-at-point~) ::
- #+kindex: C-c C-o
- #+findex: org-open-at-point
- Access the agenda for the date given by the timestamp or -range
- at point (see [[*Weekly/daily agenda]]).
+ #+kindex: C-c C-o
+ #+findex: org-open-at-point
+ Access the agenda for the date given by the timestamp or -range at
+ point (see [[*Weekly/daily agenda]]).
- {{{kbd(S-LEFT)}}} (~org-timestamp-down-day~), {{{kbd(S-RIGHT)}}} (~org-timestamp-up-day~) ::
- #+kindex: S-LEFT
- #+kindex: S-RIGHT
- #+findex: org-timestamp-down-day
- #+findex: org-timestamp-up-day
- Change date at point by one day. These key bindings conflict
- with shift-selection and related modes (see [[*Packages that
- conflict with Org mode]]).
+ #+kindex: S-LEFT
+ #+kindex: S-RIGHT
+ #+findex: org-timestamp-down-day
+ #+findex: org-timestamp-up-day
+ Change date at point by one day. These key bindings conflict with
+ shift-selection and related modes (see [[*Packages that conflict with
+ Org mode]]).
- {{{kbd(S-UP)}}} (~org-timestamp-up~), {{{kbd(S-DOWN)}}} (~org-timestamp-down~) ::
- #+kindex: S-UP
- #+kindex: S-DOWN
- On the beginning or enclosing bracket of a timestamp, change its
- type. Within a timestamp, change the item under point. Point
- can be on a year, month, day, hour or minute. When the timestamp
- contains a time range like =15:30-16:30=, modifying the first
- time also shifts the second, shifting the time block with
- constant length. To change the length, modify the second time.
- Note that if point is in a headline and not at a timestamp, these
- same keys modify the priority of an item (see [[*Priorities]]). The
- key bindings also conflict with shift-selection and related modes
- (see [[*Packages that conflict with Org mode]]).
+ #+kindex: S-UP
+ #+kindex: S-DOWN
+ On the beginning or enclosing bracket of a timestamp, change its
+ type. Within a timestamp, change the item under point. Point can
+ be on a year, month, day, hour or minute. When the timestamp
+ contains a time range like =15:30-16:30=, modifying the first time
+ also shifts the second, shifting the time block with constant
+ length. To change the length, modify the second time. Note that if
+ point is in a headline and not at a timestamp, these same keys
+ modify the priority of an item (see [[*Priorities]]). The key bindings
+ also conflict with shift-selection and related modes (see [[*Packages
+ that conflict with Org mode]]).
- {{{kbd(C-c C-y)}}} (~org-evaluate-time-range~) ::
- #+kindex: C-c C-y
- #+findex: org-evaluate-time-range
- #+cindex: evaluate time range
- Evaluate a time range by computing the difference between start
- and end. With a prefix argument, insert result after the time
- range (in a table: into the following column).
+ #+kindex: C-c C-y
+ #+findex: org-evaluate-time-range
+ #+cindex: evaluate time range
+ Evaluate a time range by computing the difference between start and
+ end. With a prefix argument, insert result after the time range (in
+ a table: into the following column).
*** The date/time prompt
:PROPERTIES:
@@ -5883,7 +5895,7 @@ a range, it is taken from the stamp in the buffer. When filling in
information, Org mode assumes that most of the time you want to enter
a date in the future: if you omit the month/year and the given
day/month is /before/ today, it assumes that you mean a future
-date[fn:63]. If the date has been automatically shifted into the
+date[fn:61]. If the date has been automatically shifted into the
future, the time prompt shows this with =(=>F)=.
For example, let's assume that today is *June 13, 2006*. Here is how
@@ -5945,7 +5957,7 @@ separator in the latter case, e.g.:
#+cindex: calendar, for selecting date
#+vindex: org-popup-calendar-for-date-prompt
-Parallel to the minibuffer prompt, a calendar is popped up[fn:64].
+Parallel to the minibuffer prompt, a calendar is popped up[fn:62].
When you exit the date prompt, either by clicking on a date in the
calendar, or by pressing {{{kbd(RET)}}}, the date selected in the
calendar is combined with the information entered at the prompt. You
@@ -5982,7 +5994,7 @@ The actions of the date/time prompt may seem complex, but I assure you
they will grow on you, and you will start getting annoyed by pretty
much any other way of entering a date/time out there. To help you
understand what is going on, the current interpretation of your input
-is displayed live in the minibuffer[fn:65].
+is displayed live in the minibuffer[fn:63].
*** Custom time format
:PROPERTIES:
@@ -6002,9 +6014,9 @@ it by customizing the variables ~org-display-custom-times~ and
- {{{kbd(C-c C-x C-t)}}} (~org-toggle-time-stamp-overlays~) ::
- #+kindex: C-c C-x C-t
- #+findex: org-toggle-time-stamp-overlays
- Toggle the display of custom formats for dates and times.
+ #+kindex: C-c C-x C-t
+ #+findex: org-toggle-time-stamp-overlays
+ Toggle the display of custom formats for dates and times.
Org mode needs the default format for scanning, so the custom
date/time format does not /replace/ the default format. Instead, it
@@ -6043,82 +6055,81 @@ immediately after the task they refer to.
- =DEADLINE= ::
- #+cindex: @samp{DEADLINE} marker
- Meaning: the task (most likely a TODO item, though not
- necessarily) is supposed to be finished on that date.
-
- #+vindex: org-deadline-warning-days
- On the deadline date, the task is listed in the agenda. In
- addition, the agenda for /today/ carries a warning about the
- approaching or missed deadline, starting
- ~org-deadline-warning-days~ before the due date, and continuing
- until the entry is marked DONE. An example:
-
- #+begin_example
- ,*** TODO write article about the Earth for the Guide
- DEADLINE: <2004-02-29 Sun>
- The editor in charge is [[bbdb:Ford Prefect]]
- #+end_example
-
- #+vindex: org-agenda-skip-deadline-prewarning-if-scheduled
- You can specify a different lead time for warnings for a specific
- deadlines using the following syntax. Here is an example with
- a warning period of 5 days =DEADLINE: <2004-02-29 Sun -5d>=.
- This warning is deactivated if the task gets scheduled and you
- set ~org-agenda-skip-deadline-prewarning-if-scheduled~ to ~t~.
+ #+cindex: @samp{DEADLINE} marker
+ Meaning: the task---most likely a TODO item, though not
+ necessarily---is supposed to be finished on that date.
+
+ #+vindex: org-deadline-warning-days
+ On the deadline date, the task is listed in the agenda. In
+ addition, the agenda for /today/ carries a warning about the
+ approaching or missed deadline, starting ~org-deadline-warning-days~
+ before the due date, and continuing until the entry is marked as
+ done. An example:
+
+ #+begin_example
+ ,*** TODO write article about the Earth for the Guide
+ DEADLINE: <2004-02-29 Sun>
+ The editor in charge is [[bbdb:Ford Prefect]]
+ #+end_example
+
+ #+vindex: org-agenda-skip-deadline-prewarning-if-scheduled
+ You can specify a different lead time for warnings for a specific
+ deadlines using the following syntax. Here is an example with
+ a warning period of 5 days =DEADLINE: <2004-02-29 Sun -5d>=. This
+ warning is deactivated if the task gets scheduled and you set
+ ~org-agenda-skip-deadline-prewarning-if-scheduled~ to ~t~.
- =SCHEDULED= ::
- #+cindex: @samp{SCHEDULED} marker
- Meaning: you are planning to start working on that task on the
- given date.
-
- #+vindex: org-agenda-skip-scheduled-if-done
- The headline is listed under the given date[fn:66]. In addition,
- a reminder that the scheduled date has passed is present in the
- compilation for /today/, until the entry is marked DONE, i.e.,
- the task is automatically forwarded until completed.
-
- #+begin_example
- ,*** TODO Call Trillian for a date on New Years Eve.
- SCHEDULED: <2004-12-25 Sat>
- #+end_example
-
- #+vindex: org-scheduled-delay-days
- #+vindex: org-agenda-skip-scheduled-delay-if-deadline
- If you want to /delay/ the display of this task in the agenda,
- use =SCHEDULED: <2004-12-25 Sat -2d>=: the task is still
- scheduled on the 25th but will appear two days later. In case
- the task contains a repeater, the delay is considered to affect
- all occurrences; if you want the delay to only affect the first
- scheduled occurrence of the task, use =--2d= instead. See
- ~org-scheduled-delay-days~ and
- ~org-agenda-skip-scheduled-delay-if-deadline~ for details on how
- to control this globally or per agenda.
-
- #+attr_texinfo: :tag Important
- #+begin_quote
- Scheduling an item in Org mode should /not/ be understood in the
- same way that we understand /scheduling a meeting/. Setting
- a date for a meeting is just a simple appointment, you should
- mark this entry with a simple plain timestamp, to get this item
- shown on the date where it applies. This is a frequent
- misunderstanding by Org users. In Org mode, /scheduling/ means
- setting a date when you want to start working on an action item.
- #+end_quote
+ #+cindex: @samp{SCHEDULED} marker
+ Meaning: you are planning to start working on that task on the given
+ date.
+
+ #+vindex: org-agenda-skip-scheduled-if-done
+ The headline is listed under the given date[fn:64]. In addition,
+ a reminder that the scheduled date has passed is present in the
+ compilation for /today/, until the entry is marked as done, i.e.,
+ the task is automatically forwarded until completed.
+
+ #+begin_example
+ ,*** TODO Call Trillian for a date on New Years Eve.
+ SCHEDULED: <2004-12-25 Sat>
+ #+end_example
+
+ #+vindex: org-scheduled-delay-days
+ #+vindex: org-agenda-skip-scheduled-delay-if-deadline
+ If you want to /delay/ the display of this task in the agenda, use
+ =SCHEDULED: <2004-12-25 Sat -2d>=: the task is still scheduled on
+ the 25th but will appear two days later. In case the task contains
+ a repeater, the delay is considered to affect all occurrences; if
+ you want the delay to only affect the first scheduled occurrence of
+ the task, use =--2d= instead. See ~org-scheduled-delay-days~ and
+ ~org-agenda-skip-scheduled-delay-if-deadline~ for details on how to
+ control this globally or per agenda.
+
+ #+attr_texinfo: :tag Important
+ #+begin_quote
+ Scheduling an item in Org mode should /not/ be understood in the
+ same way that we understand /scheduling a meeting/. Setting a date
+ for a meeting is just a simple appointment, you should mark this
+ entry with a simple plain timestamp, to get this item shown on the
+ date where it applies. This is a frequent misunderstanding by Org
+ users. In Org mode, /scheduling/ means setting a date when you want
+ to start working on an action item.
+ #+end_quote
You may use timestamps with repeaters in scheduling and deadline
entries. Org mode issues early and late warnings based on the
assumption that the timestamp represents the /nearest instance/ of the
-repeater. However, the use of diary S-exp entries like
+repeater. However, the use of diary expression entries like
: <%%(diary-float t 42)>
#+texinfo: @noindent
in scheduling and deadline timestamps is limited. Org mode does not
-know enough about the internals of each S-exp function to issue early
-and late warnings. However, it shows the item on each day where the
-S-exp entry matches.
+know enough about the internals of each function to issue early and
+late warnings. However, it shows the item on each day where the
+expression entry matches.
*** Inserting deadlines or schedules
:PROPERTIES:
@@ -6127,56 +6138,55 @@ S-exp entry matches.
:END:
The following commands allow you to quickly insert a deadline or to
-schedule an item:[fn:67]
+schedule an item:[fn:65]
- {{{kbd(C-c C-d)}}} (~org-deadline~) ::
- #+kindex: C-c C-d
- #+findex: org-deadline
- #+vindex: org-log-redeadline
- Insert =DEADLINE= keyword along with a stamp. The insertion
- happens in the line directly following the headline. Remove any
- =CLOSED= timestamp . When called with a prefix argument, also
- remove any existing deadline from the entry. Depending on the
- variable ~org-log-redeadline~, take a note when changing an
- existing deadline[fn:68].
+ #+kindex: C-c C-d
+ #+findex: org-deadline
+ #+vindex: org-log-redeadline
+ Insert =DEADLINE= keyword along with a stamp. The insertion happens
+ in the line directly following the headline. Remove any =CLOSED=
+ timestamp . When called with a prefix argument, also remove any
+ existing deadline from the entry. Depending on the variable
+ ~org-log-redeadline~, take a note when changing an existing
+ deadline[fn:66].
- {{{kbd(C-c C-s)}}} (~org-schedule~) ::
- #+kindex: C-c C-s
- #+findex: org-schedule
- #+vindex: org-log-reschedule
- Insert =SCHEDULED= keyword along with a stamp. The insertion
- happens in the line directly following the headline. Remove any
- =CLOSED= timestamp. When called with a prefix argument, also
- remove the scheduling date from the entry. Depending on the
- variable ~org-log-reschedule~, take a note when changing an
- existing scheduling time[fn:69].
+ #+kindex: C-c C-s
+ #+findex: org-schedule
+ #+vindex: org-log-reschedule
+ Insert =SCHEDULED= keyword along with a stamp. The insertion
+ happens in the line directly following the headline. Remove any
+ =CLOSED= timestamp. When called with a prefix argument, also remove
+ the scheduling date from the entry. Depending on the variable
+ ~org-log-reschedule~, take a note when changing an existing
+ scheduling time[fn:67].
- {{{kbd(C-c / d)}}} (~org-check-deadlines~) ::
- #+kindex: C-c / d
- #+findex: org-check-deadlines
- #+cindex: sparse tree, for deadlines
- #+vindex: org-deadline-warning-days
- Create a sparse tree with all deadlines that are either past-due,
- or which will become due within ~org-deadline-warning-days~.
- With {{{kbd(C-u)}}} prefix, show all deadlines in the file. With
- a numeric prefix, check that many days. For example, {{{kbd(C-1
- C-c / d)}}} shows all deadlines due tomorrow.
+ #+kindex: C-c / d
+ #+findex: org-check-deadlines
+ #+cindex: sparse tree, for deadlines
+ #+vindex: org-deadline-warning-days
+ Create a sparse tree with all deadlines that are either past-due, or
+ which will become due within ~org-deadline-warning-days~. With
+ {{{kbd(C-u)}}} prefix, show all deadlines in the file. With
+ a numeric prefix, check that many days. For example, {{{kbd(C-1 C-c
+ / d)}}} shows all deadlines due tomorrow.
- {{{kbd(C-c / b)}}} (~org-check-before-date~) ::
- #+kindex: C-c / b
- #+findex: org-check-before-date
- Sparse tree for deadlines and scheduled items before a given
- date.
+ #+kindex: C-c / b
+ #+findex: org-check-before-date
+ Sparse tree for deadlines and scheduled items before a given date.
- {{{kbd(C-c / a)}}} (~org-check-after-date~) ::
- #+kindex: C-c / a
- #+findex: org-check-after-date
- Sparse tree for deadlines and scheduled items after a given date.
+ #+kindex: C-c / a
+ #+findex: org-check-after-date
+ Sparse tree for deadlines and scheduled items after a given date.
Note that ~org-schedule~ and ~org-deadline~ supports setting the date
by indicating a relative time e.g., =+1d= sets the date to the next
@@ -6192,7 +6202,7 @@ any current timestamp.
Some tasks need to be repeated again and again. Org mode helps to
organize such tasks using a so-called repeater in a =DEADLINE=,
-=SCHEDULED=, or plain timestamps[fn:70]. In the following example:
+=SCHEDULED=, or plain timestamps[fn:68]. In the following example:
#+begin_example
,** TODO Pay the rent
@@ -6213,15 +6223,15 @@ period last
#+vindex: org-todo-repeat-to-state
Deadlines and scheduled items produce entries in the agenda when they
are over-due, so it is important to be able to mark such an entry as
-DONE once you have done so. When you mark a =DEADLINE= or a
-=SCHEDULED= with the TODO keyword =DONE=, it no longer produces
+done once you have done so. When you mark a =DEADLINE= or
+a =SCHEDULED= with the TODO keyword =DONE=, it no longer produces
entries in the agenda. The problem with this is, however, is that
then also the /next/ instance of the repeated entry will not be
active. Org mode deals with this in the following way: when you try
-to mark such an entry DONE, using {{{kbd(C-c C-t)}}}, it shifts the
+to mark such an entry as done, using {{{kbd(C-c C-t)}}}, it shifts the
base date of the repeating timestamp by the repeater interval, and
-immediately sets the entry state back to TODO[fn:71]. In the example
-above, setting the state to DONE would actually switch the date like
+immediately sets the entry state back to TODO[fn:69]. In the example
+above, setting the state to =DONE= would actually switch the date like
this:
#+begin_example
@@ -6233,7 +6243,7 @@ To mark a task with a repeater as DONE, use {{{kbd(C-- 1 C-c C-t)}}},
i.e., ~org-todo~ with a numeric prefix argument of =-1=.
#+vindex: org-log-repeat
-A timestamp[fn:72] is added under the deadline, to keep a record that
+A timestamp[fn:70] is added under the deadline, to keep a record that
you actually acted on the previous instance of this deadline.
As a consequence of shifting the base date, this entry is no longer
@@ -6299,7 +6309,7 @@ a project. When you start working on an item, you can start the
clock. When you stop working on that task, or when you mark the task
done, the clock is stopped and the corresponding time interval is
recorded. It also computes the total time spent on each
-subtree[fn:73] of a project. And it remembers a history or tasks
+subtree[fn:71] of a project. And it remembers a history or tasks
recently clocked, to that you can jump quickly between a number of
tasks absorbing your time.
@@ -6312,7 +6322,7 @@ To save the clock history across Emacs sessions, use:
#+vindex: org-clock-persist
When you clock into a new task after resuming Emacs, the incomplete
-clock[fn:74] is retrieved (see [[*Resolving idle time]]) and you are
+clock[fn:72] is retrieved (see [[*Resolving idle time]]) and you are
prompted about what to do with it.
*** Clocking commands
@@ -6323,140 +6333,136 @@ prompted about what to do with it.
#+attr_texinfo: :sep ,
- {{{kbd(C-c C-x C-i)}}} (~org-clock-in~) ::
- #+kindex: C-c C-x C-i
- #+findex: org-clock-in
- #+vindex: org-clock-into-drawer
- #+vindex: org-clock-continuously
- #+cindex: @samp{LOG_INTO_DRAWER}, property
- Start the clock on the current item (clock-in). This inserts the
- CLOCK keyword together with a timestamp. If this is not the
- first clocking of this item, the multiple CLOCK lines are wrapped
- into a =LOGBOOK= drawer (see also the variable
- ~org-clock-into-drawer~). You can also overrule the setting of
- this variable for a subtree by setting a =CLOCK_INTO_DRAWER= or
- =LOG_INTO_DRAWER= property. When called with a {{{kbd(C-u)}}}
- prefix argument, select the task from a list of recently clocked
- tasks. With two {{{kbd(C-u C-u)}}} prefixes, clock into the task
- at point and mark it as the default task; the default task is
- always be available with letter {{{kbd(d)}}} when selecting
- a clocking task. With three {{{kbd(C-u C-u C-u)}}} prefixes,
- force continuous clocking by starting the clock when the last
- clock stopped.
-
- #+cindex: @samp{CLOCK_MODELINE_TOTAL}, property
- #+cindex: @samp{LAST_REPEAT}, property
- #+vindex: org-clock-mode-line-total
- #+vindex: org-clock-in-prepare-hook
- While the clock is running, Org shows the current clocking time
- in the mode line, along with the title of the task. The clock
- time shown is all time ever clocked for this task and its
- children. If the task has an effort estimate (see [[*Effort
- Estimates]]), the mode line displays the current clocking time
- against it[fn:75]. If the task is a repeating one (see [[*Repeated
- tasks]]), show only the time since the last reset of the
- task[fn:76]. You can exercise more control over show time with
- the =CLOCK_MODELINE_TOTAL= property. It may have the values
- =current= to show only the current clocking instance, =today= to
- show all time clocked on this tasks today---see also the
- variable ~org-extend-today-until~, ~all~ to include all time, or
- ~auto~ which is the default[fn:77]. Clicking with
- {{{kbd(mouse-1)}}} onto the mode line entry pops up a menu with
- clocking options.
+ #+kindex: C-c C-x C-i
+ #+findex: org-clock-in
+ #+vindex: org-clock-into-drawer
+ #+vindex: org-clock-continuously
+ #+cindex: @samp{LOG_INTO_DRAWER}, property
+ Start the clock on the current item (clock-in). This inserts the
+ =CLOCK= keyword together with a timestamp. If this is not the first
+ clocking of this item, the multiple =CLOCK= lines are wrapped into
+ a =LOGBOOK= drawer (see also the variable ~org-clock-into-drawer~).
+ You can also overrule the setting of this variable for a subtree by
+ setting a =CLOCK_INTO_DRAWER= or =LOG_INTO_DRAWER= property. When
+ called with a {{{kbd(C-u)}}} prefix argument, select the task from
+ a list of recently clocked tasks. With two {{{kbd(C-u C-u)}}}
+ prefixes, clock into the task at point and mark it as the default
+ task; the default task is always be available with letter
+ {{{kbd(d)}}} when selecting a clocking task. With three {{{kbd(C-u
+ C-u C-u)}}} prefixes, force continuous clocking by starting the
+ clock when the last clock stopped.
+
+ #+cindex: @samp{CLOCK_MODELINE_TOTAL}, property
+ #+cindex: @samp{LAST_REPEAT}, property
+ #+vindex: org-clock-mode-line-total
+ #+vindex: org-clock-in-prepare-hook
+ While the clock is running, Org shows the current clocking time in
+ the mode line, along with the title of the task. The clock time
+ shown is all time ever clocked for this task and its children. If
+ the task has an effort estimate (see [[*Effort Estimates]]), the mode
+ line displays the current clocking time against it[fn:73]. If the
+ task is a repeating one (see [[*Repeated tasks]]), show only the time
+ since the last reset of the task[fn:74]. You can exercise more
+ control over show time with the =CLOCK_MODELINE_TOTAL= property. It
+ may have the values =current= to show only the current clocking
+ instance, =today= to show all time clocked on this tasks today---see
+ also the variable ~org-extend-today-until~, ~all~ to include all
+ time, or ~auto~ which is the default[fn:75]. Clicking with
+ {{{kbd(mouse-1)}}} onto the mode line entry pops up a menu with
+ clocking options.
- {{{kbd(C-c C-x C-o)}}} (~org-clock-out~) ::
- #+kindex: C-c C-x C-o
- #+findex: org-clock-out
- #+vindex: org-log-note-clock-out
- Stop the clock (clock-out). This inserts another timestamp at
- the same location where the clock was last started. It also
- directly computes the resulting time in inserts it after the time
- range as ==>HH:MM=. See the variable ~org-log-note-clock-out~
- for the possibility to record an additional note together with
- the clock-out timestamp[fn:78].
+ #+kindex: C-c C-x C-o
+ #+findex: org-clock-out
+ #+vindex: org-log-note-clock-out
+ Stop the clock (clock-out). This inserts another timestamp at the
+ same location where the clock was last started. It also directly
+ computes the resulting time in inserts it after the time range as
+ ==>HH:MM=. See the variable ~org-log-note-clock-out~ for the
+ possibility to record an additional note together with the clock-out
+ timestamp[fn:76].
- {{{kbd(C-c C-x C-x)}}} (~org-clock-in-last~) ::
- #+kindex: C-c C-x C-x
- #+findex: org-clock-in-last
- #+vindex: org-clock-continuously
- Re-clock the last clocked task. With one {{{kbd(C-u)}}} prefix
- argument, select the task from the clock history. With two
- {{{kbd(C-u)}}} prefixes, force continuous clocking by starting
- the clock when the last clock stopped.
+ #+kindex: C-c C-x C-x
+ #+findex: org-clock-in-last
+ #+vindex: org-clock-continuously
+ Re-clock the last clocked task. With one {{{kbd(C-u)}}} prefix
+ argument, select the task from the clock history. With two
+ {{{kbd(C-u)}}} prefixes, force continuous clocking by starting the
+ clock when the last clock stopped.
- {{{kbd(C-c C-x C-e)}}} (~org-clock-modify-effort-estimate~) ::
- #+kindex: C-c C-x C-e
- #+findex: org-clock-modify-effort-estimate
- Update the effort estimate for the current clock task.
+ #+kindex: C-c C-x C-e
+ #+findex: org-clock-modify-effort-estimate
+ Update the effort estimate for the current clock task.
- {{{kbd(C-c C-c)}}} or {{{kbd(C-c C-y)}}} (~org-evaluate-time-range~) ::
- #+kindex: C-c C-c
- #+kindex: C-c C-y
- #+findex: org-evaluate-time-range
- Recompute the time interval after changing one of the timestamps.
- This is only necessary if you edit the timestamps directly. If
- you change them with {{{kbd(S-<cursor>)}}} keys, the update is
- automatic.
+ #+kindex: C-c C-c
+ #+kindex: C-c C-y
+ #+findex: org-evaluate-time-range
+ Recompute the time interval after changing one of the timestamps.
+ This is only necessary if you edit the timestamps directly. If you
+ change them with {{{kbd(S-<cursor>)}}} keys, the update is
+ automatic.
- {{{kbd(C-S-UP)}}} (~org-clock-timestamps-up~), {{{kbd(C-S-DOWN)}}} (~org-clock-timestamps-down~) ::
- #+kindex: C-S-UP
- #+findex: org-clock-timestamps-up
- #+kindex: C-S-DOWN
- #+findex: org-clock-timestamps-down
- On CLOCK log lines, increase/decrease both timestamps so that the
- clock duration keeps the same value.
+ #+kindex: C-S-UP
+ #+findex: org-clock-timestamps-up
+ #+kindex: C-S-DOWN
+ #+findex: org-clock-timestamps-down
+ On CLOCK log lines, increase/decrease both timestamps so that the
+ clock duration keeps the same value.
- {{{kbd(S-M-UP)}}} (~org-timestamp-up~), {{{kbd(S-M-DOWN)}}} (~org-timestamp-down~) ::
- #+kindex: S-M-UP
- #+findex: org-clock-timestamp-up
- #+kindex: S-M-DOWN
- #+findex: org-clock-timestamp-down
- On =CLOCK= log lines, increase/decrease the timestamp at point
- and the one of the previous, or the next, clock timestamp by the
- same duration. For example, if you hit {{{kbd(S-M-UP)}}} to
- increase a clocked-out timestamp by five minutes, then the
- clocked-in timestamp of the next clock is increased by five
- minutes.
+ #+kindex: S-M-UP
+ #+findex: org-clock-timestamp-up
+ #+kindex: S-M-DOWN
+ #+findex: org-clock-timestamp-down
+ On =CLOCK= log lines, increase/decrease the timestamp at point and
+ the one of the previous, or the next, clock timestamp by the same
+ duration. For example, if you hit {{{kbd(S-M-UP)}}} to increase
+ a clocked-out timestamp by five minutes, then the clocked-in
+ timestamp of the next clock is increased by five minutes.
- {{{kbd(C-c C-t)}}} (~org-todo~) ::
- #+kindex: C-c C-t
- #+findex: org-todo
- Changing the TODO state of an item to DONE automatically stops
- the clock if it is running in this same item.
+ #+kindex: C-c C-t
+ #+findex: org-todo
+ Changing the TODO state of an item to DONE automatically stops the
+ clock if it is running in this same item.
- {{{kbd(C-c C-x C-q)}}} (~org-clock-cancel~) ::
- #+kindex: C-c C-x C-q
- #+findex: org-clock-cancel
- Cancel the current clock. This is useful if a clock was started
- by mistake, or if you ended up working on something else.
+ #+kindex: C-c C-x C-q
+ #+findex: org-clock-cancel
+ Cancel the current clock. This is useful if a clock was started by
+ mistake, or if you ended up working on something else.
- {{{kbd(C-c C-x C-j)}}} (~org-clock-goto~) ::
- #+kindex: C-c C-x C-j
- #+findex: or-clock-goto
- Jump to the headline of the currently clocked in task. With
- a {{{kbd(C-u)}}} prefix argument, select the target task from
- a list of recently clocked tasks.
+ #+kindex: C-c C-x C-j
+ #+findex: or-clock-goto
+ Jump to the headline of the currently clocked in task. With
+ a {{{kbd(C-u)}}} prefix argument, select the target task from a list
+ of recently clocked tasks.
- {{{kbd(C-c C-x C-d)}}} (~org-clock-display~) ::
- #+kindex: C-c C-x C-d
- #+findex: org-clock-display
- #+vindex: org-remove-highlights-with-change
- Display time summaries for each subtree in the current buffer.
- This puts overlays at the end of each headline, showing the total
- time recorded under that heading, including the time of any
- subheadings. You can use visibility cycling to study the tree,
- but the overlays disappear when you change the buffer (see
- variable ~org-remove-highlights-with-change~) or press {{{kbd(C-c
- C-c)}}}.
+ #+kindex: C-c C-x C-d
+ #+findex: org-clock-display
+ #+vindex: org-remove-highlights-with-change
+ Display time summaries for each subtree in the current buffer. This
+ puts overlays at the end of each headline, showing the total time
+ recorded under that heading, including the time of any subheadings.
+ You can use visibility cycling to study the tree, but the overlays
+ disappear when you change the buffer (see variable
+ ~org-remove-highlights-with-change~) or press {{{kbd(C-c C-c)}}}.
The {{{kbd(l)}}} key may be used in the agenda (see [[*Weekly/daily
agenda]]) to show which tasks have been worked on or closed during
@@ -6476,39 +6482,35 @@ Org mode can produce quite complex reports based on the time clocking
information. Such a report is called a /clock table/, because it is
formatted as one or several Org tables.
-#+attr_texinfo: :sep ,
-- {{{kbd(C-c C-x C-r)}}} (~org-clock-report~) ::
-
- #+kindex: C-c C-x C-r
- #+findex: org-clock-report
- Insert a dynamic block (see [[*Dynamic Blocks]]) containing a clock
- report as an Org mode table into the current file. When point is
- at an existing clock table, just update it. When called with a
- prefix argument, jump to the first clock report in the current
- document and update it. The clock table includes archived trees.
+You can insert, or update, a clock table through Org dynamic blocks
+insert command (see [[*Dynamic Blocks]]), by pressing {{{kbd(C-c C-x
+x c l o c k t a b l e RET)}}}. When called with a prefix argument,
+jump to the first clock table in the current document and update it.
+The clock table includes archived trees.
+#+attr_texinfo: :sep ,
- {{{kbd(C-c C-c)}}} or {{{kbd(C-c C-x C-u)}}} (~org-dblock-update~) ::
- #+kindex: C-c C-c
- #+kindex: C-c C-x C-u
- #+findex: org-dblock-update
- Update dynamic block at point. Point needs to be in the =BEGIN=
- line of the dynamic block.
+ #+kindex: C-c C-c
+ #+kindex: C-c C-x C-u
+ #+findex: org-dblock-update
+ Update dynamic block at point. Point needs to be in the =BEGIN=
+ line of the dynamic block.
- {{{kbd(C-u C-c C-x C-u)}}} ::
- #+kindex: C-u C-c C-x C-u
- Update all dynamic blocks (see [[*Dynamic Blocks]]). This is useful
- if you have several clock table blocks in a buffer.
+ #+kindex: C-u C-c C-x C-u
+ Update all dynamic blocks (see [[*Dynamic Blocks]]). This is useful if
+ you have several clock table blocks in a buffer.
- {{{kbd(S-LEFT)}}}, {{{kbd(S-RIGHT)}}} (~org-clocktable-try-shift~) ::
- #+kindex: S-LEFT
- #+kindex: S-RIGHT
- #+findex: org-clocktable-try-shift
- Shift the current =:block= interval and update the table. Point
- needs to be in the =#+BEGIN: clocktable= line for this command.
- If =:block= is =today=, it is shifted to =today-1=, etc.
+ #+kindex: S-LEFT
+ #+kindex: S-RIGHT
+ #+findex: org-clocktable-try-shift
+ Shift the current =:block= interval and update the table. Point
+ needs to be in the =#+BEGIN: clocktable= line for this command. If
+ =:block= is =today=, it is shifted to =today-1=, etc.
Here is an example of the frame for a clock table as it is inserted
into the buffer with the {{{kbd(C-c C-x C-r)}}} command:
@@ -6530,87 +6532,88 @@ be selected:
- =:maxlevel= ::
- Maximum level depth to which times are listed in the table.
- Clocks at deeper levels are summed into the upper level.
+ Maximum level depth to which times are listed in the table. Clocks
+ at deeper levels are summed into the upper level.
- =:scope= ::
- The scope to consider. This can be any of the following:
+ The scope to consider. This can be any of the following:
- | =nil= | the current buffer or narrowed region |
- | =file= | the full current buffer |
- | =subtree= | the subtree where the clocktable is located |
- | =treeN= | the surrounding level N tree, for example =tree3= |
- | =tree= | the surrounding level 1 tree |
- | =agenda= | all agenda files |
- | =("file" ...)= | scan these files |
- | =FUNCTION= | scan files returned by calling {{{var(FUNCTION)}}} with no argument |
- | =file-with-archives= | current file and its archives |
- | =agenda-with-archives= | all agenda files, including archives |
+ | =nil= | the current buffer or narrowed region |
+ | =file= | the full current buffer |
+ | =subtree= | the subtree where the clocktable is located |
+ | =treeN= | the surrounding level N tree, for example =tree3= |
+ | =tree= | the surrounding level 1 tree |
+ | =agenda= | all agenda files |
+ | =("file" ...)= | scan these files |
+ | =FUNCTION= | scan files returned by calling {{{var(FUNCTION)}}} with no argument |
+ | =file-with-archives= | current file and its archives |
+ | =agenda-with-archives= | all agenda files, including archives |
- =:block= ::
- The time block to consider. This block is specified either
- absolutely, or relative to the current time and may be any of
- these formats:
-
- | =2007-12-31= | New year eve 2007 |
- | =2007-12= | December 2007 |
- | =2007-W50= | ISO-week 50 in 2007 |
- | =2007-Q2= | 2nd quarter in 2007 |
- | =2007= | the year 2007 |
- | =today=, =yesterday=, =today-N= | a relative day |
- | =thisweek=, =lastweek=, =thisweek-N= | a relative week |
- | =thismonth=, =lastmonth=, =thismonth-N= | a relative month |
- | =thisyear=, =lastyear=, =thisyear-N= | a relative year |
- | =untilnow=[fn:79] | all clocked time ever |
-
- #+vindex: org-clock-display-default-range
- When this option is not set, Org falls back to the value in
- ~org-clock-display-default-range~, which defaults to the current
- year.
-
- Use {{{kbd(S-LEFT)}}} or {{{kbd(S-RIGHT)}}} to shift the time
- interval.
+ The time block to consider. This block is specified either
+ absolutely, or relative to the current time and may be any of these
+ formats:
+
+ | =2007-12-31= | New year eve 2007 |
+ | =2007-12= | December 2007 |
+ | =2007-W50= | ISO-week 50 in 2007 |
+ | =2007-Q2= | 2nd quarter in 2007 |
+ | =2007= | the year 2007 |
+ | =today=, =yesterday=, =today-N= | a relative day |
+ | =thisweek=, =lastweek=, =thisweek-N= | a relative week |
+ | =thismonth=, =lastmonth=, =thismonth-N= | a relative month |
+ | =thisyear=, =lastyear=, =thisyear-N= | a relative year |
+ | =untilnow=[fn:77] | all clocked time ever |
+
+ #+vindex: org-clock-display-default-range
+ When this option is not set, Org falls back to the value in
+ ~org-clock-display-default-range~, which defaults to the current
+ year.
+
+ Use {{{kbd(S-LEFT)}}} or {{{kbd(S-RIGHT)}}} to shift the time
+ interval.
- =:tstart= ::
- A time string specifying when to start considering times.
- Relative times like ="<-2w>"= can also be used. See [[*Matching
- tags and properties]] for relative time syntax.
+ A time string specifying when to start considering times. Relative
+ times like ="<-2w>"= can also be used. See [[*Matching tags and
+ properties]] for relative time syntax.
- =:tend= ::
- A time string specifying when to stop considering times.
- Relative times like ="<now>"= can also be used. See [[*Matching
- tags and properties]] for relative time syntax.
+ A time string specifying when to stop considering times. Relative
+ times like ="<now>"= can also be used. See [[*Matching tags and
+ properties]] for relative time syntax.
- =:wstart= ::
- The starting day of the week. The default is 1 for Monday.
+ The starting day of the week. The default is 1 for Monday.
- =:mstart= ::
- The starting day of the month. The default is 1 for the first.
+ The starting day of the month. The default is 1 for the first.
- =:step= ::
- Set to ~week~ or ~day~ to split the table into chunks. To use
- this, ~:block~ or ~:tstart~, ~:tend~ are needed.
+ Set to =day=, =week=, =month= or =year= to split the table into
+ chunks. To use this, either =:block=, or =:tstart= and =:tend= are
+ required.
- =:stepskip0= ::
- When non-~nil~, do not show steps that have zero time.
+ When non-~nil~, do not show steps that have zero time.
- =:fileskip0= ::
- When non-~nil~, do not show table sections from files which did
- not contribute.
+ When non-~nil~, do not show table sections from files which did not
+ contribute.
- =:match= ::
- A tags match to select entries that should contribute. See
- [[*Matching tags and properties]] for the match syntax.
+ A tags match to select entries that should contribute. See
+ [[*Matching tags and properties]] for the match syntax.
#+findex: org-clocktable-write-default
Then there are options that determine the formatting of the table.
@@ -6620,75 +6623,80 @@ using the =:formatter= parameter.
- =:emphasize= ::
- When non-~nil~, emphasize level one and level two items.
+ When non-~nil~, emphasize level one and level two items.
- =:lang= ::
- Language[fn:80] to use for descriptive cells like "Task".
+ Language[fn:78] to use for descriptive cells like "Task".
- =:link= ::
- Link the item headlines in the table to their origins.
+ Link the item headlines in the table to their origins.
- =:narrow= ::
- An integer to limit the width of the headline column in the Org
- table. If you write it like =50!=, then the headline is also
- shortened in export.
+ An integer to limit the width of the headline column in the Org
+ table. If you write it like =50!=, then the headline is also
+ shortened in export.
- =:indent= ::
- Indent each headline field according to its level.
+ Indent each headline field according to its level.
+
+- =:hidefiles= ::
+
+ Hide the file column when multiple files are used to produce the
+ table.
- =:tcolumns= ::
- Number of columns to be used for times. If this is smaller than
- =:maxlevel=, lower levels are lumped into one column.
+ Number of columns to be used for times. If this is smaller than
+ =:maxlevel=, lower levels are lumped into one column.
- =:level= ::
- Should a level number column be included?
+ Should a level number column be included?
- =:sort= ::
- A cons cell containing the column to sort and a sorting type.
- E.g., =:sort (1 . ?a)= sorts the first column alphabetically.
+ A cons cell containing the column to sort and a sorting type. E.g.,
+ =:sort (1 . ?a)= sorts the first column alphabetically.
- =:compact= ::
- Abbreviation for =:level nil :indent t :narrow 40! :tcolumns 1=.
- All are overwritten except if there is an explicit =:narrow=.
+ Abbreviation for =:level nil :indent t :narrow 40! :tcolumns 1=.
+ All are overwritten except if there is an explicit =:narrow=.
- =:timestamp= ::
- A timestamp for the entry, when available. Look for =SCHEDULED=,
- =DEADLINE=, =TIMESTAMP= and =TIMESTAMP_IA= special properties
- (see [[*Special Properties]]), in this order.
+ A timestamp for the entry, when available. Look for =SCHEDULED=,
+ =DEADLINE=, =TIMESTAMP= and =TIMESTAMP_IA= special properties (see
+ [[*Special Properties]]), in this order.
- =:tags= ::
- When this flag is non-~nil~, show the headline's tags.
+ When this flag is non-~nil~, show the headline's tags.
- =:properties= ::
- List of properties shown in the table. Each property gets its
- own column.
+ List of properties shown in the table. Each property gets its own
+ column.
- =:inherit-props= ::
- When this flag is non-~nil~, the values for =:properties= are
- inherited.
+ When this flag is non-~nil~, the values for =:properties= are
+ inherited.
- =:formula= ::
- Content of a =TBLFM= keyword to be added and evaluated. As
- a special case, =:formula %= adds a column with % time. If you
- do not specify a formula here, any existing formula below the
- clock table survives updates and is evaluated.
+ Content of a =TBLFM= keyword to be added and evaluated. As
+ a special case, =:formula %= adds a column with % time. If you do
+ not specify a formula here, any existing formula below the clock
+ table survives updates and is evaluated.
- =:formatter= ::
- A function to format clock data and insert it into the buffer.
+ A function to format clock data and insert it into the buffer.
To get a clock summary of the current level 1 tree, for the current
day, you could write:
@@ -6699,7 +6707,7 @@ day, you could write:
#+end_example
#+texinfo: @noindent
-To use a specific time range you could write[fn:81]
+To use a specific time range you could write[fn:79]
#+begin_example
,#+BEGIN: clocktable :tstart "<2006-08-10 Thu 10:00>"
@@ -6755,7 +6763,7 @@ current clock, or applying it to another one.
#+vindex: org-clock-x11idle-program-name
By customizing the variable ~org-clock-idle-time~ to some integer,
such as 10 or 15, Emacs can alert you when you get back to your
-computer after being idle for that many minutes[fn:82], and ask what
+computer after being idle for that many minutes[fn:80], and ask what
you want to do with the idle time. There will be a question waiting
for you when you get back, indicating how much idle time has passed
constantly updated with the current amount, as well as a set of
@@ -6763,42 +6771,42 @@ choices to correct the discrepancy:
- {{{kbd(k)}}} ::
- #+kindex: k
- To keep some or all of the minutes and stay clocked in, press
- {{{kbd(k)}}}. Org asks how many of the minutes to keep. Press
- {{{kbd(RET)}}} to keep them all, effectively changing nothing, or
- enter a number to keep that many minutes.
+ #+kindex: k
+ To keep some or all of the minutes and stay clocked in, press
+ {{{kbd(k)}}}. Org asks how many of the minutes to keep. Press
+ {{{kbd(RET)}}} to keep them all, effectively changing nothing, or
+ enter a number to keep that many minutes.
- {{{kbd(K)}}} ::
- #+kindex: K
- If you use the shift key and press {{{kbd(K)}}}, it keeps however
- many minutes you request and then immediately clock out of that
- task. If you keep all of the minutes, this is the same as just
- clocking out of the current task.
+ #+kindex: K
+ If you use the shift key and press {{{kbd(K)}}}, it keeps however
+ many minutes you request and then immediately clock out of that
+ task. If you keep all of the minutes, this is the same as just
+ clocking out of the current task.
- {{{kbd(s)}}} ::
- #+kindex: s
- To keep none of the minutes, use {{{kbd(s)}}} to subtract all the
- away time from the clock, and then check back in from the moment
- you returned.
+ #+kindex: s
+ To keep none of the minutes, use {{{kbd(s)}}} to subtract all the
+ away time from the clock, and then check back in from the moment you
+ returned.
- {{{kbd(S)}}} ::
- #+kindex: S
- To keep none of the minutes and just clock out at the start of
- the away time, use the shift key and press {{{kbd(S)}}}.
- Remember that using shift always leave you clocked out, no matter
- which option you choose.
+ #+kindex: S
+ To keep none of the minutes and just clock out at the start of the
+ away time, use the shift key and press {{{kbd(S)}}}. Remember that
+ using shift always leave you clocked out, no matter which option you
+ choose.
- {{{kbd(C)}}} ::
- #+kindex: C
- To cancel the clock altogether, use {{{kbd(C)}}}. Note that if
- instead of canceling you subtract the away time, and the
- resulting clock amount is less than a minute, the clock is still
- canceled rather than cluttering up the log with an empty entry.
+ #+kindex: C
+ To cancel the clock altogether, use {{{kbd(C)}}}. Note that if
+ instead of canceling you subtract the away time, and the resulting
+ clock amount is less than a minute, the clock is still canceled
+ rather than cluttering up the log with an empty entry.
What if you subtracted those away minutes from the current clock, and
now want to apply them to a new clock? Simply clock in to any task
@@ -6861,18 +6869,18 @@ commands:
- {{{kbd(C-c C-x e)}}} (~org-set-effort~) ::
- #+kindex: C-c C-x e
- #+findex: org-set-effort
- Set the effort estimate for the current entry. With a prefix
- argument, set it to the next allowed value---see below. This
- command is also accessible from the agenda with the {{{kbd(e)}}}
- key.
+ #+kindex: C-c C-x e
+ #+findex: org-set-effort
+ Set the effort estimate for the current entry. With a prefix
+ argument, set it to the next allowed value---see below. This
+ command is also accessible from the agenda with the {{{kbd(e)}}}
+ key.
- {{{kbd(C-c C-x C-e)}}} (~org-clock-modify-effort-estimate~) ::
- #+kindex: C-c C-x C-e
- #+findex: org-clock-modify-effort-estimate
- Modify the effort estimate of the item currently being clocked.
+ #+kindex: C-c C-x C-e
+ #+findex: org-clock-modify-effort-estimate
+ Modify the effort estimate of the item currently being clocked.
Clearly the best way to work with effort estimates is through column
view (see [[*Column View]]). You should start by setting up discrete
@@ -6901,7 +6909,7 @@ displayed.
#+vindex: org-agenda-columns-add-appointments-to-effort-sum
If you switch to column view in the daily/weekly agenda, the effort
-column summarizes the estimated work effort for each day[fn:83], and
+column summarizes the estimated work effort for each day[fn:81], and
you can use this to find space in your schedule. To get an overview
of the entire part of the day that is committed, you can set the
option ~org-agenda-columns-add-appointments-to-effort-sum~. The
@@ -6930,79 +6938,338 @@ The relative and countdown are started with separate commands.
- {{{kbd(C-c C-x 0)}}} (~org-timer-start~) ::
- #+kindex: C-c C-x 0
- #+findex: org-timer-start
- Start or reset the relative timer. By default, the timer is set
- to 0. When called with a {{{kbd(C-u)}}} prefix, prompt the user
- for a starting offset. If there is a timer string at point, this
- is taken as the default, providing a convenient way to restart
- taking notes after a break in the process. When called with
- a double prefix argument {{{kbd(C-u C-u)}}}, change all timer
- strings in the active region by a certain amount. This can be
- used to fix timer strings if the timer was not started at exactly
- the right moment.
+ #+kindex: C-c C-x 0
+ #+findex: org-timer-start
+ Start or reset the relative timer. By default, the timer is set
+ to 0. When called with a {{{kbd(C-u)}}} prefix, prompt the user for
+ a starting offset. If there is a timer string at point, this is
+ taken as the default, providing a convenient way to restart taking
+ notes after a break in the process. When called with a double
+ prefix argument {{{kbd(C-u C-u)}}}, change all timer strings in the
+ active region by a certain amount. This can be used to fix timer
+ strings if the timer was not started at exactly the right moment.
- {{{kbd(C-c C-x ;)}}} (~org-timer-set-timer~) ::
- #+kindex: C-c C-x ;
- #+findex: org-timer-set-timer
- #+vindex: org-timer-default-timer
- Start a countdown timer. The user is prompted for a duration.
- ~org-timer-default-timer~ sets the default countdown value.
- Giving a numeric prefix argument overrides this default value.
- This command is available as {{{kbd(;)}}} in agenda buffers.
+ #+kindex: C-c C-x ;
+ #+findex: org-timer-set-timer
+ #+vindex: org-timer-default-timer
+ Start a countdown timer. The user is prompted for a duration.
+ ~org-timer-default-timer~ sets the default countdown value. Giving
+ a numeric prefix argument overrides this default value. This
+ command is available as {{{kbd(;)}}} in agenda buffers.
Once started, relative and countdown timers are controlled with the
same commands.
- {{{kbd(C-c C-x .)}}} (~org-timer~) ::
- #+kindex: C-c C-x .
- #+findex: org-timer
- Insert a relative time into the buffer. The first time you use
- this, the timer starts. Using a prefix argument restarts it.
+ #+kindex: C-c C-x .
+ #+findex: org-timer
+ Insert a relative time into the buffer. The first time you use
+ this, the timer starts. Using a prefix argument restarts it.
- {{{kbd(C-c C-x -)}}} (~org-timer-item~) ::
- #+kindex: C-c C-x -
- #+findex: org-timer-item
- Insert a description list item with the current relative time.
- With a prefix argument, first reset the timer to 0.
+ #+kindex: C-c C-x -
+ #+findex: org-timer-item
+ Insert a description list item with the current relative time. With
+ a prefix argument, first reset the timer to 0.
- {{{kbd(M-RET)}}} (~org-insert-heading~) ::
- #+kindex: M-RET
- #+findex: org-insert-heading
- Once the timer list is started, you can also use
- {{{kbd(M-RET)}}} to insert new timer items.
+ #+kindex: M-RET
+ #+findex: org-insert-heading
+ Once the timer list is started, you can also use {{{kbd(M-RET)}}} to
+ insert new timer items.
- {{{kbd(C-c C-x \,)}}} (~org-timer-pause-or-continue~) ::
- #+kindex: C-c C-x ,
- #+findex: org-timer-pause-or-continue
- Pause the timer, or continue it if it is already paused.
+ #+kindex: C-c C-x ,
+ #+findex: org-timer-pause-or-continue
+ Pause the timer, or continue it if it is already paused.
- {{{kbd(C-c C-x _)}}} (~org-timer-stop~) ::
- #+kindex: C-c C-x _
- #+findex: org-timer-stop
- Stop the timer. After this, you can only start a new timer, not
- continue the old one. This command also removes the timer from
- the mode line.
+ #+kindex: C-c C-x _
+ #+findex: org-timer-stop
+ Stop the timer. After this, you can only start a new timer, not
+ continue the old one. This command also removes the timer from the
+ mode line.
-* Capture, Refile, Archive
+* Refiling and Archiving
:PROPERTIES:
-:DESCRIPTION: The ins and outs for projects.
+:DESCRIPTION: Moving and copying information with ease.
+:END:
+#+cindex: refiling notes
+#+cindex: copying notes
+#+cindex: archiving
+
+Once information is in the system, it may need to be moved around.
+Org provides Refile, Copy and Archive commands for this. Refile and
+Copy helps with moving and copying outlines. Archiving helps to keep
+the system compact and fast.
+
+** Refile and Copy
+:PROPERTIES:
+:DESCRIPTION: Moving/copying a tree from one place to another.
+:END:
+#+cindex: refiling notes
+#+cindex: copying notes
+
+When reviewing the captured data, you may want to refile or to copy
+some of the entries into a different list, for example into a project.
+Cutting, finding the right location, and then pasting the note is
+cumbersome. To simplify this process, you can use the following
+special command:
+
+- {{{kbd(C-c C-w)}}} (~org-refile~) ::
+
+ #+kindex: C-c C-w
+ #+findex: org-refile
+ #+vindex: org-reverse-note-order
+ #+vindex: org-refile-targets
+ #+vindex: org-refile-use-outline-path
+ #+vindex: org-outline-path-complete-in-steps
+ #+vindex: org-refile-allow-creating-parent-nodes
+ #+vindex: org-log-refile
+ Refile the entry or region at point. This command offers possible
+ locations for refiling the entry and lets you select one with
+ completion. The item (or all items in the region) is filed below
+ the target heading as a subitem. Depending on
+ ~org-reverse-note-order~, it is either the first or last subitem.
+
+ By default, all level 1 headlines in the current buffer are
+ considered to be targets, but you can have more complex definitions
+ across a number of files. See the variable ~org-refile-targets~ for
+ details. If you would like to select a location via
+ a file-path-like completion along the outline path, see the
+ variables ~org-refile-use-outline-path~ and
+ ~org-outline-path-complete-in-steps~. If you would like to be able
+ to create new nodes as new parents for refiling on the fly, check
+ the variable ~org-refile-allow-creating-parent-nodes~. When the
+ variable ~org-log-refile~[fn:82] is set, a timestamp or a note is
+ recorded whenever an entry is refiled.
+
+- {{{kbd(C-u C-c C-w)}}} ::
+
+ #+kindex: C-u C-c C-w
+ Use the refile interface to jump to a heading.
+
+- {{{kbd(C-u C-u C-c C-w)}}} (~org-refile-goto-last-stored~) ::
+
+ #+kindex: C-u C-u C-c C-w
+ #+findex: org-refile-goto-last-stored
+ Jump to the location where ~org-refile~ last moved a tree to.
+
+- {{{kbd(C-2 C-c C-w)}}} ::
+
+ #+kindex: C-2 C-c C-w
+ Refile as the child of the item currently being clocked.
+
+- {{{kbd(C-3 C-c C-w)}}} ::
+
+ #+kindex: C-3 C-c C-w
+ #+vindex: org-refile-keep
+ Refile and keep the entry in place. Also see ~org-refile-keep~ to
+ make this the default behavior, and beware that this may result in
+ duplicated =ID= properties.
+
+- {{{kbd(C-0 C-c C-w)}}} or {{{kbd(C-u C-u C-u C-c C-w)}}} (~org-refile-cache-clear~) ::
+
+ #+kindex: C-u C-u C-u C-c C-w
+ #+kindex: C-0 C-c C-w
+ #+findex: org-refile-cache-clear
+ #+vindex: org-refile-use-cache
+ Clear the target cache. Caching of refile targets can be turned on
+ by setting ~org-refile-use-cache~. To make the command see new
+ possible targets, you have to clear the cache with this command.
+
+- {{{kbd(C-c M-w)}}} (~org-copy~) ::
+
+ #+kindex: C-c M-w
+ #+findex: org-copy
+ Copying works like refiling, except that the original note is not
+ deleted.
+
+** Archiving
+:PROPERTIES:
+:DESCRIPTION: What to do with finished products.
+:END:
+#+cindex: archiving
+
+When a project represented by a (sub)tree is finished, you may want to
+move the tree out of the way and to stop it from contributing to the
+agenda. Archiving is important to keep your working files compact and
+global searches like the construction of agenda views fast.
+
+- {{{kbd(C-c C-x C-a)}}} (~org-archive-subtree-default~) ::
+
+ #+kindex: C-c C-x C-a
+ #+findex: org-archive-subtree-default
+ #+vindex: org-archive-default-command
+ Archive the current entry using the command specified in the
+ variable ~org-archive-default-command~.
+
+*** Moving a tree to an archive file
+:PROPERTIES:
+:DESCRIPTION: Moving a tree to an archive file.
+:ALT_TITLE: Moving subtrees
+:END:
+#+cindex: external archiving
+
+The most common archiving action is to move a project tree to another
+file, the archive file.
+
+- {{{kbd(C-c C-x C-s)}}} or short {{{kbd(C-c $)}}} (~org-archive-subtree~) ::
+
+ #+kindex: C-c C-x C-s
+ #+kindex: C-c $
+ #+findex: org-archive-subtree
+ #+vindex: org-archive-location
+ Archive the subtree starting at point position to the location given
+ by ~org-archive-location~.
+
+- {{{kbd(C-u C-c C-x C-s)}}} ::
+
+ #+kindex: C-u C-c C-x C-s
+ Check if any direct children of the current headline could be moved
+ to the archive. To do this, check each subtree for open TODO
+ entries. If none is found, the command offers to move it to the
+ archive location. If point is /not/ on a headline when this command
+ is invoked, check level 1 trees.
+
+- {{{kbd(C-u C-u C-c C-x C-s)}}} ::
+
+ #+kindex: C-u C-u C-c C-x C-s
+ As above, but check subtree for timestamps instead of TODO entries.
+ The command offers to archive the subtree if it /does/ contain
+ a timestamp, and that timestamp is in the past.
+
+#+cindex: archive locations
+The default archive location is a file in the same directory as the
+current file, with the name derived by appending =_archive= to the
+current file name. You can also choose what heading to file archived
+items under, with the possibility to add them to a datetree in a file.
+For information and examples on how to specify the file and the
+heading, see the documentation string of the variable
+~org-archive-location~.
+
+There is also an in-buffer option for setting this variable, for
+example:
+
+#+cindex: @samp{ARCHIVE}, keyword
+: #+ARCHIVE: %s_done::
+
+#+cindex: ARCHIVE, property
+If you would like to have a special archive location for a single
+entry or a (sub)tree, give the entry an =ARCHIVE= property with the
+location as the value (see [[*Properties and Columns]]).
+
+#+vindex: org-archive-save-context-info
+When a subtree is moved, it receives a number of special properties
+that record context information like the file from where the entry
+came, its outline path the archiving time etc. Configure the variable
+~org-archive-save-context-info~ to adjust the amount of information
+added.
+
+*** Internal archiving
+:PROPERTIES:
+:DESCRIPTION: Switch off a tree but keep it in the file.
+:END:
+
+#+cindex: @samp{ARCHIVE}, tag
+If you want to just switch off---for agenda views---certain subtrees
+without moving them to a different file, you can use the =ARCHIVE=
+tag.
+
+A headline that is marked with the =ARCHIVE= tag (see [[*Tags]]) stays at
+its location in the outline tree, but behaves in the following way:
+
+-
+ #+vindex: org-cycle-open-archived-trees
+ It does not open when you attempt to do so with a visibility cycling
+ command (see [[*Visibility Cycling]]). You can force cycling archived
+ subtrees with {{{kbd(C-TAB)}}}, or by setting the option
+ ~org-cycle-open-archived-trees~. Also normal outline commands, like
+ ~outline-show-all~, open archived subtrees.
+
+-
+ #+vindex: org-sparse-tree-open-archived-trees
+ During sparse tree construction (see [[*Sparse Trees]]), matches in
+ archived subtrees are not exposed, unless you configure the option
+ ~org-sparse-tree-open-archived-trees~.
+
+-
+ #+vindex: org-agenda-skip-archived-trees
+ During agenda view construction (see [[*Agenda Views]]), the content of
+ archived trees is ignored unless you configure the option
+ ~org-agenda-skip-archived-trees~, in which case these trees are
+ always included. In the agenda you can press {{{kbd(v a)}}} to get
+ archives temporarily included.
+
+-
+ #+vindex: org-export-with-archived-trees
+ Archived trees are not exported (see [[*Exporting]]), only the headline
+ is. Configure the details using the variable
+ ~org-export-with-archived-trees~.
+
+-
+ #+vindex: org-columns-skip-archived-trees
+ Archived trees are excluded from column view unless the variable
+ ~org-columns-skip-archived-trees~ is configured to ~nil~.
+
+The following commands help manage the =ARCHIVE= tag:
+
+- {{{kbd(C-c C-x a)}}} (~org-toggle-archive-tag~) ::
+
+ #+kindex: C-c C-x a
+ #+findex: org-toggle-archive-tag
+ Toggle the archive tag for the current headline. When the tag is
+ set, the headline changes to a shadowed face, and the subtree below
+ it is hidden.
+
+- {{{kbd(C-u C-c C-x a)}}} ::
+
+ #+kindex: C-u C-c C-x a
+ Check if any direct children of the current headline should be
+ archived. To do this, check each subtree for open TODO entries. If
+ none is found, the command offers to set the =ARCHIVE= tag for the
+ child. If point is /not/ on a headline when this command is
+ invoked, check the level 1 trees.
+
+- {{{kbd(C-TAB)}}} (~org-force-cycle-archived~) ::
+
+ #+kindex: C-TAB
+ Cycle a tree even if it is tagged with =ARCHIVE=.
+
+- {{{kbd(C-c C-x A)}}} (~org-archive-to-archive-sibling~) ::
+
+ #+kindex: C-c C-x A
+ #+findex: org-archive-to-archive-sibling
+ Move the current entry to the /Archive Sibling/. This is a sibling
+ of the entry with the heading =Archive= and the archive tag. The
+ entry becomes a child of that sibling and in this way retains a lot
+ of its original context, including inherited tags and approximate
+ position in the outline.
+
+* Capture and Attachments
+:PROPERTIES:
+:DESCRIPTION: Dealing with external data.
:END:
#+cindex: capture
+#+cindex: attachments
+#+cindex: RSS feeds
+#+cindex: Atom feeds
+#+cindex: protocols, for external access
An important part of any organization system is the ability to quickly
capture new ideas and tasks, and to associate reference material with
them. Org does this using a process called /capture/. It also can
store files related to a task (/attachments/) in a special directory.
-Once in the system, tasks and projects need to be moved around.
-Moving completed project trees to an archive file keeps the system
-compact and fast.
+Finally, it can parse RSS feeds for information. To learn how to let
+external programs (for example a web browser) trigger Org to capture
+material, see [[*Protocols for External Access]].
** Capture
:PROPERTIES:
@@ -7036,42 +7303,42 @@ You may also define a global key for capturing new material (see
- {{{kbd(M-x org-capture)}}} (~org-capture~) ::
- #+findex: org-capture
- #+cindex: date tree
- Display the capture templates menu. If you have templates
- defined (see [[*Capture templates]]), it offers these templates for
- selection or use a new Org outline node as the default template.
- It inserts the template into the target file and switch to an
- indirect buffer narrowed to this new node. You may then insert
- the information you want.
+ #+findex: org-capture
+ #+cindex: date tree
+ Display the capture templates menu. If you have templates defined
+ (see [[*Capture templates]]), it offers these templates for selection or
+ use a new Org outline node as the default template. It inserts the
+ template into the target file and switch to an indirect buffer
+ narrowed to this new node. You may then insert the information you
+ want.
- {{{kbd(C-c C-c)}}} (~org-capture-finalize~) ::
- #+kindex: C-c C-c @r{(Capture buffer)}
- #+findex: org-capture-finalize
- Once you have finished entering information into the capture
- buffer, {{{kbd(C-c C-c)}}} returns you to the window
- configuration before the capture process, so that you can resume
- your work without further distraction. When called with a prefix
- argument, finalize and then jump to the captured item.
+ #+kindex: C-c C-c @r{(Capture buffer)}
+ #+findex: org-capture-finalize
+ Once you have finished entering information into the capture buffer,
+ {{{kbd(C-c C-c)}}} returns you to the window configuration before
+ the capture process, so that you can resume your work without
+ further distraction. When called with a prefix argument, finalize
+ and then jump to the captured item.
- {{{kbd(C-c C-w)}}} (~org-capture-refile~) ::
- #+kindex: C-c C-w @r{(Capture buffer)}
- #+findex: org-capture-refile
- Finalize the capture process by refiling the note to a different
- place (see [[*Refile and Copy]]). Please realize that this is a
- normal refiling command that will be executed---so point position
- at the moment you run this command is important. If you have
- inserted a tree with a parent and children, first move point back
- to the parent. Any prefix argument given to this command is
- passed on to the ~org-refile~ command.
+ #+kindex: C-c C-w @r{(Capture buffer)}
+ #+findex: org-capture-refile
+ Finalize the capture process by refiling the note to a different
+ place (see [[*Refile and Copy]]). Please realize that this is a normal
+ refiling command that will be executed---so point position at the
+ moment you run this command is important. If you have inserted
+ a tree with a parent and children, first move point back to the
+ parent. Any prefix argument given to this command is passed on to
+ the ~org-refile~ command.
- {{{kbd(C-c C-k)}}} (~org-capture-kill~) ::
- #+kindex: C-c C-k @r{(Capture buffer)}
- #+findex: org-capture-kill
- Abort the capture process and return to the previous state.
+ #+kindex: C-c C-k @r{(Capture buffer)}
+ #+findex: org-capture-kill
+ Abort the capture process and return to the previous state.
#+kindex: k c @r{(Agenda)}
You can also call ~org-capture~ in a special way from the agenda,
@@ -7084,12 +7351,12 @@ with prefix commands:
- {{{kbd(C-u M-x org-capture)}}} ::
- Visit the target location of a capture template. You get to
- select the template in the usual way.
+ Visit the target location of a capture template. You get to select
+ the template in the usual way.
- {{{kbd(C-u C-u M-x org-capture)}}} ::
- Visit the last stored capture item in its buffer.
+ Visit the last stored capture item in its buffer.
#+vindex: org-capture-bookmark
#+vindex: org-capture-last-stored
@@ -7111,9 +7378,9 @@ is through the customize interface.
- {{{kbd(C)}}} ::
- #+kindex: C @r{(Capture menu}
- #+vindex: org-capture-templates
- Customize the variable ~org-capture-templates~.
+ #+kindex: C @r{(Capture menu}
+ #+vindex: org-capture-templates
+ Customize the variable ~org-capture-templates~.
Before we give the formal description of template definitions, let's
look at an example. Say you would like to use one template to create
@@ -7130,7 +7397,6 @@ configuration would look like:
"* %?\nEntered on %U\n %i\n %a")))
#+end_src
-#+texinfo: @noindent
If you then press {{{kbd(t)}}} from the capture menu, Org will prepare
the template for you like this:
@@ -7165,330 +7431,327 @@ Now lets look at the elements of a template definition. Each entry in
- keys ::
- The keys that selects the template, as a string, characters only,
- for example ="a"=, for a template to be selected with a single
- key, or ="bt"= for selection with two keys. When using several
- keys, keys using the same prefix key must be sequential in the
- list and preceded by a 2-element entry explaining the prefix key,
- for example:
+ The keys that selects the template, as a string, characters only,
+ for example ="a"=, for a template to be selected with a single key,
+ or ="bt"= for selection with two keys. When using several keys,
+ keys using the same prefix key must be sequential in the list and
+ preceded by a 2-element entry explaining the prefix key, for
+ example:
- #+begin_src emacs-lisp
- ("b" "Templates for marking stuff to buy")
- #+end_src
+ #+begin_src emacs-lisp
+ ("b" "Templates for marking stuff to buy")
+ #+end_src
- If you do not define a template for the {{{kbd(C)}}} key, this
- key opens the Customize buffer for this complex variable.
+ If you do not define a template for the {{{kbd(C)}}} key, this key
+ opens the Customize buffer for this complex variable.
- description ::
- A short string describing the template, shown during selection.
+ A short string describing the template, shown during selection.
- type ::
- The type of entry, a symbol. Valid values are:
+ The type of entry, a symbol. Valid values are:
- - ~entry~ ::
+ - ~entry~ ::
- An Org mode node, with a headline. Will be filed as the child
- of the target entry or as a top-level entry. The target file
- should be an Org file.
+ An Org mode node, with a headline. Will be filed as the child of
+ the target entry or as a top-level entry. The target file should
+ be an Org file.
- - ~item~ ::
+ - ~item~ ::
- A plain list item, placed in the first plain list at the
- target location. Again the target file should be an Org
- file.
+ A plain list item, placed in the first plain list at the target
+ location. Again the target file should be an Org file.
- - ~checkitem~ ::
+ - ~checkitem~ ::
- A checkbox item. This only differs from the plain list item
- by the default template.
+ A checkbox item. This only differs from the plain list item by
+ the default template.
- - ~table-line~ ::
+ - ~table-line~ ::
- A new line in the first table at the target location. Where
- exactly the line will be inserted depends on the properties
- ~:prepend~ and ~:table-line-pos~ (see below).
+ A new line in the first table at the target location. Where
+ exactly the line will be inserted depends on the properties
+ ~:prepend~ and ~:table-line-pos~ (see below).
- - ~plain~ ::
+ - ~plain~ ::
- Text to be inserted as it is.
+ Text to be inserted as it is.
- target ::
- #+vindex: org-default-notes-file
- #+vindex: org-directory
- Specification of where the captured item should be placed. In
- Org files, targets usually define a node. Entries will become
- children of this node. Other types will be added to the table or
- list in the body of this node. Most target specifications
- contain a file name. If that file name is the empty string, it
- defaults to ~org-default-notes-file~. A file can also be given
- as a variable or as a function called with no argument. When an
- absolute path is not specified for a target, it is taken as
- relative to ~org-directory~.
+ #+vindex: org-default-notes-file
+ #+vindex: org-directory
+ Specification of where the captured item should be placed. In Org
+ files, targets usually define a node. Entries will become children
+ of this node. Other types will be added to the table or list in the
+ body of this node. Most target specifications contain a file name.
+ If that file name is the empty string, it defaults to
+ ~org-default-notes-file~. A file can also be given as a variable or
+ as a function called with no argument. When an absolute path is not
+ specified for a target, it is taken as relative to ~org-directory~.
- Valid values are:
+ Valid values are:
- - =(file "path/to/file")= ::
+ - =(file "path/to/file")= ::
- Text will be placed at the beginning or end of that file.
+ Text will be placed at the beginning or end of that file.
- - =(id "id of existing org entry")= ::
+ - =(id "id of existing org entry")= ::
- Filing as child of this entry, or in the body of the entry.
+ Filing as child of this entry, or in the body of the entry.
- - =(file+headline "filename" "node headline")= ::
+ - =(file+headline "filename" "node headline")= ::
- Fast configuration if the target heading is unique in the file.
+ Fast configuration if the target heading is unique in the file.
- - =(file+olp "filename" "Level 1 heading" "Level 2" ...)= ::
+ - =(file+olp "filename" "Level 1 heading" "Level 2" ...)= ::
- For non-unique headings, the full path is safer.
+ For non-unique headings, the full path is safer.
- - =(file+regexp "filename" "regexp to find location")= ::
+ - =(file+regexp "filename" "regexp to find location")= ::
- Use a regular expression to position point.
+ Use a regular expression to position point.
- - =(file+olp+datetree "filename" [ "Level 1 heading" ...])= ::
+ - =(file+olp+datetree "filename" [ "Level 1 heading" ...])= ::
- This target[fn:84] creates a heading in a date tree[fn:85] for
- today's date. If the optional outline path is given, the tree
- will be built under the node it is pointing to, instead of at
- top level. Check out the ~:time-prompt~ and ~:tree-type~
- properties below for additional options.
+ This target[fn:83] creates a heading in a date tree[fn:84] for
+ today's date. If the optional outline path is given, the tree
+ will be built under the node it is pointing to, instead of at top
+ level. Check out the ~:time-prompt~ and ~:tree-type~ properties
+ below for additional options.
- - =(file+function "filename" function-finding-location)= ::
+ - =(file+function "filename" function-finding-location)= ::
- A function to find the right location in the file.
+ A function to find the right location in the file.
- - =(clock)= ::
+ - =(clock)= ::
- File to the entry that is currently being clocked.
+ File to the entry that is currently being clocked.
- - =(function function-finding-location)= ::
+ - =(function function-finding-location)= ::
- Most general way: write your own function which both visits the
- file and moves point to the right location.
+ Most general way: write your own function which both visits the
+ file and moves point to the right location.
- template ::
- The template for creating the capture item. If you leave this
- empty, an appropriate default template will be used. Otherwise
- this is a string with escape codes, which will be replaced
- depending on time and context of the capture call. The string
- with escapes may be loaded from a template file, using the
- special syntax =(file "template filename")=. See below for more
- details.
+ The template for creating the capture item. If you leave this
+ empty, an appropriate default template will be used. Otherwise this
+ is a string with escape codes, which will be replaced depending on
+ time and context of the capture call. The string with escapes may
+ be loaded from a template file, using the special syntax =(file
+ "template filename")=. See below for more details.
- properties ::
- The rest of the entry is a property list of additional options.
- Recognized properties are:
+ The rest of the entry is a property list of additional options.
+ Recognized properties are:
- - ~:prepend~ ::
+ - ~:prepend~ ::
- Normally new captured information will be appended at the
- target location (last child, last table line, last list item,
- ...). Setting this property changes that.
+ Normally new captured information will be appended at the target
+ location (last child, last table line, last list item, ...).
+ Setting this property changes that.
- - ~:immediate-finish~ ::
+ - ~:immediate-finish~ ::
- When set, do not offer to edit the information, just file it
- away immediately. This makes sense if the template only needs
- information that can be added automatically.
+ When set, do not offer to edit the information, just file it away
+ immediately. This makes sense if the template only needs
+ information that can be added automatically.
- - ~:empty-lines~ ::
+ - ~:empty-lines~ ::
- Set this to the number of lines to insert before and after the
- new item. Default 0, and the only other common value is 1.
+ Set this to the number of lines to insert before and after the new
+ item. Default 0, and the only other common value is 1.
- - ~:clock-in~ ::
+ - ~:clock-in~ ::
- Start the clock in this item.
+ Start the clock in this item.
- - ~:clock-keep~ ::
+ - ~:clock-keep~ ::
- Keep the clock running when filing the captured entry.
+ Keep the clock running when filing the captured entry.
- - ~:clock-resume~ ::
+ - ~:clock-resume~ ::
- If starting the capture interrupted a clock, restart that clock
- when finished with the capture. Note that ~:clock-keep~ has
- precedence over ~:clock-resume~. When setting both to
- non-~nil~, the current clock will run and the previous one will
- not be resumed.
+ If starting the capture interrupted a clock, restart that clock
+ when finished with the capture. Note that ~:clock-keep~ has
+ precedence over ~:clock-resume~. When setting both to non-~nil~,
+ the current clock will run and the previous one will not be
+ resumed.
- - ~:time-prompt~ ::
+ - ~:time-prompt~ ::
- Prompt for a date/time to be used for date/week trees and when
- filling the template. Without this property, capture uses the
- current date and time. Even if this property has not been set,
- you can force the same behavior by calling ~org-capture~ with
- a {{{kbd(C-1)}}} prefix argument.
+ Prompt for a date/time to be used for date/week trees and when
+ filling the template. Without this property, capture uses the
+ current date and time. Even if this property has not been set,
+ you can force the same behavior by calling ~org-capture~ with
+ a {{{kbd(C-1)}}} prefix argument.
- - ~:tree-type~ ::
+ - ~:tree-type~ ::
- When ~week~, make a week tree instead of the month tree, i.e.,
- place the headings for each day under a heading with the
- current ISO week.
+ When ~week~, make a week tree instead of the month tree, i.e.,
+ place the headings for each day under a heading with the current
+ ISO week.
- - ~:unnarrowed~ ::
+ - ~:unnarrowed~ ::
- Do not narrow the target buffer, simply show the full buffer. Default
- is to narrow it so that you only see the new material.
+ Do not narrow the target buffer, simply show the full buffer.
+ Default is to narrow it so that you only see the new material.
- - ~:table-line-pos~ ::
+ - ~:table-line-pos~ ::
- Specification of the location in the table where the new line
- should be inserted. It should be a string like =II-3= meaning
- that the new line should become the third line before the
- second horizontal separator line.
+ Specification of the location in the table where the new line
+ should be inserted. It should be a string like =II-3= meaning
+ that the new line should become the third line before the second
+ horizontal separator line.
- - ~:kill-buffer~ ::
+ - ~:kill-buffer~ ::
- If the target file was not yet visited when capture was invoked, kill
- the buffer again after capture is completed.
+ If the target file was not yet visited when capture was invoked,
+ kill the buffer again after capture is completed.
- - ~:no-save~ ::
+ - ~:no-save~ ::
- Do not save the target file after finishing the capture.
+ Do not save the target file after finishing the capture.
**** Template expansion
:PROPERTIES:
:DESCRIPTION: Filling in information about time and context.
:END:
-In the template itself, special "%-escapes"[fn:86] allow dynamic
+In the template itself, special "%-escapes"[fn:85] allow dynamic
insertion of content. The templates are expanded in the order given
here:
- =%[FILE]= ::
- Insert the contents of the file given by {{{var(FILE)}}}.
+ Insert the contents of the file given by {{{var(FILE)}}}.
- =%(EXP)= ::
- Evaluate Elisp expression {{{var(EXP)}}} and replace it with the
- result. The {{{var(EXP)}}} form must return a string. Only
- placeholders pre-existing within the template, or introduced with
- =%[file]=, are expanded this way. Since this happens after
- expanding non-interactive "%-escapes", those can be used to fill
- the expression.
+ Evaluate Elisp expression {{{var(EXP)}}} and replace it with the
+ result. The {{{var(EXP)}}} form must return a string. Only
+ placeholders pre-existing within the template, or introduced with
+ =%[file]=, are expanded this way. Since this happens after
+ expanding non-interactive "%-escapes", those can be used to fill the
+ expression.
- =%<FORMAT>= ::
- The result of format-time-string on the {{{var(FORMAT)}}}
- specification.
+ The result of format-time-string on the {{{var(FORMAT)}}}
+ specification.
- =%t= ::
- Timestamp, date only.
+ Timestamp, date only.
- =%T= ::
- Timestamp, with date and time.
+ Timestamp, with date and time.
- =%u=, =%U= ::
- Like =%t=, =%T= above, but inactive timestamps.
+ Like =%t=, =%T= above, but inactive timestamps.
- =%i= ::
- Initial content, the region when capture is called while the
- region is active. If there is text before =%i= on the same line,
- such as indentation, and =%i= is not inside a =%(exp)= form, that
- prefix is added before every line in the inserted text.
+ Initial content, the region when capture is called while the region
+ is active. If there is text before =%i= on the same line, such as
+ indentation, and =%i= is not inside a =%(exp)= form, that prefix is
+ added before every line in the inserted text.
- =%a= ::
- Annotation, normally the link created with ~org-store-link~.
+ Annotation, normally the link created with ~org-store-link~.
- =%A= ::
- Like =%a=, but prompt for the description part.
+ Like =%a=, but prompt for the description part.
- =%l= ::
- Like =%a=, but only insert the literal link.
+ Like =%a=, but only insert the literal link.
- =%c= ::
- Current kill ring head.
+ Current kill ring head.
- =%x= ::
- Content of the X clipboard.
+ Content of the X clipboard.
- =%k= ::
- Title of the currently clocked task.
+ Title of the currently clocked task.
- =%K= ::
- Link to the currently clocked task.
+ Link to the currently clocked task.
- =%n= ::
- User name (taken from ~user-full-name~).
+ User name (taken from ~user-full-name~).
- =%f= ::
- File visited by current buffer when org-capture was called.
+ File visited by current buffer when org-capture was called.
- =%F= ::
- Full path of the file or directory visited by current buffer.
+ Full path of the file or directory visited by current buffer.
- =%:keyword= ::
- Specific information for certain link types, see below.
+ Specific information for certain link types, see below.
- =%^g= ::
- Prompt for tags, with completion on tags in target file.
+ Prompt for tags, with completion on tags in target file.
- =%^G= ::
- Prompt for tags, with completion all tags in all agenda files.
+ Prompt for tags, with completion all tags in all agenda files.
- =%^t= ::
- Like =%t=, but prompt for date. Similarly =%^T=, =%^u=, =%^U=. You may
- define a prompt like =%^{Birthday}t=.
+ Like =%t=, but prompt for date. Similarly =%^T=, =%^u=, =%^U=. You
+ may define a prompt like =%^{Birthday}t=.
- =%^C= ::
- Interactive selection of which kill or clip to use.
+ Interactive selection of which kill or clip to use.
- =%^L= ::
- Like =%^C=, but insert as link.
+ Like =%^C=, but insert as link.
- =%^{PROP}p= ::
- Prompt the user for a value for property {{{var(PROP)}}}.
+ Prompt the user for a value for property {{{var(PROP)}}}.
- =%^{PROMPT}= ::
- Prompt the user for a string and replace this sequence with it.
- You may specify a default value and a completion table with
- =%^{prompt|default|completion2|completion3...}=. The arrow keys
- access a prompt-specific history.
+ Prompt the user for a string and replace this sequence with it. You
+ may specify a default value and a completion table with
+ =%^{prompt|default|completion2|completion3...}=. The arrow keys
+ access a prompt-specific history.
- =%\N= ::
- Insert the text entered at the {{{var(N)}}}th =%^{PROMPT}=, where
- {{{var(N)}}} is a number, starting from 1.
+ Insert the text entered at the {{{var(N)}}}th =%^{PROMPT}=, where
+ {{{var(N)}}} is a number, starting from 1.
- =%?= ::
- After completing the template, position point here.
+ After completing the template, position point here.
#+vindex: org-store-link-props
-For specific link types, the following keywords are defined[fn:87]:
+For specific link types, the following keywords are defined[fn:86]:
-#+vindex: org-from-is-user-regexp
+#+vindex: org-link-from-user-regexp
| Link type | Available keywords |
|--------------+----------------------------------------------------------|
| bbdb | =%:name=, =%:company= |
@@ -7499,7 +7762,7 @@ For specific link types, the following keywords are defined[fn:87]:
| | =%:date= (message date header field) |
| | =%:date-timestamp= (date as active timestamp) |
| | =%:date-timestamp-inactive= (date as inactive timestamp) |
-| | =%:fromto= (either "to NAME" or "from NAME")[fn:88] |
+| | =%:fromto= (either "to NAME" or "from NAME")[fn:87] |
| gnus | =%:group=, for messages also all email fields |
| w3, w3m | =%:url= |
| info | =%:file=, =%:node= |
@@ -7535,125 +7798,267 @@ See the docstring of the variable for more information.
** Attachments
:PROPERTIES:
-:DESCRIPTION: Add files to tasks.
+:DESCRIPTION: Attach files to outlines.
:END:
#+cindex: attachments
-#+vindex: org-attach-directory
It is often useful to associate reference material with an outline
-node/task. Small chunks of plain text can simply be stored in the
-subtree of a project. Hyperlinks (see [[*Hyperlinks]]) can establish
-associations with files that live elsewhere on your computer or in the
-cloud, like emails or source code files belonging to a project.
-Another method is /attachments/, which are files located in
-a directory belonging to an outline node. Org uses directories named
-by the unique ID of each entry. These directories are located in the
-=data/= directory which lives in the same directory where your Org
-file lives[fn:89]. If you initialize this directory with =git init=,
-Org automatically commits changes when it sees them. The attachment
-system has been contributed to Org by John Wiegley.
-
-In cases where it seems better to do so, you can attach a directory of
-your choice to an entry. You can also make children inherit the
-attachment directory from a parent, so that an entire subtree uses the
-same attached directory.
+node. Small chunks of plain text can simply be stored in the subtree
+of a project. Hyperlinks (see [[*Hyperlinks]]) can establish associations
+with files that live elsewhere on your computer or in the cloud, like
+emails or source code files belonging to a project.
+
+Another method is /attachments/, which are files located in a
+directory belonging to an outline node. Org uses directories either
+named by a unique ID of each entry, or by a =DIR= property.
+
+*** Attachment defaults and dispatcher
+:PROPERTIES:
+:DESCRIPTION: How to access attachment commands
+:END:
+By default, org-attach will use ID properties when adding attachments
+to outline nodes. This makes working with attachments fully
+automated. There is no decision needed for folder-name or location.
+ID-based directories are by default located in the =data/= directory,
+which lives in the same directory where your Org file lives[fn:88].
+For more control over the setup, see [[*Attachment options]].
+
+When attachments are made using ~org-attach~ a default tag =ATTACH= is
+added to the node that gets the attachments.
The following commands deal with attachments:
- {{{kbd(C-c C-a)}}} (~org-attach~) ::
- #+kindex: C-c C-a
- #+findex: org-attach
- The dispatcher for commands related to the attachment system.
- After these keys, a list of commands is displayed and you must
- press an additional key to select a command:
+ #+kindex: C-c C-a
+ #+findex: org-attach
+ The dispatcher for commands related to the attachment system. After
+ these keys, a list of commands is displayed and you must press an
+ additional key to select a command:
+
+ - {{{kbd(a)}}} (~org-attach-attach~) ::
- - {{{kbd(a)}}} (~org-attach-attach~) ::
+ #+kindex: C-c C-a a
+ #+findex: org-attach-attach
+ #+vindex: org-attach-method
+ Select a file and move it into the task's attachment directory.
+ The file is copied, moved, or linked, depending on
+ ~org-attach-method~. Note that hard links are not supported on
+ all systems.
- #+kindex: C-c C-a a
- #+findex: org-attach-attach
- #+vindex: org-attach-method
- Select a file and move it into the task's attachment
- directory. The file is copied, moved, or linked, depending
- on ~org-attach-method~. Note that hard links are not
- supported on all systems.
+ - {{{kbd(c)}}}/{{{kbd(m)}}}/{{{kbd(l)}}} ::
- - {{{kbd(c)}}}/{{{kbd(m)}}}/{{{kbd(l)}}} ::
+ #+kindex: C-c C-a c
+ #+kindex: C-c C-a m
+ #+kindex: C-c C-a l
+ Attach a file using the copy/move/link method. Note that hard
+ links are not supported on all systems.
- #+kindex: C-c C-a c
- #+kindex: C-c C-a m
- #+kindex: C-c C-a l
- Attach a file using the copy/move/link method. Note that
- hard links are not supported on all systems.
+ - {{{kbd(b)}}} (~org-attach-buffer~) ::
- - {{{kbd(n)}}} (~org-attach-new~) ::
+ #+kindex: C-c C-a b
+ #+findex: org-attach-buffer
+ Select a buffer and save it as a file in the task's attachment
+ directory.
- #+kindex: C-c C-a n
- #+findex: org-attach-new
- Create a new attachment as an Emacs buffer.
+ - {{{kbd(n)}}} (~org-attach-new~) ::
- - {{{kbd(z)}}} (~org-attach-sync~) ::
+ #+kindex: C-c C-a n
+ #+findex: org-attach-new
+ Create a new attachment as an Emacs buffer.
- #+kindex: C-c C-a z
- #+findex: org-attach-sync
- Synchronize the current task with its attachment directory, in case
- you added attachments yourself.
+ - {{{kbd(z)}}} (~org-attach-sync~) ::
- - {{{kbd(o)}}} (~org-attach-open~) ::
+ #+kindex: C-c C-a z
+ #+findex: org-attach-sync
+ Synchronize the current task with its attachment directory, in
+ case you added attachments yourself.
- #+kindex: C-c C-a o
- #+findex: org-attach-open
- #+vindex: org-file-apps
- Open current task's attachment. If there is more than one,
- prompt for a file name first. Opening follows the rules set
- by ~org-file-apps~. For more details, see the information
- on following hyperlinks (see [[*Handling Links]]).
+ - {{{kbd(o)}}} (~org-attach-open~) ::
- - {{{kbd(O)}}} (~org-attach-open-in-emacs~) ::
+ #+kindex: C-c C-a o
+ #+findex: org-attach-open
+ #+vindex: org-file-apps
+ Open current task's attachment. If there is more than one, prompt
+ for a file name first. Opening follows the rules set by
+ ~org-file-apps~. For more details, see the information on
+ following hyperlinks (see [[*Handling Links]]).
- #+kindex: C-c C-a O
- #+findex: org-attach-open-in-emacs
- Also open the attachment, but force opening the file in
- Emacs.
+ - {{{kbd(O)}}} (~org-attach-open-in-emacs~) ::
- - {{{kbd(f)}}} (~org-attach-reveal~) ::
+ #+kindex: C-c C-a O
+ #+findex: org-attach-open-in-emacs
+ Also open the attachment, but force opening the file in Emacs.
- #+kindex: C-c C-a f
- #+findex: org-attach-reveal
- Open the current task's attachment directory.
+ - {{{kbd(f)}}} (~org-attach-reveal~) ::
- - {{{kbd(F)}}} (~org-attach-reveal-in-emacs~) ::
+ #+kindex: C-c C-a f
+ #+findex: org-attach-reveal
+ Open the current task's attachment directory.
- #+kindex: C-c C-a F
- #+findex: org-attach-reveal-in-emacs
- Also open the directory, but force using Dired in Emacs.
+ - {{{kbd(F)}}} (~org-attach-reveal-in-emacs~) ::
- - {{{kbd(d)}}} (~org-attach-delete-one~) ::
+ #+kindex: C-c C-a F
+ #+findex: org-attach-reveal-in-emacs
+ Also open the directory, but force using Dired in Emacs.
- #+kindex: C-c C-a d
- Select and delete a single attachment.
+ - {{{kbd(d)}}} (~org-attach-delete-one~) ::
- - {{{kbd(D)}}} (~org-attach-delete-all~) ::
+ #+kindex: C-c C-a d
+ Select and delete a single attachment.
- #+kindex: C-c C-a D
- Delete all of a task's attachments. A safer way is to open
- the directory in Dired and delete from there.
+ - {{{kbd(D)}}} (~org-attach-delete-all~) ::
- - {{{kbd(s)}}} (~org-attach-set-directory~) ::
+ #+kindex: C-c C-a D
+ Delete all of a task's attachments. A safer way is to open the
+ directory in Dired and delete from there.
- #+kindex: C-c C-a s
- #+cindex: @samp{ATTACH_DIR}, property
- Set a specific directory as the entry's attachment
- directory. This works by putting the directory path into
- the =ATTACH_DIR= property.
+ - {{{kbd(s)}}} (~org-attach-set-directory~) ::
- - {{{kbd(i)}}} (~org-attach-set-inherit~) ::
+ #+kindex: C-c C-a s
+ #+cindex: @samp{DIR}, property
+ Set a specific directory as the entry's attachment directory.
+ This works by putting the directory path into the =DIR=
+ property.
- #+kindex: C-c C-a i
- #+cindex: @samp{ATTACH_DIR_INHERIT}, property
- Set the =ATTACH_DIR_INHERIT= property, so that children use
- the same directory for attachments as the parent does.
+ - {{{kbd(S)}}} (~org-attach-unset-directory~) ::
+ #+kindex: C-c C-a S
+ #+cindex: @samp{DIR}, property
+ Remove the attachment directory. This command removes the =DIR=
+ property and asks the user to either move content inside that
+ folder, if an =ID= property is set, delete the content, or to
+ leave the attachment directory as is but no longer attached to the
+ outline node.
+
+*** Attachment options
+:PROPERTIES:
+:DESCRIPTION: Configuring the attachment system
+:END:
+There are a couple of options for attachments that are worth
+mentioning.
+
+- ~org-attach-id-dir~ ::
+ #+vindex: org-attach-id-dir
+ The directory where attachments are stored when =ID= is used as
+ method.
+
+- ~org-attach-dir-relative~ ::
+ #+vindex: org-attach-dir-relative
+ When setting the =DIR= property on a node using {{{kbd(C-c C-a s)}}}
+ (~org-attach-set-directory~), absolute links are entered by default.
+ This option changes that to relative links.
+
+- ~org-attach-use-inheritance~ ::
+ #+vindex: org-attach-use-inheritance
+ By default folders attached to an outline node are inherited from
+ parents according to ~org-use-property-inheritance~. If one instead
+ want to set inheritance specifically for org-attach that can be done
+ using ~org-attach-use-inheritance~. Inheriting documents through
+ the node hierarchy makes a lot of sense in most cases. Especially
+ since the introduction of [[* Attachment links]]. The following example
+ shows one use case for attachment inheritance:
+
+ #+begin_example
+ ,* Chapter A ...
+ :PROPERTIES:
+ :DIR: Chapter A/
+ :END:
+ ,** Introduction
+ Some text
+
+ #+NAME: Image 1
+ [[Attachment:image 1.jpg]]
+ #+end_example
+
+ Without inheritance one would not be able to resolve the link to
+ image =1.jpg=, since the link is inside a sub-heading to =Chapter
+ A=.
+
+ Inheritance works the same way for both =ID= and =DIR= property. If
+ both properties are defined on the same headline then =DIR= takes
+ precedance. This is also true if inheritance is enabled. If =DIR=
+ is inherited from a parent node in the outline, that property still
+ takes precedence over an =ID= property defined on the node itself.
+
+- ~org-attach-method~ ::
+ #+vindex: org-attach-method
+ When attaching files using the dispatcher {{{kbd(C-c C-a)}}} it
+ defaults to copying files. The behaviour can be changed by
+ customizing ~org-attach-method~. Options are Copy, Move/Rename,
+ Hard link or Symbolic link.
+
+- ~org-attach-preferred-new-method~ ::
+ #+vindex: org-attach-preferred-new-method
+ This customization lets you choose the default way to attach to
+ nodes without existing =ID= and =DIR= property. It defaults to ~id~
+ but can also be set to ~dir~, ~ask~ or ~nil~.
+
+- ~org-attach-archive-delete~ ::
+ #+vindex: org-attach-archive-delete
+ Configure this to determine if attachments should be deleted or not
+ when a subtree that has attachments is archived.
+
+- ~org-attach-auto-tag~ ::
+ #+vindex: org-attach-auto-tag
+ When attaching files to a heading it will be assigned a tag
+ according to what is set here.
+
+- ~org-attach-id-to-path-function-list~ ::
+ #+vindex: org-attach-id-to-path-function-list
+ When =ID= is used for attachments, the ID is parsed into a part of a
+ directory-path. See ~org-attach-id-uuid-folder-format~ for the
+ default function. Define a new one and add it as first element in
+ ~org-attach-id-to-path-function-list~ if you want the folder
+ structure in any other way. All functions in this list will be
+ tried when resolving existing ID's into paths, to maintain backward
+ compatibility with existing folders in your system.
+
+- ~org-attach-expert~ ::
+ #+vindex: org-attach-expert
+ Do not show the splash buffer with the attach dispatcher when
+ ~org-attach-expert~ is set to non-~nil~.
+
+See customization group =Org Attach= if you want to change the
+default settings.
+
+*** Attachment links
+:PROPERTIES:
+:DESCRIPTION: Hyperlink access to attachments
+:END:
+Attached files and folders can be referenced using attachment links.
+This makes it easy to refer to the material added to an outline node.
+Especially if it was attached using the unique ID of the entry!
+
+#+begin_example
+,* TODO Some task
+ :PROPERTIES:
+ :ID: 95d50008-c12e-479f-a4f2-cc0238205319
+ :END:
+See attached document for more information: [[attachment:info.org]]
+#+end_example
+
+See [[*External Links]] for more information about these links.
+
+*** Automatic version-control with Git
+:PROPERTIES:
+:DESCRIPTION: Everything safely stored away
+:END:
+If the directory attached to an outline node is a Git repository, Org
+can be configured to automatically commit changes to that repository
+when it sees them.
+
+To make Org mode take care of versioning of attachments for you, add
+the following to your Emacs config:
+
+#+begin_src emacs-lisp
+ (require 'org-attach-git)
+#+end_src
+
+*** Attach from Dired
+:PROPERTIES:
+:DESCRIPTION: Using dired to select an attachment
+:END:
#+cindex: attach from Dired
#+findex: org-attach-dired-to-subtree
It is possible to attach files to a subtree from a Dired buffer. To
@@ -7717,14 +8122,14 @@ Entries=, whenever the following command is used:
- {{{kbd(C-c C-x g)}}} (~org-feed-update-all~) ::
- #+kindex: C-c C-x g
- Collect items from the feeds configured in ~org-feed-alist~ and
- act upon them.
+ #+kindex: C-c C-x g
+ Collect items from the feeds configured in ~org-feed-alist~ and act
+ upon them.
- {{{kbd(C-c C-x G)}}} (~org-feed-goto-inbox~) ::
- #+kindex: C-c C-x G
- Prompt for a feed name and go to the inbox configured for this feed.
+ #+kindex: C-c C-x G
+ Prompt for a feed name and go to the inbox configured for this feed.
Under the same headline, Org creates a drawer =FEEDSTATUS= in which it
stores information about the status of items in the feed, to avoid
@@ -7733,441 +8138,6 @@ adding the same item several times.
For more information, including how to read atom feeds, see
=org-feed.el= and the docstring of ~org-feed-alist~.
-** Protocols for External Access
-:PROPERTIES:
-:DESCRIPTION: External access to Emacs and Org.
-:ALT_TITLE: Protocols
-:END:
-#+cindex: protocols, for external access
-
-Org protocol is a means to trigger custom actions in Emacs from
-external applications. Any application that supports calling external
-programs with an URL as argument may be used with this functionality.
-For example, you can configure bookmarks in your web browser to send
-a link to the current page to Org and create a note from it using
-capture (see [[*Capture]]). You can also create a bookmark that tells
-Emacs to open the local source file of a remote website you are
-browsing.
-
-#+cindex: Org protocol, set-up
-#+cindex: Installing Org protocol
-In order to use Org protocol from an application, you need to register
-=org-protocol://= as a valid scheme-handler. External calls are
-passed to Emacs through the =emacsclient= command, so you also need to
-ensure an Emacs server is running. More precisely, when the
-application calls
-
-: emacsclient org-protocol://PROTOCOL?key1=val1&key2=val2
-
-#+texinfo: @noindent
-Emacs calls the handler associated to {{{var(PROTOCOL)}}} with
-argument =(:key1 val1 :key2 val2)=.
-
-#+cindex: protocol, new protocol
-#+cindex: defining new protocols
-Org protocol comes with three predefined protocols, detailed in the
-following sections. Configure ~org-protocol-protocol-alist~ to define
-your own.
-
-*** ~store-link~ protocol
-:PROPERTIES:
-:DESCRIPTION: Store a link, push URL to kill-ring.
-:END:
-#+cindex: store-link protocol
-#+cindex: protocol, store-link
-
-Using ~store-link~ handler, you can copy links, insertable through
-{{{kbd(M-x org-insert-link)}}} or yanking thereafter. More precisely,
-the command
-
-: emacsclient org-protocol://store-link?url=URL&title=TITLE
-
-#+texinfo: @noindent
-stores the following link:
-
-: [[URL][TITLE]]
-
-In addition, {{{var(URL)}}} is pushed on the kill-ring for yanking.
-You need to encode {{{var(URL)}}} and {{{var(TITLE)}}} if they contain
-slashes, and probably quote those for the shell.
-
-To use this feature from a browser, add a bookmark with an arbitrary
-name, e.g., =Org: store-link= and enter this as /Location/:
-
-#+begin_example
-javascript:location.href='org-protocol://store-link?url='+
- encodeURIComponent(location.href);
-#+end_example
-
-*** ~capture~ protocol
-:PROPERTIES:
-:DESCRIPTION: Fill a buffer with external information.
-:END:
-#+cindex: capture protocol
-#+cindex: protocol, capture
-
-Activating "capture" handler pops up a =Capture= buffer and fills the
-capture template associated to the =X= key with them.
-
-: emacsclient org-protocol://capture?template=X?url=URL?title=TITLE?body=BODY
-
-To use this feature, add a bookmark with an arbitrary name, e.g.,
-=Org: capture=, and enter this as =Location=:
-
-#+begin_example
-javascript:location.href='org-protocol://capture?template=x'+
- '&url='+encodeURIComponent(window.location.href)+
- '&title='+encodeURIComponent(document.title)+
- '&body='+encodeURIComponent(window.getSelection());
-#+end_example
-
-#+vindex: org-protocol-default-template-key
-The result depends on the capture template used, which is set in the
-bookmark itself, as in the example above, or in
-~org-protocol-default-template-key~.
-
-The following template placeholders are available:
-
-#+begin_example
-%:link The URL
-%:description The webpage title
-%:annotation Equivalent to [[%:link][%:description]]
-%i The selected text
-#+end_example
-
-*** ~open-source~ protocol
-:PROPERTIES:
-:DESCRIPTION: Edit published contents.
-:END:
-#+cindex: open-source protocol
-#+cindex: protocol, open-source
-
-The ~open-source~ handler is designed to help with editing local
-sources when reading a document. To that effect, you can use
-a bookmark with the following location:
-
-#+begin_example
-javascript:location.href='org-protocol://open-source?&url='+
- encodeURIComponent(location.href)
-#+end_example
-
-#+vindex: org-protocol-project-alist
-The variable ~org-protocol-project-alist~ maps URLs to local file
-names, by stripping URL parameters from the end and replacing the
-~:base-url~ with ~:working-directory~ and ~:online-suffix~ with
-~:working-suffix~. For example, assuming you own a local copy of
-=https://orgmode.org/worg/= contents at =/home/user/worg=, you can set
-~org-protocol-project-alist~ to the following
-
-#+begin_src emacs-lisp
-(setq org-protocol-project-alist
- '(("Worg"
- :base-url "https://orgmode.org/worg/"
- :working-directory "/home/user/worg/"
- :online-suffix ".html"
- :working-suffix ".org")))
-#+end_src
-
-#+texinfo: @noindent
-If you are now browsing
-=https://orgmode.org/worg/org-contrib/org-protocol.html= and find
-a typo or have an idea about how to enhance the documentation, simply
-click the bookmark and start editing.
-
-#+cindex: rewritten URL in open-source protocol
-#+cindex: protocol, open-source rewritten URL
-However, such mapping may not yield the desired results. Suppose you
-maintain an online store located at =http://example.com/=. The local
-sources reside in =/home/user/example/=. It is common practice to
-serve all products in such a store through one file and rewrite URLs
-that do not match an existing file on the server. That way, a request
-to =http://example.com/print/posters.html= might be rewritten on the
-server to something like
-=http://example.com/shop/products.php/posters.html.php=. The
-~open-source~ handler probably cannot find a file named
-=/home/user/example/print/posters.html.php= and fails.
-
-Such an entry in ~org-protocol-project-alist~ may hold an additional
-property ~:rewrites~. This property is a list of cons cells, each of
-which maps a regular expression to a path relative to the
-~:working-directory~.
-
-Now map the URL to the path =/home/user/example/products.php= by
-adding ~:rewrites~ rules like this:
-
-#+begin_src emacs-lisp
-(setq org-protocol-project-alist
- '(("example.com"
- :base-url "http://example.com/"
- :working-directory "/home/user/example/"
- :online-suffix ".php"
- :working-suffix ".php"
- :rewrites (("example.com/print/" . "products.php")
- ("example.com/$" . "index.php")))))
-#+end_src
-
-#+texinfo: @noindent
-Since =example.com/$= is used as a regular expression, it maps
-=http://example.com/=, =https://example.com=,
-=http://www.example.com/= and similar to
-=/home/user/example/index.php=.
-
-The ~:rewrites~ rules are searched as a last resort if and only if no
-existing file name is matched.
-
-#+cindex: protocol, open-source, set-up mapping
-#+cindex: mappings in open-source protocol
-#+findex: org-protocol-create
-#+findex: org-protocol-create-for-org
-Two functions can help you filling ~org-protocol-project-alist~ with
-valid contents: ~org-protocol-create~ and
-~org-protocol-create-for-org~. The latter is of use if you're editing
-an Org file that is part of a publishing project.
-
-** Refile and Copy
-:PROPERTIES:
-:DESCRIPTION: Moving/copying a tree from one place to another.
-:END:
-#+cindex: refiling notes
-#+cindex: copying notes
-
-When reviewing the captured data, you may want to refile or to copy
-some of the entries into a different list, for example into a project.
-Cutting, finding the right location, and then pasting the note is
-cumbersome. To simplify this process, you can use the following
-special command:
-
-- {{{kbd(C-c M-w)}}} (~org-copy~) ::
-
- #+kindex: C-c M-w
- #+findex: org-copy
- Copying works like refiling, except that the original note is not
- deleted.
-
-- {{{kbd(C-c C-w)}}} (~org-refile~) ::
-
- #+kindex: C-c C-w
- #+findex: org-refile
- #+vindex: org-reverse-note-order
- #+vindex: org-refile-targets
- #+vindex: org-refile-use-outline-path
- #+vindex: org-outline-path-complete-in-steps
- #+vindex: org-refile-allow-creating-parent-nodes
- #+vindex: org-log-refile
- Refile the entry or region at point. This command offers
- possible locations for refiling the entry and lets you select one
- with completion. The item (or all items in the region) is filed
- below the target heading as a subitem. Depending on
- ~org-reverse-note-order~, it is either the first or last subitem.
-
- By default, all level 1 headlines in the current buffer are
- considered to be targets, but you can have more complex
- definitions across a number of files. See the variable
- ~org-refile-targets~ for details. If you would like to select
- a location via a file-path-like completion along the outline
- path, see the variables ~org-refile-use-outline-path~ and
- ~org-outline-path-complete-in-steps~. If you would like to be
- able to create new nodes as new parents for refiling on the fly,
- check the variable ~org-refile-allow-creating-parent-nodes~.
- When the variable ~org-log-refile~[fn:90] is set, a timestamp or
- a note is recorded whenever an entry is refiled.
-
-- {{{kbd(C-u C-c C-w)}}} ::
-
- #+kindex: C-u C-c C-w
- Use the refile interface to jump to a heading.
-
-- {{{kbd(C-u C-u C-c C-w)}}} (~org-refile-goto-last-stored~) ::
-
- #+kindex: C-u C-u C-c C-w
- #+findex: org-refile-goto-last-stored
- Jump to the location where ~org-refile~ last moved a tree to.
-
-- {{{kbd(C-2 C-c C-w)}}} ::
-
- #+kindex: C-2 C-c C-w
- Refile as the child of the item currently being clocked.
-
-- {{{kbd(C-3 C-c C-w)}}} ::
-
- #+kindex: C-3 C-c C-w
- #+vindex: org-refile-keep
- Refile and keep the entry in place. Also see ~org-refile-keep~
- to make this the default behavior, and beware that this may
- result in duplicated =ID= properties.
-
-- {{{kbd(C-0 C-c C-w)}}} or {{{kbd(C-u C-u C-u C-c C-w)}}} (~org-refile-cache-clear~) ::
-
- #+kindex: C-u C-u C-u C-c C-w
- #+kindex: C-0 C-c C-w
- #+findex: org-refile-cache-clear
- #+vindex: org-refile-use-cache
- Clear the target cache. Caching of refile targets can be turned
- on by setting ~org-refile-use-cache~. To make the command see
- new possible targets, you have to clear the cache with this
- command.
-
-** Archiving
-:PROPERTIES:
-:DESCRIPTION: What to do with finished products.
-:END:
-#+cindex: archiving
-
-When a project represented by a (sub)tree is finished, you may want to
-move the tree out of the way and to stop it from contributing to the
-agenda. Archiving is important to keep your working files compact and
-global searches like the construction of agenda views fast.
-
-- {{{kbd(C-c C-x C-a)}}} (~org-archive-subtree-default~) ::
-
- #+kindex: C-c C-x C-a
- #+findex: org-archive-subtree-default
- #+vindex: org-archive-default-command
- Archive the current entry using the command specified in the
- variable ~org-archive-default-command~.
-
-*** Moving a tree to an archive file
-:PROPERTIES:
-:DESCRIPTION: Moving a tree to an archive file.
-:ALT_TITLE: Moving subtrees
-:END:
-#+cindex: external archiving
-
-The most common archiving action is to move a project tree to another
-file, the archive file.
-
-- {{{kbd(C-c C-x C-s)}}} or short {{{kbd(C-c $)}}} (~org-archive-subtree~) ::
-
- #+kindex: C-c C-x C-s
- #+kindex: C-c $
- #+findex: org-archive-subtree
- #+vindex: org-archive-location
- Archive the subtree starting at point position to the location
- given by ~org-archive-location~.
-
-- {{{kbd(C-u C-c C-x C-s)}}} ::
-
- #+kindex: C-u C-c C-x C-s
- Check if any direct children of the current headline could be
- moved to the archive. To do this, check each subtree for open
- TODO entries. If none is found, the command offers to move it to
- the archive location. If point is /not/ on a headline when this
- command is invoked, check level 1 trees.
-
-- {{{kbd(C-u C-u C-c C-x C-s)}}} ::
-
- #+kindex: C-u C-u C-c C-x C-s
- As above, but check subtree for timestamps instead of TODO
- entries. The command offers to archive the subtree if it /does/
- contain a timestamp, and that timestamp is in the past.
-
-#+cindex: archive locations
-The default archive location is a file in the same directory as the
-current file, with the name derived by appending =_archive= to the
-current file name. You can also choose what heading to file archived
-items under, with the possibility to add them to a datetree in a file.
-For information and examples on how to specify the file and the
-heading, see the documentation string of the variable
-~org-archive-location~.
-
-There is also an in-buffer option for setting this variable, for
-example:
-
-#+cindex: @samp{ARCHIVE}, keyword
-: #+ARCHIVE: %s_done::
-
-#+cindex: ARCHIVE, property
-If you would like to have a special archive location for a single
-entry or a (sub)tree, give the entry an =ARCHIVE= property with the
-location as the value (see [[*Properties and Columns]]).
-
-#+vindex: org-archive-save-context-info
-When a subtree is moved, it receives a number of special properties
-that record context information like the file from where the entry
-came, its outline path the archiving time etc. Configure the variable
-~org-archive-save-context-info~ to adjust the amount of information
-added.
-
-*** Internal archiving
-:PROPERTIES:
-:DESCRIPTION: Switch off a tree but keep it in the file.
-:END:
-
-#+cindex: @samp{ARCHIVE}, tag
-If you want to just switch off---for agenda views---certain subtrees
-without moving them to a different file, you can use the =ARCHIVE=
-tag.
-
-A headline that is marked with the =ARCHIVE= tag (see [[*Tags]]) stays at
-its location in the outline tree, but behaves in the following way:
-
--
- #+vindex: org-cycle-open-archived-trees
- It does not open when you attempt to do so with a visibility cycling
- command (see [[*Visibility Cycling]]). You can force cycling archived
- subtrees with {{{kbd(C-TAB)}}}, or by setting the option
- ~org-cycle-open-archived-trees~. Also normal outline commands, like
- ~outline-show-all~, open archived subtrees.
-
--
- #+vindex: org-sparse-tree-open-archived-trees
- During sparse tree construction (see [[*Sparse Trees]]), matches in
- archived subtrees are not exposed, unless you configure the option
- ~org-sparse-tree-open-archived-trees~.
-
--
- #+vindex: org-agenda-skip-archived-trees
- During agenda view construction (see [[*Agenda Views]]), the content of
- archived trees is ignored unless you configure the option
- ~org-agenda-skip-archived-trees~, in which case these trees are
- always included. In the agenda you can press {{{kbd(v a)}}} to get
- archives temporarily included.
-
--
- #+vindex: org-export-with-archived-trees
- Archived trees are not exported (see [[*Exporting]]), only the headline
- is. Configure the details using the variable
- ~org-export-with-archived-trees~.
-
--
- #+vindex: org-columns-skip-archived-trees
- Archived trees are excluded from column view unless the variable
- ~org-columns-skip-archived-trees~ is configured to ~nil~.
-
-The following commands help manage the =ARCHIVE= tag:
-
-- {{{kbd(C-c C-x a)}}} (~org-toggle-archive-tag~) ::
-
- #+kindex: C-c C-x a
- #+findex: org-toggle-archive-tag
- Toggle the archive tag for the current headline. When the tag is
- set, the headline changes to a shadowed face, and the subtree
- below it is hidden.
-
-- {{{kbd(C-u C-c C-x a)}}} ::
-
- #+kindex: C-u C-c C-x a
- Check if any direct children of the current headline should be
- archived. To do this, check each subtree for open TODO entries.
- If none is found, the command offers to set the =ARCHIVE= tag for
- the child. If point is /not/ on a headline when this command is
- invoked, check the level 1 trees.
-
-- {{{kbd(C-TAB)}}} (~org-force-cycle-archived~) ::
-
- #+kindex: C-TAB
- Cycle a tree even if it is tagged with =ARCHIVE=.
-
-- {{{kbd(C-c C-x A)}}} (~org-archive-to-archive-sibling~) ::
-
- #+kindex: C-c C-x A
- #+findex: org-archive-to-archive-sibling
- Move the current entry to the /Archive Sibling/. This is
- a sibling of the entry with the heading =Archive= and the archive
- tag. The entry becomes a child of that sibling and in this way
- retains a lot of its original context, including inherited tags
- and approximate position in the outline.
-
* Agenda Views
:PROPERTIES:
:DESCRIPTION: Collecting information into views.
@@ -8229,44 +8199,44 @@ the window configuration is restored when the agenda exits:
#+vindex: org-agenda-files
The information to be shown is normally collected from all /agenda
-files/, the files listed in the variable ~org-agenda-files~[fn:91].
+files/, the files listed in the variable ~org-agenda-files~[fn:89].
If a directory is part of this list, all files with the extension
=.org= in this directory are part of the list.
Thus, even if you only work with a single Org file, that file should
-be put into the list[fn:92]. You can customize ~org-agenda-files~,
+be put into the list[fn:90]. You can customize ~org-agenda-files~,
but the easiest way to maintain it is through the following commands
#+attr_texinfo: :sep and
- {{{kbd(C-c [)}}} (~org-agenda-file-to-front~) ::
- #+kindex: C-c [
- #+findex: org-agenda-file-to-front
- #+cindex: files, adding to agenda list
- Add current file to the list of agenda files. The file is added
- to the front of the list. If it was already in the list, it is
- moved to the front. With a prefix argument, file is added/moved
- to the end.
+ #+kindex: C-c [
+ #+findex: org-agenda-file-to-front
+ #+cindex: files, adding to agenda list
+ Add current file to the list of agenda files. The file is added to
+ the front of the list. If it was already in the list, it is moved
+ to the front. With a prefix argument, file is added/moved to the
+ end.
- {{{kbd(C-c ])}}} (~org-remove-file~) ::
- #+kindex: C-c ]
- #+findex: org-remove-file
- Remove current file from the list of agenda files.
+ #+kindex: C-c ]
+ #+findex: org-remove-file
+ Remove current file from the list of agenda files.
- {{{kbd(C-')}}} and {{{kbd(C-\,)}}} (~org-cycle-agenda-files~) ::
- #+kindex: C-'
- #+kindex: C-,
- #+findex: org-cycle-agenda-files
- #+cindex: cycling, of agenda files
- Cycle through agenda file list, visiting one file after the other.
+ #+kindex: C-'
+ #+kindex: C-,
+ #+findex: org-cycle-agenda-files
+ #+cindex: cycling, of agenda files
+ Cycle through agenda file list, visiting one file after the other.
- {{{kbd(M-x org-switchb)}}} ::
- #+findex: org-switchb
- Command to use an iswitchb-like interface to switch to and
- between Org buffers.
+ #+findex: org-switchb
+ Command to use an Iswitchb-like interface to switch to and between
+ Org buffers.
#+texinfo: @noindent
The Org menu contains the current list of files and can be used to
@@ -8281,39 +8251,39 @@ scope for an extended period, use the following commands:
- {{{kbd(C-c C-x <)}}} (~org-agenda-set-restriction-lock~) ::
- #+kindex: C-c C-x <
- #+findex: org-agenda-set-restriction-lock
- Restrict the agenda to the current subtree. If there already is
- a restriction at point, remove it. When called with a universal
- prefix argument or with point before the first headline in
- a file, set the agenda scope to the entire file. This
- restriction remains in effect until removed with {{{kbd(C-c C-x
- >)}}}, or by typing either {{{kbd(<)}}} or {{{kbd(>)}}} in the
- agenda dispatcher. If there is a window displaying an agenda
- view, the new restriction takes effect immediately.
+ #+kindex: C-c C-x <
+ #+findex: org-agenda-set-restriction-lock
+ Restrict the agenda to the current subtree. If there already is
+ a restriction at point, remove it. When called with a universal
+ prefix argument or with point before the first headline in a file,
+ set the agenda scope to the entire file. This restriction remains
+ in effect until removed with {{{kbd(C-c C-x >)}}}, or by typing
+ either {{{kbd(<)}}} or {{{kbd(>)}}} in the agenda dispatcher. If
+ there is a window displaying an agenda view, the new restriction
+ takes effect immediately.
- {{{kbd(C-c C-x >)}}} (~org-agenda-remove-restriction-lock~) ::
- #+kindex: C-c C-x >
- #+findex: org-agenda-remove-restriction-lock
- Remove the restriction created by {{{kbd(C-c C-x <)}}}.
+ #+kindex: C-c C-x >
+ #+findex: org-agenda-remove-restriction-lock
+ Remove the restriction created by {{{kbd(C-c C-x <)}}}.
When working with Speedbar, you can use the following commands in the
Speedbar frame:
- {{{kbd(<)}}} (~org-speedbar-set-agenda-restriction~) ::
- #+findex: org-speedbar-set-agenda-restriction
- Restrict the agenda to the item---either an Org file or a subtree
- in such a file---at point in the Speedbar frame. If agenda is
- already restricted there, remove the restriction. If there is
- a window displaying an agenda view, the new restriction takes
- effect immediately.
+ #+findex: org-speedbar-set-agenda-restriction
+ Restrict the agenda to the item---either an Org file or a subtree in
+ such a file---at point in the Speedbar frame. If agenda is already
+ restricted there, remove the restriction. If there is a window
+ displaying an agenda view, the new restriction takes effect
+ immediately.
- {{{kbd(>)}}} (~org-agenda-remove-restriction-lock~) ::
- #+findex: org-agenda-remove-restriction-lock
- Remove the restriction.
+ #+findex: org-agenda-remove-restriction-lock
+ Remove the restriction.
** The Agenda Dispatcher
:PROPERTIES:
@@ -8329,71 +8299,71 @@ It displays a menu from which an additional letter is required to
execute a command. The dispatcher offers the following default
commands:
+#+attr_texinfo: :sep ,
- {{{kbd(a)}}} ::
- Create the calendar-like agenda (see [[*Weekly/daily agenda]]).
+ Create the calendar-like agenda (see [[*Weekly/daily agenda]]).
-- {{{kbd(t)}}} or {{{kbd(T)}}} ::
+- {{{kbd(t)}}}, {{{kbd(T)}}} ::
- Create a list of all TODO items (see [[*The global TODO list]]).
+ Create a list of all TODO items (see [[*The global TODO list]]).
-- {{{kbd(m)}}} or {{{kbd(M)}}} ::
+- {{{kbd(m)}}}, {{{kbd(M)}}} ::
- Create a list of headlines matching a given expression (see
- [[*Matching tags and properties]]).
+ Create a list of headlines matching a given expression (see
+ [[*Matching tags and properties]]).
- {{{kbd(s)}}} ::
- #+kindex: s @r{(Agenda dispatcher)}
- Create a list of entries selected by a boolean expression of
- keywords and/or regular expressions that must or must not occur
- in the entry.
+ #+kindex: s @r{(Agenda dispatcher)}
+ Create a list of entries selected by a boolean expression of
+ keywords and/or regular expressions that must or must not occur in
+ the entry.
- {{{kbd(/)}}} ::
- #+kindex: / @r{(Agenda dispatcher)}
- #+vindex: org-agenda-text-search-extra-files
- Search for a regular expression in all agenda files and
- additionally in the files listed in
- ~org-agenda-text-search-extra-files~. This uses the Emacs
- command ~multi-occur~. A prefix argument can be used to specify
- the number of context lines for each match, default is
- 1.
+ #+kindex: / @r{(Agenda dispatcher)}
+ #+vindex: org-agenda-text-search-extra-files
+ Search for a regular expression in all agenda files and additionally
+ in the files listed in ~org-agenda-text-search-extra-files~. This
+ uses the Emacs command ~multi-occur~. A prefix argument can be used
+ to specify the number of context lines for each match, default is
+ 1.
-- {{{kbd(#)}}} or {{{kbd(!)}}} ::
+- {{{kbd(#)}}}, {{{kbd(!)}}} ::
- Create a list of stuck projects (see [[*Stuck projects]]).
+ Create a list of stuck projects (see [[*Stuck projects]]).
- {{{kbd(<)}}} ::
- #+kindex: < @r{(Agenda dispatcher)}
- Restrict an agenda command to the current buffer[fn:93]. After
- pressing {{{kbd(<)}}}, you still need to press the character
- selecting the command.
+ #+kindex: < @r{(Agenda dispatcher)}
+ Restrict an agenda command to the current buffer[fn:91]. If
+ narrowing is in effect restrict to the narrowed part of the buffer.
+ After pressing {{{kbd(<)}}}, you still need to press the character
+ selecting the command.
- {{{kbd(< <)}}} ::
- #+kindex: < < @r{(Agenda dispatcher)}
- If there is an active region, restrict the following agenda
- command to the region. Otherwise, restrict it to the current
- subtree[fn:94]. After pressing {{{kbd(< <)}}}, you still need to
- press the character selecting the command.
+ #+kindex: < < @r{(Agenda dispatcher)}
+ If there is an active region, restrict the following agenda command
+ to the region. Otherwise, restrict it to the current
+ subtree[fn:92]. After pressing {{{kbd(< <)}}}, you still need to
+ press the character selecting the command.
- {{{kbd(*)}}} ::
- #+kindex: * @r{(Agenda dispatcher)}
- #+vindex: org-agenda-sticky
- #+findex: org-toggle-sticky-agenda
- Toggle sticky agenda views. By default, Org maintains only
- a single agenda buffer and rebuilds it each time you change the
- view, to make sure everything is always up to date. If you
- switch between views often and the build time bothers you, you
- can turn on sticky agenda buffers (make this the default by
- customizing the variable ~org-agenda-sticky~). With sticky
- agendas, the dispatcher only switches to the selected view, you
- need to update it by hand with {{{kbd(r)}}} or {{{kbd(g)}}}. You
- can toggle sticky agenda view any time with
- ~org-toggle-sticky-agenda~.
+ #+kindex: * @r{(Agenda dispatcher)}
+ #+vindex: org-agenda-sticky
+ #+findex: org-toggle-sticky-agenda
+ Toggle sticky agenda views. By default, Org maintains only a single
+ agenda buffer and rebuilds it each time you change the view, to make
+ sure everything is always up to date. If you switch between views
+ often and the build time bothers you, you can turn on sticky agenda
+ buffers (make this the default by customizing the variable
+ ~org-agenda-sticky~). With sticky agendas, the dispatcher only
+ switches to the selected view, you need to update it by hand with
+ {{{kbd(r)}}} or {{{kbd(g)}}}. You can toggle sticky agenda view any
+ time with ~org-toggle-sticky-agenda~.
You can also define custom commands that are accessible through the
dispatcher, just like the default commands. This includes the
@@ -8422,13 +8392,13 @@ a paper agenda, showing all the tasks for the current week or day.
- {{{kbd(M-x org-agenda a)}}} (~org-agenda-list~) ::
- #+kindex: a @r{(Agenda dispatcher)}
- #+findex: org-agenda-list
- #+cindex: org-agenda, command
- Compile an agenda for the current week from a list of Org files.
- The agenda shows the entries for each day. With a numeric prefix
- argument[fn:95]---like {{{kbd(C-u 2 1 M-x org-agenda a)}}}---you
- may set the number of days to be displayed.
+ #+kindex: a @r{(Agenda dispatcher)}
+ #+findex: org-agenda-list
+ #+cindex: org-agenda, command
+ Compile an agenda for the current week from a list of Org files.
+ The agenda shows the entries for each day. With a numeric prefix
+ argument[fn:93]---like {{{kbd(C-u 2 1 M-x org-agenda a)}}}---you may
+ set the number of days to be displayed.
#+vindex: org-agenda-span
#+vindex: org-agenda-start-day
@@ -8480,13 +8450,13 @@ buffer, as well as the commands {{{kbd(S)}}}, {{{kbd(M)}}}, and
convert to other calendars, respectively. {{{kbd(c)}}} can be used to
switch back and forth between calendar and agenda.
-If you are using the diary only for S-exp entries and holidays, it is
-faster to not use the above setting, but instead to copy or even move
-the entries into an Org file. Org mode evaluates diary-style sexp
-entries, and does it faster because there is no overhead for first
-creating the diary display. Note that the sexp entries must start at
-the left margin, no whitespace is allowed before them, as seen in the
-following segment of an Org file:[fn:96]
+If you are using the diary only for expression entries and holidays,
+it is faster to not use the above setting, but instead to copy or even
+move the entries into an Org file. Org mode evaluates diary-style
+expression entries, and does it faster because there is no overhead
+for first creating the diary display. Note that the expression
+entries must start at the left margin, no whitespace is allowed before
+them, as seen in the following segment of an Org file:[fn:94]
#+begin_example
,* Holidays
@@ -8531,7 +8501,7 @@ which contains the date in the format =YYYY-MM-DD= or =MM-DD=,
followed by a space and the class of the anniversary (=birthday=,
=wedding=, or a format string). If you omit the class, it defaults to
=birthday=. Here are a few examples, the header for the file
-=org-bbdb.el= contains more detailed information.
+=ol-bbdb.el= contains more detailed information.
#+begin_example
1973-06-22
@@ -8594,37 +8564,37 @@ collected into a single place.
- {{{kbd(M-x org-agenda t)}}} (~org-todo-list~) ::
- #+kindex: t @r{(Agenda dispatcher)}
- #+findex: org-todo-list
- Show the global TODO list. This collects the TODO items from all
- agenda files (see [[*Agenda Views]]) into a single buffer. By
- default, this lists items with a state the is not a DONE state.
- The buffer is in ~agenda-mode~, so there are commands to examine
- and manipulate the TODO entries directly from that buffer (see
- [[*Commands in the Agenda Buffer]]).
+ #+kindex: t @r{(Agenda dispatcher)}
+ #+findex: org-todo-list
+ Show the global TODO list. This collects the TODO items from all
+ agenda files (see [[*Agenda Views]]) into a single buffer. By default,
+ this lists items with a state the is not a DONE state. The buffer
+ is in Agenda mode, so there are commands to examine and manipulate
+ the TODO entries directly from that buffer (see [[*Commands in the
+ Agenda Buffer]]).
- {{{kbd(M-x org-agenda T)}}} (~org-todo-list~) ::
- #+kindex: T @r{(Agenda dispatcher)}
- #+findex: org-todo-list
- #+cindex: TODO keyword matching
- #+vindex: org-todo-keywords
- Like the above, but allows selection of a specific TODO keyword.
- You can also do this by specifying a prefix argument to
- {{{kbd(t)}}}. You are prompted for a keyword, and you may also
- specify several keywords by separating them with =|= as the
- boolean OR operator. With a numeric prefix, the Nth keyword in
- ~org-todo-keywords~ is selected.
-
- #+kindex: r
- The {{{kbd(r)}}} key in the agenda buffer regenerates it, and you
- can give a prefix argument to this command to change the selected
- TODO keyword, for example {{{kbd(3 r)}}}. If you often need
- a search for a specific keyword, define a custom command for it
- (see [[*The Agenda Dispatcher]]).
-
- Matching specific TODO keywords can also be done as part of
- a tags search (see [[*Tag Searches]]).
+ #+kindex: T @r{(Agenda dispatcher)}
+ #+findex: org-todo-list
+ #+cindex: TODO keyword matching
+ #+vindex: org-todo-keywords
+ Like the above, but allows selection of a specific TODO keyword.
+ You can also do this by specifying a prefix argument to
+ {{{kbd(t)}}}. You are prompted for a keyword, and you may also
+ specify several keywords by separating them with =|= as the boolean
+ OR operator. With a numeric prefix, the Nth keyword in
+ ~org-todo-keywords~ is selected.
+
+ #+kindex: r
+ The {{{kbd(r)}}} key in the agenda buffer regenerates it, and you
+ can give a prefix argument to this command to change the selected
+ TODO keyword, for example {{{kbd(3 r)}}}. If you often need
+ a search for a specific keyword, define a custom command for it (see
+ [[*The Agenda Dispatcher]]).
+
+ Matching specific TODO keywords can also be done as part of a tags
+ search (see [[*Tag Searches]]).
Remote editing of TODO items means that you can change the state of
a TODO entry with a single key press. The commands available in the
@@ -8641,13 +8611,14 @@ it more compact:
#+vindex: org-agenda-todo-ignore-timestamp
#+vindex: org-agenda-todo-ignore-with-date
Some people view a TODO item that has been /scheduled/ for execution
- or have a /deadline/ (see [[*Timestamps, Deadlines and Scheduling]]) as
- no longer /open/. Configure the variables
- ~org-agenda-todo-ignore-scheduled~,
- ~org-agenda-todo-ignore-deadlines~,
- ~org-agenda-todo-ignore-timestamp~ and/or
- ~org-agenda-todo-ignore-with-date~ to exclude such items from the
- global TODO list.
+ or have a /deadline/ (see [[*Timestamps]]) as no longer /open/.
+ Configure the variables ~org-agenda-todo-ignore-scheduled~ to
+ exclude some or all scheduled items from the global TODO list,
+ ~org-agenda-todo-ignore-deadlines~ to exclude some or all items with
+ a deadline set, ~org-agenda-todo-ignore-timestamp~ to exclude some
+ or all items with an active timestamp other than a DEADLINE or
+ a SCHEDULED timestamp and/or ~org-agenda-todo-ignore-with-date~ to
+ exclude items with at least one active timestamp.
-
#+vindex: org-agenda-todo-list-sublevels
@@ -8673,27 +8644,26 @@ sparse trees with {{{kbd(C-c / m)}}}.
- {{{kbd(M-x org-agenda m)}}} (~org-tags-view~) ::
- #+kindex: m @r{(Agenda dispatcher)}
- #+findex: org-tags-view
- Produce a list of all headlines that match a given set of tags.
- The command prompts for a selection criterion, which is a boolean
- logic expression with tags, like =+work+urgent-withboss= or
- =work|home= (see [[*Tags]]). If you often need a specific search,
- define a custom command for it (see [[*The Agenda Dispatcher]]).
+ #+kindex: m @r{(Agenda dispatcher)}
+ #+findex: org-tags-view
+ Produce a list of all headlines that match a given set of tags. The
+ command prompts for a selection criterion, which is a boolean logic
+ expression with tags, like =+work+urgent-withboss= or =work|home=
+ (see [[*Tags]]). If you often need a specific search, define a custom
+ command for it (see [[*The Agenda Dispatcher]]).
- {{{kbd(M-x org-agenda M)}}} (~org-tags-view~) ::
- #+kindex: M @r{(Agenda dispatcher)}
- #+findex: org-tags-view
- #+vindex: org-tags-match-list-sublevels
- #+vindex: org-agenda-tags-todo-honor-ignore-options
- Like {{{kbd(m)}}}, but only select headlines that are also TODO
- items and force checking subitems (see the variable
- ~org-tags-match-list-sublevels~). To exclude scheduled/deadline
- items, see the variable
- ~org-agenda-tags-todo-honor-ignore-options~. Matching specific
- TODO keywords together with a tags match is also possible, see
- [[*Tag Searches]].
+ #+kindex: M @r{(Agenda dispatcher)}
+ #+findex: org-tags-view
+ #+vindex: org-tags-match-list-sublevels
+ #+vindex: org-agenda-tags-todo-honor-ignore-options
+ Like {{{kbd(m)}}}, but only select headlines that are also TODO
+ items and force checking subitems (see the variable
+ ~org-tags-match-list-sublevels~). To exclude scheduled/deadline
+ items, see the variable ~org-agenda-tags-todo-honor-ignore-options~.
+ Matching specific TODO keywords together with a tags match is also
+ possible, see [[*Tag Searches]].
The commands available in the tags list are described in [[*Commands in
the Agenda Buffer]].
@@ -8709,19 +8679,19 @@ syntactic sugar for positive selection. The AND operator =&= is
optional when =+= or =-= is present. Here are some examples, using
only tags.
-- ~+work-boss~ ::
+- =+work-boss= ::
- Select headlines tagged =work=, but discard those also tagged
- =boss=.
+ Select headlines tagged =work=, but discard those also tagged
+ =boss=.
-- ~work|laptop~ ::
+- =work|laptop= ::
- Selects lines tagged =work= or =laptop=.
+ Selects lines tagged =work= or =laptop=.
-- ~work|laptop+night~ ::
+- =work|laptop+night= ::
- Like before, but require the =laptop= lines to be tagged
- also =night=.
+ Like before, but require the =laptop= lines to be tagged also
+ =night=.
#+cindex: regular expressions, with tags search
Instead of a tag, you may also specify a regular expression enclosed
@@ -8754,12 +8724,12 @@ Here are more examples:
- =work+TODO​="WAITING"= ::
- Select =work=-tagged TODO lines with the specific TODO keyword
- =WAITING=.
+ Select =work=-tagged TODO lines with the specific TODO keyword
+ =WAITING=.
- =work+TODO​="WAITING"|home+TODO​="WAITING"= ::
- Waiting tasks both at work and at home.
+ Waiting tasks both at work and at home.
When matching properties, a number of different operators can be used
to test the value of a property. Here is a complex example:
@@ -8819,17 +8789,16 @@ TODO keywords in a DONE state. Examples:
- =work/WAITING= ::
- Same as =work+TODO​="WAITING"=.
+ Same as =work+TODO​="WAITING"=.
- =work/!-WAITING-NEXT= ::
- Select =work=-tagged TODO lines that are neither =WAITING= nor
- =NEXT=.
+ Select =work=-tagged TODO lines that are neither =WAITING= nor
+ =NEXT=.
- =work/!+WAITING|+NEXT= ::
- Select =work=-tagged TODO lines that are either =WAITING= or
- =NEXT=.
+ Select =work=-tagged TODO lines that are either =WAITING= or =NEXT=.
*** Search view
:PROPERTIES:
@@ -8844,10 +8813,10 @@ entries. It is particularly useful to find notes.
- {{{kbd(M-x org-agenda s)}}} (~org-search-view~) ::
- #+kindex: s @r{(Agenda dispatcher)}
- #+findex: org-search-view
- This is a special search that lets you select entries by matching
- a substring or specific words using a boolean logic.
+ #+kindex: s @r{(Agenda dispatcher)}
+ #+findex: org-search-view
+ This is a special search that lets you select entries by matching
+ a substring or specific words using a boolean logic.
For example, the search string =computer equipment= matches entries
that contain =computer equipment= as a substring, even if the two
@@ -8863,7 +8832,8 @@ necessary to turn on boolean search, other =+= characters are
optional. For more details, see the docstring of the command
~org-search-view~.
-You can incrementally adjust a boolean search with the following keys
+You can incrementally and conveniently adjust a boolean search from
+the agenda search view with the following keys
#+attr_texinfo: :columns 0.1 0.6
| {{{kbd([)}}} | Add a positive search word |
@@ -8890,16 +8860,16 @@ and define next actions for them.
- {{{kbd(M-x org-agenda #)}}} (~org-agenda-list-stuck-projects~) ::
- #+kindex: # @r{(Agenda dispatcher)}
- #+findex: org-agenda-list-stuck-projects
- List projects that are stuck.
+ #+kindex: # @r{(Agenda dispatcher)}
+ #+findex: org-agenda-list-stuck-projects
+ List projects that are stuck.
- {{{kbd(M-x org-agenda !)}}} ::
- #+kindex: ! @r{(Agenda dispatcher)}
- #+vindex: org-stuck-projects
- Customize the variable ~org-stuck-projects~ to define what
- a stuck project is and how to find it.
+ #+kindex: ! @r{(Agenda dispatcher)}
+ #+vindex: org-stuck-projects
+ Customize the variable ~org-stuck-projects~ to define what a stuck
+ project is and how to find it.
You almost certainly need to configure this view before it works for
you. The built-in default assumes that all your projects are level-2
@@ -8964,12 +8934,10 @@ If you would like to have a special category for a single entry or
a (sub)tree, give the entry a =CATEGORY= property with the special
category you want to apply as the value.
-The display in the agenda buffer looks best if the category is not
-longer than 10 characters.
-
#+vindex: org-agenda-category-icon-alist
-You can set up icons for category by customizing the
-~org-agenda-category-icon-alist~ variable.
+The display in the agenda buffer looks best if the category is not
+longer than 10 characters. You can set up icons for category by
+customizing the ~org-agenda-category-icon-alist~ variable.
*** Time-of-day specifications
:PROPERTIES:
@@ -8990,7 +8958,7 @@ Time ranges can be specified with two timestamps:
#+vindex: org-agenda-search-headline-for-time
In the headline of the entry itself, a time(range)---like =12:45= or
-a =8:30-1pm=---may also appear as plain text[fn:97].
+a =8:30-1pm=---may also appear as plain text[fn:95].
If the agenda integrates the Emacs diary (see [[*Weekly/daily agenda]]),
time specifications in diary entries are recognized as well.
@@ -9066,18 +9034,25 @@ Sorting can be customized using the variable
~org-agenda-sorting-strategy~, and may also include criteria based on
the estimated effort of an entry (see [[*Effort Estimates]]).
-*** Filtering/limiting agenda times
+*** Filtering/limiting agenda items
:PROPERTIES:
:DESCRIPTION: Dynamically narrow the agenda.
:END:
-Agenda built-in or customized commands are statically defined. Agenda
-filters and limits provide two ways of dynamically narrowing down the
-list of agenda entries: /filters/ and /limits/. Filters only act on
-the display of the items, while limits take effect before the list of
-agenda entries is built. Filters are more often used interactively,
-while limits are mostly useful when defined as local variables within
-custom agenda commands.
+#+vindex: org-agenda-category-filter-preset
+#+vindex: org-agenda-tag-filter-preset
+#+vindex: org-agenda-effort-filter-preset
+#+vindex: org-agenda-regexp-filter-preset
+Agenda built-in or custom commands are statically defined. Agenda
+filters and limits allow to flexibly narrow down the list of agenda
+entries.
+
+/Filters/ only change the visibility of items, are very fast and are
+mostly used interactively[fn:96]. You can switch quickly between
+different filters without having to recreate the agenda. /Limits/ on
+the other hand take effect before the agenda buffer is populated, so
+they are mostly useful when defined as local variables within custom
+agenda commands.
**** Filtering in the agenda
:PROPERTIES:
@@ -9091,120 +9066,136 @@ custom agenda commands.
#+cindex: effort filtering, in agenda
#+cindex: query editing, in agenda
-- {{{kbd(/)}}} (~org-agenda-filter-by-tag~) ::
-
- #+findex: org-agenda-filter-by-tag
- #+vindex: org-agenda-tag-filter-preset
- Filter the agenda view with respect to a tag and/or effort
- estimates. The difference between this and a custom agenda
- command is that filtering is very fast, so that you can switch
- quickly between different filters without having to recreate the
- agenda.[fn:98]
-
- You are prompted for a tag selection letter; {{{kbd(SPC)}}} means
- any tag at all. Pressing {{{kbd(TAB)}}} at that prompt offers
- completion to select a tag, including any tags that do not have
- a selection character. The command then hides all entries that
- do not contain or inherit this tag. When called with prefix
- argument, remove the entries that /do/ have the tag. A second
- {{{kbd(/)}}} at the prompt turns off the filter and shows any
- hidden entries. Pressing {{{kbd(+)}}} or {{{kbd(-)}}} switches
- between filtering and excluding the next tag.
-
- #+vindex: org-agenda-auto-exclude-function
- Org also supports automatic, context-aware tag filtering. If the
- variable ~org-agenda-auto-exclude-function~ is set to
- a user-defined function, that function can decide which tags
- should be excluded from the agenda automatically. Once this is
- set, the {{{kbd(/)}}} command then accepts {{{kbd(RET)}}} as
- a sub-option key and runs the auto exclusion logic. For example,
- let's say you use a =Net= tag to identify tasks which need
- network access, an =Errand= tag for errands in town, and a =Call=
- tag for making phone calls. You could auto-exclude these tags
- based on the availability of the Internet, and outside of
- business hours, with something like this:
-
- #+begin_src emacs-lisp
- (defun org-my-auto-exclude-function (tag)
- (and (cond
- ((string= tag "Net")
- (/= 0 (call-process "/sbin/ping" nil nil nil
- "-c1" "-q" "-t1" "mail.gnu.org")))
- ((or (string= tag "Errand") (string= tag "Call"))
- (let ((hour (nth 2 (decode-time))))
- (or (< hour 8) (> hour 21)))))
- (concat "-" tag)))
-
- (setq org-agenda-auto-exclude-function 'org-my-auto-exclude-function)
- #+end_src
+The general filtering command is ~org-agenda-filter~, bound to
+{{{kbd(/)}}}. Before we introduce it, we describe commands for
+individual filter types. All filtering commands handle prefix
+arguments in the same way: A single {{{kbd(C-u)}}} prefix negates the
+filter, so it removes lines selected by the filter. A double prefix
+adds the new filter condition to the one(s) already in place, so
+filter elements are accumulated.
+
+- {{{kbd(\)}}} (~org-agenda-filter-by-tag~) ::
+
+ #+findex: org-agenda-filter-by-tag
+ Filter the agenda view with respect to a tag. You are prompted for
+ a tag selection letter; {{{kbd(SPC)}}} means any tag at all.
+ Pressing {{{kbd(TAB)}}} at that prompt offers completion to select a
+ tag, including any tags that do not have a selection character. The
+ command then hides all entries that do not contain or inherit this
+ tag. Pressing {{{kbd(+)}}} or {{{kbd(-)}}} at the prompt switches
+ between filtering for and against the next tag. To clear the
+ filter, press {{{kbd(\)}}} twice (once to call the command again,
+ and once at the prompt).
- {{{kbd(<)}}} (~org-agenda-filter-by-category~) ::
- #+findex: org-agenda-filter-by-category
- Filter the current agenda view with respect to the category of
- the item at point. Pressing {{{kbd(<)}}} another time removes
- this filter. When called with a prefix argument exclude the
- category of the item at point from the agenda.
+ #+findex: org-agenda-filter-by-category
+ Filter by category of the line at point, and show only entries with
+ this category. When called with a prefix argument, hide all entries
+ with the category at point. To clear the filter, call this command
+ again by pressing {{{kbd(<)}}}.
- #+vindex: org-agenda-category-filter-preset
- You can add a filter preset in custom agenda commands through the
- option ~org-agenda-category-filter-preset~. See [[*Setting options
- for custom commands]].
+- {{{kbd(=)}}} (~org-agenda-filter-by-regexp~) ::
-- {{{kbd(^)}}} (~org-agenda-filter-by-top-headline~) ::
+ #+findex: org-agenda-filter-by-regexp
+ Filter the agenda view by a regular expression: only show agenda
+ entries matching the regular expression the user entered. To clear
+ the filter, call the command again by pressing {{{kbd(=)}}}.
- #+findex: org-agenda-filter-by-top-headline
- Filter the current agenda view and only display the siblings and
- the parent headline of the one at point.
+- {{{kbd(_)}}} (~org-agenda-filter-by-effort~) ::
-- {{{kbd(=)}}} (~org-agenda-filter-by-regexp~) ::
+ #+findex: org-agenda-filter-by-effort
+ Filter the agenda view with respect to effort estimates, so select
+ tasks that take the right amount of time. You first need to set up
+ a list of efforts globally, for example
- #+findex: org-agenda-filter-by-regexp
- Filter the agenda view by a regular expression: only show agenda
- entries matching the regular expression the user entered. When
- called with a prefix argument, it filters /out/ entries matching
- the regexp. Called in a regexp-filtered agenda view, remove the
- filter, unless there are two universal prefix arguments, in which
- case filters are cumulated.
+ #+begin_src emacs-lisp
+ (setq org-global-properties
+ '(("Effort_ALL". "0 0:10 0:30 1:00 2:00 3:00 4:00")))
+ #+end_src
- #+vindex: org-agenda-regexp-filter-preset
- You can add a filter preset in custom agenda commands through the
- option ~org-agenda-regexp-filter-preset~. See [[*Setting options
- for custom commands]].
+ #+vindex: org-sort-agenda-noeffort-is-high
+ You can then filter for an effort by first typing an operator, one
+ of {{{kbd(<)}}}, {{{kbd(>)}}} and {{{kbd(=)}}}, and then the
+ one-digit index of an effort estimate in your array of allowed
+ values, where {{{kbd(0)}}} means the 10th value. The filter then
+ restricts to entries with effort smaller-or-equal, equal, or
+ larger-or-equal than the selected value. For application of the
+ operator, entries without a defined effort are treated according to
+ the value of ~org-sort-agenda-noeffort-is-high~. To clear the
+ filter, press {{{kbd(_)}}} twice (once to call the command again,
+ and once at the first prompt).
-- {{{kbd(_)}}} (~org-agenda-filter-by-effort~) ::
+- {{{kbd(^)}}} (~org-agenda-filter-by-top-headline~) ::
- #+findex: org-agenda-filter-by-effort
- Filter the agenda view with respect to effort estimates. You
- first need to set up allowed efforts globally, for example
-
- #+begin_src emacs-lisp
- (setq org-global-properties
- '(("Effort_ALL". "0 0:10 0:30 1:00 2:00 3:00 4:00")))
- #+end_src
-
- #+vindex: org-sort-agenda-noeffort-is-high
- You can then filter for an effort by first typing an operator,
- one of {{{kbd(<)}}}, {{{kbd(>)}}} and {{{kbd(=)}}}, and then the
- one-digit index of an effort estimate in your array of allowed
- values, where {{{kbd(0)}}} means the 10th value. The filter then
- restricts to entries with effort smaller-or-equal, equal, or
- larger-or-equal than the selected value. For application of the
- operator, entries without a defined effort are treated according
- to the value of ~org-sort-agenda-noeffort-is-high~.
-
- When called with a prefix argument, it removes entries matching
- the condition. With two universal prefix arguments, it clears
- effort filters, which can be accumulated.
-
- #+vindex: org-agenda-effort-filter-preset
- You can add a filter preset in custom agenda commands through the
- option ~org-agenda-effort-filter-preset~. See [[*Setting options
- for custom commands]].
+ #+findex: org-agenda-filter-by-top-headline
+ Filter the current agenda view and only display items that fall
+ under the same top-level headline as the current entry. To clear
+ the filter, call this command again by pressing {{{kbd(^)}}}.
+
+- {{{kbd(/)}}} (~org-agenda-filter~) ::
+
+ #+findex: org-agenda-filter
+ This is the unified interface to four of the five filter methods
+ described above. At the prompt, specify different filter elements
+ in a single string, with full completion support. For example,
+
+ #+begin_example
+ +work-John+<0:10-/plot/
+ #+end_example
+
+ selects entries with category `work' and effort estimates below 10
+ minutes, and deselects entries with tag `John' or matching the
+ regexp `plot'. `+' can be left out if that does not lead to
+ ambiguities. The sequence of elements is arbitrary. The filter
+ syntax assumes that there is no overlap between categories and tags
+ (tags will take priority). If you reply to the prompt with the
+ empty string, all filtering is removed. If a filter is specified,
+ it replaces all current filters. But if you call the command with a
+ double prefix argument, or if you add an additional `+'
+ (e.g. `++work') to the front of the string, the new filter elements
+ are added to the active ones. A single prefix argument applies the
+ entire filter in a negative sense.
- {{{kbd(|)}}} (~org-agenda-filter-remove-all~) ::
- Remove all filters in the current agenda view.
+ Remove all filters in the current agenda view.
+
+**** Computed tag filtering
+:PROPERTIES:
+:UNNUMBERED: notoc
+:END:
+
+#+vindex: org-agenda-auto-exclude-function
+If the variable ~org-agenda-auto-exclude-function~ is set to a
+user-defined function, that function can select tags that should be
+used as a tag filter when requested. The function will be called with
+lower-case versions of all tags represented in the current view. The
+function should the return ="-tag"= if the filter should remove
+entries with that tag, ="+tag"= if only entries with this tag should
+be kept, or =nil= if that tag is irrelevant. For example, let's say
+you use a =Net= tag to identify tasks which need network access, an
+=Errand= tag for errands in town, and a =Call= tag for making phone
+calls. You could auto-exclude these tags based on the availability of
+the Internet, and outside of business hours, with something like this:
+
+#+begin_src emacs-lisp
+ (defun org-my-auto-exclude-fn (tag)
+ (if (cond
+ ((string= tag "net")
+ (/= 0 (call-process "/sbin/ping" nil nil nil
+ "-c1" "-q" "-t1" "mail.gnu.org")))
+ ((member tag '("errand" "call"))
+ (let ((hr (nth 2 (decode-time))))
+ (or (< hr 8) (> hr 21)))))
+ (concat "-" tag)))
+
+ (setq org-agenda-auto-exclude-function 'org-my-auto-exclude-fn)
+#+end_src
+
+You can apply this self-adapting filter by using a double prefix
+argument to ~org-agenda-filter~, i.e. press {{{kbd(C-u C-u /)}}}, or
+by pressing {{{kbd(RET)}}} in ~org-agenda-filter-by-tag~.
**** Setting limits for the agenda
:PROPERTIES:
@@ -9217,23 +9208,23 @@ locally in your custom agenda views (see [[*Custom Agenda Views]]).
- ~org-agenda-max-entries~ ::
- #+vindex: org-agenda-max-entries
- Limit the number of entries.
+ #+vindex: org-agenda-max-entries
+ Limit the number of entries.
- ~org-agenda-max-effort~ ::
- #+vindex: org-agenda-max-effort
- Limit the duration of accumulated efforts (as minutes).
+ #+vindex: org-agenda-max-effort
+ Limit the duration of accumulated efforts (as minutes).
- ~org-agenda-max-todos~ ::
- #+vindex: org-agenda-max-todos
- Limit the number of entries with TODO keywords.
+ #+vindex: org-agenda-max-todos
+ Limit the number of entries with TODO keywords.
- ~org-agenda-max-tags~ ::
- #+vindex: org-agenda-max-tags
- Limit the number of tagged entries.
+ #+vindex: org-agenda-max-tags
+ Limit the number of tagged entries.
When set to a positive integer, each option excludes entries from
other categories: for example, =(setq org-agenda-max-effort 100)=
@@ -9259,8 +9250,8 @@ rebuilding the agenda:
- {{{kbd(~ )}}} (~org-agenda-limit-interactively~) ::
- #+findex: org-agenda-limit-interactively
- This prompts for the type of limit to apply and its value.
+ #+findex: org-agenda-limit-interactively
+ This prompts for the type of limit to apply and its value.
** Commands in the Agenda Buffer
:PROPERTIES:
@@ -9287,15 +9278,15 @@ the other commands, point needs to be in the desired line.
- {{{kbd(n)}}} (~org-agenda-next-line~) ::
- #+kindex: n
- #+findex: org-agenda-next-line
- Next line (same as {{{kbd(DOWN)}}} and {{{kbd(C-n)}}}).
+ #+kindex: n
+ #+findex: org-agenda-next-line
+ Next line (same as {{{kbd(DOWN)}}} and {{{kbd(C-n)}}}).
- {{{kbd(p)}}} (~org-agenda-previous-line~) ::
- #+kindex: p
- #+findex: org-agenda-previous-line
- Previous line (same as {{{kbd(UP)}}} and {{{kbd(C-p)}}}).
+ #+kindex: p
+ #+findex: org-agenda-previous-line
+ Previous line (same as {{{kbd(UP)}}} and {{{kbd(C-p)}}}).
*** View/Go to Org file
:PROPERTIES:
@@ -9305,58 +9296,58 @@ the other commands, point needs to be in the desired line.
- {{{kbd(SPC)}}} or {{{kbd(mouse-3)}}} (~org-agenda-show-and-scroll-up~) ::
- #+kindex: SPC
- #+kindex: mouse-3
- #+findex: org-agenda-show-and-scroll-up
- Display the original location of the item in another window.
- With a prefix argument, make sure that drawers stay folded.
+ #+kindex: SPC
+ #+kindex: mouse-3
+ #+findex: org-agenda-show-and-scroll-up
+ Display the original location of the item in another window.
+ With a prefix argument, make sure that drawers stay folded.
- {{{kbd(L)}}} (~org-agenda-recenter~) ::
- #+findex: org-agenda-recenter
- Display original location and recenter that window.
+ #+findex: org-agenda-recenter
+ Display original location and recenter that window.
- {{{kbd(TAB)}}} or {{{kbd(mouse-2)}}} (~org-agenda-goto~) ::
- #+kindex: TAB
- #+kindex: mouse-2
- #+findex: org-agenda-goto
- Go to the original location of the item in another window.
+ #+kindex: TAB
+ #+kindex: mouse-2
+ #+findex: org-agenda-goto
+ Go to the original location of the item in another window.
- {{{kbd(RET)}}} (~org-agenda-switch-to~) ::
- #+kindex: RET
- #+findex: org-agenda-switch-to
- Go to the original location of the item and delete other windows.
+ #+kindex: RET
+ #+findex: org-agenda-switch-to
+ Go to the original location of the item and delete other windows.
- {{{kbd(F)}}} (~org-agenda-follow-mode~) ::
- #+kindex: F
- #+findex: org-agenda-follow-mode
- #+vindex: org-agenda-start-with-follow-mode
- Toggle Follow mode. In Follow mode, as you move point through
- the agenda buffer, the other window always shows the
- corresponding location in the Org file. The initial setting for
- this mode in new agenda buffers can be set with the variable
- ~org-agenda-start-with-follow-mode~.
+ #+kindex: F
+ #+findex: org-agenda-follow-mode
+ #+vindex: org-agenda-start-with-follow-mode
+ Toggle Follow mode. In Follow mode, as you move point through the
+ agenda buffer, the other window always shows the corresponding
+ location in the Org file. The initial setting for this mode in new
+ agenda buffers can be set with the variable
+ ~org-agenda-start-with-follow-mode~.
- {{{kbd(C-c C-x b)}}} (~org-agenda-tree-to-indirect-buffer~) ::
- #+kindex: C-c C-x b
- #+findex: org-agenda-tree-to-indirect-buffer
- Display the entire subtree of the current item in an indirect
- buffer. With a numeric prefix argument N, go up to level N and
- then take that tree. If N is negative, go up that many levels.
- With a {{{kbd(C-u)}}} prefix, do not remove the previously used
- indirect buffer.
+ #+kindex: C-c C-x b
+ #+findex: org-agenda-tree-to-indirect-buffer
+ Display the entire subtree of the current item in an indirect
+ buffer. With a numeric prefix argument N, go up to level N and then
+ take that tree. If N is negative, go up that many levels. With
+ a {{{kbd(C-u)}}} prefix, do not remove the previously used indirect
+ buffer.
- {{{kbd(C-c C-o)}}} (~org-agenda-open-link~) ::
- #+kindex: C-c C-o
- #+findex: org-agenda-open-link
- Follow a link in the entry. This offers a selection of any links
- in the text belonging to the referenced Org node. If there is
- only one link, follow it without a selection prompt.
+ #+kindex: C-c C-o
+ #+findex: org-agenda-open-link
+ Follow a link in the entry. This offers a selection of any links in
+ the text belonging to the referenced Org node. If there is only one
+ link, follow it without a selection prompt.
*** Change display
:PROPERTIES:
@@ -9368,258 +9359,255 @@ the other commands, point needs to be in the desired line.
#+attr_texinfo: :sep ,
- {{{kbd(A)}}} ::
- #+kindex: A
- Interactively select another agenda view and append it to the
- current view.
+ #+kindex: A
+ Interactively select another agenda view and append it to the
+ current view.
- {{{kbd(o)}}} ::
- #+kindex: o
- Delete other windows.
+ #+kindex: o
+ Delete other windows.
- {{{kbd(v d)}}} or short {{{kbd(d)}}} (~org-agenda-day-view~) ::
- #+kindex: v d
- #+kindex: d
- #+findex: org-agenda-day-view
- Switch to day view. When switching to day view, this setting
- becomes the default for subsequent agenda refreshes. A numeric
- prefix argument may be used to jump directly to a specific day of
- the year. For example, {{{kbd(32 d)}}} jumps to February 1st.
- When setting day view, a year may be encoded in the prefix
- argument as well. For example, {{{kbd(200712 d)}}} jumps to
- January 12, 2007. If such a year specification has only one or
- two digits, it is expanded into one of the 30 next years or the
- last 69 years.
+ #+kindex: v d
+ #+kindex: d
+ #+findex: org-agenda-day-view
+ Switch to day view. When switching to day view, this setting
+ becomes the default for subsequent agenda refreshes. A numeric
+ prefix argument may be used to jump directly to a specific day of
+ the year. For example, {{{kbd(32 d)}}} jumps to February 1st. When
+ setting day view, a year may be encoded in the prefix argument as
+ well. For example, {{{kbd(200712 d)}}} jumps to January 12, 2007.
+ If such a year specification has only one or two digits, it is
+ expanded into one of the 30 next years or the last 69 years.
- {{{kbd(v w)}}} or short {{{kbd(w)}}} (~org-agenda-week-view~) ::
- #+kindex: v w
- #+kindex: w
- #+findex: org-agenda-week-view
- Switch to week view. When switching week view, this setting
- becomes the default for subsequent agenda refreshes. A numeric
- prefix argument may be used to jump directly to a specific day of
- the ISO week. For example {{{kbd(9 w)}}} to ISO week number 9.
- When setting week view, a year may be encoded in the prefix
- argument as well. For example, {{{kbd(200712 w)}}} jumps to week
- 12 in 2007. If such a year specification has only one or two
- digits, it is expanded into one of the 30 next years or the last
- 69 years.
+ #+kindex: v w
+ #+kindex: w
+ #+findex: org-agenda-week-view
+ Switch to week view. When switching week view, this setting becomes
+ the default for subsequent agenda refreshes. A numeric prefix
+ argument may be used to jump directly to a specific day of the ISO
+ week. For example {{{kbd(9 w)}}} to ISO week number 9. When
+ setting week view, a year may be encoded in the prefix argument as
+ well. For example, {{{kbd(200712 w)}}} jumps to week 12 in 2007.
+ If such a year specification has only one or two digits, it is
+ expanded into one of the 30 next years or the last 69 years.
- {{{kbd(v m)}}} (~org-agenda-month-view~) ::
- #+kindex: v m
- #+findex: org-agenda-month-view
- Switch to month view. Because month views are slow to create,
- they do not become the default for subsequent agenda refreshes.
- A numeric prefix argument may be used to jump directly to
- a specific day of the month. When setting month view, a year may
- be encoded in the prefix argument as well. For example,
- {{{kbd(200712 m)}}} jumps to December, 2007. If such a year
- specification has only one or two digits, it is expanded into one
- of the 30 next years or the last 69 years.
+ #+kindex: v m
+ #+findex: org-agenda-month-view
+ Switch to month view. Because month views are slow to create, they
+ do not become the default for subsequent agenda refreshes.
+ A numeric prefix argument may be used to jump directly to a specific
+ day of the month. When setting month view, a year may be encoded in
+ the prefix argument as well. For example, {{{kbd(200712 m)}}} jumps
+ to December, 2007. If such a year specification has only one or two
+ digits, it is expanded into one of the 30 next years or the last 69
+ years.
- {{{kbd(v y)}}} (~org-agenda-year-view~) ::
- #+kindex: v y
- #+findex: org-agenda-year-view
- Switch to year view. Because year views are slow to create, they
- do not become the default for subsequent agenda refreshes.
- A numeric prefix argument may be used to jump directly to
- a specific day of the year.
+ #+kindex: v y
+ #+findex: org-agenda-year-view
+ Switch to year view. Because year views are slow to create, they do
+ not become the default for subsequent agenda refreshes. A numeric
+ prefix argument may be used to jump directly to a specific day of
+ the year.
- {{{kbd(v SPC)}}} (~org-agenda-reset-view~) ::
- #+kindex: v SPC
- #+findex: org-agenda-reset-view
- #+vindex: org-agenda-span
- Reset the current view to ~org-agenda-span~.
+ #+kindex: v SPC
+ #+findex: org-agenda-reset-view
+ #+vindex: org-agenda-span
+ Reset the current view to ~org-agenda-span~.
- {{{kbd(f)}}} (~org-agenda-later~) ::
- #+kindex: f
- #+findex: org-agenda-later
- Go forward in time to display the span following the current one.
- For example, if the display covers a week, switch to the
- following week. With a prefix argument, repeat that many times.
+ #+kindex: f
+ #+findex: org-agenda-later
+ Go forward in time to display the span following the current one.
+ For example, if the display covers a week, switch to the following
+ week. With a prefix argument, repeat that many times.
- {{{kbd(b)}}} (~org-agenda-earlier~) ::
- #+kindex: b
- #+findex: org-agenda-earlier
- Go backward in time to display earlier dates.
+ #+kindex: b
+ #+findex: org-agenda-earlier
+ Go backward in time to display earlier dates.
- {{{kbd(.)}}} (~org-agenda-goto-today~) ::
- #+kindex: .
- #+findex: org-agenda-goto-today
- Go to today.
+ #+kindex: .
+ #+findex: org-agenda-goto-today
+ Go to today.
- {{{kbd(j)}}} (~org-agenda-goto-date~) ::
- #+kindex: j
- #+findex: org-agenda-goto-date
- Prompt for a date and go there.
+ #+kindex: j
+ #+findex: org-agenda-goto-date
+ Prompt for a date and go there.
- {{{kbd(J)}}} (~org-agenda-clock-goto~) ::
- #+kindex: J
- #+findex: org-agenda-clock-goto
- Go to the currently clocked-in task /in the agenda buffer/.
+ #+kindex: J
+ #+findex: org-agenda-clock-goto
+ Go to the currently clocked-in task /in the agenda buffer/.
- {{{kbd(D)}}} (~org-agenda-toggle-diary~) ::
- #+kindex: D
- #+findex: org-agenda-toggle-diary
- Toggle the inclusion of diary entries. See [[*Weekly/daily agenda]].
+ #+kindex: D
+ #+findex: org-agenda-toggle-diary
+ Toggle the inclusion of diary entries. See [[*Weekly/daily agenda]].
- {{{kbd(v l)}}} or {{{kbd(v L)}}} or short {{{kbd(l)}}} (~org-agenda-log-mode~) ::
- #+kindex: v l
- #+kindex: l
- #+kindex: v L
- #+findex: org-agenda-log-mode
- #+vindex: org-log-done
- #+vindex: org-agenda-log-mode-items
- Toggle Logbook mode. In Logbook mode, entries that were marked
- DONE while logging was on (see the variable ~org-log-done~) are
- shown in the agenda, as are entries that have been clocked on
- that day. You can configure the entry types that should be
- included in log mode using the variable
- ~org-agenda-log-mode-items~. When called with a {{{kbd(C-u)}}}
- prefix, show all possible logbook entries, including state
- changes. When called with two prefix arguments {{{kbd(C-u
- C-u)}}}, show only logging information, nothing else. {{{kbd(v
- L)}}} is equivalent to {{{kbd(C-u v l)}}}.
+ #+kindex: v l
+ #+kindex: l
+ #+kindex: v L
+ #+findex: org-agenda-log-mode
+ #+vindex: org-log-done
+ #+vindex: org-agenda-log-mode-items
+ Toggle Logbook mode. In Logbook mode, entries that were marked as
+ done while logging was on (see the variable ~org-log-done~) are
+ shown in the agenda, as are entries that have been clocked on that
+ day. You can configure the entry types that should be included in
+ log mode using the variable ~org-agenda-log-mode-items~. When
+ called with a {{{kbd(C-u)}}} prefix argument, show all possible
+ logbook entries, including state changes. When called with two
+ prefix arguments {{{kbd(C-u C-u)}}}, show only logging information,
+ nothing else. {{{kbd(v L)}}} is equivalent to {{{kbd(C-u v l)}}}.
- {{{kbd(v [)}}} or short {{{kbd([)}}} (~org-agenda-manipulate-query-add~) ::
- #+kindex: v [
- #+kindex: [
- #+findex: org-agenda-manipulate-query-add
- Include inactive timestamps into the current view. Only for
- weekly/daily agenda.
+ #+kindex: v [
+ #+kindex: [
+ #+findex: org-agenda-manipulate-query-add
+ Include inactive timestamps into the current view. Only for
+ weekly/daily agenda.
- {{{kbd(v a)}}} (~org-agenda-archives-mode~) ::
- #+kindex: v a
- #+findex: org-agenda-archives-mode
- Toggle Archives mode. In Archives mode, trees that are archived
- (see [[*Internal archiving]]) are also scanned when producing the
- agenda. To exit archives mode, press {{{kbd(v a)}}} again.
+ #+kindex: v a
+ #+findex: org-agenda-archives-mode
+ Toggle Archives mode. In Archives mode, trees that are archived
+ (see [[*Internal archiving]]) are also scanned when producing the
+ agenda. To exit archives mode, press {{{kbd(v a)}}} again.
- {{{kbd(v A)}}} ::
- #+kindex: v A
- Toggle Archives mode. Include all archive files as well.
+ #+kindex: v A
+ Toggle Archives mode. Include all archive files as well.
- {{{kbd(v R)}}} or short {{{kbd(R)}}} (~org-agenda-clockreport-mode~) ::
- #+kindex: v R
- #+kindex: R
- #+findex: org-agenda-clockreport-mode
- #+vindex: org-agenda-start-with-clockreport-mode
- #+vindex: org-clock-report-include-clocking-task
- Toggle Clockreport mode. In Clockreport mode, the daily/weekly
- agenda always shows a table with the clocked times for the time
- span and file scope covered by the current agenda view. The
- initial setting for this mode in new agenda buffers can be set
- with the variable ~org-agenda-start-with-clockreport-mode~. By
- using a prefix argument when toggling this mode (i.e., {{{kbd(C-u
- R)}}}), the clock table does not show contributions from entries
- that are hidden by agenda filtering[fn:99]. See also the
- variable ~org-clock-report-include-clocking-task~.
+ #+kindex: v R
+ #+kindex: R
+ #+findex: org-agenda-clockreport-mode
+ #+vindex: org-agenda-start-with-clockreport-mode
+ #+vindex: org-clock-report-include-clocking-task
+ Toggle Clockreport mode. In Clockreport mode, the daily/weekly
+ agenda always shows a table with the clocked times for the time span
+ and file scope covered by the current agenda view. The initial
+ setting for this mode in new agenda buffers can be set with the
+ variable ~org-agenda-start-with-clockreport-mode~. By using
+ a prefix argument when toggling this mode (i.e., {{{kbd(C-u R)}}}),
+ the clock table does not show contributions from entries that are
+ hidden by agenda filtering[fn:97]. See also the variable
+ ~org-clock-report-include-clocking-task~.
- {{{kbd(v c)}}} ::
- #+kindex: v c
- #+vindex: org-agenda-clock-consistency-checks
- Show overlapping clock entries, clocking gaps, and other clocking
- problems in the current agenda range. You can then visit
- clocking lines and fix them manually. See the variable
- ~org-agenda-clock-consistency-checks~ for information on how to
- customize the definition of what constituted a clocking problem.
- To return to normal agenda display, press {{{kbd(l)}}} to exit
- Logbook mode.
+ #+kindex: v c
+ #+vindex: org-agenda-clock-consistency-checks
+ Show overlapping clock entries, clocking gaps, and other clocking
+ problems in the current agenda range. You can then visit clocking
+ lines and fix them manually. See the variable
+ ~org-agenda-clock-consistency-checks~ for information on how to
+ customize the definition of what constituted a clocking problem. To
+ return to normal agenda display, press {{{kbd(l)}}} to exit Logbook
+ mode.
- {{{kbd(v E)}}} or short {{{kbd(E)}}} (~org-agenda-entry-text-mode~) ::
- #+kindex: v E
- #+kindex: E
- #+findex: org-agenda-entry-text-mode
- #+vindex: org-agenda-start-with-entry-text-mode
- #+vindex: org-agenda-entry-text-maxlines
- Toggle entry text mode. In entry text mode, a number of lines
- from the Org outline node referenced by an agenda line are
- displayed below the line. The maximum number of lines is given
- by the variable ~org-agenda-entry-text-maxlines~. Calling this
- command with a numeric prefix argument temporarily modifies that
- number to the prefix value.
+ #+kindex: v E
+ #+kindex: E
+ #+findex: org-agenda-entry-text-mode
+ #+vindex: org-agenda-start-with-entry-text-mode
+ #+vindex: org-agenda-entry-text-maxlines
+ Toggle entry text mode. In entry text mode, a number of lines from
+ the Org outline node referenced by an agenda line are displayed
+ below the line. The maximum number of lines is given by the
+ variable ~org-agenda-entry-text-maxlines~. Calling this command
+ with a numeric prefix argument temporarily modifies that number to
+ the prefix value.
- {{{kbd(G)}}} (~org-agenda-toggle-time-grid~) ::
- #+kindex: G
- #+vindex: org-agenda-use-time-grid
- #+vindex: org-agenda-time-grid
- Toggle the time grid on and off. See also the variables
- ~org-agenda-use-time-grid~ and ~org-agenda-time-grid~.
+ #+kindex: G
+ #+vindex: org-agenda-use-time-grid
+ #+vindex: org-agenda-time-grid
+ Toggle the time grid on and off. See also the variables
+ ~org-agenda-use-time-grid~ and ~org-agenda-time-grid~.
- {{{kbd(r)}}} (~org-agenda-redo~), {{{kbd(g)}}} ::
- #+kindex: r
- #+kindex: g
- #+findex: org-agenda-redo
- Recreate the agenda buffer, for example to reflect the changes
- after modification of the timestamps of items with
- {{{kbd(S-LEFT)}}} and {{{kbd(S-RIGHT)}}}. When the
- buffer is the global TODO list, a prefix argument is interpreted
- to create a selective list for a specific TODO keyword.
+ #+kindex: r
+ #+kindex: g
+ #+findex: org-agenda-redo
+ Recreate the agenda buffer, for example to reflect the changes after
+ modification of the timestamps of items with {{{kbd(S-LEFT)}}} and
+ {{{kbd(S-RIGHT)}}}. When the buffer is the global TODO list,
+ a prefix argument is interpreted to create a selective list for
+ a specific TODO keyword.
- {{{kbd(C-x C-s)}}} or short {{{kbd(s)}}} (~org-save-all-org-buffers~) ::
- #+kindex: C-x C-s
- #+findex: org-save-all-org-buffers
- #+kindex: s
- Save all Org buffers in the current Emacs session, and also the
- locations of IDs.
+ #+kindex: C-x C-s
+ #+findex: org-save-all-org-buffers
+ #+kindex: s
+ Save all Org buffers in the current Emacs session, and also the
+ locations of IDs.
- {{{kbd(C-c C-x C-c)}}} (~org-agenda-columns~) ::
- #+kindex: C-c C-x C-c
- #+findex: org-agenda-columns
- #+vindex: org-columns-default-format
- Invoke column view (see [[*Column View]]) in the agenda buffer. The
- column view format is taken from the entry at point, or, if there
- is no entry at point, from the first entry in the agenda view.
- So whatever the format for that entry would be in the original
- buffer (taken from a property, from a =COLUMNS= keyword, or from
- the default variable ~org-columns-default-format~) is used in the
- agenda.
+ #+kindex: C-c C-x C-c
+ #+findex: org-agenda-columns
+ #+vindex: org-columns-default-format
+ Invoke column view (see [[*Column View]]) in the agenda buffer. The
+ column view format is taken from the entry at point, or, if there is
+ no entry at point, from the first entry in the agenda view. So
+ whatever the format for that entry would be in the original buffer
+ (taken from a property, from a =COLUMNS= keyword, or from the
+ default variable ~org-columns-default-format~) is used in the
+ agenda.
- {{{kbd(C-c C-x >)}}} (~org-agenda-remove-restriction-lock~) ::
- #+kindex: C-c C-x >
- #+findex: org-agenda-remove-restriction-lock
- Remove the restriction lock on the agenda, if it is currently
- restricted to a file or subtree (see [[*Agenda Files]]).
+ #+kindex: C-c C-x >
+ #+findex: org-agenda-remove-restriction-lock
+ Remove the restriction lock on the agenda, if it is currently
+ restricted to a file or subtree (see [[*Agenda Files]]).
- {{{kbd(M-UP)}}} (~org-agenda-drag-line-backward~) ::
- #+kindex: M-UP
- #+findex: org-agenda-drag-line-backward
- Drag the line at point backward one line. With a numeric prefix
- argument, drag backward by that many lines.
+ #+kindex: M-UP
+ #+findex: org-agenda-drag-line-backward
+ Drag the line at point backward one line. With a numeric prefix
+ argument, drag backward by that many lines.
- Moving agenda lines does not persist after an agenda refresh and
- does not modify the contributing Org files.
+ Moving agenda lines does not persist after an agenda refresh and
+ does not modify the contributing Org files.
- {{{kbd(M-DOWN)}}} (~org-agenda-drag-line-forward~) ::
- #+kindex: M-DOWN
- #+findex: org-agenda-drag-line-forward
- Drag the line at point forward one line. With a numeric prefix
- argument, drag forward by that many lines.
+ #+kindex: M-DOWN
+ #+findex: org-agenda-drag-line-forward
+ Drag the line at point forward one line. With a numeric prefix
+ argument, drag forward by that many lines.
*** Remote editing
:PROPERTIES:
@@ -9629,225 +9617,227 @@ the other commands, point needs to be in the desired line.
- {{{kbd(0--9)}}} ::
- Digit argument.
+ Digit argument.
- {{{kbd(C-_)}}} (~org-agenda-undo~) ::
- #+kindex: C-_
- #+findex: org-agenda-undo
- #+cindex: undoing remote-editing events
- #+cindex: remote editing, undo
- Undo a change due to a remote editing command. The change is
- undone both in the agenda buffer and in the remote buffer.
+ #+kindex: C-_
+ #+findex: org-agenda-undo
+ #+cindex: undoing remote-editing events
+ #+cindex: remote editing, undo
+ Undo a change due to a remote editing command. The change is undone
+ both in the agenda buffer and in the remote buffer.
- {{{kbd(t)}}} (~org-agenda-todo~) ::
- #+kindex: t
- #+findex: org-agenda-todo
- Change the TODO state of the item, both in the agenda and in the
- original Org file.
+ #+kindex: t
+ #+findex: org-agenda-todo
+ Change the TODO state of the item, both in the agenda and in the
+ original Org file. A prefix arg is passed through to the ~org-todo~
+ command, so for example a {{{kbd(C-u)}}} prefix are will trigger
+ taking a note to document the state change.
- {{{kbd(C-S-RIGHT)}}} (~org-agenda-todo-nextset~) ::
- #+kindex: C-S-RIGHT
- #+findex: org-agenda-todo-nextset
- Switch to the next set of TODO keywords.
+ #+kindex: C-S-RIGHT
+ #+findex: org-agenda-todo-nextset
+ Switch to the next set of TODO keywords.
- {{{kbd(C-S-LEFT)}}}, ~org-agenda-todo-previousset~ ::
- #+kindex: C-S-LEFT
- Switch to the previous set of TODO keywords.
+ #+kindex: C-S-LEFT
+ Switch to the previous set of TODO keywords.
- {{{kbd(C-k)}}} (~org-agenda-kill~) ::
- #+kindex: C-k
- #+findex: org-agenda-kill
- #+vindex: org-agenda-confirm-kill
- Delete the current agenda item along with the entire subtree
- belonging to it in the original Org file. If the text to be
- deleted remotely is longer than one line, the kill needs to be
- confirmed by the user. See variable ~org-agenda-confirm-kill~.
+ #+kindex: C-k
+ #+findex: org-agenda-kill
+ #+vindex: org-agenda-confirm-kill
+ Delete the current agenda item along with the entire subtree
+ belonging to it in the original Org file. If the text to be deleted
+ remotely is longer than one line, the kill needs to be confirmed by
+ the user. See variable ~org-agenda-confirm-kill~.
- {{{kbd(C-c C-w)}}} (~org-agenda-refile~) ::
- #+kindex: C-c C-w
- #+findex: org-agenda-refile
- Refile the entry at point.
+ #+kindex: C-c C-w
+ #+findex: org-agenda-refile
+ Refile the entry at point.
- {{{kbd(C-c C-x C-a)}}} or short {{{kbd(a)}}} (~org-agenda-archive-default-with-confirmation~) ::
- #+kindex: C-c C-x C-a
- #+kindex: a
- #+findex: org-agenda-archive-default-with-confirmation
- #+vindex: org-archive-default-command
- Archive the subtree corresponding to the entry at point using the
- default archiving command set in ~org-archive-default-command~.
- When using the {{{kbd(a)}}} key, confirmation is required.
+ #+kindex: C-c C-x C-a
+ #+kindex: a
+ #+findex: org-agenda-archive-default-with-confirmation
+ #+vindex: org-archive-default-command
+ Archive the subtree corresponding to the entry at point using the
+ default archiving command set in ~org-archive-default-command~.
+ When using the {{{kbd(a)}}} key, confirmation is required.
- {{{kbd(C-c C-x a)}}} (~org-agenda-toggle-archive-tag~) ::
- #+kindex: C-c C-x a
- #+findex: org-agenda-toggle-archive-tag
- Toggle the archive tag (see [[*Internal archiving]]) for the current
- headline.
+ #+kindex: C-c C-x a
+ #+findex: org-agenda-toggle-archive-tag
+ Toggle the archive tag (see [[*Internal archiving]]) for the current
+ headline.
- {{{kbd(C-c C-x A)}}} (~org-agenda-archive-to-archive-sibling~) ::
- #+kindex: C-c C-x A
- #+findex: org-agenda-archive-to-archive-sibling
- Move the subtree corresponding to the current entry to its
- /archive sibling/.
+ #+kindex: C-c C-x A
+ #+findex: org-agenda-archive-to-archive-sibling
+ Move the subtree corresponding to the current entry to its /archive
+ sibling/.
- {{{kbd(C-c C-x C-s)}}} or short {{{kbd($)}}} (~org-agenda-archive~) ::
- #+kindex: C-c C-x C-s
- #+kindex: $
- #+findex: org-agenda-archive
- Archive the subtree corresponding to the current headline. This
- means the entry is moved to the configured archive location, most
- likely a different file.
+ #+kindex: C-c C-x C-s
+ #+kindex: $
+ #+findex: org-agenda-archive
+ Archive the subtree corresponding to the current headline. This
+ means the entry is moved to the configured archive location, most
+ likely a different file.
- {{{kbd(T)}}} (~org-agenda-show-tags~) ::
- #+kindex: T
- #+findex: org-agenda-show-tags
- #+vindex: org-agenda-show-inherited-tags
- Show all tags associated with the current item. This is useful
- if you have turned off ~org-agenda-show-inherited-tags~, but
- still want to see all tags of a headline occasionally.
+ #+kindex: T
+ #+findex: org-agenda-show-tags
+ #+vindex: org-agenda-show-inherited-tags
+ Show all tags associated with the current item. This is useful if
+ you have turned off ~org-agenda-show-inherited-tags~, but still want
+ to see all tags of a headline occasionally.
- {{{kbd(:)}}} (~org-agenda-set-tags~) ::
- #+kindex: :
- #+findex: org-agenda-set-tags
- Set tags for the current headline. If there is an active region
- in the agenda, change a tag for all headings in the region.
+ #+kindex: :
+ #+findex: org-agenda-set-tags
+ Set tags for the current headline. If there is an active region in
+ the agenda, change a tag for all headings in the region.
- {{{kbd(\,)}}} (~org-agenda-priority~) ::
- #+kindex: ,
- #+findex: org-agenda-priority
- Set the priority for the current item. Org mode prompts for the
- priority character. If you reply with {{{kbd(SPC)}}}, the
- priority cookie is removed from the entry.
+ #+kindex: ,
+ #+findex: org-agenda-priority
+ Set the priority for the current item. Org mode prompts for the
+ priority character. If you reply with {{{kbd(SPC)}}}, the priority
+ cookie is removed from the entry.
- {{{kbd(P)}}} (~org-agenda-show-priority~) ::
- #+kindex: P
- #+findex: org-agenda-show-priority
- Display weighted priority of current item.
+ #+kindex: P
+ #+findex: org-agenda-show-priority
+ Display weighted priority of current item.
- {{{kbd(+)}}} or {{{kbd(S-UP)}}} (~org-agenda-priority-up~) ::
- #+kindex: +
- #+kindex: S-UP
- #+findex: org-agenda-priority-up
- Increase the priority of the current item. The priority is
- changed in the original buffer, but the agenda is not resorted.
- Use the {{{kbd(r)}}} key for this.
+ #+kindex: +
+ #+kindex: S-UP
+ #+findex: org-agenda-priority-up
+ Increase the priority of the current item. The priority is changed
+ in the original buffer, but the agenda is not resorted. Use the
+ {{{kbd(r)}}} key for this.
- {{{kbd(-)}}} or {{{kbd(S-DOWN)}}} (~org-agenda-priority-down~) ::
- #+kindex: -
- #+kindex: S-DOWN
- #+findex: org-agenda-priority-down
- Decrease the priority of the current item.
+ #+kindex: -
+ #+kindex: S-DOWN
+ #+findex: org-agenda-priority-down
+ Decrease the priority of the current item.
- {{{kbd(C-c C-z)}}} or short {{{kbd(z)}}} (~org-agenda-add-note~) ::
- #+kindex: z
- #+kindex: C-c C-z
- #+findex: org-agenda-add-note
- #+vindex: org-log-into-drawer
- Add a note to the entry. This note is recorded, and then filed
- to the same location where state change notes are put. Depending
- on ~org-log-into-drawer~, this may be inside a drawer.
+ #+kindex: z
+ #+kindex: C-c C-z
+ #+findex: org-agenda-add-note
+ #+vindex: org-log-into-drawer
+ Add a note to the entry. This note is recorded, and then filed to
+ the same location where state change notes are put. Depending on
+ ~org-log-into-drawer~, this may be inside a drawer.
- {{{kbd(C-c C-a)}}} (~org-attach~) ::
- #+kindex: C-c C-a
- #+findex: org-attach
- Dispatcher for all command related to attachments.
+ #+kindex: C-c C-a
+ #+findex: org-attach
+ Dispatcher for all command related to attachments.
- {{{kbd(C-c C-s)}}} (~org-agenda-schedule~) ::
- #+kindex: C-c C-s
- #+findex: org-agenda-schedule
- Schedule this item. With a prefix argument, remove the
- scheduling timestamp
+ #+kindex: C-c C-s
+ #+findex: org-agenda-schedule
+ Schedule this item. With a prefix argument, remove the
+ scheduling timestamp
- {{{kbd(C-c C-d)}}} (~org-agenda-deadline~) ::
- #+kindex: C-c C-d
- #+findex: org-agenda-deadline
- Set a deadline for this item. With a prefix argument, remove the
- deadline.
+ #+kindex: C-c C-d
+ #+findex: org-agenda-deadline
+ Set a deadline for this item. With a prefix argument, remove the
+ deadline.
- {{{kbd(S-RIGHT)}}} (~org-agenda-do-date-later~) ::
- #+kindex: S-RIGHT
- #+findex: org-agenda-do-date-later
- Change the timestamp associated with the current line by one day
- into the future. If the date is in the past, the first call to
- this command moves it to today. With a numeric prefix argument,
- change it by that many days. For example, {{{kbd(3
- 6 5 S-RIGHT)}}} changes it by a year. With a {{{kbd(C-u)}}}
- prefix, change the time by one hour. If you immediately repeat
- the command, it will continue to change hours even without the
- prefix argument. With a double {{{kbd(C-u C-u)}}} prefix, do the
- same for changing minutes. The stamp is changed in the original
- Org file, but the change is not directly reflected in the agenda
- buffer. Use {{{kbd(r)}}} or {{{kbd(g)}}} to update the buffer.
+ #+kindex: S-RIGHT
+ #+findex: org-agenda-do-date-later
+ Change the timestamp associated with the current line by one day
+ into the future. If the date is in the past, the first call to this
+ command moves it to today. With a numeric prefix argument, change
+ it by that many days. For example, {{{kbd(3 6 5 S-RIGHT)}}} changes
+ it by a year. With a {{{kbd(C-u)}}} prefix, change the time by one
+ hour. If you immediately repeat the command, it will continue to
+ change hours even without the prefix argument. With a double
+ {{{kbd(C-u C-u)}}} prefix, do the same for changing minutes. The
+ stamp is changed in the original Org file, but the change is not
+ directly reflected in the agenda buffer. Use {{{kbd(r)}}} or
+ {{{kbd(g)}}} to update the buffer.
- {{{kbd(S-LEFT)}}} (~org-agenda-do-date-earlier~) ::
- #+kindex: S-LEFT
- #+findex: org-agenda-do-date-earlier
- Change the timestamp associated with the current line by one day
- into the past.
+ #+kindex: S-LEFT
+ #+findex: org-agenda-do-date-earlier
+ Change the timestamp associated with the current line by one day
+ into the past.
- {{{kbd(>)}}} (~org-agenda-date-prompt~) ::
- #+kindex: >
- #+findex: org-agenda-date-prompt
- Change the timestamp associated with the current line. The key
- {{{kbd(>)}}} has been chosen, because it is the same as
- {{{kbd(S-.)}}} on my keyboard.
+ #+kindex: >
+ #+findex: org-agenda-date-prompt
+ Change the timestamp associated with the current line. The key
+ {{{kbd(>)}}} has been chosen, because it is the same as
+ {{{kbd(S-.)}}} on my keyboard.
- {{{kbd(I)}}} (~org-agenda-clock-in~) ::
- #+kindex: I
- #+findex: org-agenda-clock-in
- Start the clock on the current item. If a clock is running
- already, it is stopped first.
+ #+kindex: I
+ #+findex: org-agenda-clock-in
+ Start the clock on the current item. If a clock is running already,
+ it is stopped first.
- {{{kbd(O)}}} (~org-agenda-clock-out~) ::
- #+kindex: O
- #+findex: org-agenda-clock-out
- Stop the previously started clock.
+ #+kindex: O
+ #+findex: org-agenda-clock-out
+ Stop the previously started clock.
- {{{kbd(X)}}} (~org-agenda-clock-cancel~) ::
- #+kindex: X
- #+findex: org-agenda-clock-cancel
- Cancel the currently running clock.
+ #+kindex: X
+ #+findex: org-agenda-clock-cancel
+ Cancel the currently running clock.
- {{{kbd(J)}}} (~org-agenda-clock-goto~) ::
- #+kindex: J
- #+findex: org-agenda-clock-goto
- Jump to the running clock in another window.
+ #+kindex: J
+ #+findex: org-agenda-clock-goto
+ Jump to the running clock in another window.
- {{{kbd(k)}}} (~org-agenda-capture~) ::
- #+kindex: k
- #+findex: org-agenda-capture
- #+cindex: capturing, from agenda
- #+vindex: org-capture-use-agenda-date
- Like ~org-capture~, but use the date at point as the default date
- for the capture template. See ~org-capture-use-agenda-date~ to
- make this the default behavior of ~org-capture~.
+ #+kindex: k
+ #+findex: org-agenda-capture
+ #+cindex: capturing, from agenda
+ #+vindex: org-capture-use-agenda-date
+ Like ~org-capture~, but use the date at point as the default date
+ for the capture template. See ~org-capture-use-agenda-date~ to make
+ this the default behavior of ~org-capture~.
*** Bulk remote editing selected entries
:PROPERTIES:
@@ -9857,128 +9847,127 @@ the other commands, point needs to be in the desired line.
#+vindex: org-agenda-bulk-custom-functions
- {{{kbd(m)}}} (~org-agenda-bulk-mark~) ::
- #+kindex: m
- #+findex: org-agenda-bulk-mark
+ #+kindex: m
+ #+findex: org-agenda-bulk-mark
- Mark the entry at point for bulk action. If there is an active
- region in the agenda, mark the entries in the region. With
- numeric prefix argument, mark that many successive entries.
+ Mark the entry at point for bulk action. If there is an active
+ region in the agenda, mark the entries in the region. With numeric
+ prefix argument, mark that many successive entries.
- {{{kbd(*)}}} (~org-agenda-bulk-mark-all~) ::
- #+kindex: *
- #+findex: org-agenda-bulk-mark-all
+ #+kindex: *
+ #+findex: org-agenda-bulk-mark-all
- Mark all visible agenda entries for bulk action.
+ Mark all visible agenda entries for bulk action.
- {{{kbd(u)}}} (~org-agenda-bulk-unmark~) ::
- #+kindex: u
- #+findex: org-agenda-bulk-unmark
+ #+kindex: u
+ #+findex: org-agenda-bulk-unmark
- Unmark entry for bulk action.
+ Unmark entry for bulk action.
- {{{kbd(U)}}} (~org-agenda-bulk-remove-all-marks~) ::
- #+kindex: U
- #+findex: org-agenda-bulk-remove-all-marks
+ #+kindex: U
+ #+findex: org-agenda-bulk-remove-all-marks
- Unmark all marked entries for bulk action.
+ Unmark all marked entries for bulk action.
- {{{kbd(M-m)}}} (~org-agenda-bulk-toggle~) ::
- #+kindex: M-m
- #+findex: org-agenda-bulk-toggle
+ #+kindex: M-m
+ #+findex: org-agenda-bulk-toggle
- Toggle mark of the entry at point for bulk action.
+ Toggle mark of the entry at point for bulk action.
- {{{kbd(M-*)}}} (~org-agenda-bulk-toggle-all~) ::
- #+kindex: M-*
- #+findex: org-agenda-bulk-toggle-all
+ #+kindex: M-*
+ #+findex: org-agenda-bulk-toggle-all
- Toggle mark of every entry for bulk action.
+ Toggle mark of every entry for bulk action.
- {{{kbd(%)}}} (~org-agenda-bulk-mark-regexp~) ::
- #+kindex: %
- #+findex: org-agenda-bulk-mark-regexp
+ #+kindex: %
+ #+findex: org-agenda-bulk-mark-regexp
- Mark entries matching a regular expression for bulk action.
+ Mark entries matching a regular expression for bulk action.
- {{{kbd(B)}}} (~org-agenda-bulk-action~) ::
- #+kindex: B
- #+findex: org-agenda-bulk-action
- #+vindex: org-agenda-bulk-persistent-marks
+ #+kindex: B
+ #+findex: org-agenda-bulk-action
+ #+vindex: org-agenda-bulk-persistent-marks
- Bulk action: act on all marked entries in the agenda. This
- prompts for another key to select the action to be applied. The
- prefix argument to {{{kbd(B)}}} is passed through to the
- {{{kbd(s)}}} and {{{kbd(d)}}} commands, to bulk-remove these
- special timestamps. By default, marks are removed after the
- bulk. If you want them to persist, set
- ~org-agenda-bulk-persistent-marks~ to ~t~ or hit {{{kbd(p)}}} at
- the prompt.
+ Bulk action: act on all marked entries in the agenda. This prompts
+ for another key to select the action to be applied. The prefix
+ argument to {{{kbd(B)}}} is passed through to the {{{kbd(s)}}} and
+ {{{kbd(d)}}} commands, to bulk-remove these special timestamps. By
+ default, marks are removed after the bulk. If you want them to
+ persist, set ~org-agenda-bulk-persistent-marks~ to ~t~ or hit
+ {{{kbd(p)}}} at the prompt.
- - {{{kbd(*)}}} ::
+ - {{{kbd(p)}}} ::
- Toggle persistent marks.
+ Toggle persistent marks.
- - {{{kbd($)}}} ::
+ - {{{kbd($)}}} ::
- Archive all selected entries.
+ Archive all selected entries.
- - {{{kbd(A)}}} ::
+ - {{{kbd(A)}}} ::
- Archive entries by moving them to their respective archive
- siblings.
+ Archive entries by moving them to their respective archive
+ siblings.
- - {{{kbd(t)}}} ::
+ - {{{kbd(t)}}} ::
- Change TODO state. This prompts for a single TODO keyword and
- changes the state of all selected entries, bypassing blocking
- and suppressing logging notes---but not timestamps.
+ Change TODO state. This prompts for a single TODO keyword and
+ changes the state of all selected entries, bypassing blocking and
+ suppressing logging notes---but not timestamps.
- - {{{kbd(+)}}} ::
+ - {{{kbd(+)}}} ::
- Add a tag to all selected entries.
+ Add a tag to all selected entries.
- - {{{kbd(-)}}} ::
+ - {{{kbd(-)}}} ::
- Remove a tag from all selected entries.
+ Remove a tag from all selected entries.
- - {{{kbd(s)}}} ::
+ - {{{kbd(s)}}} ::
- Schedule all items to a new date. To shift existing schedule
- dates by a fixed number of days, use something starting with
- double plus at the prompt, for example =++8d= or =++2w=.
+ Schedule all items to a new date. To shift existing schedule
+ dates by a fixed number of days, use something starting with
+ double plus at the prompt, for example =++8d= or =++2w=.
- - {{{kbd(d)}}} ::
+ - {{{kbd(d)}}} ::
- Set deadline to a specific date.
+ Set deadline to a specific date.
- - {{{kbd(r)}}} ::
+ - {{{kbd(r)}}} ::
- Prompt for a single refile target and move all entries. The
- entries are no longer in the agenda; refresh ({{{kbd(g)}}}) to
- bring them back.
+ Prompt for a single refile target and move all entries. The
+ entries are no longer in the agenda; refresh ({{{kbd(g)}}}) to
+ bring them back.
- - {{{kbd(S)}}} ::
+ - {{{kbd(S)}}} ::
- Reschedule randomly into the coming N days. N is prompted for.
- With a prefix argument ({{{kbd(C-u B S)}}}), scatter only
- across weekdays.
+ Reschedule randomly into the coming N days. N is prompted for.
+ With a prefix argument ({{{kbd(C-u B S)}}}), scatter only across
+ weekdays.
- - {{{kbd(f)}}} ::
+ - {{{kbd(f)}}} ::
- #+vindex: org-agenda-bulk-custom-functions
- Apply a function[fn:100] to marked entries. For example, the
- function below sets the =CATEGORY= property of the entries to
- =web=.
+ #+vindex: org-agenda-bulk-custom-functions
+ Apply a function[fn:98] to marked entries. For example, the
+ function below sets the =CATEGORY= property of the entries to
+ =web=.
- #+begin_src emacs-lisp
- (defun set-category ()
- (interactive "P")
- (let ((marker (or (org-get-at-bol 'org-hd-marker)
- (org-agenda-error))))
- (org-with-point-at marker
- (org-back-to-heading t)
- (org-set-property "CATEGORY" "web"))))
- #+end_src
+ #+begin_src emacs-lisp
+ (defun set-category ()
+ (interactive "P")
+ (let ((marker (or (org-get-at-bol 'org-hd-marker)
+ (org-agenda-error))))
+ (org-with-point-at marker
+ (org-back-to-heading t)
+ (org-set-property "CATEGORY" "web"))))
+ #+end_src
*** Calendar commands
:PROPERTIES:
@@ -9988,69 +9977,67 @@ the other commands, point needs to be in the desired line.
- {{{kbd(c)}}} (~org-agenda-goto-calendar~) ::
- #+kindex: c
- #+findex: org-agenda-goto-calendar
- Open the Emacs calendar and go to the date at point in the
- agenda.
+ #+kindex: c
+ #+findex: org-agenda-goto-calendar
+ Open the Emacs calendar and go to the date at point in the agenda.
- {{{kbd(c)}}} (~org-calendar-goto-agenda~) ::
- #+kindex: c
- #+findex: org-calendar-goto-agenda
- When in the calendar, compute and show the Org agenda for the
- date at point.
+ #+kindex: c
+ #+findex: org-calendar-goto-agenda
+ When in the calendar, compute and show the Org agenda for the date
+ at point.
- {{{kbd(i)}}} (~org-agenda-diary-entry~) ::
- #+kindex: i
- #+findex: org-agenda-diary-entry
-
- #+cindex: diary entries, creating from agenda
- Insert a new entry into the diary, using the date at point and
- (for block entries) the date at the mark. This adds to the Emacs
- diary file[fn:101], in a way similar to the {{{kbd(i)}}} command
- in the calendar. The diary file pops up in another window, where
- you can add the entry.
-
- #+vindex: org-agenda-diary-file
- If you configure ~org-agenda-diary-file~ to point to an Org file,
- Org creates entries in that file instead. Most entries are
- stored in a date-based outline tree that will later make it easy
- to archive appointments from previous months/years. The tree is
- built under an entry with a =DATE_TREE= property, or else with
- years as top-level entries. Emacs prompts you for the entry
- text---if you specify it, the entry is created in
- ~org-agenda-diary-file~ without further interaction. If you
- directly press {{{kbd(RET)}}} at the prompt without typing text,
- the target file is shown in another window for you to finish the
- entry there. See also the {{{kbd(k r)}}} command.
+ #+kindex: i
+ #+findex: org-agenda-diary-entry
+
+ #+cindex: diary entries, creating from agenda
+ Insert a new entry into the diary, using the date at point and (for
+ block entries) the date at the mark. This adds to the Emacs diary
+ file[fn:99], in a way similar to the {{{kbd(i)}}} command in the
+ calendar. The diary file pops up in another window, where you can
+ add the entry.
+
+ #+vindex: org-agenda-diary-file
+ If you configure ~org-agenda-diary-file~ to point to an Org file,
+ Org creates entries in that file instead. Most entries are stored
+ in a date-based outline tree that will later make it easy to archive
+ appointments from previous months/years. The tree is built under an
+ entry with a =DATE_TREE= property, or else with years as top-level
+ entries. Emacs prompts you for the entry text---if you specify it,
+ the entry is created in ~org-agenda-diary-file~ without further
+ interaction. If you directly press {{{kbd(RET)}}} at the prompt
+ without typing text, the target file is shown in another window for
+ you to finish the entry there. See also the {{{kbd(k r)}}} command.
- {{{kbd(M)}}} (~org-agenda-phases-of-moon~) ::
- #+kindex: M
- #+findex: org-agenda-phases-of-moon
- Show the phases of the moon for the three months around current
- date.
+ #+kindex: M
+ #+findex: org-agenda-phases-of-moon
+ Show the phases of the moon for the three months around current
+ date.
- {{{kbd(S)}}} (~org-agenda-sunrise-sunset~) ::
- #+kindex: S
- #+findex: org-agenda-sunrise-sunset
- Show sunrise and sunset times. The geographical location must be
- set with calendar variables, see the documentation for the Emacs
- calendar.
+ #+kindex: S
+ #+findex: org-agenda-sunrise-sunset
+ Show sunrise and sunset times. The geographical location must be
+ set with calendar variables, see the documentation for the Emacs
+ calendar.
- {{{kbd(C)}}} (~org-agenda-convert-date~) ::
- #+kindex: C
- #+findex: org-agenda-convert-date
- Convert the date at point into many other cultural and historic
- calendars.
+ #+kindex: C
+ #+findex: org-agenda-convert-date
+ Convert the date at point into many other cultural and historic
+ calendars.
- {{{kbd(H)}}} (~org-agenda-holidays~) ::
- #+kindex: H
- #+findex: org-agenda-holidays
- Show holidays for three months around point date.
+ #+kindex: H
+ #+findex: org-agenda-holidays
+ Show holidays for three months around point date.
*** Quit and exit
:PROPERTIES:
@@ -10058,19 +10045,19 @@ the other commands, point needs to be in the desired line.
:END:
- {{{kbd(q)}}} (~org-agenda-quit~) ::
- #+kindex: q
- #+findex: org-agenda-quit
+ #+kindex: q
+ #+findex: org-agenda-quit
- Quit agenda, remove the agenda buffer.
+ Quit agenda, remove the agenda buffer.
- {{{kbd(x)}}} (~org-agenda-exit~) ::
- #+kindex: x
- #+findex: org-agenda-exit
+ #+kindex: x
+ #+findex: org-agenda-exit
- #+cindex: agenda files, removing buffers
- Exit agenda, remove the agenda buffer and all buffers loaded by
- Emacs for the compilation of the agenda. Buffers created by the
- user to visit Org files are not removed.
+ #+cindex: agenda files, removing buffers
+ Exit agenda, remove the agenda buffer and all buffers loaded by
+ Emacs for the compilation of the agenda. Buffers created by the
+ user to visit Org files are not removed.
** Custom Agenda Views
:PROPERTIES:
@@ -10129,62 +10116,59 @@ views:
("hk" tags "+home+Kim")))
#+end_src
-#+texinfo: @noindent
The initial string in each entry defines the keys you have to press
after the dispatcher command in order to access the command. Usually
-this will be just a single character, but if you have many similar
+this is just a single character, but if you have many similar
commands, you can also define two-letter combinations where the first
character is the same in several combinations and serves as a prefix
-key[fn:102]. The second parameter is the search type, followed by the
+key[fn:100]. The second parameter is the search type, followed by the
string or regular expression to be used for the matching. The example
above will therefore define:
- {{{kbd(x)}}} ::
- as a global search for agenda entries planned[fn:103] this
- week/day.
+ as a global search for agenda entries planned[fn:101] this week/day.
- {{{kbd(y)}}} ::
- as the same search, but only for entries with an hour
- specification like =[h]h:mm=---think of them as appointments.
+ as the same search, but only for entries with an hour specification
+ like =[h]h:mm=---think of them as appointments.
- {{{kbd(w)}}} ::
- as a global search for TODO entries with =WAITING= as the TODO
- keyword.
+ as a global search for TODO entries with =WAITING= as the TODO
+ keyword.
- {{{kbd(W)}}} ::
- as the same search, but only in the current buffer and displaying
- the results as a sparse tree.
+ as the same search, but only in the current buffer and displaying
+ the results as a sparse tree.
- {{{kbd(u)}}} ::
- as a global tags search for headlines tagged =boss= but not
- =urgent=.
+ as a global tags search for headlines tagged =boss= but not
+ =urgent=.
- {{{kbd(v)}}} ::
- The same search, but limiting it to headlines that are also TODO
- items.
+ The same search, but limiting it to headlines that are also TODO
+ items.
- {{{kbd(U)}}} ::
- as the same search, but only in the current buffer and displaying
- the result as a sparse tree.
+ as the same search, but only in the current buffer and displaying
+ the result as a sparse tree.
- {{{kbd(f)}}} ::
- to create a sparse tree (again, current buffer only) with all
- entries containing the word =FIXME=.
+ to create a sparse tree (again, current buffer only) with all
+ entries containing the word =FIXME=.
- {{{kbd(h)}}} ::
- as a prefix command for a =HOME= tags search where you have to
- press an additional key ({{{kbd(l)}}}, {{{kbd(p)}}} or
- {{{kbd(k)}}}) to select a name (Lisa, Peter, or Kim) as
- additional tag to match.
+ as a prefix command for a =HOME= tags search where you have to press
+ an additional key ({{{kbd(l)}}}, {{{kbd(p)}}} or {{{kbd(k)}}}) to
+ select a name (Lisa, Peter, or Kim) as additional tag to match.
Note that ~*-tree~ agenda views need to be called from an Org buffer
as they operate on the current buffer only.
@@ -10323,22 +10307,22 @@ See the docstring of the variable for more information.
If you are away from your computer, it can be very useful to have
a printed version of some agenda views to carry around. Org mode can
-export custom agenda views as plain text, HTML[fn:104], Postscript,
-PDF[fn:105], and iCalendar files. If you want to do this only
+export custom agenda views as plain text, HTML[fn:102], Postscript,
+PDF[fn:103], and iCalendar files. If you want to do this only
occasionally, use the following command:
- {{{kbd(C-x C-w)}}} (~org-agenda-write~) ::
- #+kindex: C-x C-w
- #+findex: org-agenda-write
- #+cindex: exporting agenda views
- #+cindex: agenda views, exporting
+ #+kindex: C-x C-w
+ #+findex: org-agenda-write
+ #+cindex: exporting agenda views
+ #+cindex: agenda views, exporting
- #+vindex: org-agenda-exporter-settings
- Write the agenda view to a file.
+ #+vindex: org-agenda-exporter-settings
+ Write the agenda view to a file.
If you need to export certain agenda views frequently, you can
associate any custom agenda command with a list of output file
-names[fn:106]. Here is an example that first defines custom commands
+names[fn:104]. Here is an example that first defines custom commands
for the agenda and the global TODO list, together with a number of
files to which to export them. Then we define two block agenda
commands and specify file names for them as well. File names can be
@@ -10378,10 +10362,10 @@ files in one step:
- {{{kbd(e)}}} (~org-store-agenda-views~) ::
- #+kindex: e @r{(Agenda dispatcher)}
- #+findex: org-store-agenda-views
- Export all agenda views that have export file names associated
- with them.
+ #+kindex: e @r{(Agenda dispatcher)}
+ #+findex: org-store-agenda-views
+ Export all agenda views that have export file names associated with
+ them.
You can use the options section of the custom agenda commands to also
set options for the export commands. For example:
@@ -10426,7 +10410,7 @@ emacs -eval (org-batch-store-agenda-views) -kill
#+end_src
#+texinfo: @noindent
-or, if you need to modify some parameters[fn:107]
+or, if you need to modify some parameters[fn:105]
#+begin_src shell
emacs -eval '(org-batch-store-agenda-views \
@@ -10459,27 +10443,30 @@ can be quite useful to use column view also from the agenda, where
entries are collected by certain criteria.
- {{{kbd(C-c C-x C-c)}}} (~org-agenda-columns~) ::
- #+kindex: C-c C-x C-c
- #+findex: org-agenda-columns
+ #+kindex: C-c C-x C-c
+ #+findex: org-agenda-columns
- Turn on column view in the agenda.
+ Turn on column view in the agenda.
To understand how to use this properly, it is important to realize
that the entries in the agenda are no longer in their proper outline
environment. This causes the following issues:
1.
+ #+vindex: org-columns-default-format-for-agenda
#+vindex: org-columns-default-format
- #+vindex: org-overriding-columns-format
Org needs to make a decision which columns format to use. Since
the entries in the agenda are collected from different files, and
- different files may have different columns formats, this is
- a non-trivial problem. Org first checks if the variable
+ different files may have different columns formats, this is a
+ non-trivial problem. Org first checks if
~org-overriding-columns-format~ is currently set, and if so, takes
- the format from there. Otherwise it takes the format associated
- with the first item in the agenda, or, if that item does not have
- a specific format (defined in a property, or in its file), it uses
- ~org-columns-default-format~.
+ the format from there. You should set this variable only in the
+ /local settings section/ of a custom agenda command (see [[*Custom
+ Agenda Views]]) to make it valid for that specific agenda view. If
+ no such binding exists, it checks, in sequence,
+ ~org-columns-default-format-for-agenda~, the format associated with
+ the first item in the agenda (through a property or a =#+COLUMNS=
+ setting in that buffer) and finally ~org-columns-default-format~.
2.
#+cindex: @samp{CLOCKSUM}, special property
@@ -10594,8 +10581,8 @@ but not any simpler
You can make words =*bold*=, =/italic/=, =_underlined_=, ==verbatim==
and =~code~=, and, if you must, =+strike-through+=. Text in the code
-and verbatim string is not processed for Org mode specific syntax; it
-is exported verbatim.
+and verbatim string is not processed for Org specific syntax; it is
+exported verbatim.
#+vindex: org-fontify-emphasized-text
To turn off fontification for marked up text, you can set
@@ -10628,9 +10615,9 @@ change this convention. For example, when setting this variable to
- {{{kbd(C-c C-x \)}}} (~org-toggle-pretty-entities~) ::
- #+kindex: C-c C-x \
- #+findex: org-toggle-pretty-entities
- This command formats sub- and superscripts in a WYSIWYM way.
+ #+kindex: C-c C-x \
+ #+findex: org-toggle-pretty-entities
+ This command formats sub- and superscripts in a WYSIWYM way.
** Special Symbols
:PROPERTIES:
@@ -10667,21 +10654,21 @@ becomes =&nbsp;= in HTML and =~= in LaTeX.
#+cindex: special symbols, in-buffer display
If you would like to see entities displayed as UTF-8 characters, use
-the following command[fn:108]:
+the following command[fn:106]:
- {{{kbd(C-c C-x \)}}} (~org-toggle-pretty-entities~) ::
- #+kindex: C-c C-x \
- #+findex: org-toggle-pretty-entities
+ #+kindex: C-c C-x \
+ #+findex: org-toggle-pretty-entities
- Toggle display of entities as UTF-8 characters. This does not
- change the buffer content which remains plain ASCII, but it
- overlays the UTF-8 character for display purposes only.
+ Toggle display of entities as UTF-8 characters. This does not
+ change the buffer content which remains plain ASCII, but it overlays
+ the UTF-8 character for display purposes only.
#+cindex: shy hyphen, special symbol
#+cindex: dash, special symbol
#+cindex: ellipsis, special symbol
In addition to regular entities defined above, Org exports in
-a special way[fn:109] the following commonly used character
+a special way[fn:107] the following commonly used character
combinations: =\-= is treated as a shy hyphen, =--= and =---= are
converted into dashes, and =...= becomes a compact set of dots.
@@ -10694,7 +10681,7 @@ converted into dashes, and =...= becomes a compact set of dots.
Plain ASCII is normally sufficient for almost all note taking.
Exceptions include scientific notes, which often require mathematical
-symbols and the occasional formula. LaTeX[fn:110] is widely used to
+symbols and the occasional formula. LaTeX[fn:108] is widely used to
typeset scientific documents. Org mode supports embedding LaTeX code
into its files, because many academics are used to writing and reading
LaTeX source code, and because it can be readily processed to produce
@@ -10716,7 +10703,7 @@ into images (see [[*Previewing LaTeX fragments]]).
LaTeX fragments do not need any special marking at all. The following
snippets are identified as LaTeX source code:
-- Environments of any kind[fn:111]. The only requirement is that the
+- Environments of any kind[fn:109]. The only requirement is that the
=\begin= statement appears on a new line, preceded by only
whitespace.
@@ -10760,7 +10747,7 @@ lines:
#+vindex: org-preview-latex-default-process
If you have a working LaTeX installation and =dvipng=, =dvisvgm= or
-=convert= installed[fn:112], LaTeX fragments can be processed to
+=convert= installed[fn:110], LaTeX fragments can be processed to
produce images of the typeset expressions to be used for inclusion
while exporting to HTML (see [[*LaTeX fragments]]), or for inline
previewing within Org mode.
@@ -10773,16 +10760,18 @@ In particular, the ~:scale~ (and for HTML export, ~:html-scale~)
property of the former can be used to adjust the size of the preview
images.
-- {{{kbd(C-c C-x C-l)}}} (~org-toggle-latex-fragment~) ::
- #+kindex: C-c C-x C-l
- #+findex: org-toggle-latex-fragment
+- {{{kbd(C-c C-x C-l)}}} (~org-latex-preview~) ::
+ #+kindex: C-c C-x C-l
+ #+findex: org-latex-preview
- Produce a preview image of the LaTeX fragment at point and
- overlay it over the source code. If there is no fragment at
- point, process all fragments in the current entry (between two
- headlines). When called with a prefix argument, process the
- entire subtree. When called with two prefix arguments, or when
- point is before the first headline, process the entire buffer.
+ Produce a preview image of the LaTeX fragment at point and overlay
+ it over the source code. If there is no fragment at point, process
+ all fragments in the current entry---between two headlines.
+
+ When called with a single prefix argument, clear all images in the
+ current entry. Two prefix arguments produce a preview image for all
+ fragments in the buffer, while three of them clear all the images in
+ that buffer.
#+vindex: org-startup-with-latex-preview
You can turn on the previewing of all LaTeX fragments in a file with
@@ -10805,9 +10794,10 @@ a major LaTeX mode like AUCTeX in order to speed-up insertion of
environments and math templates. Inside Org mode, you can make use of
some of the features of CDLaTeX mode. You need to install
=cdlatex.el= and =texmathp.el= (the latter comes also with AUCTeX)
-from [[http://www.astro.uva.nl/~dominik/Tools/cdlatex]]. Do not use
-CDLaTeX mode itself under Org mode, but use the light version
-~org-cdlatex-mode~ that comes as part of Org mode. Turn it on for the
+using [[https://melpa.org/][MELPA]] with the [[https://www.gnu.org/software/emacs/manual/html_node/emacs/Package-Installation.html][Emacs packaging system]] or alternatively from
+[[https://staff.fnwi.uva.nl/c.dominik/Tools/cdlatex/]]. Do not use
+CDLaTeX mode itself under Org mode, but use the special version Org
+CDLaTeX minor mode that comes as part of Org. Turn it on for the
current buffer with {{{kbd(M-x org-cdlatex-mode)}}}, or for all Org
files with
@@ -10820,51 +10810,51 @@ more details see the documentation of CDLaTeX mode):
#+attr_texinfo: :sep ,
- {{{kbd(C-c {)}}} ::
- #+kindex: C-c @{
+ #+kindex: C-c @{
- Insert an environment template.
+ Insert an environment template.
- {{{kbd(TAB)}}} ::
- #+kindex: TAB
+ #+kindex: TAB
- The {{{kbd(TAB)}}} key expands the template if point is inside
- a LaTeX fragment[fn:113]. For example, {{{kbd(TAB)}}} expands
- =fr= to =\frac{}{}= and position point correctly inside the first
- brace. Another {{{kbd(TAB)}}} gets you into the second brace.
+ The {{{kbd(TAB)}}} key expands the template if point is inside
+ a LaTeX fragment[fn:111]. For example, {{{kbd(TAB)}}} expands =fr=
+ to =\frac{}{}= and position point correctly inside the first brace.
+ Another {{{kbd(TAB)}}} gets you into the second brace.
- Even outside fragments, {{{kbd(TAB)}}} expands environment
- abbreviations at the beginning of a line. For example, if you
- write =equ= at the beginning of a line and press {{{kbd(TAB)}}},
- this abbreviation is expanded to an =equation= environment. To
- get a list of all abbreviations, type {{{kbd(M-x
- cdlatex-command-help)}}}.
+ Even outside fragments, {{{kbd(TAB)}}} expands environment
+ abbreviations at the beginning of a line. For example, if you write
+ =equ= at the beginning of a line and press {{{kbd(TAB)}}}, this
+ abbreviation is expanded to an =equation= environment. To get
+ a list of all abbreviations, type {{{kbd(M-x
+ cdlatex-command-help)}}}.
- {{{kbd(^)}}}, {{{kbd(_)}}} ::
- #+kindex: _
- #+kindex: ^
- #+vindex: cdlatex-simplify-sub-super-scripts
+ #+kindex: _
+ #+kindex: ^
+ #+vindex: cdlatex-simplify-sub-super-scripts
- Pressing {{{kbd(_)}}} and {{{kbd(^)}}} inside a LaTeX fragment
- inserts these characters together with a pair of braces. If you
- use {{{kbd(TAB)}}} to move out of the braces, and if the braces
- surround only a single character or macro, they are removed again
- (depending on the variable ~cdlatex-simplify-sub-super-scripts~).
+ Pressing {{{kbd(_)}}} and {{{kbd(^)}}} inside a LaTeX fragment
+ inserts these characters together with a pair of braces. If you use
+ {{{kbd(TAB)}}} to move out of the braces, and if the braces surround
+ only a single character or macro, they are removed again (depending
+ on the variable ~cdlatex-simplify-sub-super-scripts~).
- {{{kbd(`)}}} ::
- #+kindex: `
+ #+kindex: `
- Pressing the backquote followed by a character inserts math
- macros, also outside LaTeX fragments. If you wait more than 1.5
- seconds after the backquote, a help window pops up.
+ Pressing the backquote followed by a character inserts math macros,
+ also outside LaTeX fragments. If you wait more than 1.5 seconds
+ after the backquote, a help window pops up.
- {{{kbd(')}}} ::
- #+kindex: '
+ #+kindex: '
- Pressing the single-quote followed by another character modifies
- the symbol before point with an accent or a font. If you wait
- more than 1.5 seconds after the single-quote, a help window pops
- up. Character modification works only inside LaTeX fragments;
- outside the quote is normal.
+ Pressing the single-quote followed by another character modifies the
+ symbol before point with an accent or a font. If you wait more than
+ 1.5 seconds after the single-quote, a help window pops up.
+ Character modification works only inside LaTeX fragments; outside
+ the quote is normal.
** Literal Examples
:PROPERTIES:
@@ -10885,11 +10875,22 @@ suited for source code and similar examples.
,#+END_EXAMPLE
#+end_example
-Note that such blocks may be /indented/ in order to align nicely with
-indented text and in particular with plain list structure (see
-[[*Plain Lists]]). For simplicity when using small examples, you can
-also start the example lines with a colon followed by a space. There
-may also be additional whitespace before the colon:
+#+cindex: comma escape, in literal examples
+There is one limitation, however. You must insert a comma right
+before lines starting with either =*=, =,*=, =#+= or =,#+=, as those
+may be interpreted as outlines nodes or some other special syntax.
+Org transparently strips these additional commas whenever it accesses
+the contents of the block.
+
+#+begin_example
+,#+BEGIN_EXAMPLE
+,,* I am no real headline
+,#+END_EXAMPLE
+#+end_example
+
+For simplicity when using small examples, you can also start the
+example lines with a colon followed by a space. There may also be
+additional whitespace before the colon:
#+begin_example
Here is an example
@@ -10900,9 +10901,9 @@ Here is an example
#+vindex: org-latex-listings
If the example is source code from a programming language, or any
other text that can be marked up by Font Lock in Emacs, you can ask
-for the example to look like the fontified Emacs buffer[fn:114]. This
+for the example to look like the fontified Emacs buffer[fn:112]. This
is done with the code block, where you also need to specify the name
-of the major mode that should be used to fontify the example[fn:115],
+of the major mode that should be used to fontify the example[fn:113],
see [[*Structure Templates]] for shortcuts to easily insert code blocks.
#+cindex: @samp{BEGIN_SRC}
@@ -10943,7 +10944,7 @@ In HTML, hovering the mouse over such a link remote-highlights the
corresponding code line, which is kind of cool.
You can also add a =-r= switch which /removes/ the labels from the
-source code[fn:116]. With the =-n= switch, links to these references
+source code[fn:114]. With the =-n= switch, links to these references
are labeled by the line numbers from the code listing. Otherwise
links use the labels with no parentheses. Here is an example:
@@ -10957,8 +10958,12 @@ jumps to point-min.
#+end_example
#+cindex: indentation, in source blocks
-Finally, you can use =-i= to preserve the indentation of a specific
-code block (see [[*Editing Source Code]]).
+Source code and examples may be /indented/ in order to align nicely
+with the surrounding text, and in particular with plain list structure
+(see [[*Plain Lists]]). By default, Org only retains the relative
+indentation between lines, e.g., when exporting the contents of the
+block. However, you can use the =-i= switch to also preserve the
+global indentation, if it does matter. See [[*Editing Source Code]].
#+vindex: org-coderef-label-format
If the syntax for the label format conflicts with the language syntax,
@@ -10977,16 +10982,16 @@ a shortcut is provided (see [[*Structure Templates]]).
- {{{kbd(C-c ')}}} (~org-edit-special~) ::
- #+kindex: C-c '
- #+findex: org-edit-special
- Edit the source code example at point in its native mode. This
- works by switching to a temporary buffer with the source code.
- You need to exit by pressing {{{kbd(C-c ')}}} again[fn:117]. The
- edited version then replaces the old version in the Org buffer.
- Fixed-width regions---where each line starts with a colon
- followed by a space---are edited using ~artist-mode~[fn:118] to
- allow creating ASCII drawings easily. Using this command in an
- empty line creates a new fixed-width region.
+ #+kindex: C-c '
+ #+findex: org-edit-special
+ Edit the source code example at point in its native mode. This
+ works by switching to a temporary buffer with the source code. You
+ need to exit by pressing {{{kbd(C-c ')}}} again. The edited version
+ then replaces the old version in the Org buffer. Fixed-width
+ regions---where each line starts with a colon followed by
+ a space---are edited using Artist mode[fn:115] to allow creating
+ ASCII drawings easily. Using this command in an empty line creates
+ a new fixed-width region.
#+cindex: storing link, in a source code buffer
Calling ~org-store-link~ (see [[*Handling Links]]) while editing a source
@@ -11003,7 +11008,7 @@ the end of the current line. Then the label is stored as a link
#+cindex: inlining images
#+cindex: images, markup rules
-An image is a link to an image file[fn:119] that does not have
+An image is a link to an image file[fn:116] that does not have
a description part, for example
: ./img/cat.jpg
@@ -11019,20 +11024,19 @@ make sure that the link is on a line by itself and precede it with
[[./img/a.jpg]]
#+end_example
-#+texinfo: @noindent
Such images can be displayed within the buffer with the following
command:
- {{{kbd(C-c C-x C-v)}}} (~org-toggle-inline-images~) ::
- #+kindex: C-c C-x C-v
- #+findex: org-toggle-inline-images
- #+vindex: org-startup-with-inline-images
- Toggle the inline display of linked images. When called with
- a prefix argument, also display images that do have a link
- description. You can ask for inline images to be displayed at
- startup by configuring the variable
- ~org-startup-with-inline-images~[fn:120].
+ #+kindex: C-c C-x C-v
+ #+findex: org-toggle-inline-images
+ #+vindex: org-startup-with-inline-images
+ Toggle the inline display of linked images. When called with
+ a prefix argument, also display images that do have a link
+ description. You can ask for inline images to be displayed at
+ startup by configuring the variable
+ ~org-startup-with-inline-images~[fn:117].
** Captions
:PROPERTIES:
@@ -11068,6 +11072,97 @@ export back-end, those may or may not be handled.
A line consisting of only dashes, and at least 5 of them, is exported
as a horizontal line.
+** Creating Footnotes
+:PROPERTIES:
+:DESCRIPTION: Edit and read footnotes.
+:END:
+#+cindex: footnotes
+
+A footnote is started by a footnote marker in square brackets in
+column 0, no indentation allowed. It ends at the next footnote
+definition, headline, or after two consecutive empty lines. The
+footnote reference is simply the marker in square brackets, inside
+text. Markers always start with =fn:=. For example:
+
+#+begin_example
+The Org homepage[fn:1] now looks a lot better than it used to.
+...
+[fn:1] The link is: https://orgmode.org
+#+end_example
+
+Org mode extends the number-based syntax to /named/ footnotes and
+optional inline definition. Here are the valid references:
+
+- =[fn:NAME]= ::
+
+ A named footnote reference, where {{{var(NAME)}}} is a unique
+ label word, or, for simplicity of automatic creation, a number.
+
+- =[fn:: This is the inline definition of this footnote]= ::
+
+ An anonymous footnote where the definition is given directly at the
+ reference point.
+
+- =[fn:NAME: a definition]= ::
+
+ An inline definition of a footnote, which also specifies a name for
+ the note. Since Org allows multiple references to the same note,
+ you can then use =[fn:NAME]= to create additional references.
+
+#+vindex: org-footnote-auto-label
+Footnote labels can be created automatically, or you can create names
+yourself. This is handled by the variable ~org-footnote-auto-label~
+and its corresponding =STARTUP= keywords. See the docstring of that
+variable for details.
+
+The following command handles footnotes:
+
+- {{{kbd(C-c C-x f)}}} ::
+
+ The footnote action command.
+
+ #+kindex: C-c C-x f
+ When point is on a footnote reference, jump to the definition. When
+ it is at a definition, jump to the---first---reference.
+
+ #+vindex: org-footnote-define-inline
+ #+vindex: org-footnote-section
+ Otherwise, create a new footnote. Depending on the variable
+ ~org-footnote-define-inline~[fn:118], the definition is placed right
+ into the text as part of the reference, or separately into the
+ location determined by the variable ~org-footnote-section~.
+
+ When this command is called with a prefix argument, a menu of
+ additional options is offered:
+
+ #+attr_texinfo: :columns 0.1 0.9
+ | {{{kbd(s)}}} | Sort the footnote definitions by reference sequence. |
+ | {{{kbd(r)}}} | Renumber the simple =fn:N= footnotes. |
+ | {{{kbd(S)}}} | Short for first {{{kbd(r)}}}, then {{{kbd(s)}}} action. |
+ | {{{kbd(n)}}} | Rename all footnotes into a =fn:1= ... =fn:n= sequence. |
+ | {{{kbd(d)}}} | Delete the footnote at point, including definition and references. |
+
+ #+vindex: org-footnote-auto-adjust
+ Depending on the variable ~org-footnote-auto-adjust~[fn:119],
+ renumbering and sorting footnotes can be automatic after each
+ insertion or deletion.
+
+- {{{kbd(C-c C-c)}}} ::
+
+ #+kindex: C-c C-c
+ If point is on a footnote reference, jump to the definition. If it
+ is at the definition, jump back to the reference. When called at
+ a footnote location with a prefix argument, offer the same menu as
+ {{{kbd(C-c C-x f)}}}.
+
+- {{{kbd(C-c C-o)}}} or {{{kbd(mouse-1/2)}}} ::
+
+ #+kindex: C-c C-o
+ #+kindex: mouse-1
+ #+kindex: mouse-2
+ Footnote labels are also links to the corresponding definition or
+ reference, and you can use the usual commands to follow these links.
+
* Exporting
:PROPERTIES:
:DESCRIPTION: Sharing and publishing notes.
@@ -11131,13 +11226,12 @@ a non-~nil~ value, Org prompts in the minibuffer. To switch back to
the hierarchical menu, press {{{kbd(?)}}}.
- {{{kbd(C-c C-e)}}} (~org-export~) ::
- #+kindex: C-c C-e
- #+findex: org-export
+ #+kindex: C-c C-e
+ #+findex: org-export
- Invokes the export dispatcher interface. The options show
- default settings. The {{{kbd(C-u)}}} prefix argument preserves
- options from the previous export, including any sub-tree
- selections.
+ Invokes the export dispatcher interface. The options show default
+ settings. The {{{kbd(C-u)}}} prefix argument preserves options from
+ the previous export, including any sub-tree selections.
Org exports the entire buffer by default. If the Org buffer has an
active region, then Org exports just that region.
@@ -11146,53 +11240,53 @@ Within the dispatcher interface, the following key combinations can
further alter what is exported, and how.
- {{{kbd(C-a)}}} ::
- #+kindex: C-c C-e C-a
+ #+kindex: C-c C-e C-a
- Toggle asynchronous export. Asynchronous export uses an external
- Emacs process with a specially configured initialization file to
- complete the exporting process in the background, without tying-up
- Emacs. This is particularly useful when exporting long documents.
+ Toggle asynchronous export. Asynchronous export uses an external
+ Emacs process with a specially configured initialization file to
+ complete the exporting process in the background, without tying-up
+ Emacs. This is particularly useful when exporting long documents.
- Output from an asynchronous export is saved on the /export
- stack/. To view this stack, call the export dispatcher with
- a double {{{kbd(C-u)}}} prefix argument. If already in the
- export dispatcher menu, {{{kbd(&)}}} displays the stack.
+ Output from an asynchronous export is saved on the /export stack/.
+ To view this stack, call the export dispatcher with a double
+ {{{kbd(C-u)}}} prefix argument. If already in the export dispatcher
+ menu, {{{kbd(&)}}} displays the stack.
- #+vindex: org-export-in-background
- You can make asynchronous export the default by setting
- ~org-export-in-background~.
+ #+vindex: org-export-in-background
+ You can make asynchronous export the default by setting
+ ~org-export-in-background~.
- #+vindex: org-export-async-init-file
- You can set the initialization file used by the background process
- by setting ~org-export-async-init-file~.
+ #+vindex: org-export-async-init-file
+ You can set the initialization file used by the background process
+ by setting ~org-export-async-init-file~.
- {{{kbd(C-b)}}} ::
- #+kindex: C-c C-e C-b
+ #+kindex: C-c C-e C-b
- Toggle body-only export. Useful for excluding headers and
- footers in the export. Affects only those back-end formats that
- have sections like =<head>...</head>= in HTML.
+ Toggle body-only export. Useful for excluding headers and footers
+ in the export. Affects only those back-end formats that have
+ sections like =<head>...</head>= in HTML.
- {{{kbd(C-s)}}} ::
- #+kindex: C-c C-e C-s
+ #+kindex: C-c C-e C-s
- Toggle sub-tree export. When turned on, Org exports only the
- sub-tree starting from point position at the time the export
- dispatcher was invoked. Org uses the top heading of this
- sub-tree as the document's title. If point is not on a heading,
- Org uses the nearest enclosing header. If point is in the
- document preamble, Org signals an error and aborts export.
+ Toggle sub-tree export. When turned on, Org exports only the
+ sub-tree starting from point position at the time the export
+ dispatcher was invoked. Org uses the top heading of this sub-tree
+ as the document's title. If point is not on a heading, Org uses the
+ nearest enclosing header. If point is in the document preamble, Org
+ signals an error and aborts export.
- #+vindex: org-export-initial-scope
- To make sub-tree export the default, customize the variable
- ~org-export-initial-scope~.
+ #+vindex: org-export-initial-scope
+ To make sub-tree export the default, customize the variable
+ ~org-export-initial-scope~.
- {{{kbd(C-v)}}} ::
- #+kindex: C-c C-e C-v
+ #+kindex: C-c C-e C-v
- Toggle visible-only export. This is useful for exporting only certain
- parts of an Org document by adjusting the visibility
- of particular headings.
+ Toggle visible-only export. This is useful for exporting only
+ certain parts of an Org document by adjusting the visibility of
+ particular headings.
** Export Settings
:PROPERTIES:
@@ -11224,73 +11318,72 @@ global variables, include:
- =AUTHOR= ::
- #+cindex: @samp{AUTHOR}, keyword
- #+vindex: user-full-name
- The document author (~user-full-name~).
+ #+cindex: @samp{AUTHOR}, keyword
+ #+vindex: user-full-name
+ The document author (~user-full-name~).
- =CREATOR= ::
- #+cindex: @samp{CREATOR}, keyword
- #+vindex: org-expot-creator-string
- Entity responsible for output generation
- (~org-export-creator-string~).
+ #+cindex: @samp{CREATOR}, keyword
+ #+vindex: org-expot-creator-string
+ Entity responsible for output generation
+ (~org-export-creator-string~).
- =DATE= ::
- #+cindex: @samp{DATE}, keyword
- #+vindex: org-export-date-timestamp-format
- A date or a time-stamp[fn:121].
+ #+cindex: @samp{DATE}, keyword
+ #+vindex: org-export-date-timestamp-format
+ A date or a time-stamp[fn:120].
- =EMAIL= ::
- #+cindex: @samp{EMAIL}, keyword
- #+vindex: user-mail-address
- The email address (~user-mail-address~).
+ #+cindex: @samp{EMAIL}, keyword
+ #+vindex: user-mail-address
+ The email address (~user-mail-address~).
- =LANGUAGE= ::
- #+cindex: @samp{LANGUAGE}, keyword
- #+vindex: org-export-default-language
- Language to use for translating certain strings
- (~org-export-default-language~). With =#+LANGUAGE: fr=, for
- example, Org translates =Table of contents= to the French =Table
- des matières=[fn:122].
+ #+cindex: @samp{LANGUAGE}, keyword
+ #+vindex: org-export-default-language
+ Language to use for translating certain strings
+ (~org-export-default-language~). With =#+LANGUAGE: fr=, for
+ example, Org translates =Table of contents= to the French =Table des
+ matières=[fn:121].
- =SELECT_TAGS= ::
- #+cindex: @samp{SELECT_TAGS}, keyword
- #+vindex: org-export-select-tags
- The default value is =("export")=. When a tree is tagged with
- =export= (~org-export-select-tags~), Org selects that tree and
- its sub-trees for export. Org excludes trees with =noexport=
- tags, see below. When selectively exporting files with =export=
- tags set, Org does not export any text that appears before the
- first headline.
+ #+cindex: @samp{SELECT_TAGS}, keyword
+ #+vindex: org-export-select-tags
+ The default value is =("export")=. When a tree is tagged with
+ =export= (~org-export-select-tags~), Org selects that tree and its
+ sub-trees for export. Org excludes trees with =noexport= tags, see
+ below. When selectively exporting files with =export= tags set, Org
+ does not export any text that appears before the first headline.
- =EXCLUDE_TAGS= ::
- #+cindex: @samp{EXCLUDE_TAGS}, keyword
- #+vindex: org-export-exclude-tags
- The default value is =("noexport")=. When a tree is tagged with
- =noexport= (~org-export-exclude-tags~), Org excludes that tree
- and its sub-trees from export. Entries tagged with =noexport=
- are unconditionally excluded from the export, even if they have
- an =export= tag. Even if a sub-tree is not exported, Org
- executes any code blocks contained there.
+ #+cindex: @samp{EXCLUDE_TAGS}, keyword
+ #+vindex: org-export-exclude-tags
+ The default value is =("noexport")=. When a tree is tagged with
+ =noexport= (~org-export-exclude-tags~), Org excludes that tree and
+ its sub-trees from export. Entries tagged with =noexport= are
+ unconditionally excluded from the export, even if they have an
+ =export= tag. Even if a sub-tree is not exported, Org executes any
+ code blocks contained there.
- =TITLE= ::
- #+cindex: @samp{TITLE}, keyword
- #+cindex: document title
- Org displays this title. For long titles, use multiple =#+TITLE=
- lines.
+ #+cindex: @samp{TITLE}, keyword
+ #+cindex: document title
+ Org displays this title. For long titles, use multiple =#+TITLE=
+ lines.
- =EXPORT_FILE_NAME= ::
- #+cindex: @samp{EXPORT_FILE_NAME}, keyword
- The name of the output file to be generated. Otherwise, Org
- generates the file name based on the buffer name and the
- extension based on the back-end format.
+ #+cindex: @samp{EXPORT_FILE_NAME}, keyword
+ The name of the output file to be generated. Otherwise, Org
+ generates the file name based on the buffer name and the extension
+ based on the back-end format.
The =OPTIONS= keyword is a compact form. To configure multiple
options, use several =OPTIONS= lines. =OPTIONS= recognizes the
@@ -11298,202 +11391,201 @@ following arguments.
- ~'~ ::
- #+vindex: org-export-with-smart-quotes
- Toggle smart quotes (~org-export-with-smart-quotes~). Depending
- on the language used, when activated, Org treats pairs of double
- quotes as primary quotes, pairs of single quotes as secondary
- quotes, and single quote marks as apostrophes.
+ #+vindex: org-export-with-smart-quotes
+ Toggle smart quotes (~org-export-with-smart-quotes~). Depending on
+ the language used, when activated, Org treats pairs of double quotes
+ as primary quotes, pairs of single quotes as secondary quotes, and
+ single quote marks as apostrophes.
- ~*~ ::
- #+vindex: org-export-with-emphasize
- Toggle emphasized text (~org-export-with-emphasize~).
+ #+vindex: org-export-with-emphasize
+ Toggle emphasized text (~org-export-with-emphasize~).
- ~-~ ::
- #+vindex: org-export-with-special-strings
- Toggle conversion of special strings
- (~org-export-with-special-strings~).
+ #+vindex: org-export-with-special-strings
+ Toggle conversion of special strings
+ (~org-export-with-special-strings~).
- ~:~ ::
- #+vindex: org-export-with-fixed-width
- Toggle fixed-width sections (~org-export-with-fixed-width~).
+ #+vindex: org-export-with-fixed-width
+ Toggle fixed-width sections (~org-export-with-fixed-width~).
- ~<~ ::
- #+vindex: org-export-with-timestamps
- Toggle inclusion of time/date active/inactive stamps
- (~org-export-with-timestamps~).
+ #+vindex: org-export-with-timestamps
+ Toggle inclusion of time/date active/inactive stamps
+ (~org-export-with-timestamps~).
- ~\n~ ::
- #+vindex: org-export-preserve-breaks
- Toggles whether to preserve line breaks
- (~org-export-preserve-breaks~).
+ #+vindex: org-export-preserve-breaks
+ Toggles whether to preserve line breaks
+ (~org-export-preserve-breaks~).
- ~^~ ::
- #+vindex: org-export-with-sub-superscripts
- Toggle TeX-like syntax for sub- and superscripts. If you write
- =^:{}=, =a_{b}= is interpreted, but the simple =a_b= is left as
- it is (~org-export-with-sub-superscripts~).
+ #+vindex: org-export-with-sub-superscripts
+ Toggle TeX-like syntax for sub- and superscripts. If you write
+ =^:{}=, =a_{b}= is interpreted, but the simple =a_b= is left as it
+ is (~org-export-with-sub-superscripts~).
- ~arch~ ::
- #+vindex: org-export-with-archived-trees
- Configure how archived trees are exported. When set to
- ~headline~, the export process skips the contents and processes
- only the headlines (~org-export-with-archived-trees~).
+ #+vindex: org-export-with-archived-trees
+ Configure how archived trees are exported. When set to ~headline~,
+ the export process skips the contents and processes only the
+ headlines (~org-export-with-archived-trees~).
- ~author~ ::
- #+vindex: org-export-with-author
- Toggle inclusion of author name into exported file
- (~org-export-with-author~).
+ #+vindex: org-export-with-author
+ Toggle inclusion of author name into exported file
+ (~org-export-with-author~).
- ~broken-links~ ::
- #+vindex: org-export-with-broken-links
- Toggles if Org should continue exporting upon finding a broken
- internal link. When set to ~mark~, Org clearly marks the problem
- link in the output (~org-export-with-broken-links~).
+ #+vindex: org-export-with-broken-links
+ Toggles if Org should continue exporting upon finding a broken
+ internal link. When set to ~mark~, Org clearly marks the problem
+ link in the output (~org-export-with-broken-links~).
- ~c~ ::
- #+vindex: org-export-with-clocks
- Toggle inclusion of CLOCK keywords (~org-export-with-clocks~).
+ #+vindex: org-export-with-clocks
+ Toggle inclusion of =CLOCK= keywords (~org-export-with-clocks~).
- ~creator~ ::
- #+vindex: org-export-with-creator
- Toggle inclusion of creator information in the exported file
- (~org-export-with-creator~).
+ #+vindex: org-export-with-creator
+ Toggle inclusion of creator information in the exported file
+ (~org-export-with-creator~).
- ~d~ ::
- #+vindex: org-export-with-drawers
- Toggles inclusion of drawers, or list of drawers to include, or
- list of drawers to exclude (~org-export-with-drawers~).
+ #+vindex: org-export-with-drawers
+ Toggles inclusion of drawers, or list of drawers to include, or list
+ of drawers to exclude (~org-export-with-drawers~).
- ~date~ ::
- #+vindex: org-export-with-date
- Toggle inclusion of a date into exported file
- (~org-export-with-date~).
+ #+vindex: org-export-with-date
+ Toggle inclusion of a date into exported file
+ (~org-export-with-date~).
- ~e~ ::
- #+vindex: org-export-with-entities
- Toggle inclusion of entities (~org-export-with-entities~).
+ #+vindex: org-export-with-entities
+ Toggle inclusion of entities (~org-export-with-entities~).
- ~email~ ::
- #+vindex: org-export-with-email
- Toggle inclusion of the author's e-mail into exported file
- (~org-export-with-email~).
+ #+vindex: org-export-with-email
+ Toggle inclusion of the author's e-mail into exported file
+ (~org-export-with-email~).
- ~f~ ::
- #+vindex: org-export-with-footnotes
- Toggle the inclusion of footnotes (~org-export-with-footnotes~).
+ #+vindex: org-export-with-footnotes
+ Toggle the inclusion of footnotes (~org-export-with-footnotes~).
- ~H~ ::
- #+vindex: org-export-headline-levels
- Set the number of headline levels for export
- (~org-export-headline-levels~). Below that level, headlines are
- treated differently. In most back-ends, they become list items.
+ #+vindex: org-export-headline-levels
+ Set the number of headline levels for export
+ (~org-export-headline-levels~). Below that level, headlines are
+ treated differently. In most back-ends, they become list items.
- ~inline~ ::
- #+vindex: org-export-with-inlinetasks
- Toggle inclusion of inlinetasks (~org-export-with-inlinetasks~).
+ #+vindex: org-export-with-inlinetasks
+ Toggle inclusion of inlinetasks (~org-export-with-inlinetasks~).
- ~num~ ::
- #+vindex: org-export-with-section-numbers
- #+cindex: @samp{UNNUMBERED}, property
- Toggle section-numbers (~org-export-with-section-numbers~). When
- set to number N, Org numbers only those headlines at level N or
- above. Set =UNNUMBERED= property to non-~nil~ to disable
- numbering of heading and subheadings entirely. Moreover, when
- the value is =notoc= the headline, and all its children, do not
- appear in the table of contents either (see [[*Table of Contents]]).
+ #+vindex: org-export-with-section-numbers
+ #+cindex: @samp{UNNUMBERED}, property
+ Toggle section-numbers (~org-export-with-section-numbers~). When
+ set to number N, Org numbers only those headlines at level N or
+ above. Set =UNNUMBERED= property to non-~nil~ to disable numbering
+ of heading and subheadings entirely. Moreover, when the value is
+ =notoc= the headline, and all its children, do not appear in the
+ table of contents either (see [[*Table of Contents]]).
- ~p~ ::
- #+vindex: org-export-with-planning
- Toggle export of planning information
- (~org-export-with-planning~). "Planning information" comes from
- lines located right after the headline and contain any
- combination of these cookies: =SCHEDULED=, =DEADLINE=, or
- =CLOSED=.
+ #+vindex: org-export-with-planning
+ Toggle export of planning information (~org-export-with-planning~).
+ "Planning information" comes from lines located right after the
+ headline and contain any combination of these cookies: =SCHEDULED=,
+ =DEADLINE=, or =CLOSED=.
- ~pri~ ::
- #+vindex: org-export-with-priority
- Toggle inclusion of priority cookies
- (~org-export-with-priority~).
+ #+vindex: org-export-with-priority
+ Toggle inclusion of priority cookies
+ (~org-export-with-priority~).
- ~prop~ ::
- #+vindex: org-export-with-properties
- Toggle inclusion of property drawers, or list the properties to
- include (~org-export-with-properties~).
+ #+vindex: org-export-with-properties
+ Toggle inclusion of property drawers, or list the properties to
+ include (~org-export-with-properties~).
- ~stat~ ::
- #+vindex: org-export-with-statistics-cookies
- Toggle inclusion of statistics cookies
- (~org-export-with-statistics-cookies~).
+ #+vindex: org-export-with-statistics-cookies
+ Toggle inclusion of statistics cookies
+ (~org-export-with-statistics-cookies~).
- ~tags~ ::
- #+vindex: org-export-with-tags
- Toggle inclusion of tags, may also be ~not-in-toc~
- (~org-export-with-tags~).
+ #+vindex: org-export-with-tags
+ Toggle inclusion of tags, may also be ~not-in-toc~
+ (~org-export-with-tags~).
- ~tasks~ ::
- #+vindex: org-export-with-tasks
- Toggle inclusion of tasks (TODO items); or ~nil~ to remove all
- tasks; or ~todo~ to remove DONE tasks; or list the keywords to
- keep (~org-export-with-tasks~).
+ #+vindex: org-export-with-tasks
+ Toggle inclusion of tasks (TODO items); or ~nil~ to remove all
+ tasks; or ~todo~ to remove done tasks; or list the keywords to keep
+ (~org-export-with-tasks~).
- ~tex~ ::
- #+vindex: org-export-with-latex
- ~nil~ does not export; ~t~ exports; ~verbatim~ keeps everything
- in verbatim (~org-export-with-latex~).
+ #+vindex: org-export-with-latex
+ ~nil~ does not export; ~t~ exports; ~verbatim~ keeps everything in
+ verbatim (~org-export-with-latex~).
- ~timestamp~ ::
- #+vindex: org-export-time-stamp-file
- Toggle inclusion of the creation time in the exported file
- (~org-export-time-stamp-file~).
+ #+vindex: org-export-time-stamp-file
+ Toggle inclusion of the creation time in the exported file
+ (~org-export-time-stamp-file~).
- ~title~ ::
- #+vindex: org-export-with-title
- Toggle inclusion of title (~org-export-with-title~).
+ #+vindex: org-export-with-title
+ Toggle inclusion of title (~org-export-with-title~).
- ~toc~ ::
- #+vindex: org-export-with-toc
- Toggle inclusion of the table of contents, or set the level limit
- (~org-export-with-toc~).
+ #+vindex: org-export-with-toc
+ Toggle inclusion of the table of contents, or set the level limit
+ (~org-export-with-toc~).
- ~todo~ ::
- #+vindex: org-export-with-todo-keywords
- Toggle inclusion of TODO keywords into exported text
- (~org-export-with-todo-keywords~).
+ #+vindex: org-export-with-todo-keywords
+ Toggle inclusion of TODO keywords into exported text
+ (~org-export-with-todo-keywords~).
- ~|~ ::
- #+vindex: org-export-with-tables
- Toggle inclusion of tables (~org-export-with-tables~).
+ #+vindex: org-export-with-tables
+ Toggle inclusion of tables (~org-export-with-tables~).
When exporting sub-trees, special node properties can override the
above keywords. These properties have an =EXPORT_= prefix. For
@@ -11533,7 +11625,7 @@ keyword:
#+cindex: excluding entries from table of contents
#+cindex: table of contents, exclude entries
Org includes both numbered and unnumbered headlines in the table of
-contents[fn:123]. If you need to exclude an unnumbered headline,
+contents[fn:122]. If you need to exclude an unnumbered headline,
along with all its children, set the =UNNUMBERED= property to =notoc=
value.
@@ -11572,6 +11664,22 @@ file requires the inclusion of the titletoc package. Because of
compatibility issues, titletoc has to be loaded /before/ hyperref.
Customize the ~org-latex-default-packages-alist~ variable.
+The following example inserts a table of contents that links to the
+children of the specified target.
+
+#+begin_example
+,* Target
+ :PROPERTIES:
+ :CUSTOM_ID: TargetSection
+ :END:
+,** Heading A
+,** Heading B
+,* Another section
+,#+TOC: headlines 1 :target #TargetSection
+#+end_example
+
+The =:target= attribute is supported in HTML, Markdown, ODT, and ASCII export.
+
Use the =TOC= keyword to generate list of tables---respectively, all
listings---with captions.
@@ -11636,7 +11744,7 @@ be omitted to use the obvious defaults.
| =#+INCLUDE: "~/.emacs" :lines "10-"= | Include lines from 10 to EOF |
Inclusions may specify a file-link to extract an object matched by
-~org-link-search~[fn:124] (see [[*Search Options in File Links]]). The
+~org-link-search~[fn:123] (see [[*Search Options in File Links]]). The
ranges for =:lines= keyword are relative to the requested element.
Therefore,
@@ -11653,14 +11761,13 @@ with the custom ID =theory=, you can use
: #+INCLUDE: "./paper.org::#theory" :only-contents t
-The following command allows navigating back and forth to the included
-document:
+The following command allows navigating to the included document:
- {{{kbd(C-c ')}}} (~org-edit~special~) ::
- #+kindex: C-c '
- #+findex: org-edit-special
+ #+kindex: C-c '
+ #+findex: org-edit-special
- Visit the included file at point.
+ Visit the included file at point.
** Macro Replacement
:PROPERTIES:
@@ -11677,7 +11784,7 @@ following syntax:
: #+MACRO: name replacement text; $1, $2 are arguments
#+texinfo: @noindent
-which can be referenced using ={{{name(arg1, arg2)}}}=[fn:125]. For
+which can be referenced using ={{{name(arg1, arg2)}}}=[fn:124]. For
example
#+begin_example
@@ -11710,60 +11817,60 @@ Org comes with following pre-defined macros:
#+attr_texinfo: :sep ;
- ={{{keyword(NAME)}}}=; ={{{title}}}=; ={{{author}}}=; ={{{email}}}= ::
- #+cindex: @samp{keyword}, macro
- #+cindex: @samp{title}, macro
- #+cindex: @samp{author}, macro
- #+cindex: @samp{email}, macro
- The =keyword= macro collects all values from {{{var(NAME)}}}
- keywords throughout the buffer, separated with white space.
- =title=, =author= and =email= macros are shortcuts for,
- respectively, ={{{keyword(TITLE)}}}=, ={{{keyword(AUTHOR)}}}= and
- ={{{keyword(EMAIL)}}}=.
+ #+cindex: @samp{keyword}, macro
+ #+cindex: @samp{title}, macro
+ #+cindex: @samp{author}, macro
+ #+cindex: @samp{email}, macro
+ The =keyword= macro collects all values from {{{var(NAME)}}}
+ keywords throughout the buffer, separated with white space.
+ =title=, =author= and =email= macros are shortcuts for,
+ respectively, ={{{keyword(TITLE)}}}=, ={{{keyword(AUTHOR)}}}= and
+ ={{{keyword(EMAIL)}}}=.
- ={{{date}}}=; ={{{date(FORMAT)}}}= ::
- #+cindex: @samp{date}, macro
- This macro refers to the =DATE= keyword. {{{var(FORMAT)}}} is an
- optional argument to the =date= macro that is used only if =DATE=
- is a single timestamp. {{{var(FORMAT)}}} should be a format
- string understood by ~format-time-string~.
+ #+cindex: @samp{date}, macro
+ This macro refers to the =DATE= keyword. {{{var(FORMAT)}}} is an
+ optional argument to the =date= macro that is used only if =DATE= is
+ a single timestamp. {{{var(FORMAT)}}} should be a format string
+ understood by ~format-time-string~.
- ={{{time(FORMAT)}}}=; ={{{modification-time(FORMAT, VC)}}}= ::
- #+cindex: @samp{time}, macro
- #+cindex: @samp{modification-time}, macro
- These macros refer to the document's date and time of export and
- date and time of modification. {{{var(FORMAT)}}} is a string
- understood by ~format-time-string~. If the second argument to
- the ~modification-time~ macro is non-~nil~, Org uses =vc.el= to
- retrieve the document's modification time from the version
- control system. Otherwise Org reads the file attributes.
+ #+cindex: @samp{time}, macro
+ #+cindex: @samp{modification-time}, macro
+ These macros refer to the document's date and time of export and
+ date and time of modification. {{{var(FORMAT)}}} is a string
+ understood by ~format-time-string~. If the second argument to the
+ ~modification-time~ macro is non-~nil~, Org uses =vc.el= to retrieve
+ the document's modification time from the version control system.
+ Otherwise Org reads the file attributes.
- ={{{input-file}}}= ::
- #+cindex: @samp{input-file}, macro
- This macro refers to the filename of the exported file.
+ #+cindex: @samp{input-file}, macro
+ This macro refers to the filename of the exported file.
- ={{{property(PROPERTY-NAME)}}}=; ={{{property(PROPERTY-NAME, SEARCH OPTION)}}}= ::
- #+cindex: @samp{property}, macro
- This macro returns the value of property {{{var(PROPERTY-NAME)}}}
- in the current entry. If {{{var(SEARCH-OPTION)}}} (see [[*Search
- Options in File Links]]) refers to a remote entry, use it instead.
+ #+cindex: @samp{property}, macro
+ This macro returns the value of property {{{var(PROPERTY-NAME)}}} in
+ the current entry. If {{{var(SEARCH-OPTION)}}} (see [[*Search
+ Options in File Links]]) refers to a remote entry, use it instead.
- ={{{n}}}=; ={{{n(NAME)}}}=; ={{{n(NAME, ACTION)}}}= ::
- #+cindex: @samp{n}, macro
- #+cindex: counter, macro
- This macro implements custom counters by returning the number of
- times the macro has been expanded so far while exporting the
- buffer. You can create more than one counter using different
- {{{var(NAME)}}} values. If {{{var(ACTION)}}} is =-=, previous
- value of the counter is held, i.e., the specified counter is not
- incremented. If the value is a number, the specified counter is
- set to that value. If it is any other non-empty string, the
- specified counter is reset to 1. You may leave {{{var(NAME)}}}
- empty to reset the default counter.
+ #+cindex: @samp{n}, macro
+ #+cindex: counter, macro
+ This macro implements custom counters by returning the number of
+ times the macro has been expanded so far while exporting the buffer.
+ You can create more than one counter using different {{{var(NAME)}}}
+ values. If {{{var(ACTION)}}} is =-=, previous value of the counter
+ is held, i.e., the specified counter is not incremented. If the
+ value is a number, the specified counter is set to that value. If
+ it is any other non-empty string, the specified counter is reset
+ to 1. You may leave {{{var(NAME)}}} empty to reset the default
+ counter.
#+cindex: @samp{results}, macro
Moreover, inline source blocks (see [[*Structure of Code Blocks]]) use the
@@ -11796,14 +11903,14 @@ are not exported.
Finally, a =COMMENT= keyword at the beginning of an entry, but after
any other keyword or priority cookie, comments out the entire subtree.
In this case, the subtree is not exported and no code block within it
-is executed either[fn:126]. The command below helps changing the
+is executed either[fn:125]. The command below helps changing the
comment status of a headline.
- {{{kbd(C-c ;)}}} (~org-toggle-comment~) ::
- #+kindex: C-c ;
- #+findex: org-toggle-comment
+ #+kindex: C-c ;
+ #+findex: org-toggle-comment
- Toggle the =COMMENT= keyword at the beginning of an entry.
+ Toggle the =COMMENT= keyword at the beginning of an entry.
** ASCII/Latin-1/UTF-8 export
:PROPERTIES:
@@ -11836,24 +11943,23 @@ See the variable ~org-ascii-links-to-notes~ for details.
#+attr_texinfo: :sep ,
- {{{kbd(C-c C-e t a)}}} (~org-ascii-export-to-ascii~), {{{kbd(C-c C-e t l)}}}, {{{kbd(C-c C-e t u)}}} ::
- #+kindex: C-c C-e t a
- #+kindex: C-c C-e t l
- #+kindex: C-c C-e t u
- #+findex: org-ascii-export-to-ascii
+ #+kindex: C-c C-e t a
+ #+kindex: C-c C-e t l
+ #+kindex: C-c C-e t u
+ #+findex: org-ascii-export-to-ascii
- Export as an ASCII file with a =.txt= extension. For
- =myfile.org=, Org exports to =myfile.txt=, overwriting without
- warning. For =myfile.txt=, Org exports to =myfile.txt.txt= in
- order to prevent data loss.
+ Export as an ASCII file with a =.txt= extension. For =myfile.org=,
+ Org exports to =myfile.txt=, overwriting without warning. For
+ =myfile.txt=, Org exports to =myfile.txt.txt= in order to prevent
+ data loss.
-#+attr_texinfo: :sep ,
- {{{kbd(C-c C-e t A)}}} (~org-ascii-export-to-ascii~), {{{kbd(C-c C-e t L)}}}, {{{kbd(C-c C-e t U)}}} ::
- #+kindex: C-c C-e t A
- #+kindex: C-c C-e t L
- #+kindex: C-c C-e t U
- #+findex: org-ascii-export-to-ascii
+ #+kindex: C-c C-e t A
+ #+kindex: C-c C-e t L
+ #+kindex: C-c C-e t U
+ #+findex: org-ascii-export-as-ascii
- Export to a temporary buffer. Does not create a file.
+ Export to a temporary buffer. Does not create a file.
*** ASCII specific export settings
:PROPERTIES:
@@ -11866,10 +11972,10 @@ output. Setting this keyword works similar to the general options
- =SUBTITLE= ::
- #+cindex: @samp{SUBTITLE}, keyword
- The document subtitle. For long subtitles, use multiple
- =#+SUBTITLE= lines in the Org file. Org prints them on one
- continuous line, wrapping into multiple lines if necessary.
+ #+cindex: @samp{SUBTITLE}, keyword
+ The document subtitle. For long subtitles, use multiple
+ =#+SUBTITLE= lines in the Org file. Org prints them on one
+ continuous line, wrapping into multiple lines if necessary.
*** Header and sectioning structure
:PROPERTIES:
@@ -11938,6 +12044,9 @@ It's just a jump to the left...
#+end_example
** Beamer Export
+:PROPERTIES:
+:DESCRIPTION: Producing presentations and slides.
+:END:
#+cindex: Beamer export
Org uses Beamer export to convert an Org file tree structure into
@@ -11951,29 +12060,29 @@ popular display formats.
:END:
- {{{kbd(C-c C-e l b)}}} (~org-beamer-export-to-latex~) ::
- #+kindex: C-c C-e l b
- #+findex: org-beamer-export-to-latex
+ #+kindex: C-c C-e l b
+ #+findex: org-beamer-export-to-latex
- Export as LaTeX file with a =.tex= extension. For =myfile.org=,
- Org exports to =myfile.tex=, overwriting without warning.
+ Export as LaTeX file with a =.tex= extension. For =myfile.org=, Org
+ exports to =myfile.tex=, overwriting without warning.
- {{{kbd(C-c C-e l B)}}} (~org-beamer-export-as-latex~) ::
- #+kindex: C-c C-e l B
- #+findex: org-beamer-export-as-latex
+ #+kindex: C-c C-e l B
+ #+findex: org-beamer-export-as-latex
- Export to a temporary buffer. Does not create a file.
+ Export to a temporary buffer. Does not create a file.
- {{{kbd(C-c C-e l P)}}} (~org-beamer-export-to-pdf~) ::
- #+kindex: C-c C-e l P
- #+findex: org-beamer-export-to-pdf
+ #+kindex: C-c C-e l P
+ #+findex: org-beamer-export-to-pdf
- Export as LaTeX file and then convert it to PDF format.
+ Export as LaTeX file and then convert it to PDF format.
- {{{kbd(C-c C-e l O)}}} ::
- #+kindex: C-c C-e l O
+ #+kindex: C-c C-e l O
- Export as LaTeX file, convert it to PDF format, and then open the
- PDF file.
+ Export as LaTeX file, convert it to PDF format, and then open the
+ PDF file.
*** Beamer specific export settings
:PROPERTIES:
@@ -11986,61 +12095,60 @@ settings (see [[*Export Settings]]).
- =BEAMER_THEME= ::
- #+cindex: @samp{BEAMER_THEME}, keyword
- #+vindex: org-beamer-theme
- The Beamer layout theme (~org-beamer-theme~). Use square
- brackets for options. For example:
+ #+cindex: @samp{BEAMER_THEME}, keyword
+ #+vindex: org-beamer-theme
+ The Beamer layout theme (~org-beamer-theme~). Use square brackets
+ for options. For example:
- : #+BEAMER_THEME: Rochester [height=20pt]
+ : #+BEAMER_THEME: Rochester [height=20pt]
- =BEAMER_FONT_THEME= ::
- #+cindex: @samp{BEAMER_FONT_THEME}, keyword
- The Beamer font theme.
+ #+cindex: @samp{BEAMER_FONT_THEME}, keyword
+ The Beamer font theme.
- =BEAMER_INNER_THEME= ::
- #+cindex: @samp{BEAMER_INNER_THEME}, keyword
- The Beamer inner theme.
+ #+cindex: @samp{BEAMER_INNER_THEME}, keyword
+ The Beamer inner theme.
- =BEAMER_OUTER_THEME= ::
- #+cindex: @samp{BEAMER_OUTER_THEME}, keyword
- The Beamer outer theme.
+ #+cindex: @samp{BEAMER_OUTER_THEME}, keyword
+ The Beamer outer theme.
- =BEAMER_HEADER= ::
- #+cindex: @samp{BEAMER_HEADER}, keyword
- Arbitrary lines inserted in the preamble, just before the
- =hyperref= settings.
+ #+cindex: @samp{BEAMER_HEADER}, keyword
+ Arbitrary lines inserted in the preamble, just before the =hyperref=
+ settings.
- =DESCRIPTION= ::
- #+cindex: @samp{DESCRIPTION}, keyword
- The document description. For long descriptions, use multiple
- =DESCRIPTION= keywords. By default, =hyperref= inserts
- =DESCRIPTION= as metadata. Use ~org-latex-hyperref-template~ to
- configure document metadata. Use ~org-latex-title-command~ to
- configure typesetting of description as part of front matter.
+ #+cindex: @samp{DESCRIPTION}, keyword
+ The document description. For long descriptions, use multiple
+ =DESCRIPTION= keywords. By default, =hyperref= inserts
+ =DESCRIPTION= as metadata. Use ~org-latex-hyperref-template~ to
+ configure document metadata. Use ~org-latex-title-command~ to
+ configure typesetting of description as part of front matter.
- =KEYWORDS= ::
- #+cindex: @samp{KEYWORDS}, keyword
- The keywords for defining the contents of the document. Use
- multiple =KEYWORDS= lines if necessary. By default, =hyperref=
- inserts =KEYWORDS= as metadata. Use
- ~org-latex-hyperref-template~ to configure document metadata.
- Use ~org-latex-title-command~ to configure typesetting of
- keywords as part of front matter.
+ #+cindex: @samp{KEYWORDS}, keyword
+ The keywords for defining the contents of the document. Use
+ multiple =KEYWORDS= lines if necessary. By default, =hyperref=
+ inserts =KEYWORDS= as metadata. Use ~org-latex-hyperref-template~
+ to configure document metadata. Use ~org-latex-title-command~ to
+ configure typesetting of keywords as part of front matter.
- =SUBTITLE= ::
- #+cindex: @samp{SUBTITLE}, keyword
- Document's subtitle. For typesetting, use
- ~org-beamer-subtitle-format~ string. Use
- ~org-latex-hyperref-template~ to configure document metadata.
- Use ~org-latex-title-command~ to configure typesetting of
- subtitle as part of front matter.
+ #+cindex: @samp{SUBTITLE}, keyword
+ Document's subtitle. For typesetting, use
+ ~org-beamer-subtitle-format~ string. Use
+ ~org-latex-hyperref-template~ to configure document metadata. Use
+ ~org-latex-title-command~ to configure typesetting of subtitle as
+ part of front matter.
*** Frames and Blocks in Beamer
:PROPERTIES:
@@ -12067,7 +12175,7 @@ should in principle be exportable as a Beamer presentation.
- Org exports a Beamer frame's objects as block environments. Org can
enforce wrapping in special block types when =BEAMER_ENV= property
- is set[fn:127]. For valid values see
+ is set[fn:126]. For valid values see
~org-beamer-environments-default~. To add more values, see
~org-beamer-environments-extra~.
#+vindex: org-beamer-environments-default
@@ -12180,18 +12288,17 @@ a subgroup of $G$. Then the order of $H$ divides the order of $G$.
:DESCRIPTION: Editing support.
:END:
-The ~org-beamer-mode~ is a special minor mode for faster editing of
-Beamer documents.
+Org Beamer mode is a special minor mode for faster editing of Beamer
+documents.
: #+STARTUP: beamer
- {{{kbd(C-c C-b)}}} (~org-beamer-select-environment~) ::
- #+kindex: C-c C-b
- #+findex: org-beamer-select-environment
+ #+kindex: C-c C-b
+ #+findex: org-beamer-select-environment
- The ~org-beamer-mode~ provides this key for quicker selections in
- Beamer normal environments, and for selecting the =BEAMER_COL=
- property.
+ Org Beamer mode provides this key for quicker selections in Beamer
+ normal environments, and for selecting the =BEAMER_COL= property.
*** A Beamer example
:PROPERTIES:
@@ -12249,20 +12356,19 @@ compatible with XHTML 1.0 strict standard.
:END:
- {{{kbd(C-c C-e h h)}}} (~org-html-export-to-html~) ::
- #+kindex: C-c C-e h h
- #+kindex: C-c C-e h o
- #+findex: org-html-export-to-html
+ #+kindex: C-c C-e h h
+ #+kindex: C-c C-e h o
+ #+findex: org-html-export-to-html
- Export as HTML file with a =.html= extension. For =myfile.org=,
- Org exports to =myfile.html=, overwriting without warning.
- {{{kbd{C-c C-e h o)}}} exports to HTML and opens it in a web
- browser.
+ Export as HTML file with a =.html= extension. For =myfile.org=, Org
+ exports to =myfile.html=, overwriting without warning. {{{kbd{C-c
+ C-e h o)}}} exports to HTML and opens it in a web browser.
- {{{kbd(C-c C-e h H)}}} (~org-html-export-as-html~) ::
- #+kindex: C-c C-e h H
- #+findex: org-html-export-as-html
+ #+kindex: C-c C-e h H
+ #+findex: org-html-export-as-html
- Exports to a temporary buffer. Does not create a file.
+ Exports to a temporary buffer. Does not create a file.
*** HTML specific export settings
:PROPERTIES:
@@ -12274,80 +12380,78 @@ settings described in [[*Export Settings]].
- =DESCRIPTION= ::
- #+cindex: @samp{DESCRIPTION}, keyword
- This is the document's description, which the HTML exporter
- inserts it as a HTML meta tag in the HTML file. For long
- descriptions, use multiple =DESCRIPTION= lines. The exporter
- takes care of wrapping the lines properly.
+ #+cindex: @samp{DESCRIPTION}, keyword
+ This is the document's description, which the HTML exporter inserts
+ it as a HTML meta tag in the HTML file. For long descriptions, use
+ multiple =DESCRIPTION= lines. The exporter takes care of wrapping
+ the lines properly.
- =HTML_DOCTYPE= ::
- #+cindex: @samp{HTML_DOCTYPE}, keyword
- #+vindex: org-html-doctype
- Specify the document type, for example: HTML5
- (~org-html-doctype~).
+ #+cindex: @samp{HTML_DOCTYPE}, keyword
+ #+vindex: org-html-doctype
+ Specify the document type, for example: HTML5 (~org-html-doctype~).
- =HTML_CONTAINER= ::
- #+cindex: @samp{HTML_CONTAINER}, keyword
- #+vindex: org-html-container-element
- Specify the HTML container, such as =div=, for wrapping sections
- and elements (~org-html-container-element~).
+ #+cindex: @samp{HTML_CONTAINER}, keyword
+ #+vindex: org-html-container-element
+ Specify the HTML container, such as =div=, for wrapping sections and
+ elements (~org-html-container-element~).
- =HTML_LINK_HOME= ::
- #+cindex: @samp{HTML_LINK_HOME}, keyword
- #+vindex: org-html-link-home
- The URL for home link (~org-html-link-home~).
+ #+cindex: @samp{HTML_LINK_HOME}, keyword
+ #+vindex: org-html-link-home
+ The URL for home link (~org-html-link-home~).
- =HTML_LINK_UP= ::
- #+cindex: @samp{HTML_LINK_UP}, keyword
- #+vindex: org-html-link-up
- The URL for the up link of exported HTML pages
- (~org-html-link-up~).
+ #+cindex: @samp{HTML_LINK_UP}, keyword
+ #+vindex: org-html-link-up
+ The URL for the up link of exported HTML pages (~org-html-link-up~).
- =HTML_MATHJAX= ::
- #+cindex: @samp{HTML_MATHJAX}, keyword
- #+vindex: org-html-mathjax-options
- Options for MathJax (~org-html-mathjax-options~). MathJax is
- used to typeset LaTeX math in HTML documents. See [[*Math
- formatting in HTML export]], for an example.
+ #+cindex: @samp{HTML_MATHJAX}, keyword
+ #+vindex: org-html-mathjax-options
+ Options for MathJax (~org-html-mathjax-options~). MathJax is used
+ to typeset LaTeX math in HTML documents. See [[*Math formatting in
+ HTML export]], for an example.
- =HTML_HEAD= ::
- #+cindex: @samp{HTML_HEAD}, keyword
- #+vindex: org-html-head
- Arbitrary lines for appending to the HTML document's head
- (~org-html-head~).
+ #+cindex: @samp{HTML_HEAD}, keyword
+ #+vindex: org-html-head
+ Arbitrary lines for appending to the HTML document's head
+ (~org-html-head~).
- =HTML_HEAD_EXTRA= ::
- #+cindex: @samp{HTML_HEAD_EXTRA}, keyword
- #+vindex: org-html-head-extra
- More arbitrary lines for appending to the HTML document's head
- (~org-html-head-extra~).
+ #+cindex: @samp{HTML_HEAD_EXTRA}, keyword
+ #+vindex: org-html-head-extra
+ More arbitrary lines for appending to the HTML document's head
+ (~org-html-head-extra~).
- =KEYWORDS= ::
- #+cindex: @samp{KEYWORDS}, keyword
- Keywords to describe the document's content. HTML exporter
- inserts these keywords as HTML meta tags. For long keywords, use
- multiple =KEYWORDS= lines.
+ #+cindex: @samp{KEYWORDS}, keyword
+ Keywords to describe the document's content. HTML exporter inserts
+ these keywords as HTML meta tags. For long keywords, use multiple
+ =KEYWORDS= lines.
- =LATEX_HEADER= ::
- #+cindex: @samp{LATEX_HEADER}, keyword
- Arbitrary lines for appending to the preamble; HTML exporter
- appends when transcoding LaTeX fragments to images (see [[*Math
- formatting in HTML export]]).
+ #+cindex: @samp{LATEX_HEADER}, keyword
+ Arbitrary lines for appending to the preamble; HTML exporter appends
+ when transcoding LaTeX fragments to images (see [[*Math formatting in
+ HTML export]]).
- =SUBTITLE= ::
- #+cindex: @samp{SUBTITLE}, keyword
- The document's subtitle. HTML exporter formats subtitle if
- document type is =HTML5= and the CSS has a =subtitle= class.
+ #+cindex: @samp{SUBTITLE}, keyword
+ The document's subtitle. HTML exporter formats subtitle if document
+ type is =HTML5= and the CSS has a =subtitle= class.
Some of these keywords are explained in more detail in the following
sections of the manual.
@@ -12474,7 +12578,6 @@ insert a postamble if ~org-html-postamble~ is set to ~nil~.
:END:
The HTML export back-end transforms =<= and =>= to =&lt;= and =&gt;=.
-
To include raw HTML code in the Org file so the HTML export back-end
can insert that HTML code in the output, use this inline syntax:
=@@html:...@@=. For example:
@@ -12493,6 +12596,21 @@ For larger raw HTML code blocks, use these HTML export code blocks:
,#+END_EXPORT
#+end_example
+*** Headlines in HTML export
+:PROPERTIES:
+:DESCRIPTION: Formatting headlines.
+:END:
+#+cindex: headlines, in HTML export
+
+Headlines are exported to =<h1>=, =<h2>=, etc. Each headline gets the
+=id= attribute from =CUSTOM_ID= property, or a unique generated value,
+see [[*Internal Links]].
+
+#+vindex: org-html-self-link-headlines
+When ~org-html-self-link-headlines~ is set to a non-~nil~ value, the
+text of the headlines is also wrapped in =<a>= tags. These tags have
+a =href= attribute making the headlines link to themselves.
+
*** Links in HTML export
:PROPERTIES:
:DESCRIPTION: Inserting and formatting links.
@@ -12555,39 +12673,39 @@ Additional options for customizing tables for HTML export.
- ~org-html-table-align-individual-fields~ ::
- #+vindex: org-html-table-align-individual-fields
- Non-~nil~ attaches style attributes for alignment to each table
- field.
+ #+vindex: org-html-table-align-individual-fields
+ Non-~nil~ attaches style attributes for alignment to each table
+ field.
- ~org-html-table-caption-above~ ::
- #+vindex: org-html-table-caption-above
- Non-~nil~ places caption string at the beginning of the table.
+ #+vindex: org-html-table-caption-above
+ Non-~nil~ places caption string at the beginning of the table.
- ~org-html-table-data-tags~ ::
- #+vindex: org-html-table-data-tags
- Opening and ending tags for table data fields.
+ #+vindex: org-html-table-data-tags
+ Opening and ending tags for table data fields.
- ~org-html-table-default-attributes~ ::
- #+vindex: org-html-table-default-attributes
- Default attributes and values for table tags.
+ #+vindex: org-html-table-default-attributes
+ Default attributes and values for table tags.
- ~org-html-table-header-tags~ ::
- #+vindex: org-html-table-header-tags
- Opening and ending tags for table's header fields.
+ #+vindex: org-html-table-header-tags
+ Opening and ending tags for table's header fields.
- ~org-html-table-row-tags~ ::
- #+vindex: org-html-table-row-tags
- Opening and ending tags for table rows.
+ #+vindex: org-html-table-row-tags
+ Opening and ending tags for table rows.
- ~org-html-table-use-header-tags-for-first-column~ ::
- #+vindex: org-html-table-use-header-tags-for-first-column
- Non-~nil~ formats column one in tables with header tags.
+ #+vindex: org-html-table-use-header-tags-for-first-column
+ Non-~nil~ formats column one in tables with header tags.
*** Images in HTML export
:PROPERTIES:
@@ -12642,7 +12760,7 @@ as-is.
#+vindex: org-html-mathjax-options~
LaTeX math snippets (see [[*LaTeX fragments]]) can be displayed in two
different ways on HTML pages. The default is to use the [[http://www.mathjax.org][MathJax]],
-which should work out of the box with Org[fn:128][fn:129]. Some MathJax
+which should work out of the box with Org[fn:127][fn:128]. Some MathJax
display options can be configured via ~org-html-mathjax-options~, or
in the buffer. For example, with the following settings,
@@ -12654,7 +12772,7 @@ in the buffer. For example, with the following settings,
#+texinfo: @noindent
equation labels are displayed on the left margin and equations are
five em from the left margin. In addition, it loads the two MathJax
-extensions =cancel.js= and =noErrors.js=[fn:130].
+extensions =cancel.js= and =noErrors.js=[fn:129].
#+vindex: org-html-mathjax-template
See the docstring of ~org-html-mathjax-options~ for all supported
@@ -12717,7 +12835,7 @@ line.
#+vindex: org-export-html-todo-kwd-class-prefix
#+vindex: org-export-html-tag-class-prefix
You can modify the CSS style definitions for the exported file. The
-HTML exporter assigns the following special CSS classes[fn:131] to
+HTML exporter assigns the following special CSS classes[fn:130] to
appropriate parts of the document---your style specifications may
change these, in addition to any of the standard classes like for
headlines, tables, etc.
@@ -12784,10 +12902,12 @@ around them. Both of these approaches can avoid referring to an
external file.
#+cindex: @samp{HTML_CONTAINER_CLASS}, property
+#+cindex: @samp{HTML_HEADLINE_CLASS}, property
In order to add styles to a sub-tree, use the =HTML_CONTAINER_CLASS=
property to assign a class to the tree. In order to specify CSS
styles for a particular headline, you can use the ID specified in
-a =CUSTOM_ID= property.
+a =CUSTOM_ID= property. You can also assign a specific class to
+a headline with the =HTML_HEADLINE_CLASS= property.
Never change the ~org-html-style-default~ constant. Instead use other
simpler ways of customizing as described above.
@@ -12823,57 +12943,56 @@ options described below:
- =path:= ::
- The path to the script. The default is to grab the script from
- [[https://orgmode.org/org-info.js]], but you might want to have
- a local copy and use a path like =../scripts/org-info.js=.
+ The path to the script. The default is to grab the script from
+ [[https://orgmode.org/org-info.js]], but you might want to have a local
+ copy and use a path like =../scripts/org-info.js=.
- =view:= ::
- Initial view when the website is first shown. Possible values are:
+ Initial view when the website is first shown. Possible values are:
- | =info= | Info-like interface with one section per page |
- | =overview= | Folding interface, initially showing only top-level |
- | =content= | Folding interface, starting with all headlines visible |
- | =showall= | Folding interface, all headlines and text visible |
+ | =info= | Info-like interface with one section per page |
+ | =overview= | Folding interface, initially showing only top-level |
+ | =content= | Folding interface, starting with all headlines visible |
+ | =showall= | Folding interface, all headlines and text visible |
- =sdepth:= ::
- Maximum headline level still considered as an independent section
- for info and folding modes. The default is taken from
- ~org-export-headline-levels~, i.e., the =H= switch in =OPTIONS=.
- If this is smaller than in ~org-export-headline-levels~, each
- info/folding section can still contain child headlines.
+ Maximum headline level still considered as an independent section
+ for info and folding modes. The default is taken from
+ ~org-export-headline-levels~, i.e., the =H= switch in =OPTIONS=. If
+ this is smaller than in ~org-export-headline-levels~, each
+ info/folding section can still contain child headlines.
- =toc:= ::
- Should the table of contents /initially/ be visible? Even when
- =nil=, you can always get to the "toc" with {{{kbd(i)}}}.
+ Should the table of contents /initially/ be visible? Even when
+ =nil=, you can always get to the "toc" with {{{kbd(i)}}}.
- =tdepth:= ::
- The depth of the table of contents. The defaults are taken from
- the variables ~org-export-headline-levels~ and
- ~org-export-with-toc~.
+ The depth of the table of contents. The defaults are taken from the
+ variables ~org-export-headline-levels~ and ~org-export-with-toc~.
- =ftoc:= ::
- Does the CSS of the page specify a fixed position for the "toc"?
- If yes, the toc is displayed as a section.
+ Does the CSS of the page specify a fixed position for the "toc"? If
+ yes, the toc is displayed as a section.
- =ltoc:= ::
- Should there be short contents (children) in each section? Make
- this =above= if the section should be above initial text.
+ Should there be short contents (children) in each section? Make
+ this =above= if the section should be above initial text.
- =mouse:= ::
- Headings are highlighted when the mouse is over them. Should be
- =underline= (default) or a background color like =#cccccc=.
+ Headings are highlighted when the mouse is over them. Should be
+ =underline= (default) or a background color like =#cccccc=.
- =buttons:= ::
- Should view-toggle buttons be everywhere? When =nil= (the
- default), only one such button is present.
+ Should view-toggle buttons be everywhere? When =nil= (the default),
+ only one such button is present.
#+vindex: org-infojs-options
#+vindex: org-export-html-use-infojs
@@ -12911,35 +13030,34 @@ on blank lines to tell apart syntactical elements, such as paragraphs.
- {{{kbd(C-c C-e l l)}}} (~org-latex-export-to-latex~) ::
- #+kindex: C-c C-e l l
- #+findex: org-latex-export-to-latex~
- Export to a LaTeX file with a =.tex= extension. For
- =myfile.org=, Org exports to =myfile.tex=, overwriting without
- warning.
+ #+kindex: C-c C-e l l
+ #+findex: org-latex-export-to-latex~
+ Export to a LaTeX file with a =.tex= extension. For =myfile.org=,
+ Org exports to =myfile.tex=, overwriting without warning.
- {{{kbd(C-c C-e l L)}}} (~org-latex-export-as-latex~) ::
- #+kindex: C-c C-e l L
- #+findex: org-latex-export-as-latex
- Export to a temporary buffer. Do not create a file.
+ #+kindex: C-c C-e l L
+ #+findex: org-latex-export-as-latex
+ Export to a temporary buffer. Do not create a file.
- {{{kbd(C-c C-e l p)}}} (~org-latex-export-to-pdf~) ::
- #+kindex: C-c C-e l p
- #+findex: org-latex-export-to-pdf
- Export as LaTeX file and convert it to PDF file.
+ #+kindex: C-c C-e l p
+ #+findex: org-latex-export-to-pdf
+ Export as LaTeX file and convert it to PDF file.
- {{{kbd(C-c C-e l o)}}} ::
- #+kindex: C-c C-e l o
- Export as LaTeX file and convert it to PDF, then open the PDF
- using the default viewer.
+ #+kindex: C-c C-e l o
+ Export as LaTeX file and convert it to PDF, then open the PDF using
+ the default viewer.
- {{{kbd(M-x org-export-region-as-latex)}}} ::
- Convert the region to LaTeX under the assumption that it was in Org
- mode syntax before. This is a global command that can be invoked in
- any buffer.
+ Convert the region to LaTeX under the assumption that it was in Org
+ mode syntax before. This is a global command that can be invoked in
+ any buffer.
#+vindex: org-latex-compiler
#+vindex: org-latex-bibtex-compiler
@@ -12956,7 +13074,7 @@ LaTeX export back-end finds the compiler version to use from
Org file. See the docstring for the
~org-latex-default-packages-alist~ for loading packages with certain
compilers. Also see ~org-latex-bibtex-compiler~ to set the
-bibliography compiler[fn:132].
+bibliography compiler[fn:131].
*** LaTeX specific export settings
:PROPERTIES:
@@ -12969,91 +13087,89 @@ general options (see [[*Export Settings]]).
#+attr_texinfo: :sep ,
- =DESCRIPTION= ::
- #+cindex: @samp{DESCRIPTION}, keyword
- #+vindex: org-latex-hyperref-template
- #+vindex: org-latex-title-command
- The document's description. The description along with author
- name, keywords, and related file metadata are inserted in the
- output file by the hyperref package. See
- ~org-latex-hyperref-template~ for customizing metadata items.
- See ~org-latex-title-command~ for typesetting description into
- the document's front matter. Use multiple =DESCRIPTION= keywords
- for long descriptions.
+ #+cindex: @samp{DESCRIPTION}, keyword
+ #+vindex: org-latex-hyperref-template
+ #+vindex: org-latex-title-command
+ The document's description. The description along with author name,
+ keywords, and related file metadata are inserted in the output file
+ by the hyperref package. See ~org-latex-hyperref-template~ for
+ customizing metadata items. See ~org-latex-title-command~ for
+ typesetting description into the document's front matter. Use
+ multiple =DESCRIPTION= keywords for long descriptions.
- =LANGUAGE= ::
- #+cindex: @samp{LANGUAGE}, keyword
- #+vindex: org-latex-package-alist
- In order to be effective, the =babel= or =polyglossia=
- packages---according to the LaTeX compiler used---must be loaded
- with the appropriate language as argument. This can be
- accomplished by modifying the ~org-latex-packages-alist~ variable,
- e.g., with the following snippet:
+ #+cindex: @samp{LANGUAGE}, keyword
+ #+vindex: org-latex-packages-alist
+ In order to be effective, the =babel= or =polyglossia=
+ packages---according to the LaTeX compiler used---must be loaded
+ with the appropriate language as argument. This can be accomplished
+ by modifying the ~org-latex-packages-alist~ variable, e.g., with the
+ following snippet:
- #+begin_src emacs-lisp
- (add-to-list 'org-latex-packages-alist
- '("AUTO" "babel" t ("pdflatex")))
- (add-to-list 'org-latex-packages-alist
- '("AUTO" "polyglossia" t ("xelatex" "lualatex")))
- #+end_src
+ #+begin_src emacs-lisp
+ (add-to-list 'org-latex-packages-alist
+ '("AUTO" "babel" t ("pdflatex")))
+ (add-to-list 'org-latex-packages-alist
+ '("AUTO" "polyglossia" t ("xelatex" "lualatex")))
+ #+end_src
- =LATEX_CLASS= ::
- #+cindex: @samp{LATEX_CLASS}, keyword
- #+vindex: org-latex-default-class
- #+vindex: org-latex-classes
- This is LaTeX document class, such as /article/, /report/,
- /book/, and so on, which contain predefined preamble and headline
- level mapping that the LaTeX export back-end needs. The back-end
- reads the default class name from the ~org-latex-default-class~
- variable. Org has /article/ as the default class. A valid
- default class must be an element of ~org-latex-classes~.
+ #+cindex: @samp{LATEX_CLASS}, keyword
+ #+vindex: org-latex-default-class
+ #+vindex: org-latex-classes
+ This is LaTeX document class, such as /article/, /report/, /book/,
+ and so on, which contain predefined preamble and headline level
+ mapping that the LaTeX export back-end needs. The back-end reads
+ the default class name from the ~org-latex-default-class~ variable.
+ Org has /article/ as the default class. A valid default class must
+ be an element of ~org-latex-classes~.
- =LATEX_CLASS_OPTIONS= ::
- #+cindex: @samp{LATEX_CLASS_OPTIONS}, keyword
- Options the LaTeX export back-end uses when calling the LaTeX
- document class.
+ #+cindex: @samp{LATEX_CLASS_OPTIONS}, keyword
+ Options the LaTeX export back-end uses when calling the LaTeX
+ document class.
- =LATEX_COMPILER= ::
- #+cindex: @samp{LATEX_COMPILER}, keyword
- #+vindex: org-latex-compiler
- The compiler, such as =pdflatex=, =xelatex=, =lualatex=, for
- producing the PDF. See ~org-latex-compiler~.
+ #+cindex: @samp{LATEX_COMPILER}, keyword
+ #+vindex: org-latex-compiler
+ The compiler, such as =pdflatex=, =xelatex=, =lualatex=, for
+ producing the PDF. See ~org-latex-compiler~.
- =LATEX_HEADER=, =LATEX_HEADER_EXTRA= ::
- #+cindex: @samp{LATEX_HEADER}, keyword
- #+cindex: @samp{LATEX_HEADER_EXTRA}, keyword
- #+vindex: org-latex-classes
- Arbitrary lines to add to the document's preamble, before the
- hyperref settings. See ~org-latex-classes~ for adjusting the
- structure and order of the LaTeX headers.
+ #+cindex: @samp{LATEX_HEADER}, keyword
+ #+cindex: @samp{LATEX_HEADER_EXTRA}, keyword
+ #+vindex: org-latex-classes
+ Arbitrary lines to add to the document's preamble, before the
+ hyperref settings. See ~org-latex-classes~ for adjusting the
+ structure and order of the LaTeX headers.
- =KEYWORDS= ::
- #+cindex: @samp{KEYWORDS}, keyword
- #+vindex: org-latex-hyperref-template
- #+vindex: org-latex-title-command
- The keywords for the document. The description along with author
- name, keywords, and related file metadata are inserted in the
- output file by the hyperref package. See
- ~org-latex-hyperref-template~ for customizing metadata items.
- See ~org-latex-title-command~ for typesetting description into
- the document's front matter. Use multiple =KEYWORDS= lines if
- necessary.
+ #+cindex: @samp{KEYWORDS}, keyword
+ #+vindex: org-latex-hyperref-template
+ #+vindex: org-latex-title-command
+ The keywords for the document. The description along with author
+ name, keywords, and related file metadata are inserted in the output
+ file by the hyperref package. See ~org-latex-hyperref-template~ for
+ customizing metadata items. See ~org-latex-title-command~ for
+ typesetting description into the document's front matter. Use
+ multiple =KEYWORDS= lines if necessary.
- =SUBTITLE= ::
- #+cindex: @samp{SUBTITLE}, keyword
- #+vindex: org-latex-subtitle-separate
- #+vindex: org-latex-subtitle-format
- The document's subtitle. It is typeset as per
- ~org-latex-subtitle-format~. If ~org-latex-subtitle-separate~ is
- non-~nil~, it is typed as part of the ~\title~ macro. See
- ~org-latex-hyperref-template~ for customizing metadata items.
- See ~org-latex-title-command~ for typesetting description
- into the document's front matter.
+ #+cindex: @samp{SUBTITLE}, keyword
+ #+vindex: org-latex-subtitle-separate
+ #+vindex: org-latex-subtitle-format
+ The document's subtitle. It is typeset as per
+ ~org-latex-subtitle-format~. If ~org-latex-subtitle-separate~ is
+ non-~nil~, it is typed outside of the ~\title~ macro. See
+ ~org-latex-hyperref-template~ for customizing metadata items. See
+ ~org-latex-title-command~ for typesetting description into the
+ document's front matter.
The following sections have further details.
@@ -13165,82 +13281,79 @@ include:
#+attr_texinfo: :sep ,
- =:mode= ::
- #+vindex: org-latex-default-table-mode
- The LaTeX export back-end wraps the table differently depending
- on the mode for accurate rendering of math symbols. Mode is
- either =table=, =math=, =inline-math= or =verbatim=.
+ #+vindex: org-latex-default-table-mode
+ The LaTeX export back-end wraps the table differently depending on
+ the mode for accurate rendering of math symbols. Mode is either
+ =table=, =math=, =inline-math= or =verbatim=.
- For =math= or =inline-math= mode, LaTeX export back-end wraps the
- table in a math environment, but every cell in it is exported
- as-is. The LaTeX export back-end determines the default mode
- from ~org-latex-default-table-mode~. The LaTeX export back-end
- merges contiguous tables in the same mode into a single
- environment.
+ For =math= or =inline-math= mode, LaTeX export back-end wraps the
+ table in a math environment, but every cell in it is exported as-is.
+ The LaTeX export back-end determines the default mode from
+ ~org-latex-default-table-mode~. The LaTeX export back-end merges
+ contiguous tables in the same mode into a single environment.
- =:environment= ::
- #+vindex: org-latex-default-table-environment
- Set the default LaTeX table environment for the LaTeX export
- back-end to use when exporting Org tables. Common LaTeX table
- environments are provided by these packages: tabularx, longtable,
- array, tabu, and bmatrix. For packages, such as tabularx and
- tabu, or any newer replacements, include them in the
- ~org-latex-packages-alist~ variable so the LaTeX export back-end
- can insert the appropriate load package headers in the converted
- LaTeX file. Look in the docstring for the
- ~org-latex-packages-alist~ variable for configuring these
- packages for LaTeX snippet previews, if any.
+ #+vindex: org-latex-default-table-environment
+ Set the default LaTeX table environment for the LaTeX export
+ back-end to use when exporting Org tables. Common LaTeX table
+ environments are provided by these packages: tabularx, longtable,
+ array, tabu, and bmatrix. For packages, such as tabularx and tabu,
+ or any newer replacements, include them in the
+ ~org-latex-packages-alist~ variable so the LaTeX export back-end can
+ insert the appropriate load package headers in the converted LaTeX
+ file. Look in the docstring for the ~org-latex-packages-alist~
+ variable for configuring these packages for LaTeX snippet previews,
+ if any.
- =:caption= ::
- Use =CAPTION= keyword to set a simple caption for a table (see
- [[*Captions]]). For custom captions, use =:caption= attribute, which
- accepts raw LaTeX code. =:caption= value overrides =CAPTION=
- value.
+ Use =CAPTION= keyword to set a simple caption for a table (see
+ [[*Captions]]). For custom captions, use =:caption= attribute, which
+ accepts raw LaTeX code. =:caption= value overrides =CAPTION= value.
- =:float=, =:placement= ::
- The table environments by default are not floats in LaTeX. To
- make them floating objects use =:float= with one of the following
- options: =sideways=, =multicolumn=, =t=, and =nil=.
+ The table environments by default are not floats in LaTeX. To make
+ them floating objects use =:float= with one of the following
+ options: =sideways=, =multicolumn=, =t=, and =nil=.
- LaTeX floats can also have additional layout =:placement=
- attributes. These are the usual =[h t b p ! H]= permissions
- specified in square brackets. Note that for =:float sideways=
- tables, the LaTeX export back-end ignores =:placement=
- attributes.
+ LaTeX floats can also have additional layout =:placement=
+ attributes. These are the usual =[h t b p ! H]= permissions
+ specified in square brackets. Note that for =:float sideways=
+ tables, the LaTeX export back-end ignores =:placement= attributes.
- =:align=, =:font=, =:width= ::
- The LaTeX export back-end uses these attributes for regular
- tables to set their alignments, fonts, and widths.
+ The LaTeX export back-end uses these attributes for regular tables
+ to set their alignments, fonts, and widths.
- =:spread= ::
- When =:spread= is non-~nil~, the LaTeX export back-end spreads or
- shrinks the table by the =:width= for tabu and longtabu
- environments. =:spread= has no effect if =:width= is not set.
+ When =:spread= is non-~nil~, the LaTeX export back-end spreads or
+ shrinks the table by the =:width= for tabu and longtabu
+ environments. =:spread= has no effect if =:width= is not set.
- =:booktabs=, =:center=, =:rmlines= ::
- #+vindex: org-latex-tables-booktabs
- #+vindex: org-latex-tables-centered
- All three commands are toggles. =:booktabs= brings in modern
- typesetting enhancements to regular tables. The booktabs package
- has to be loaded through ~org-latex-packages-alist~. =:center=
- is for centering the table. =:rmlines= removes all but the very
- first horizontal line made of ASCII characters from "table.el"
- tables only.
+ #+vindex: org-latex-tables-booktabs
+ #+vindex: org-latex-tables-centered
+ All three commands are toggles. =:booktabs= brings in modern
+ typesetting enhancements to regular tables. The booktabs package
+ has to be loaded through ~org-latex-packages-alist~. =:center= is
+ for centering the table. =:rmlines= removes all but the very first
+ horizontal line made of ASCII characters from "table.el" tables
+ only.
- =:math-prefix=, =:math-suffix=, =:math-arguments= ::
- The LaTeX export back-end inserts =:math-prefix= string value in
- a math environment before the table. The LaTeX export back-end
- inserts =:math-suffix= string value in a math environment after
- the table. The LaTeX export back-end inserts =:math-arguments=
- string value between the macro name and the table's contents.
- =:math-arguments= comes in use for matrix macros that require
- more than one argument, such as =qbordermatrix=.
+ The LaTeX export back-end inserts =:math-prefix= string value in
+ a math environment before the table. The LaTeX export back-end
+ inserts =:math-suffix= string value in a math environment after the
+ table. The LaTeX export back-end inserts =:math-arguments= string
+ value between the macro name and the table's contents.
+ =:math-arguments= comes in use for matrix macros that require more
+ than one argument, such as =qbordermatrix=.
LaTeX table attributes help formatting tables for a wide range of
situations, such as matrix product or spanning multiple pages:
@@ -13284,14 +13397,16 @@ insert the image. But for TikZ (http://sourceforge.net/projects/pgf/)
images, the back-end uses an ~\input~ macro wrapped within
a ~tikzpicture~ environment.
-For specifying image =:width=, =:height=, and other =:options=, use
-this syntax:
+For specifying image =:width=, =:height=, =:scale= and other =:options=,
+use this syntax:
#+begin_example
,#+ATTR_LATEX: :width 5cm :options angle=90
[[./img/sed-hr4049.pdf]]
#+end_example
+A =:scale= attribute overrides both =:width= and =:height= attributes.
+
For custom commands for captions, use the =:caption= attribute. It
overrides the default =#+CAPTION= value:
@@ -13307,28 +13422,27 @@ attribute to one of the following:
- =t= ::
- For a standard =figure= environment; used by default whenever an
- image has a caption.
+ For a standard =figure= environment; used by default whenever an
+ image has a caption.
- =multicolumn= ::
- To span the image across multiple columns of a page; the back-end
- wraps the image in a =figure*= environment.
+ To span the image across multiple columns of a page; the back-end
+ wraps the image in a =figure*= environment.
- =wrap= ::
- For text to flow around the image on the right; the figure
- occupies the left half of the page.
+ For text to flow around the image on the right; the figure occupies
+ the left half of the page.
- =sideways= ::
- For a new page with the image sideways, rotated ninety degrees,
- in a =sidewaysfigure= environment; overrides =:placement=
- setting.
+ For a new page with the image sideways, rotated ninety degrees, in
+ a =sidewaysfigure= environment; overrides =:placement= setting.
- =nil= ::
- To avoid a =:float= even if using a caption.
+ To avoid a =:float= even if using a caption.
Use the =placement= attribute to modify a floating environment's
placement.
@@ -13396,17 +13510,17 @@ objects through the attributes =:float= and =:options=. For =:float=:
- =t= ::
- Makes a source block float; by default floats any source block
- with a caption.
+ Makes a source block float; by default floats any source block with
+ a caption.
- =multicolumn= ::
- Spans the source block across multiple columns of a page.
+ Spans the source block across multiple columns of a page.
- =nil= ::
- Avoids a =:float= even if using a caption; useful for source code
- blocks that may not fit on a page.
+ Avoids a =:float= even if using a caption; useful for source code
+ blocks that may not fit on a page.
#+begin_example
,#+ATTR_LATEX: :float nil
@@ -13543,21 +13657,21 @@ tables, to HTML.
- {{{kbd(C-c C-e m m)}}} (~org-md-export-to-markdown~) ::
- #+kindex: C-c C-c m m
- #+findex: org-md-export-to-markdown
- Export to a text file with Markdown syntax. For =myfile.org=,
- Org exports to =myfile.md=, overwritten without warning.
+ #+kindex: C-c C-c m m
+ #+findex: org-md-export-to-markdown
+ Export to a text file with Markdown syntax. For =myfile.org=, Org
+ exports to =myfile.md=, overwritten without warning.
- {{{kbd(C-c C-e m M)}}} (~org-md-export-as-markdown~) ::
- #+kindex: C-c C-c m M
- #+findex: org-md-export-as-markdown
- Export to a temporary buffer. Does not create a file.
+ #+kindex: C-c C-c m M
+ #+findex: org-md-export-as-markdown
+ Export to a temporary buffer. Does not create a file.
- {{{kbd(C-c C-e m o)}}} ::
- #+kindex: C-c C-e m o
- Export as a text file with Markdown syntax, then open it.
+ #+kindex: C-c C-e m o
+ Export as a text file with Markdown syntax, then open it.
*** Header and sectioning structure
:PROPERTIES:
@@ -13582,7 +13696,7 @@ a limit to a level before the absolute limit (see [[*Export Settings]]).
The ODT export back-end handles creating of OpenDocument Text (ODT)
format. Documents created by this exporter use the
-{{{cite(OpenDocument-v1.2 specification)}}}[fn:133] and are compatible
+{{{cite(OpenDocument-v1.2 specification)}}}[fn:132] and are compatible
with LibreOffice 3.4.
*** Pre-requisites for ODT export
@@ -13602,35 +13716,35 @@ executable. Without it, export cannot finish.
- {{{kbd(C-c C-e o o)}}} (~org-export-to-odt~) ::
- #+kindex: C-c C-e o o
- #+findex: org-export-to-odt
- Export as OpenDocument Text file.
+ #+kindex: C-c C-e o o
+ #+findex: org-export-to-odt
+ Export as OpenDocument Text file.
- #+cindex: @samp{EXPORT_FILE_NAME}, property
- #+vindex: org-odt-preferred-output-format
+ #+cindex: @samp{EXPORT_FILE_NAME}, property
+ #+vindex: org-odt-preferred-output-format
- If ~org-odt-preferred-output-format~ is specified, the ODT export
- back-end automatically converts the exported file to that format.
+ If ~org-odt-preferred-output-format~ is specified, the ODT export
+ back-end automatically converts the exported file to that format.
- For =myfile.org=, Org exports to =myfile.odt=, overwriting
- without warning. The ODT export back-end exports a region only
- if a region was active.
+ For =myfile.org=, Org exports to =myfile.odt=, overwriting without
+ warning. The ODT export back-end exports a region only if a region
+ was active.
- If the selected region is a single tree, the ODT export back-end
- makes the tree head the document title. Incidentally, {{{kbd(C-c
- @)}}} selects the current sub-tree. If the tree head entry has,
- or inherits, an =EXPORT_FILE_NAME= property, the ODT export
- back-end uses that for file name.
+ If the selected region is a single tree, the ODT export back-end
+ makes the tree head the document title. Incidentally, {{{kbd(C-c
+ @)}}} selects the current sub-tree. If the tree head entry has, or
+ inherits, an =EXPORT_FILE_NAME= property, the ODT export back-end
+ uses that for file name.
- {{{kbd(C-c C-e o O)}}} ::
- #+kindex: C-c C-e o O
- Export as an OpenDocument Text file and open the resulting file.
+ #+kindex: C-c C-e o O
+ Export as an OpenDocument Text file and open the resulting file.
- #+vindex: org-export-odt-preferred-output-format
- If ~org-export-odt-preferred-output-format~ is specified, open
- the converted file instead. See [[*Automatically exporting to
- other formats]].
+ #+vindex: org-export-odt-preferred-output-format
+ If ~org-export-odt-preferred-output-format~ is specified, open the
+ converted file instead. See [[*Automatically exporting to other
+ formats]].
*** ODT specific export settings
:PROPERTIES:
@@ -13643,30 +13757,30 @@ general options (see [[*Export Settings]]).
- =DESCRIPTION= ::
- #+cindex: @samp{DESCRIPTION}, keyword
- This is the document's description, which the ODT export back-end
- inserts as document metadata. For long descriptions, use
- multiple lines, prefixed with =DESCRIPTION=.
+ #+cindex: @samp{DESCRIPTION}, keyword
+ This is the document's description, which the ODT export back-end
+ inserts as document metadata. For long descriptions, use multiple
+ lines, prefixed with =DESCRIPTION=.
- =KEYWORDS= ::
- #+cindex: @samp{KEYWORDS}, keyword
- The keywords for the document. The ODT export back-end inserts
- the description along with author name, keywords, and related
- file metadata as metadata in the output file. Use multiple
- =KEYWORDS= if necessary.
+ #+cindex: @samp{KEYWORDS}, keyword
+ The keywords for the document. The ODT export back-end inserts the
+ description along with author name, keywords, and related file
+ metadata as metadata in the output file. Use multiple =KEYWORDS= if
+ necessary.
- =ODT_STYLES_FILE= ::
- #+cindex: @samp{ODT_STYLES_FILE}, keyword
- #+vindex: org-odt-styles-file
- The ODT export back-end uses the ~org-odt-styles-file~ by
- default. See [[*Applying custom styles]] for details.
+ #+cindex: @samp{ODT_STYLES_FILE}, keyword
+ #+vindex: org-odt-styles-file
+ The ODT export back-end uses the ~org-odt-styles-file~ by default.
+ See [[*Applying custom styles]] for details.
- =SUBTITLE= ::
- #+cindex: @samp{SUBTITLE}, keyword
- The document subtitle.
+ #+cindex: @samp{SUBTITLE}, keyword
+ The document subtitle.
*** Extending ODT export
:PROPERTIES:
@@ -13712,9 +13826,9 @@ installed. Here are some generic commands:
- {{{kbd(M-x org-odt-convert)}}} ::
- #+findex: org-odt-convert
- Convert an existing document from one format to another. With
- a prefix argument, opens the newly produced file.
+ #+findex: org-odt-convert
+ Convert an existing document from one format to another. With
+ a prefix argument, opens the newly produced file.
*** Applying custom styles
:PROPERTIES:
@@ -13896,41 +14010,41 @@ image scaling operations:
- Explicitly size the image ::
- To embed =img.png= as a 10 cm x 10 cm image, do the following:
+ To embed =img.png= as a 10 cm x 10 cm image, do the following:
- #+begin_example
- ,#+ATTR_ODT: :width 10 :height 10
- [[./img.png]]
- #+end_example
+ #+begin_example
+ ,#+ATTR_ODT: :width 10 :height 10
+ [[./img.png]]
+ #+end_example
- Scale the image ::
- To embed =img.png= at half its size, do the following:
+ To embed =img.png= at half its size, do the following:
- #+begin_example
- ,#+ATTR_ODT: :scale 0.5
- [[./img.png]]
- #+end_example
+ #+begin_example
+ ,#+ATTR_ODT: :scale 0.5
+ [[./img.png]]
+ #+end_example
- Scale the image to a specific width ::
- To embed =img.png= with a width of 10 cm while retaining the
- original height:width ratio, do the following:
+ To embed =img.png= with a width of 10 cm while retaining the
+ original height:width ratio, do the following:
- #+begin_example
- ,#+ATTR_ODT: :width 10
- [[./img.png]]
- #+end_example
+ #+begin_example
+ ,#+ATTR_ODT: :width 10
+ [[./img.png]]
+ #+end_example
- Scale the image to a specific height ::
- To embed =img.png= with a height of 10 cm while retaining the
- original height:width ratio, do the following:
+ To embed =img.png= with a height of 10 cm while retaining the
+ original height:width ratio, do the following:
- #+begin_example
- ,#+ATTR_ODT: :height 10
- [[./img.png]]
- #+end_example
+ #+begin_example
+ ,#+ATTR_ODT: :height 10
+ [[./img.png]]
+ #+end_example
**** Anchoring of images
:PROPERTIES:
@@ -13966,76 +14080,76 @@ document in one of the following ways:
- MathML ::
- #+cindex: MathML
- Add this line to the Org file. This option is activated on
- a per-file basis.
+ #+cindex: MathML
+ Add this line to the Org file. This option is activated on
+ a per-file basis.
- : #+OPTIONS: tex:t
+ : #+OPTIONS: tex:t
- With this option, LaTeX fragments are first converted into MathML
- fragments using an external LaTeX-to-MathML converter program.
- The resulting MathML fragments are then embedded as an
- OpenDocument Formula in the exported document.
+ With this option, LaTeX fragments are first converted into MathML
+ fragments using an external LaTeX-to-MathML converter program. The
+ resulting MathML fragments are then embedded as an OpenDocument
+ Formula in the exported document.
- #+vindex: org-latex-to-mathml-convert-command
- #+vindex: org-latex-to-mathml-jar-file
- You can specify the LaTeX-to-MathML converter by customizing the
- variables ~org-latex-to-mathml-convert-command~ and
- ~org-latex-to-mathml-jar-file~.
+ #+vindex: org-latex-to-mathml-convert-command
+ #+vindex: org-latex-to-mathml-jar-file
+ You can specify the LaTeX-to-MathML converter by customizing the
+ variables ~org-latex-to-mathml-convert-command~ and
+ ~org-latex-to-mathml-jar-file~.
- If you prefer to use MathToWeb[fn:134] as your converter, you can
- configure the above variables as shown below.
+ If you prefer to use MathToWeb[fn:133] as your converter, you can
+ configure the above variables as shown below.
- #+begin_src emacs-lisp
- (setq org-latex-to-mathml-convert-command
- "java -jar %j -unicode -force -df %o %I"
- org-latex-to-mathml-jar-file
- "/path/to/mathtoweb.jar")
- #+end_src
+ #+begin_src emacs-lisp
+ (setq org-latex-to-mathml-convert-command
+ "java -jar %j -unicode -force -df %o %I"
+ org-latex-to-mathml-jar-file
+ "/path/to/mathtoweb.jar")
+ #+end_src
- #+texinfo: @noindent
- or, to use LaTeX​ML[fn:135] instead,
+ #+texinfo: @noindent
+ or, to use LaTeX​ML[fn:134] instead,
- #+begin_src emacs-lisp
- (setq org-latex-to-mathml-convert-command
- "latexmlmath \"%i\" --presentationmathml=%o")
- #+end_src
+ #+begin_src emacs-lisp
+ (setq org-latex-to-mathml-convert-command
+ "latexmlmath \"%i\" --presentationmathml=%o")
+ #+end_src
- To quickly verify the reliability of the LaTeX-to-MathML
- converter, use the following commands:
+ To quickly verify the reliability of the LaTeX-to-MathML
+ converter, use the following commands:
- - {{{kbd(M-x org-export-as-odf)}}} ::
+ - {{{kbd(M-x org-export-as-odf)}}} ::
- Convert a LaTeX math snippet to an OpenDocument formula
- (=.odf=) file.
+ Convert a LaTeX math snippet to an OpenDocument formula (=.odf=)
+ file.
- - {{{kbd(M-x org-export-as-odf-and-open)}}} ::
+ - {{{kbd(M-x org-export-as-odf-and-open)}}} ::
- Convert a LaTeX math snippet to an OpenDocument formula
- (=.odf=) file and open the formula file with the
- system-registered application.
+ Convert a LaTeX math snippet to an OpenDocument formula (=.odf=)
+ file and open the formula file with the system-registered
+ application.
- PNG images ::
- #+cindex: dvipng
- #+cindex: dvisvgm
- #+cindex: ImageMagick
- Add this line to the Org file. This option is activated on
- a per-file basis.
+ #+cindex: dvipng
+ #+cindex: dvisvgm
+ #+cindex: ImageMagick
+ Add this line to the Org file. This option is activated on
+ a per-file basis.
- : #+OPTIONS: tex:dvipng
+ : #+OPTIONS: tex:dvipng
- : #+OPTIONS: tex:dvisvgm
+ : #+OPTIONS: tex:dvisvgm
- #+texinfo: @noindent
- or
+ #+texinfo: @noindent
+ or
- : #+OPTIONS: tex:imagemagick
+ : #+OPTIONS: tex:imagemagick
- Under this option, LaTeX fragments are processed into PNG or SVG
- images and the resulting images are embedded in the exported
- document. This method requires dvipng program, dvisvgm or
- ImageMagick programs.
+ Under this option, LaTeX fragments are processed into PNG or SVG
+ images and the resulting images are embedded in the exported
+ document. This method requires dvipng program, dvisvgm or
+ ImageMagick programs.
**** MathML and OpenDocument formula files
:PROPERTIES:
@@ -14134,25 +14248,24 @@ for unsupported converters or tweaking existing defaults.
- Register the converter ::
- #+vindex: org-export-odt-convert-processes
- Add the name of the converter to the ~org-odt-convert-processes~
- variable. Note that it also requires how the converter is
- invoked on the command line. See the variable's docstring for
- details.
+ #+vindex: org-export-odt-convert-processes
+ Add the name of the converter to the ~org-odt-convert-processes~
+ variable. Note that it also requires how the converter is invoked
+ on the command line. See the variable's docstring for details.
- Configure its capabilities ::
- #+vindex: org-export-odt-convert-capabilities
- Specify which formats the converter can handle by customizing the
- variable ~org-odt-convert-capabilities~. Use the entry for the
- default values in this variable for configuring the new
- converter. Also see its docstring for details.
+ #+vindex: org-export-odt-convert-capabilities
+ Specify which formats the converter can handle by customizing the
+ variable ~org-odt-convert-capabilities~. Use the entry for the
+ default values in this variable for configuring the new converter.
+ Also see its docstring for details.
- Choose the converter ::
- #+vindex: org-export-odt-convert-process
- Select the newly added converter as the preferred one by
- customizing the option ~org-odt-convert-process~.
+ #+vindex: org-export-odt-convert-process
+ Select the newly added converter as the preferred one by customizing
+ the option ~org-odt-convert-process~.
**** Working with OpenDocument style files
:PROPERTIES:
@@ -14172,29 +14285,29 @@ by the variable ~org-odt-styles-dir~. The two files are:
- =OrgOdtStyles.xml= <<x-orgodtstyles-xml>> ::
- This file contributes to the =styles.xml= file of the final ODT
- document. This file gets modified for the following purposes:
+ This file contributes to the =styles.xml= file of the final ODT
+ document. This file gets modified for the following purposes:
- 1. To control outline numbering based on user settings;
+ 1. To control outline numbering based on user settings;
- 2. To add styles generated by =htmlfontify.el= for fontification of
- code blocks.
+ 2. To add styles generated by =htmlfontify.el= for fontification of
+ code blocks.
- =OrgOdtContentTemplate.xml= <<x-orgodtcontenttemplate-xml>> ::
- This file contributes to the =content.xml= file of the final ODT
- document. The contents of the Org outline are inserted between the
- =<office:text>= ... =</office:text>= elements of this file.
+ This file contributes to the =content.xml= file of the final ODT
+ document. The contents of the Org outline are inserted between the
+ =<office:text>= ... =</office:text>= elements of this file.
- Apart from serving as a template file for the final =content.xml=,
- the file serves the following purposes:
+ Apart from serving as a template file for the final =content.xml=,
+ the file serves the following purposes:
- 1. It contains automatic styles for formatting of tables which are
- referenced by the exporter;
+ 1. It contains automatic styles for formatting of tables which are
+ referenced by the exporter;
- 2. It contains =<text:sequence-decl>= ... =</text:sequence-decl>=
- elements that control numbering of tables, images, equations, and
- similar entities.
+ 2. It contains =<text:sequence-decl>= ... =</text:sequence-decl>=
+ elements that control numbering of tables, images, equations, and
+ similar entities.
<<x-overriding-factory-styles>> The following two variables control
the location from where the ODT exporter picks up the custom styles
@@ -14203,36 +14316,36 @@ factory styles used by the exporter.
- ~org-odt-styles-file~ ::
- The ODT export back-end uses the file pointed to by this
- variable, such as =styles.xml=, for the final output. It can
- take one of the following values:
+ The ODT export back-end uses the file pointed to by this variable,
+ such as =styles.xml=, for the final output. It can take one of the
+ following values:
- - =FILE.xml= ::
+ - =FILE.xml= ::
- Use this file instead of the default =styles.xml=
+ Use this file instead of the default =styles.xml=
- - =FILE.odt= or =FILE.ott= ::
+ - =FILE.odt= or =FILE.ott= ::
- Use the =styles.xml= contained in the specified OpenDocument
- Text or Template file
+ Use the =styles.xml= contained in the specified OpenDocument
+ Text or Template file
- - =FILE.odt= or =FILE.ott= and a subset of included files ::
+ - =FILE.odt= or =FILE.ott= and a subset of included files ::
- Use the =styles.xml= contained in the specified OpenDocument
- Text or Template file. Additionally extract the specified
- member files and embed those within the final ODT document.
+ Use the =styles.xml= contained in the specified OpenDocument Text
+ or Template file. Additionally extract the specified member files
+ and embed those within the final ODT document.
- Use this option if the =styles.xml= file references additional
- files like header and footer images.
+ Use this option if the =styles.xml= file references additional
+ files like header and footer images.
- - ~nil~ ::
+ - ~nil~ ::
- Use the default =styles.xml=.
+ Use the default =styles.xml=.
- ~org-odt-content-template-file~ ::
- Use this variable to specify the blank =content.xml= used in the
- final output.
+ Use this variable to specify the blank =content.xml= used in the
+ final output.
**** Creating one-off styles
:PROPERTIES:
@@ -14245,61 +14358,61 @@ the Org file. Such direct formatting is useful for one-off instances.
- Embedding ODT tags as part of regular text ::
- Enclose OpenDocument syntax in =@@odt:...@@= for inline markup.
- For example, to highlight a region of text do the following:
+ Enclose OpenDocument syntax in =@@odt:...@@= for inline markup. For
+ example, to highlight a region of text do the following:
- #+begin_example
- @@odt:<text:span text:style-name="Highlight">This is highlighted
- text</text:span>@@. But this is regular text.
- #+end_example
+ #+begin_example
+ @@odt:<text:span text:style-name="Highlight">This is highlighted
+ text</text:span>@@. But this is regular text.
+ #+end_example
- *Hint:* To see the above example in action, edit the =styles.xml=
- (see [[x-orgodtstyles-xml][Factory styles]]) and add a custom /Highlight/ style as shown
- below:
+ *Hint:* To see the above example in action, edit the =styles.xml=
+ (see [[x-orgodtstyles-xml][Factory styles]]) and add a custom /Highlight/ style as shown
+ below:
- #+begin_example
- <style:style style:name="Highlight" style:family="text">
- <style:text-properties fo:background-color="#ff0000"/>
- </style:style>
- #+end_example
+ #+begin_example
+ <style:style style:name="Highlight" style:family="text">
+ <style:text-properties fo:background-color="#ff0000"/>
+ </style:style>
+ #+end_example
- Embedding a one-line OpenDocument XML ::
- #+cindex: @samp{ODT}, keyword
- The ODT export back-end can read one-liner options with =#+ODT:=
- in the Org file. For example, to force a page break:
+ #+cindex: @samp{ODT}, keyword
+ The ODT export back-end can read one-liner options with =#+ODT:= in
+ the Org file. For example, to force a page break:
- #+begin_example
- ,#+ODT: <text:p text:style-name="PageBreak"/>
- #+end_example
+ #+begin_example
+ ,#+ODT: <text:p text:style-name="PageBreak"/>
+ #+end_example
- *Hint:* To see the above example in action, edit your
- =styles.xml= (see [[x-orgodtstyles-xml][Factory styles]]) and add a custom =PageBreak=
- style as shown below.
+ *Hint:* To see the above example in action, edit your
+ =styles.xml= (see [[x-orgodtstyles-xml][Factory styles]]) and add a custom =PageBreak=
+ style as shown below.
- #+begin_example
- <style:style style:name="PageBreak" style:family="paragraph"
- style:parent-style-name="Text_20_body">
- <style:paragraph-properties fo:break-before="page"/>
- </style:style>
- #+end_example
+ #+begin_example
+ <style:style style:name="PageBreak" style:family="paragraph"
+ style:parent-style-name="Text_20_body">
+ <style:paragraph-properties fo:break-before="page"/>
+ </style:style>
+ #+end_example
- Embedding a block of OpenDocument XML ::
- The ODT export back-end can also read ODT export blocks for
- OpenDocument XML. Such blocks use the =#+BEGIN_EXPORT odt=
- ... =#+END_EXPORT= constructs.
+ The ODT export back-end can also read ODT export blocks for
+ OpenDocument XML. Such blocks use the =#+BEGIN_EXPORT odt=
+ ... =#+END_EXPORT= constructs.
- For example, to create a one-off paragraph that uses bold text,
- do the following:
+ For example, to create a one-off paragraph that uses bold text, do
+ the following:
- #+begin_example
- ,#+BEGIN_EXPORT odt
- <text:p text:style-name="Text_20_body_20_bold">
- This paragraph is specially formatted and uses bold text.
- </text:p>
- ,#+END_EXPORT
- #+end_example
+ #+begin_example
+ ,#+BEGIN_EXPORT odt
+ <text:p text:style-name="Text_20_body_20_bold">
+ This paragraph is specially formatted and uses bold text.
+ </text:p>
+ ,#+END_EXPORT
+ #+end_example
**** Customizing tables in ODT export
:PROPERTIES:
@@ -14314,7 +14427,7 @@ with the =#+ATTR_ODT= line. For a discussion on default formatting of
tables, see [[*Tables in ODT export]].
This feature closely mimics the way table templates are defined in the
-OpenDocument-v1.2 specification[fn:136].
+OpenDocument-v1.2 specification[fn:135].
#+vindex: org-odt-table-styles
For quick preview of this feature, install the settings below and export the
@@ -14348,7 +14461,7 @@ templates, define new styles there.
To use this feature proceed as follows:
-1. Create a table template[fn:137].
+1. Create a table template[fn:136].
A table template is set of =table-cell= and =paragraph= styles for
each of the following table cell categories:
@@ -14387,7 +14500,7 @@ To use this feature proceed as follows:
=</office:automatic-styles>= element of the content template file
(see [[x-orgodtcontenttemplate-xml][Factory styles]]).
-2. Define a table style[fn:138].
+2. Define a table style[fn:137].
#+vindex: org-odt-table-styles
To define a table style, create an entry for the style in the
@@ -14437,8 +14550,7 @@ OpenDocument Relax NG Compact (RNC) syntax schema. But first the
=.odt= files have to be decompressed using =zip=. Note that =.odt=
files are ZIP archives: [[info:emacs::File Archives]]. The contents of
ODT files are in XML. For general help with validation---and
-schema-sensitive editing---of XML files:
-[[info:nxml-mode::Introduction]].
+schema-sensitive editing---of XML files: [[info:nxml-mode::Introduction]].
#+vindex: org-export-odt-schema-dir
Customize ~org-odt-schema-dir~ to point to a directory with
@@ -14463,15 +14575,15 @@ Code Blocks]]) and removes content specific to other back-ends.
- {{{kbd(C-c C-e O o)}}} (~org-org-export-to-org~) ::
- #+kindex: C-c C-e O o
- #+findex: org-org-export-to-org
- Export as an Org file with a =.org= extension. For =myfile.org=,
- Org exports to =myfile.org.org=, overwriting without warning.
+ #+kindex: C-c C-e O o
+ #+findex: org-org-export-to-org
+ Export as an Org file with a =.org= extension. For =myfile.org=,
+ Org exports to =myfile.org.org=, overwriting without warning.
- {{{kbd(C-c C-e O v)}}} (~~) ::
- #+kindex: C-c C-e O v
- Export to an Org file, then open it.
+ #+kindex: C-c C-e O v
+ Export to an Org file, then open it.
** Texinfo Export
:PROPERTIES:
@@ -14485,20 +14597,19 @@ Code Blocks]]) and removes content specific to other back-ends.
- {{{kbd(C-c C-e i t)}}} (~org-texinfo-export-to-texinfo~) ::
- #+kindex: C-c C-e i t
- #+findex: org-texinfo-export-to-texinfo
- Export as a Texinfo file with =.texi= extension. For
- =myfile.org=, Org exports to =myfile.texi=, overwriting without
- warning.
+ #+kindex: C-c C-e i t
+ #+findex: org-texinfo-export-to-texinfo
+ Export as a Texinfo file with =.texi= extension. For =myfile.org=,
+ Org exports to =myfile.texi=, overwriting without warning.
- {{{kbd(C-c C-e i i)}}} (~org-texinfo-export-to-info~) ::
- #+kindex: C-c C-e i i
- #+findex: org-texinfo-export-to-info
- #+vindex: org-texinfo-info-process
- Export to Texinfo format first and then process it to make an
- Info file. To generate other formats, such as DocBook, customize
- the ~org-texinfo-info-process~ variable.
+ #+kindex: C-c C-e i i
+ #+findex: org-texinfo-export-to-info
+ #+vindex: org-texinfo-info-process
+ Export to Texinfo format first and then process it to make an Info
+ file. To generate other formats, such as DocBook, customize the
+ ~org-texinfo-info-process~ variable.
*** Texinfo specific export settings
:PROPERTIES:
@@ -14511,55 +14622,55 @@ the general options (see [[*Export Settings]]).
- =SUBTITLE= ::
- #+cindex: @samp{SUBTITLE}, keyword
- The document subtitle.
+ #+cindex: @samp{SUBTITLE}, keyword
+ The document subtitle.
- =SUBAUTHOR= ::
- #+cindex: @samp{SUBAUTHOR}, keyword
- Additional authors for the document.
+ #+cindex: @samp{SUBAUTHOR}, keyword
+ Additional authors for the document.
- =TEXINFO_FILENAME= ::
- #+cindex: @samp{TEXINFO_FILENAME}, keyword
- The Texinfo filename.
+ #+cindex: @samp{TEXINFO_FILENAME}, keyword
+ The Texinfo filename.
- =TEXINFO_CLASS= ::
- #+cindex: @samp{TEXINFO_CLASS}, keyword
- #+vindex: org-texinfo-default-class
- The default document class (~org-texinfo-default-class~), which
- must be a member of ~org-texinfo-classes~.
+ #+cindex: @samp{TEXINFO_CLASS}, keyword
+ #+vindex: org-texinfo-default-class
+ The default document class (~org-texinfo-default-class~), which must
+ be a member of ~org-texinfo-classes~.
- =TEXINFO_HEADER= ::
- #+cindex: @samp{TEXINFO_HEADER}, keyword
- Arbitrary lines inserted at the end of the header.
+ #+cindex: @samp{TEXINFO_HEADER}, keyword
+ Arbitrary lines inserted at the end of the header.
- =TEXINFO_POST_HEADER= ::
- #+cindex: @samp{TEXINFO_POST_HEADER}, keyword
- Arbitrary lines inserted after the end of the header.
+ #+cindex: @samp{TEXINFO_POST_HEADER}, keyword
+ Arbitrary lines inserted after the end of the header.
- =TEXINFO_DIR_CATEGORY= ::
- #+cindex: @samp{TEXINFO_DIR_CATEGORY}, keyword
- The directory category of the document.
+ #+cindex: @samp{TEXINFO_DIR_CATEGORY}, keyword
+ The directory category of the document.
- =TEXINFO_DIR_TITLE= ::
- #+cindex: @samp{TEXINFO_DIR_TITLE}, keyword
- The directory title of the document.
+ #+cindex: @samp{TEXINFO_DIR_TITLE}, keyword
+ The directory title of the document.
- =TEXINFO_DIR_DESC= ::
- #+cindex: @samp{TEXINFO_DIR_DESC}, keyword
- The directory description of the document.
+ #+cindex: @samp{TEXINFO_DIR_DESC}, keyword
+ The directory description of the document.
- =TEXINFO_PRINTED_TITLE= ::
- #+cindex: @samp{TEXINFO_PRINTED_TITLE}, keyword
- The printed title of the document.
+ #+cindex: @samp{TEXINFO_PRINTED_TITLE}, keyword
+ The printed title of the document.
*** Texinfo file header
:PROPERTIES:
@@ -14703,7 +14814,7 @@ the default menu entry:
The text before the first headline belongs to the /Top/ node, i.e.,
the node in which a reader enters an Info manual. As such, it is
expected not to appear in printed output generated from the =.texi=
-file. See [[info:texinfo::The%20Top%20Node]], for more information.
+file. See [[info:texinfo::The Top Node]], for more information.
*** Indices
:PROPERTIES:
@@ -14774,21 +14885,22 @@ This paragraph is preceded by...
#+cindex: @samp{ATTR_TEXINFO}, keyword
#+cindex: two-column tables, in Texinfo export
-
-#+cindex: table types, in Texinfo export
+#+cindex: table-type, Texinfo attribute
The Texinfo export back-end by default converts description lists in
the Org file using the default command =@table=, which results in
-a table with two columns. To change this behavior, specify
-=:table-type= with =ftable= or =vtable= attributes. For more
-information, see [[info:texinfo::Two-column Tables]].
+a table with two columns. To change this behavior, set =:table-type=
+attribute to either =ftable= or =vtable= value. For more information,
+see [[info:texinfo::Two-column Tables]].
#+vindex: org-texinfo-table-default-markup
+#+cindex: indic, Texinfo attribute
The Texinfo export back-end by default also applies a text highlight
based on the defaults stored in ~org-texinfo-table-default-markup~.
To override the default highlight command, specify another one with
the =:indic= attribute.
#+cindex: multiple items in Texinfo lists
+#+cindex: sep, Texinfo attribute
Org syntax is limited to one entry per list item. Nevertheless, the
Texinfo export back-end can split that entry according to any text
provided through the =:sep= attribute. Each part then becomes a new
@@ -14812,6 +14924,20 @@ This is the common text for variables foo and bar.
@end table
#+end_example
+#+cindex: lettered lists, in Texinfo export
+#+cindex: enum, Texinfo attribute
+Ordered lists are numbered when exported to Texinfo format. Such
+numbering obeys any counter (see [[*Plain Lists]]) in the first item of
+the list. The =:enum= attribute also let you start the list at
+a specific number, or switch to a lettered list, as illustrated here
+
+#+begin_example
+#+ATTR_TEXINFO: :enum A
+1. Alpha
+2. Bravo
+3. Charlie
+#+end_example
+
*** Tables in Texinfo export
:PROPERTIES:
:DESCRIPTION: Table attributes.
@@ -14907,7 +15033,7 @@ becomes
:END:
Here is a more detailed example Org file. See
-[[info:texinfo::GNU%20Sample%20Texts]] for an equivalent example using
+[[info:texinfo::GNU Sample Texts]] for an equivalent example using
Texinfo code.
#+begin_example
@@ -14967,7 +15093,7 @@ This manual is for GNU Sample (version {{{version}}},
:APPENDIX: t
:END:
- ,#+TEXINFO: @include fdl.texi
+ ,#+INCLUDE: fdl.org
,* Index
:PROPERTIES:
@@ -15024,43 +15150,45 @@ connections.
- {{{kbd(C-c C-e c f)}}} (~org-icalendar-export-to-ics~) ::
- #+kindex: C-c C-e c f
- #+findex: org-icalendar-export-to-ics
- Create iCalendar entries from the current Org buffer and store
- them in the same directory, using a file extension =.ics=.
+ #+kindex: C-c C-e c f
+ #+findex: org-icalendar-export-to-ics
+ Create iCalendar entries from the current Org buffer and store them
+ in the same directory, using a file extension =.ics=.
- {{{kbd(C-c C-e c a)}}} (~org-icalendar-export-agenda-files~) ::
- #+kindex: C-c C-e c a
- #+findex: org-icalendar-export-agenda-files
- Create iCalendar entries from Org files in ~org-agenda-files~ and
- store in a separate iCalendar file for each Org file.
+ #+kindex: C-c C-e c a
+ #+findex: org-icalendar-export-agenda-files
+ Create iCalendar entries from Org files in ~org-agenda-files~ and
+ store in a separate iCalendar file for each Org file.
- {{{kbd(C-c C-e c c)}}} (~org-icalendar-combine-agenda-files~) ::
- #+kindex: C-c C-e c c
- #+findex: org-icalendar-combine-agenda-files
- #+vindex: org-icalendar-combined-agenda-file
- Create a combined iCalendar file from Org files in
- ~org-agenda-files~ and write it to
- ~org-icalendar-combined-agenda-file~ file name.
+ #+kindex: C-c C-e c c
+ #+findex: org-icalendar-combine-agenda-files
+ #+vindex: org-icalendar-combined-agenda-file
+ Create a combined iCalendar file from Org files in
+ ~org-agenda-files~ and write it to
+ ~org-icalendar-combined-agenda-file~ file name.
#+cindex: @samp{SUMMARY}, property
#+cindex: @samp{DESCRIPTION}, property
#+cindex: @samp{LOCATION}, property
#+cindex: @samp{TIMEZONE}, property
+#+cindex: @samp{CLASS}, property
The iCalendar export back-end includes =SUMMARY=, =DESCRIPTION=,
-=LOCATION= and =TIMEZONE= properties from the Org entries when
-exporting. To force the back-end to inherit the =LOCATION= and
-=TIMEZONE= properties, configure the ~org-use-property-inheritance~
-variable.
+=LOCATION=, =TIMEZONE= and =CLASS= properties from the Org entries
+when exporting. To force the back-end to inherit the =LOCATION=,
+=TIMEZONE= and =CLASS= properties, configure the
+~org-use-property-inheritance~ variable.
#+vindex: org-icalendar-include-body
-When Org entries do not have =SUMMARY=, =DESCRIPTION= and =LOCATION=
-properties, the iCalendar export back-end derives the summary from the
-headline, and derives the description from the body of the Org item.
-The ~org-icalendar-include-body~ variable limits the maximum number of
-characters of the content are turned into its description.
+When Org entries do not have =SUMMARY=, =DESCRIPTION=, =LOCATION= and
+=CLASS= properties, the iCalendar export back-end derives the summary
+from the headline, and derives the description from the body of the
+Org item. The ~org-icalendar-include-body~ variable limits the
+maximum number of characters of the content are turned into its
+description.
The =TIMEZONE= property can be used to specify a per-entry time zone,
and is applied to any entry with timestamp information. Time zones
@@ -15068,6 +15196,16 @@ should be specified as per the IANA time zone database format, e.g.,
=Asia/Almaty=. Alternately, the property value can be =UTC=, to force
UTC time for this entry only.
+The =CLASS= property can be used to specify a per-entry visibility
+class or access restrictions, and is applied to any entry with class
+information. The iCalendar standard defines three visibility classes:
+- =PUBLIC= :: The entry is publicly visible (this is the default).
+- =CONFIDENTIAL= :: Only a limited group of clients get access to the
+ event.
+- =PRIVATE= :: The entry can be retrieved only by its owner.
+The server should treat unknown class properties the same as
+=PRIVATE=.
+
Exporting to iCalendar format depends in large part on the
capabilities of the destination application. Some are more lenient
than others. Consult the Org mode FAQ for advice on specific
@@ -15272,33 +15410,33 @@ functions:
- ~org-ascii-convert-region-to-ascii~ ::
- #+findex: org-ascii-convert-region-to-ascii
- Convert the selected region into ASCII.
+ #+findex: org-ascii-convert-region-to-ascii
+ Convert the selected region into ASCII.
- ~org-ascii-convert-region-to-utf8~ ::
- #+findex: org-ascii-convert-region-to-utf8
- Convert the selected region into UTF-8.
+ #+findex: org-ascii-convert-region-to-utf8
+ Convert the selected region into UTF-8.
- ~org-html-convert-region-to-html~ ::
- #+findex: org-html-convert-region-to-html
- Convert the selected region into HTML.
+ #+findex: org-html-convert-region-to-html
+ Convert the selected region into HTML.
- ~org-latex-convert-region-to-latex~ ::
- #+findex: org-latex-convert-region-to-latex
- Convert the selected region into LaTeX.
+ #+findex: org-latex-convert-region-to-latex
+ Convert the selected region into LaTeX.
- ~org-texinfo-convert-region-to-texinfo~ ::
- #+findex: org-texinfo-convert-region-to-texinfo
- Convert the selected region into Texinfo.
+ #+findex: org-texinfo-convert-region-to-texinfo
+ Convert the selected region into Texinfo.
- ~org-md-convert-region-to-md~ ::
- #+findex: org-md-convert-region-to-md
- Convert the selected region into Markdown.
+ #+findex: org-md-convert-region-to-md
+ Convert the selected region into Markdown.
In-place conversions are particularly handy for quick conversion of
tables and lists in foreign buffers. For example, in an HTML buffer,
@@ -15377,29 +15515,28 @@ where to put published files.
- ~:base-directory~ ::
- Directory containing publishing source files.
+ Directory containing publishing source files.
- ~:publishing-directory~ ::
- Directory where output files are published. You can directly
- publish to a webserver using a file name syntax appropriate for
- the Emacs tramp package. Or you can publish to a local directory
- and use external tools to upload your website (see [[*Uploading
- Files]]).
+ Directory where output files are published. You can directly
+ publish to a webserver using a file name syntax appropriate for the
+ Emacs tramp package. Or you can publish to a local directory and
+ use external tools to upload your website (see [[*Uploading Files]]).
- ~:preparation-function~ ::
- Function or list of functions to be called before starting the
- publishing process, for example, to run =make= for updating files
- to be published. Each preparation function is called with
- a single argument, the project property list.
+ Function or list of functions to be called before starting the
+ publishing process, for example, to run =make= for updating files to
+ be published. Each preparation function is called with a single
+ argument, the project property list.
- ~:completion-function~ ::
- Function or list of functions called after finishing the
- publishing process, for example, to change permissions of the
- resulting files. Each completion function is called with
- a single argument, the project property list.
+ Function or list of functions called after finishing the publishing
+ process, for example, to change permissions of the resulting files.
+ Each completion function is called with a single argument, the
+ project property list.
*** Selecting files
:PROPERTIES:
@@ -15413,25 +15550,24 @@ following properties
- ~:base-extension~ ::
- Extension---without the dot---of source files. This actually
- is a regular expression. Set this to the symbol ~any~ if you
- want to get all files in ~:base-directory~, even without
- extension.
+ Extension---without the dot---of source files. This actually is
+ a regular expression. Set this to the symbol ~any~ if you want to
+ get all files in ~:base-directory~, even without extension.
- ~:exclude~ ::
- Regular expression to match file names that should not be published,
- even though they have been selected on the basis of their extension.
+ Regular expression to match file names that should not be published,
+ even though they have been selected on the basis of their extension.
- ~:include~ ::
- List of files to be included regardless of ~:base-extension~ and
- ~:exclude~.
+ List of files to be included regardless of ~:base-extension~ and
+ ~:exclude~.
- ~:recursive~ ::
- Non-~nil~ means, check base-directory recursively for files to
- publish.
+ Non-~nil~ means, check base-directory recursively for files to
+ publish.
*** Publishing action
:PROPERTIES:
@@ -15452,7 +15588,7 @@ If you want to publish the Org file as an =.org= file but with
~org-publish-org-to-org~. This produces =file.org= and put it in the
publishing directory. If you want a htmlized version of this file,
set the parameter ~:htmlized-source~ to ~t~. It produces
-=file.org.html= in the publishing directory[fn:139].
+=file.org.html= in the publishing directory[fn:138].
Other files like images only need to be copied to the publishing
destination; for this you can use ~org-publish-attachment~. For
@@ -15460,12 +15596,12 @@ non-Org files, you always need to specify the publishing function:
- ~:publishing-function~ ::
- Function executing the publication of a file. This may also be
- a list of functions, which are all called in turn.
+ Function executing the publication of a file. This may also be
+ a list of functions, which are all called in turn.
- ~:htmlized-source~ ::
- Non-~nil~ means, publish htmlized source.
+ Non-~nil~ means, publish htmlized source.
The function must accept three arguments: a property list containing
at least a ~:publishing-directory~ property, the name of the file to
@@ -15608,6 +15744,7 @@ Settings]]), however, override everything.
| ~:html-postamble~ | ~org-html-postamble~ |
| ~:html-preamble-format~ | ~org-html-preamble-format~ |
| ~:html-preamble~ | ~org-html-preamble~ |
+| ~:html-self-link-headlines~ | ~org-html-self-link-headlines~ |
| ~:html-table-align-individual-field~ | ~de{org-html-table-align-individual-fields~ |
| ~:html-table-attributes~ | ~org-html-table-default-attributes~ |
| ~:html-table-caption-above~ | ~org-html-table-caption-above~ |
@@ -15622,6 +15759,7 @@ Settings]]), however, override everything.
| ~:html-use-infojs~ | ~org-html-use-infojs~ |
| ~:html-validation-link~ | ~org-html-validation-link~ |
| ~:html-viewport~ | ~org-html-viewport~ |
+| ~:html-wrap-src-lines~ | ~org-html-wrap-src-lines~ |
| ~:html-xml-declaration~ | ~org-html-xml-declaration~ |
**** LaTeX specific properties
@@ -15759,81 +15897,77 @@ a map of files for a given project.
- ~:auto-sitemap~ ::
- When non-~nil~, publish a sitemap during
- ~org-publish-current-project~ or ~org-publish-all~.
+ When non-~nil~, publish a sitemap during
+ ~org-publish-current-project~ or ~org-publish-all~.
- ~:sitemap-filename~ ::
- Filename for output of sitemap. Defaults to =sitemap.org=, which
- becomes =sitemap.html=.
+ Filename for output of sitemap. Defaults to =sitemap.org=, which
+ becomes =sitemap.html=.
- ~:sitemap-title~ ::
- Title of sitemap page. Defaults to name of file.
+ Title of sitemap page. Defaults to name of file.
- ~:sitemap-format-entry~ ::
- #+findex: org-publish-find-date
- #+findex: org-publish-find-property
- #+findex: org-publish-find-title
- With this option one can tell how a site-map entry is formatted
- in the site-map. It is a function called with three arguments:
- the file or directory name relative to base directory of the
- project, the site-map style and the current project. It is
- expected to return a string. Default value turns file names into
- links and use document titles as descriptions. For specific
- formatting needs, one can use ~org-publish-find-date~,
- ~org-publish-find-title~ and ~org-publish-find-property~, to
- retrieve additional information about published documents.
+ #+findex: org-publish-find-date
+ #+findex: org-publish-find-property
+ #+findex: org-publish-find-title
+ With this option one can tell how a site-map entry is formatted in
+ the site-map. It is a function called with three arguments: the
+ file or directory name relative to base directory of the project,
+ the site-map style and the current project. It is expected to
+ return a string. Default value turns file names into links and use
+ document titles as descriptions. For specific formatting needs, one
+ can use ~org-publish-find-date~, ~org-publish-find-title~ and
+ ~org-publish-find-property~, to retrieve additional information
+ about published documents.
- ~:sitemap-function~ ::
- Plug-in function to use for generation of the sitemap. It is
- called with two arguments: the title of the site-map and
- a representation of the files and directories involved in the
- project as a nested list, which can further be transformed using
- ~org-list-to-generic~, ~org-list-to-subtree~ and alike. Default
- value generates a plain list of links to all files in the
- project.
+ Plug-in function to use for generation of the sitemap. It is called
+ with two arguments: the title of the site-map and a representation
+ of the files and directories involved in the project as a nested
+ list, which can further be transformed using ~org-list-to-generic~,
+ ~org-list-to-subtree~ and alike. Default value generates a plain
+ list of links to all files in the project.
- ~:sitemap-sort-folders~ ::
- Where folders should appear in the sitemap. Set this to ~first~
- (default) or ~last~ to display folders first or last,
- respectively. When set to ~ignore~, folders are ignored
- altogether. Any other value mixes files and folders. This
- variable has no effect when site-map style is ~tree~.
+ Where folders should appear in the sitemap. Set this to ~first~
+ (default) or ~last~ to display folders first or last, respectively.
+ When set to ~ignore~, folders are ignored altogether. Any other
+ value mixes files and folders. This variable has no effect when
+ site-map style is ~tree~.
- ~:sitemap-sort-files~ ::
- How the files are sorted in the site map. Set this to
- ~alphabetically~ (default), ~chronologically~ or
- ~anti-chronologically~. ~chronologically~ sorts the files with
- older date first while ~anti-chronologically~ sorts the files
- with newer date first. ~alphabetically~ sorts the files
- alphabetically. The date of a file is retrieved with
- ~org-publish-find-date~.
+ How the files are sorted in the site map. Set this to
+ ~alphabetically~ (default), ~chronologically~ or
+ ~anti-chronologically~. ~chronologically~ sorts the files with
+ older date first while ~anti-chronologically~ sorts the files with
+ newer date first. ~alphabetically~ sorts the files alphabetically.
+ The date of a file is retrieved with ~org-publish-find-date~.
- ~:sitemap-ignore-case~ ::
- Should sorting be case-sensitive? Default ~nil~.
+ Should sorting be case-sensitive? Default ~nil~.
- ~:sitemap-file-entry-format~ ::
- With this option one can tell how a sitemap's entry is formatted
- in the sitemap. This is a format string with some escape
- sequences: ~%t~ stands for the title of the file, ~%a~ stands for
- the author of the file and ~%d~ stands for the date of the file.
- The date is retrieved with the ~org-publish-find-date~ function
- and formatted with ~org-publish-sitemap-date-format~. Default
- ~%t~.
+ With this option one can tell how a sitemap's entry is formatted in
+ the sitemap. This is a format string with some escape sequences:
+ ~%t~ stands for the title of the file, ~%a~ stands for the author of
+ the file and ~%d~ stands for the date of the file. The date is
+ retrieved with the ~org-publish-find-date~ function and formatted
+ with ~org-publish-sitemap-date-format~. Default ~%t~.
- ~:sitemap-date-format~ ::
- Format string for the ~format-time-string~ function that tells
- how a sitemap entry's date is to be formatted. This property
- bypasses ~org-publish-sitemap-date-format~ which defaults to
- ~%Y-%m-%d~.
+ Format string for the ~format-time-string~ function that tells how
+ a sitemap entry's date is to be formatted. This property bypasses
+ ~org-publish-sitemap-date-format~ which defaults to ~%Y-%m-%d~.
*** Generating an index
:PROPERTIES:
@@ -15845,8 +15979,8 @@ Org mode can generate an index across the files of a publishing project.
- ~:makeindex~ ::
- When non-~nil~, generate in index in the file =theindex.org= and
- publish it as =theindex.html=.
+ When non-~nil~, generate in index in the file =theindex.org= and
+ publish it as =theindex.html=.
The file is created when first publishing a project with the
~:makeindex~ set. The file only contains a statement =#+INCLUDE:
@@ -15988,30 +16122,30 @@ place on the web server, and publishing images to it.
Once properly configured, Org can publish with the following commands:
-- {{{kbd(C-c C-e X)}}} (~org-publish~) ::
+- {{{kbd(C-c C-e P x)}}} (~org-publish~) ::
- #+kindex: C-c C-e X
- #+findex: org-publish
- Prompt for a specific project and publish all files that belong
- to it.
+ #+kindex: C-c C-e P x
+ #+findex: org-publish
+ Prompt for a specific project and publish all files that belong to
+ it.
-- {{{kbd(C-c C-e P)}}} (~org-publish-current-project~) ::
+- {{{kbd(C-c C-e P p)}}} (~org-publish-current-project~) ::
- #+kindex: C-c C-e P
- #+findex: org-publish-current-project
- Publish the project containing the current file.
+ #+kindex: C-c C-e P p
+ #+findex: org-publish-current-project
+ Publish the project containing the current file.
-- {{{kbd(C-c C-e F)}}} (~org-publish-current-file~) ::
+- {{{kbd(C-c C-e P f)}}} (~org-publish-current-file~) ::
- #+kindex: C-c C-e F
- #+findex: org-publish-current-file
- Publish only the current file.
+ #+kindex: C-c C-e P f
+ #+findex: org-publish-current-file
+ Publish only the current file.
-- {{{kbd(C-c C-e E)}}} (~org-publish-all~) ::
+- {{{kbd(C-c C-e P a)}}} (~org-publish-all~) ::
- #+kindex: C-c C-e E
- #+findex: org-publish-all
- Publish every project.
+ #+kindex: C-c C-e P a
+ #+findex: org-publish-all
+ Publish every project.
#+vindex: org-publish-use-timestamps-flag
Org uses timestamps to track when a file has changed. The above
@@ -16145,46 +16279,45 @@ or
- =#+NAME: <name>= ::
- Optional. Names the source block so it can be called, like
- a function, from other source blocks or inline code to evaluate
- or to capture the results. Code from other blocks, other files,
- and from table formulas (see [[*The Spreadsheet]]) can use the name
- to reference a source block. This naming serves the same purpose
- as naming Org tables. Org mode requires unique names. For
- duplicate names, Org mode's behavior is undefined.
+ Optional. Names the source block so it can be called, like
+ a function, from other source blocks or inline code to evaluate or
+ to capture the results. Code from other blocks, other files, and
+ from table formulas (see [[*The Spreadsheet]]) can use the name to
+ reference a source block. This naming serves the same purpose as
+ naming Org tables. Org mode requires unique names. For duplicate
+ names, Org mode's behavior is undefined.
- =#+BEGIN_SRC= ... =#+END_SRC= ::
- Mandatory. They mark the start and end of a block that Org
- requires. The =#+BEGIN_SRC= line takes additional arguments, as
- described next.
+ Mandatory. They mark the start and end of a block that Org
+ requires. The =#+BEGIN_SRC= line takes additional arguments, as
+ described next.
- =<language>= ::
- #+cindex: language, in code blocks
- Mandatory. It is the identifier of the source code language in
- the block. See [[*Languages]], for identifiers of supported
- languages.
+ #+cindex: language, in code blocks
+ Mandatory. It is the identifier of the source code language in the
+ block. See [[*Languages]], for identifiers of supported languages.
- =<switches>= ::
- #+cindex: switches, in code blocks
- Optional. Switches provide finer control of the code execution,
- export, and format (see the discussion of switches in [[*Literal
- Examples]]).
+ #+cindex: switches, in code blocks
+ Optional. Switches provide finer control of the code execution,
+ export, and format (see the discussion of switches in [[*Literal
+ Examples]]).
- =<header arguments>= ::
- #+cindex: header arguments, in code blocks
- Optional. Heading arguments control many aspects of evaluation,
- export and tangling of code blocks (see [[*Using Header Arguments]]).
- Using Org's properties feature, header arguments can be
- selectively applied to the entire buffer or specific sub-trees of
- the Org document.
+ #+cindex: header arguments, in code blocks
+ Optional. Heading arguments control many aspects of evaluation,
+ export and tangling of code blocks (see [[*Using Header Arguments]]).
+ Using Org's properties feature, header arguments can be selectively
+ applied to the entire buffer or specific sub-trees of the Org
+ document.
- =<body>= ::
- Source code in the dialect of the specified language identifier.
+ Source code in the dialect of the specified language identifier.
** Using Header Arguments
:PROPERTIES:
@@ -16414,158 +16547,158 @@ Here are examples of passing values by reference:
- table ::
- A table named with a =NAME= keyword.
-
- #+begin_example
- ,#+NAME: example-table
- | 1 |
- | 2 |
- | 3 |
- | 4 |
-
- ,#+NAME: table-length
- ,#+BEGIN_SRC emacs-lisp :var table=example-table
- (length table)
- ,#+END_SRC
-
- ,#+RESULTS: table-length
- : 4
- #+end_example
-
- When passing a table, you can treat specially the row, or the
- column, containing labels for the columns, or the rows, in the
- table.
-
- #+cindex: @samp{colnames}, header argument
- The =colnames= header argument accepts =yes=, =no=, or =nil=
- values. The default value is =nil=: if an input table has column
- names---because the second row is a horizontal rule---then Org
- removes the column names, processes the table, puts back the
- column names, and then writes the table to the results block.
- Using =yes=, Org does the same to the first row, even if the
- initial table does not contain any horizontal rule. When set to
- =no=, Org does not pre-process column names at all.
-
- #+begin_example
- ,#+NAME: less-cols
- | a |
- |---|
- | b |
- | c |
-
- ,#+BEGIN_SRC python :var tab=less-cols :colnames nil
- return [[val + '*' for val in row] for row in tab]
- ,#+END_SRC
-
- ,#+RESULTS:
- | a |
- |----|
- | b* |
- | c* |
- #+end_example
-
- #+cindex: @samp{rownames}, header argument
- Similarly, the =rownames= header argument can take two values:
- =yes= or =no=. When set to =yes=, Org removes the first column,
- processes the table, puts back the first column, and then writes
- the table to the results block. The default is =no=, which means
- Org does not pre-process the first column. Note that Emacs Lisp
- code blocks ignore =rownames= header argument because of the ease
- of table-handling in Emacs.
-
- #+begin_example
- ,#+NAME: with-rownames
- | one | 1 | 2 | 3 | 4 | 5 |
- | two | 6 | 7 | 8 | 9 | 10 |
-
- ,#+BEGIN_SRC python :var tab=with-rownames :rownames yes
- return [[val + 10 for val in row] for row in tab]
- ,#+END_SRC
-
- ,#+RESULTS:
- | one | 11 | 12 | 13 | 14 | 15 |
- | two | 16 | 17 | 18 | 19 | 20 |
- #+end_example
+ A table named with a =NAME= keyword.
+
+ #+begin_example
+ ,#+NAME: example-table
+ | 1 |
+ | 2 |
+ | 3 |
+ | 4 |
+
+ ,#+NAME: table-length
+ ,#+BEGIN_SRC emacs-lisp :var table=example-table
+ (length table)
+ ,#+END_SRC
+
+ ,#+RESULTS: table-length
+ : 4
+ #+end_example
+
+ When passing a table, you can treat specially the row, or the
+ column, containing labels for the columns, or the rows, in the
+ table.
+
+ #+cindex: @samp{colnames}, header argument
+ The =colnames= header argument accepts =yes=, =no=, or =nil= values.
+ The default value is =nil=: if an input table has column
+ names---because the second row is a horizontal rule---then Org
+ removes the column names, processes the table, puts back the column
+ names, and then writes the table to the results block. Using =yes=,
+ Org does the same to the first row, even if the initial table does
+ not contain any horizontal rule. When set to =no=, Org does not
+ pre-process column names at all.
+
+ #+begin_example
+ ,#+NAME: less-cols
+ | a |
+ |---|
+ | b |
+ | c |
+
+ ,#+BEGIN_SRC python :var tab=less-cols :colnames nil
+ return [[val + '*' for val in row] for row in tab]
+ ,#+END_SRC
+
+ ,#+RESULTS:
+ | a |
+ |----|
+ | b* |
+ | c* |
+ #+end_example
+
+ #+cindex: @samp{rownames}, header argument
+ Similarly, the =rownames= header argument can take two values: =yes=
+ or =no=. When set to =yes=, Org removes the first column, processes
+ the table, puts back the first column, and then writes the table to
+ the results block. The default is =no=, which means Org does not
+ pre-process the first column. Note that Emacs Lisp code blocks
+ ignore =rownames= header argument because of the ease of
+ table-handling in Emacs.
+
+ #+begin_example
+ ,#+NAME: with-rownames
+ | one | 1 | 2 | 3 | 4 | 5 |
+ | two | 6 | 7 | 8 | 9 | 10 |
+
+ ,#+BEGIN_SRC python :var tab=with-rownames :rownames yes
+ return [[val + 10 for val in row] for row in tab]
+ ,#+END_SRC
+
+ ,#+RESULTS:
+ | one | 11 | 12 | 13 | 14 | 15 |
+ | two | 16 | 17 | 18 | 19 | 20 |
+ #+end_example
- list ::
- A simple named list.
+ A simple named list.
- #+begin_example
- ,#+NAME: example-list
- - simple
- - not
- - nested
- - list
+ #+begin_example
+ ,#+NAME: example-list
+ - simple
+ - not
+ - nested
+ - list
- ,#+BEGIN_SRC emacs-lisp :var x=example-list
- (print x)
- ,#+END_SRC
+ ,#+BEGIN_SRC emacs-lisp :var x=example-list
+ (print x)
+ ,#+END_SRC
- ,#+RESULTS:
- | simple | list |
- #+end_example
+ ,#+RESULTS:
+ | simple | list |
+ #+end_example
- Note that only the top level list items are passed along. Nested
- list items are ignored.
+ Note that only the top level list items are passed along. Nested
+ list items are ignored.
- code block without arguments ::
- A code block name, as assigned by =NAME= keyword from the example
- above, optionally followed by parentheses.
+ A code block name, as assigned by =NAME= keyword from the example
+ above, optionally followed by parentheses.
- #+begin_example
- ,#+BEGIN_SRC emacs-lisp :var length=table-length()
- (* 2 length)
- ,#+END_SRC
+ #+begin_example
+ ,#+BEGIN_SRC emacs-lisp :var length=table-length()
+ (* 2 length)
+ ,#+END_SRC
- ,#+RESULTS:
- : 8
- #+end_example
+ ,#+RESULTS:
+ : 8
+ #+end_example
- code block with arguments ::
- A code block name, as assigned by =NAME= keyword, followed by
- parentheses and optional arguments passed within the parentheses.
+ A code block name, as assigned by =NAME= keyword, followed by
+ parentheses and optional arguments passed within the parentheses.
- #+begin_example
- ,#+NAME: double
- ,#+BEGIN_SRC emacs-lisp :var input=8
- (* 2 input)
- ,#+END_SRC
+ #+begin_example
+ ,#+NAME: double
+ ,#+BEGIN_SRC emacs-lisp :var input=8
+ (* 2 input)
+ ,#+END_SRC
- ,#+RESULTS: double
- : 16
+ ,#+RESULTS: double
+ : 16
- ,#+NAME: squared
- ,#+BEGIN_SRC emacs-lisp :var input=double(input=1)
- (* input input)
- ,#+END_SRC
+ ,#+NAME: squared
+ ,#+BEGIN_SRC emacs-lisp :var input=double(input=1)
+ (* input input)
+ ,#+END_SRC
- ,#+RESULTS: squared
- : 4
- #+end_example
+ ,#+RESULTS: squared
+ : 4
+ #+end_example
- literal example ::
- A literal example block named with a =NAME= keyword.
+ A literal example block named with a =NAME= keyword.
- #+begin_example
- ,#+NAME: literal-example
- ,#+BEGIN_EXAMPLE
- A literal example
- on two lines
- ,#+END_EXAMPLE
+ #+begin_example
+ ,#+NAME: literal-example
+ ,#+BEGIN_EXAMPLE
+ A literal example
+ on two lines
+ ,#+END_EXAMPLE
- ,#+NAME: read-literal-example
- ,#+BEGIN_SRC emacs-lisp :var x=literal-example
- (concatenate #'string x " for you.")
- ,#+END_SRC
+ ,#+NAME: read-literal-example
+ ,#+BEGIN_SRC emacs-lisp :var x=literal-example
+ (concatenate #'string x " for you.")
+ ,#+END_SRC
- ,#+RESULTS: read-literal-example
- : A literal example
- : on two lines for you.
- #+end_example
+ ,#+RESULTS: read-literal-example
+ : A literal example
+ : on two lines for you.
+ #+end_example
Indexing variable values enables referencing portions of a variable.
Indexes are 0 based with negative values counting backwards from the
@@ -16702,20 +16835,20 @@ interpreter process.
- =none= ::
- Default. Each code block gets a new interpreter process to
- execute. The process terminates once the block is evaluated.
+ Default. Each code block gets a new interpreter process to execute.
+ The process terminates once the block is evaluated.
- {{{var(STRING)}}} ::
- Any string besides =none= turns that string into the name of that
- session. For example, =:session STRING= names it =STRING=. If
- =session= has no value, then the session name is derived from the
- source language identifier. Subsequent blocks with the same
- source code language use the same session. Depending on the
- language, state variables, code from other blocks, and the
- overall interpreted environment may be shared. Some interpreted
- languages support concurrent sessions when subsequent source code
- language blocks change session names.
+ Any string besides =none= turns that string into the name of that
+ session. For example, =:session STRING= names it =STRING=. If
+ =session= has no value, then the session name is derived from the
+ source language identifier. Subsequent blocks with the same source
+ code language use the same session. Depending on the language,
+ state variables, code from other blocks, and the overall interpreted
+ environment may be shared. Some interpreted languages support
+ concurrent sessions when subsequent source code language blocks
+ change session names.
Only languages that provide interactive evaluation can have session
support. Not all languages provide this support, such as C and ditaa.
@@ -16731,13 +16864,15 @@ for those code blocks running in a session.
#+cindex: working directory, in a code block
#+cindex: @samp{dir}, header argument
+#+cindex: @samp{mkdirp}, header argument
The =dir= header argument specifies the default directory during code
block execution. If it is absent, then the directory associated with
-the current buffer is used. In other words, supplying =:dir PATH=
-temporarily has the same effect as changing the current directory with
-{{{kbd(M-x cd PATH)}}}, and then not setting =dir=. Under the
-surface, =dir= simply sets the value of the Emacs variable
-~default-directory~.
+the current buffer is used. In other words, supplying =:dir
+DIRECTORY= temporarily has the same effect as changing the current
+directory with {{{kbd(M-x cd RET DIRECTORY)}}}, and then not setting
+=dir=. Under the surface, =dir= simply sets the value of the Emacs
+variable ~default-directory~. Setting =mkdirp= header argument to
+a non-~nil~ value creates the directory, if necessary.
For example, to save the plot file in the =Work/= folder of the home
directory---notice tilde is expanded:
@@ -16826,13 +16961,13 @@ See [[*Languages]] to enable other languages.
#+kindex: C-c C-v e
#+findex: org-babel-execute-src-block
Org provides many ways to execute code blocks. {{{kbd(C-c C-c)}}} or
-{{{kbd(C-c C-v e)}}} with the point on a code block[fn:140] calls the
+{{{kbd(C-c C-v e)}}} with the point on a code block[fn:139] calls the
~org-babel-execute-src-block~ function, which executes the code in the
block, collects the results, and inserts them in the buffer.
#+cindex: @samp{CALL}, keyword
#+vindex: org-babel-inline-result-wrap
-By calling a named code block[fn:141] from an Org mode buffer or
+By calling a named code block[fn:140] from an Org mode buffer or
a table. Org can call the named code blocks from the current Org mode
buffer or from the "Library of Babel" (see [[*Library of Babel]]).
@@ -16856,42 +16991,41 @@ variable ~org-babel-inline-result-wrap~, which by default is set to
- =<name>= ::
- This is the name of the code block (see [[*Structure of Code
- Blocks]]) to be evaluated in the current document. If the block is
- located in another file, start =<name>= with the file name
- followed by a colon. For example, in order to execute a block
- named =clear-data= in =file.org=, you can write the following:
+ This is the name of the code block (see [[*Structure of Code Blocks]])
+ to be evaluated in the current document. If the block is located in
+ another file, start =<name>= with the file name followed by
+ a colon. For example, in order to execute a block named =clear-data=
+ in =file.org=, you can write the following:
- : #+CALL: file.org:clear-data()
+ : #+CALL: file.org:clear-data()
- =<arguments>= ::
- Org passes arguments to the code block using standard function
- call syntax. For example, a =#+CALL:= line that passes =4= to
- a code block named =double=, which declares the header argument
- =:var n=2=, would be written as:
+ Org passes arguments to the code block using standard function call
+ syntax. For example, a =#+CALL:= line that passes =4= to a code
+ block named =double=, which declares the header argument =:var n=2=,
+ would be written as:
- : #+CALL: double(n=4)
+ : #+CALL: double(n=4)
- #+texinfo: @noindent
- Note how this function call syntax is different from the header
- argument syntax.
+ #+texinfo: @noindent
+ Note how this function call syntax is different from the header
+ argument syntax.
- =<inside header arguments>= ::
- Org passes inside header arguments to the named code block using
- the header argument syntax. Inside header arguments apply to
- code block evaluation. For example, =[:results output]= collects
- results printed to stdout during code execution of that block.
- Note how this header argument syntax is different from the
- function call syntax.
+ Org passes inside header arguments to the named code block using the
+ header argument syntax. Inside header arguments apply to code block
+ evaluation. For example, =[:results output]= collects results
+ printed to stdout during code execution of that block. Note how
+ this header argument syntax is different from the function call
+ syntax.
- =<end header arguments>= ::
- End header arguments affect the results returned by the code
- block. For example, =:results html= wraps the results in
- a =#+BEGIN_EXPORT html= block before inserting the results in the
- Org buffer.
+ End header arguments affect the results returned by the code block.
+ For example, =:results html= wraps the results in a =#+BEGIN_EXPORT
+ html= block before inserting the results in the Org buffer.
*** Limit code block evaluation
:PROPERTIES:
@@ -16906,21 +17040,21 @@ evaluating untrusted code blocks by prompting for a confirmation.
- =never= or =no= ::
- Org never evaluates the source code.
+ Org never evaluates the source code.
- =query= ::
- Org prompts the user for permission to evaluate the source code.
+ Org prompts the user for permission to evaluate the source code.
- =never-export= or =no-export= ::
- Org does not evaluate the source code when exporting, yet the
- user can evaluate it interactively.
+ Org does not evaluate the source code when exporting, yet the user
+ can evaluate it interactively.
- =query-export= ::
- Org prompts the user for permission to evaluate the source code
- during export.
+ Org prompts the user for permission to evaluate the source code
+ during export.
If =eval= header argument is not set, then Org determines whether to
evaluate the source code from the ~org-confirm-babel-evaluate~
@@ -16962,18 +17096,17 @@ The =cache= header argument can have one of two values: =yes= or =no=.
- =no= ::
- Default. No caching of results; code block evaluated every
- time.
+ Default. No caching of results; code block evaluated every time.
- =yes= ::
- Whether to run the code or return the cached results is
- determined by comparing the SHA1 hash value of the combined code
- block and arguments passed to it. This hash value is packed on
- the =#+RESULTS:= line from previous evaluation. When hash values
- match, Org does not evaluate the code block. When hash values
- mismatch, Org evaluates the code block, inserts the results,
- recalculates the hash value, and updates =#+RESULTS:= line.
+ Whether to run the code or return the cached results is determined
+ by comparing the SHA1 hash value of the combined code block and
+ arguments passed to it. This hash value is packed on the
+ =#+RESULTS:= line from previous evaluation. When hash values match,
+ Org does not evaluate the code block. When hash values mismatch,
+ Org evaluates the code block, inserts the results, recalculates the
+ hash value, and updates =#+RESULTS:= line.
In this example, both functions are cached. But =caller= runs only if
the result from =random= has changed since the last run.
@@ -17009,23 +17142,22 @@ header arguments working together. The primary determinant, however,
is the =results= header argument. It accepts four classes of options.
Each code block can take only one option per class:
-- collection ::
+- Collection ::
- For how the results should be collected from the code block;
+ For how the results should be collected from the code block;
-- type ::
+- Type ::
- For which type of result the code block will return; affects how
- Org processes and inserts results in the Org buffer;
+ For which type of result the code block will return; affects how Org
+ processes and inserts results in the Org buffer;
-- format ::
+- Format ::
- For the result; affects how Org processes and inserts results in
- the Org buffer;
+ For the result; affects how Org processes results;
-- handling ::
+- Handling ::
- For processing results after evaluation of the code block;
+ For inserting results once they are properly formatted.
*** Collection
:PROPERTIES:
@@ -17037,67 +17169,66 @@ they are mutually exclusive.
- =value= ::
- Default. Functional mode. Org gets the value by wrapping the
- code in a function definition in the language of the source
- block. That is why when using =:results value=, code should
- execute like a function and return a value. For languages like
- Python, an explicit ~return~ statement is mandatory when using
- =:results value=. Result is the value returned by the last
- statement in the code block.
-
- When evaluating the code block in a session (see [[*Environment of
- a Code Block]]), Org passes the code to an interpreter running as
- an interactive Emacs inferior process. Org gets the value from
- the source code interpreter's last statement output. Org has to
- use language-specific methods to obtain the value. For example,
- from the variable ~_~ in Python and Ruby, and the value of
- ~.Last.value~ in R.
+ Default. Functional mode. Org gets the value by wrapping the code
+ in a function definition in the language of the source block. That
+ is why when using =:results value=, code should execute like
+ a function and return a value. For languages like Python, an
+ explicit ~return~ statement is mandatory when using =:results
+ value=. Result is the value returned by the last statement in the
+ code block.
+
+ When evaluating the code block in a session (see [[*Environment of
+ a Code Block]]), Org passes the code to an interpreter running as an
+ interactive Emacs inferior process. Org gets the value from the
+ source code interpreter's last statement output. Org has to use
+ language-specific methods to obtain the value. For example, from
+ the variable ~_~ in Python and Ruby, and the value of ~.Last.value~
+ in R.
- =output= ::
- Scripting mode. Org passes the code to an external process
- running the interpreter. Org returns the contents of the
- standard output stream as text results.
-
- When using a session, Org passes the code to the interpreter
- running as an interactive Emacs inferior process. Org
- concatenates any text output from the interpreter and returns the
- collection as a result.
-
- Note that this collection is not the same as that would be
- collected from stdout of a non-interactive interpreter running as
- an external process. Compare for example these two blocks:
-
- #+begin_example
- ,#+BEGIN_SRC python :results output
- print "hello"
- 2
- print "bye"
- ,#+END_SRC
-
- ,#+RESULTS:
- : hello
- : bye
- #+end_example
-
- In the above non-session mode, the "2" is not printed; so it does
- not appear in results.
-
- #+begin_example
- ,#+BEGIN_SRC python :results output :session
- print "hello"
- 2
- print "bye"
- ,#+END_SRC
-
- ,#+RESULTS:
- : hello
- : 2
- : bye
- #+end_example
-
- In the above session, the interactive interpreter receives and
- prints "2". Results show that.
+ Scripting mode. Org passes the code to an external process running
+ the interpreter. Org returns the contents of the standard output
+ stream as text results.
+
+ When using a session, Org passes the code to the interpreter running
+ as an interactive Emacs inferior process. Org concatenates any text
+ output from the interpreter and returns the collection as a result.
+
+ Note that this collection is not the same as that would be collected
+ from stdout of a non-interactive interpreter running as an external
+ process. Compare for example these two blocks:
+
+ #+begin_example
+ ,#+BEGIN_SRC python :results output
+ print "hello"
+ 2
+ print "bye"
+ ,#+END_SRC
+
+ ,#+RESULTS:
+ : hello
+ : bye
+ #+end_example
+
+ In the above non-session mode, the "2" is not printed; so it does
+ not appear in results.
+
+ #+begin_example
+ ,#+BEGIN_SRC python :results output :session
+ print "hello"
+ 2
+ print "bye"
+ ,#+END_SRC
+
+ ,#+RESULTS:
+ : hello
+ : 2
+ : bye
+ #+end_example
+
+ In the above session, the interactive interpreter receives and
+ prints "2". Results show that.
*** Type
:PROPERTIES:
@@ -17111,105 +17242,103 @@ default behavior is to automatically determine the result type.
#+attr_texinfo: :sep ,
- =table=, =vector= ::
- Interpret the results as an Org table. If the result is a single
- value, create a table with one row and one column. Usage
- example: =:results value table=.
-
- #+cindex: @samp{hlines}, header argument
- In-between each table row or below the table headings, sometimes
- results have horizontal lines, which are also known as "hlines".
- The =hlines= argument with the default =no= value strips such
- lines from the input table. For most code, this is desirable, or
- else those =hline= symbols raise unbound variable errors.
- A =yes= accepts such lines, as demonstrated in the following
- example.
-
- #+begin_example
- ,#+NAME: many-cols
- | a | b | c |
- |---+---+---|
- | d | e | f |
- |---+---+---|
- | g | h | i |
-
- ,#+NAME: no-hline
- ,#+BEGIN_SRC python :var tab=many-cols :hlines no
- return tab
- ,#+END_SRC
-
- ,#+RESULTS: no-hline
- | a | b | c |
- | d | e | f |
- | g | h | i |
-
- ,#+NAME: hlines
- ,#+BEGIN_SRC python :var tab=many-cols :hlines yes
- return tab
- ,#+END_SRC
-
- ,#+RESULTS: hlines
- | a | b | c |
- |---+---+---|
- | d | e | f |
- |---+---+---|
- | g | h | i |
- #+end_example
+ Interpret the results as an Org table. If the result is a single
+ value, create a table with one row and one column. Usage example:
+ =:results value table=.
+
+ #+cindex: @samp{hlines}, header argument
+ In-between each table row or below the table headings, sometimes
+ results have horizontal lines, which are also known as "hlines".
+ The =hlines= argument with the default =no= value strips such lines
+ from the input table. For most code, this is desirable, or else
+ those =hline= symbols raise unbound variable errors. A =yes=
+ accepts such lines, as demonstrated in the following example.
+
+ #+begin_example
+ ,#+NAME: many-cols
+ | a | b | c |
+ |---+---+---|
+ | d | e | f |
+ |---+---+---|
+ | g | h | i |
+
+ ,#+NAME: no-hline
+ ,#+BEGIN_SRC python :var tab=many-cols :hlines no
+ return tab
+ ,#+END_SRC
+
+ ,#+RESULTS: no-hline
+ | a | b | c |
+ | d | e | f |
+ | g | h | i |
+
+ ,#+NAME: hlines
+ ,#+BEGIN_SRC python :var tab=many-cols :hlines yes
+ return tab
+ ,#+END_SRC
+
+ ,#+RESULTS: hlines
+ | a | b | c |
+ |---+---+---|
+ | d | e | f |
+ |---+---+---|
+ | g | h | i |
+ #+end_example
- =list= ::
- Interpret the results as an Org list. If the result is a single
- value, create a list of one element.
+ Interpret the results as an Org list. If the result is a single
+ value, create a list of one element.
- =scalar=, =verbatim= ::
- Interpret literally and insert as quoted text. Do not create
- a table. Usage example: =:results value verbatim=.
+ Interpret literally and insert as quoted text. Do not create
+ a table. Usage example: =:results value verbatim=.
- =file= ::
- Interpret as a filename. Save the results of execution of the
- code block to that file, then insert a link to it. You can
- control both the filename and the description associated to the
- link.
-
- #+cindex: @samp{file}, header argument
- #+cindex: @samp{output-dir}, header argument
- Org first tries to generate the filename from the value of the
- =file= header argument and the directory specified using the
- =output-dir= header arguments. If =output-dir= is not specified,
- Org assumes it is the current directory.
-
- #+begin_example
- ,#+BEGIN_SRC asymptote :results value file :file circle.pdf :output-dir img/
- size(2cm);
- draw(unitcircle);
- ,#+END_SRC
- #+end_example
-
- #+cindex: @samp{file-ext}, header argument
- If =file= is missing, Org generates the base name of the output
- file from the name of the code block, and its extension from the
- =file-ext= header argument. In that case, both the name and the
- extension are mandatory[fn:142].
-
- #+begin_example
- ,#+name: circle
- ,#+BEGIN_SRC asymptote :results value file :file-ext pdf
- size(2cm);
- draw(unitcircle);
- ,#+END_SRC
- #+end_example
-
- #+cindex: @samp{file-desc}, header argument
- The =file-desc= header argument defines the description (see
- [[*Link Format]]) for the link. If =file-desc= has no value, Org
- uses the generated file name for both the "link" and
- "description" parts of the link.
-
- #+cindex: @samp{sep}, header argument
- By default, Org assumes that a table written to a file has
- TAB-delimited output. You can choose a different separator with
- the =sep= header argument.
+ Interpret as a filename. Save the results of execution of the code
+ block to that file, then insert a link to it. You can control both
+ the filename and the description associated to the link.
+
+ #+cindex: @samp{file}, header argument
+ #+cindex: @samp{output-dir}, header argument
+ Org first tries to generate the filename from the value of the
+ =file= header argument and the directory specified using the
+ =output-dir= header arguments. If =output-dir= is not specified,
+ Org assumes it is the current directory.
+
+ #+begin_example
+ ,#+BEGIN_SRC asymptote :results value file :file circle.pdf :output-dir img/
+ size(2cm);
+ draw(unitcircle);
+ ,#+END_SRC
+ #+end_example
+
+ #+cindex: @samp{file-ext}, header argument
+ If =file= header argument is missing, Org generates the base name of
+ the output file from the name of the code block, and its extension
+ from the =file-ext= header argument. In that case, both the name
+ and the extension are mandatory.
+
+ #+begin_example
+ ,#+name: circle
+ ,#+BEGIN_SRC asymptote :results value file :file-ext pdf
+ size(2cm);
+ draw(unitcircle);
+ ,#+END_SRC
+ #+end_example
+
+ #+cindex: @samp{file-desc}, header argument
+ The =file-desc= header argument defines the description (see
+ [[*Link Format]]) for the link. If =file-desc= has no value, Org
+ uses the generated file name for both the "link" and
+ "description" parts of the link.
+
+ #+cindex: @samp{sep}, header argument
+ By default, Org assumes that a table written to a file has
+ TAB-delimited output. You can choose a different separator with
+ the =sep= header argument.
*** Format
:PROPERTIES:
@@ -17223,57 +17352,57 @@ follows from the type specified above.
#+attr_texinfo: :sep ,
- =code= ::
- Result enclosed in a code block. Useful for parsing. Usage
- example: =:results value code=.
+ Result enclosed in a code block. Useful for parsing. Usage
+ example: =:results value code=.
- =drawer= ::
- Result wrapped in a =RESULTS= drawer. Useful for containing
- =raw= or =org= results for later scripting and automated
- processing. Usage example: =:results value drawer=.
+ Result wrapped in a =RESULTS= drawer. Useful for containing =raw=
+ or =org= results for later scripting and automated processing.
+ Usage example: =:results value drawer=.
- =html= ::
- Results enclosed in a =BEGIN_EXPORT html= block. Usage example:
- =:results value html=.
+ Results enclosed in a =BEGIN_EXPORT html= block. Usage example:
+ =:results value html=.
- =latex= ::
- Results enclosed in a =BEGIN_EXPORT latex= block. Usage example:
- =:results value latex=.
+ Results enclosed in a =BEGIN_EXPORT latex= block. Usage example:
+ =:results value latex=.
- =link=, =graphics= ::
- Result is a link to the file specified in =:file= header
- argument. However, unlike plain =:file=, nothing is written to
- the disk. The block is used for its side-effects only, as in the
- following example:
+ Result is a link to the file specified in =:file= header argument.
+ However, unlike plain =:file=, nothing is written to the disk. The
+ block is used for its side-effects only, as in the following
+ example:
- #+begin_example
- ,#+begin_src shell :results link :file "download.tar.gz"
- wget -c "http://example.com/download.tar.gz"
- ,#+end_src
- #+end_example
+ #+begin_example
+ ,#+begin_src shell :results link :file "download.tar.gz"
+ wget -c "http://example.com/download.tar.gz"
+ ,#+end_src
+ #+end_example
- =org= ::
- Results enclosed in a =BEGIN_SRC org= block. For comma-escape,
- either {{{kbd(TAB)}}} in the block, or export the file. Usage
- example: =:results value org=.
+ Results enclosed in a =BEGIN_SRC org= block. For comma-escape,
+ either {{{kbd(TAB)}}} in the block, or export the file. Usage
+ example: =:results value org=.
- =pp= ::
- Result converted to pretty-print source code. Enclosed in a code
- block. Languages supported: Emacs Lisp, Python, and Ruby. Usage
- example: =:results value pp=.
+ Result converted to pretty-print source code. Enclosed in a code
+ block. Languages supported: Emacs Lisp, Python, and Ruby. Usage
+ example: =:results value pp=.
- =raw= ::
- Interpreted as raw Org mode. Inserted directly into the buffer.
- Aligned if it is a table. Usage example: =:results value raw=.
+ Interpreted as raw Org mode. Inserted directly into the buffer.
+ Aligned if it is a table. Usage example: =:results value raw=.
#+cindex: @samp{wrap}, header argument
-The =wrap= header argument unconditionnally marks the results block by
+The =wrap= header argument unconditionally marks the results block by
appending strings to =#+BEGIN_= and =#+END_=. If no string is
specified, Org wraps the results in a =#+BEGIN_results=
... =#+END_results= block. It takes precedent over the =results=
@@ -17299,25 +17428,25 @@ Handling options after collecting the results.
- =silent= ::
- Do not insert results in the Org mode buffer, but echo them in
- the minibuffer. Usage example: =:results output silent=.
+ Do not insert results in the Org mode buffer, but echo them in the
+ minibuffer. Usage example: =:results output silent=.
- =replace= ::
- Default. Insert results in the Org buffer. Remove previous
- results. Usage example: =:results output replace=.
+ Default. Insert results in the Org buffer. Remove previous
+ results. Usage example: =:results output replace=.
- =append= ::
- Append results to the Org buffer. Latest results are at the
- bottom. Does not remove previous results. Usage example:
- =:results output append=.
+ Append results to the Org buffer. Latest results are at the bottom.
+ Does not remove previous results. Usage example: =:results output
+ append=.
- =prepend= ::
- Prepend results to the Org buffer. Latest results are at the
- top. Does not remove previous results. Usage example: =:results
- output prepend=.
+ Prepend results to the Org buffer. Latest results are at the top.
+ Does not remove previous results. Usage example: =:results output
+ prepend=.
*** Post-processing
:PROPERTIES:
@@ -17407,24 +17536,24 @@ file is exported to, say, HTML or LaTeX formats.
- =code= ::
- The default. The body of code is included into the exported
- file. Example: =:exports code=.
+ The default. The body of code is included into the exported file.
+ Example: =:exports code=.
- =results= ::
- The results of evaluation of the code is included in the exported
- file. Example: =:exports results=.
+ The results of evaluation of the code is included in the exported
+ file. Example: =:exports results=.
- =both= ::
- Both the code and results of evaluation are included in the
- exported file. Example: =:exports both=.
+ Both the code and results of evaluation are included in the exported
+ file. Example: =:exports both=.
- =none= ::
- Neither the code nor the results of evaluation is included in the
- exported file. Whether the code is evaluated at all depends on
- other options. Example: =:exports none=.
+ Neither the code nor the results of evaluation is included in the
+ exported file. Whether the code is evaluated at all depends on
+ other options. Example: =:exports none=.
#+vindex: org-export-use-babel
To stop Org from evaluating code blocks to speed exports, use the
@@ -17479,27 +17608,27 @@ to source file(s).
- =yes= ::
- Export the code block to source file. The file name for the
- source file is derived from the name of the Org file, and the
- file extension is derived from the source code language
- identifier. Example: =:tangle yes=.
+ Export the code block to source file. The file name for the source
+ file is derived from the name of the Org file, and the file
+ extension is derived from the source code language identifier.
+ Example: =:tangle yes=.
- =no= ::
- The default. Do not extract the code in a source code file.
- Example: =:tangle no=.
+ The default. Do not extract the code in a source code file.
+ Example: =:tangle no=.
- {{{var(FILENAME)}}} ::
- Export the code block to source file whose file name is derived
- from any string passed to the =tangle= header argument. Org
- derives the file name as being relative to the directory of the
- Org file's location. Example: =:tangle FILENAME=.
+ Export the code block to source file whose file name is derived from
+ any string passed to the =tangle= header argument. Org derives the
+ file name as being relative to the directory of the Org file's
+ location. Example: =:tangle FILENAME=.
#+cindex: @samp{mkdirp}, header argument
The =mkdirp= header argument creates parent directories for tangled
-files if the directory does not exist. =yes= enables directory
-creation and =no= inhibits directory creation.
+files if the directory does not exist. A =yes= value enables
+directory creation whereas =no= inhibits it.
#+cindex: @samp{comments}, header argument
The =comments= header argument controls inserting comments into
@@ -17508,32 +17637,32 @@ already exist in the code block.
- =no= ::
- The default. Do not insert any extra comments during tangling.
+ The default. Do not insert any extra comments during tangling.
- =link= ::
- Wrap the code block in comments. Include links pointing back to
- the place in the Org file from where the code was tangled.
+ Wrap the code block in comments. Include links pointing back to the
+ place in the Org file from where the code was tangled.
- =yes= ::
- Kept for backward compatibility; same as =link=.
+ Kept for backward compatibility; same as =link=.
- =org= ::
- Nearest headline text from Org file is inserted as comment. The
- exact text that is inserted is picked from the leading context of
- the source block.
+ Nearest headline text from Org file is inserted as comment. The
+ exact text that is inserted is picked from the leading context of
+ the source block.
- =both= ::
- Includes both =link= and =org= options.
+ Includes both =link= and =org= options.
- =noweb= ::
- Includes =link= option, expands Noweb references (see [[*Noweb
- Reference Syntax]]), and wraps them in link comments inside the
- body of the code block.
+ Includes =link= option, expands Noweb references (see [[*Noweb
+ Reference Syntax]]), and wraps them in link comments inside the body
+ of the code block.
#+cindex: @samp{padline}, header argument
The =padline= header argument controls insertion of newlines to pad
@@ -17541,12 +17670,12 @@ source code in the tangled file.
- =yes= ::
- Default. Insert a newline before and after each code block in
- the tangled file.
+ Default. Insert a newline before and after each code block in the
+ tangled file.
- =no= ::
- Do not insert newlines to pad the tangled code blocks.
+ Do not insert newlines to pad the tangled code blocks.
#+cindex: @samp{shebang}, header argument
The =shebang= header argument can turn results into executable script
@@ -17583,17 +17712,17 @@ expanded anyway.
- ~org-babel-tangle~ ::
- #+findex: org-babel-tangle
- #+kindex: C-c C-v t
- Tangle the current file. Bound to {{{kbd(C-c C-v t)}}}.
+ #+findex: org-babel-tangle
+ #+kindex: C-c C-v t
+ Tangle the current file. Bound to {{{kbd(C-c C-v t)}}}.
- With prefix argument only tangle the current code block.
+ With prefix argument only tangle the current code block.
- ~org-babel-tangle-file~ ::
- #+findex: org-babel-tangle-file
- #+kindex: C-c C-v f
- Choose a file to tangle. Bound to {{{kbd(C-c C-v f)}}}.
+ #+findex: org-babel-tangle-file
+ #+kindex: C-c C-v f
+ Choose a file to tangle. Bound to {{{kbd(C-c C-v f)}}}.
*** Hooks
:PROPERTIES:
@@ -17602,10 +17731,10 @@ expanded anyway.
- ~org-babel-post-tangle-hook~ ::
- #+vindex: org-babel-post-tangle-hook
- This hook is run from within code files tangled by
- ~org-babel-tangle~, making it suitable for post-processing,
- compilation, and evaluation of code in the tangled files.
+ #+vindex: org-babel-post-tangle-hook
+ This hook is run from within code files tangled by
+ ~org-babel-tangle~, making it suitable for post-processing,
+ compilation, and evaluation of code in the tangled files.
*** Jumping between code and Org
:PROPERTIES:
@@ -17634,29 +17763,29 @@ code block header arguments:
Code blocks in the following languages are supported.
#+attr_texinfo: :columns 0.20 0.35 0.20 0.20
-| Language | Identifier | Language | Identifier |
-|------------+---------------+---------------+--------------|
-| Asymptote | =asymptote= | Lua | =lua= |
-| Awk | =awk= | MATLAB | =matlab= |
-| C | =C= | Mscgen | =mscgen= |
-| C++ | =C++=[fn:143] | OCaml | =ocaml= |
-| Clojure | =clojure= | Octave | =octave= |
-| CSS | =css= | Org mode | =org= |
-| D | =D=[fn:144] | Oz | =oz= |
-| ditaa | =ditaa= | Perl | =perl= |
-| Emacs Calc | =calc= | Plantuml | =plantuml= |
-| Emacs Lisp | =emacs-lisp= | Processing.js | =processing= |
-| Fortran | =fortran= | Python | =python= |
-| Gnuplot | =gnuplot= | R | =R= |
-| GNU Screen | =screen= | Ruby | =ruby= |
-| Graphviz | =dot= | Sass | =sass= |
-| Haskell | =haskell= | Scheme | =scheme= |
-| Java | =java= | Sed | =sed= |
-| Javascript | =js= | shell | =sh= |
-| LaTeX | =latex= | SQL | =sql= |
-| Ledger | =ledger= | SQLite | =sqlite= |
-| Lilypond | =lilypond= | Vala | =vala= |
-| Lisp | =lisp= | | |
+| Language | Identifier | Language | Identifier |
+|------------+---------------+----------------+--------------|
+| Asymptote | =asymptote= | Lisp | =lisp= |
+| Awk | =awk= | Lua | =lua= |
+| C | =C= | MATLAB | =matlab= |
+| C++ | =C++=[fn:141] | Mscgen | =mscgen= |
+| Clojure | =clojure= | Objective Caml | =ocaml= |
+| CSS | =css= | Octave | =octave= |
+| D | =D=[fn:142] | Org mode | =org= |
+| ditaa | =ditaa= | Oz | =oz= |
+| Emacs Calc | =calc= | Perl | =perl= |
+| Emacs Lisp | =emacs-lisp= | Plantuml | =plantuml= |
+| Eshell | =eshell= | Processing.js | =processing= |
+| Fortran | =fortran= | Python | =python= |
+| Gnuplot | =gnuplot= | R | =R= |
+| GNU Screen | =screen= | Ruby | =ruby= |
+| Graphviz | =dot= | Sass | =sass= |
+| Haskell | =haskell= | Scheme | =scheme= |
+| Java | =java= | Sed | =sed= |
+| Javascript | =js= | shell | =sh= |
+| LaTeX | =latex= | SQL | =sql= |
+| Ledger | =ledger= | SQLite | =sqlite= |
+| Lilypond | =lilypond= | Vala | =vala= |
Additional documentation for some languages is at
https://orgmode.org/worg/org-contrib/babel/languages.html.
@@ -17694,7 +17823,7 @@ the following enables execution of Clojure code blocks:
#+kindex: C-c '
Use {{{kbd(C-c ')}}} to edit the current code block. It opens a new
-major-mode edit buffer containing the body of the source code block,
+major mode edit buffer containing the body of the source code block,
ready for any edits. Use {{{kbd(C-c ')}}} again to close the buffer
and return to the Org buffer.
@@ -17714,34 +17843,34 @@ group ~org-edit-structure~.
- ~org-src-lang-modes~ ::
- #+vindex: org-src-lang-modes
- If an Emacs major-mode named ~<LANG>-mode~ exists, where
- {{{var(<LANG>)}}} is the language identifier from code block's
- header line, then the edit buffer uses that major mode. Use this
- variable to arbitrarily map language identifiers to major modes.
+ #+vindex: org-src-lang-modes
+ If an Emacs major-mode named ~<LANG>-mode~ exists, where
+ {{{var(<LANG>)}}} is the language identifier from code block's
+ header line, then the edit buffer uses that major mode. Use this
+ variable to arbitrarily map language identifiers to major modes.
- ~org-src-window-setup~ ::
- #+vindex: org-src-window-setup
- For specifying Emacs window arrangement when the new edit buffer
- is created.
+ #+vindex: org-src-window-setup
+ For specifying Emacs window arrangement when the new edit buffer is
+ created.
- ~org-src-preserve-indentation~ ::
- #+cindex: indentation, in code blocks
- #+vindex: org-src-preserve-indentation
- Default is ~nil~. Source code is indented. This indentation
- applies during export or tangling, and depending on the context,
- may alter leading spaces and tabs. When non-~nil~, source code
- is aligned with the leftmost column. No lines are modified
- during export or tangling, which is very useful for white-space
- sensitive languages, such as Python.
+ #+cindex: indentation, in code blocks
+ #+vindex: org-src-preserve-indentation
+ Default is ~nil~. Source code is indented. This indentation
+ applies during export or tangling, and depending on the context, may
+ alter leading spaces and tabs. When non-~nil~, source code is
+ aligned with the leftmost column. No lines are modified during
+ export or tangling, which is very useful for white-space sensitive
+ languages, such as Python.
- ~org-src-ask-before-returning-to-edit-buffer~ ::
- #+vindex: org-src-ask-before-returning-to-edit-buffer
- When ~nil~, Org returns to the edit buffer without further
- prompts. The default prompts for a confirmation.
+ #+vindex: org-src-ask-before-returning-to-edit-buffer
+ When ~nil~, Org returns to the edit buffer without further prompts.
+ The default prompts for a confirmation.
#+vindex: org-src-fontify-natively
#+vindex: org-src-block-faces
@@ -17771,7 +17900,7 @@ for Python and Emacs Lisp languages.
#+cindex: syntax, Noweb
#+cindex: source code, Noweb reference
-Org supports named blocks in Noweb[fn:145] style syntax:
+Org supports named blocks in Noweb[fn:143] style syntax:
: <<CODE-BLOCK-ID>>
@@ -17785,34 +17914,34 @@ tangled, or exported.
- =no= ::
- Default. No expansion of Noweb syntax references in the body of
- the code when evaluating, tangling, or exporting.
+ Default. No expansion of Noweb syntax references in the body of the
+ code when evaluating, tangling, or exporting.
- =yes= ::
- Expansion of Noweb syntax references in the body of the code
- block when evaluating, tangling, or exporting.
+ Expansion of Noweb syntax references in the body of the code block
+ when evaluating, tangling, or exporting.
- =tangle= ::
- Expansion of Noweb syntax references in the body of the code
- block when tangling. No expansion when evaluating or exporting.
+ Expansion of Noweb syntax references in the body of the code block
+ when tangling. No expansion when evaluating or exporting.
- =no-export= ::
- Expansion of Noweb syntax references in the body of the code
- block when evaluating or tangling. No expansion when exporting.
+ Expansion of Noweb syntax references in the body of the code block
+ when evaluating or tangling. No expansion when exporting.
- =strip-export= ::
- Expansion of Noweb syntax references in the body of the code
- block when expanding prior to evaluating or tangling. Removes
- Noweb syntax references when exporting.
+ Expansion of Noweb syntax references in the body of the code block
+ when expanding prior to evaluating or tangling. Removes Noweb
+ syntax references when exporting.
- =eval= ::
- Expansion of Noweb syntax references in the body of the code
- block only before evaluating.
+ Expansion of Noweb syntax references in the body of the code block
+ only before evaluating.
In the following example,
@@ -18201,40 +18330,37 @@ have become an integral part of Emacs and Org provides several
shortcuts.
- {{{kbd(M-TAB)}}} ::
- #+kindex: M-TAB
-
- Complete word at point.
+ #+kindex: M-TAB
- - At the beginning of a headline, complete TODO keywords.
+ Complete word at point.
- - After =\=, complete TeX symbols supported by the exporter.
+ - At the beginning of an empty headline, complete TODO keywords.
- - After =*=, complete headlines in the current buffer so that
- they can be used in search links like:
+ - After =\=, complete TeX symbols supported by the exporter.
- : [[*find this headline]]
+ - After =*=, complete headlines in the current buffer so that they
+ can be used in search links like: =[[*find this headline]]=
- - After =:= in a headline, complete tags. Org deduces the list
- of tags from the =TAGS= in-buffer option (see [[*Setting Tags]]),
- the variable ~org-tag-alist~, or from all tags used in the
- current buffer.
+ - After =:= in a headline, complete tags. Org deduces the list of
+ tags from the =TAGS= in-buffer option (see [[*Setting Tags]]), the
+ variable ~org-tag-alist~, or from all tags used in the current
+ buffer.
- - After =:= and not in a headline, complete property keys. The
- list of keys is constructed dynamically from all keys used in
- the current buffer.
+ - After =:= and not in a headline, complete property keys. The list
+ of keys is constructed dynamically from all keys used in the
+ current buffer.
- - After =[=, complete link abbreviations (see [[*Link
- Abbreviations]]).
+ - After =[=, complete link abbreviations (see [[*Link Abbreviations]]).
- - After =#+=, complete the special keywords like =TYP_TODO= or
- file-specific =OPTIONS=. After option keyword is complete,
- pressing {{{kbd(M-TAB)}}} again inserts example settings for
- this keyword.
+ - After =#+=, complete the special keywords like =TYP_TODO= or
+ file-specific =OPTIONS=. After option keyword is complete,
+ pressing {{{kbd(M-TAB)}}} again inserts example settings for this
+ keyword.
- - After =STARTUP= keyword, complete startup items.
+ - After =STARTUP= keyword, complete startup items.
- - When point is anywhere else, complete dictionary words using
- Ispell.
+ - When point is anywhere else, complete dictionary words using
+ Ispell.
** Structure Templates
:PROPERTIES:
@@ -18249,14 +18375,13 @@ text in such a block.
- {{{kbd(C-c C-\,)}}} (~org-insert-structure-template~) ::
- #+findex: org-insert-structure-template
- #+kindex: C-c C-,
- Prompt for a type of block structure, and insert the block at
- point. If the region is active, it is wrapped in the block.
- First prompts the user for keys, which are used to look up
- a structure type from the variable below. If the key is
- {{{kbd(TAB)}}}, {{{kbd(RET)}}}, or {{{kbd(SPC)}}}, the user is
- prompted to enter a block type.
+ #+findex: org-insert-structure-template
+ #+kindex: C-c C-,
+ Prompt for a type of block structure, and insert the block at point.
+ If the region is active, it is wrapped in the block. First prompts
+ the user for keys, which are used to look up a structure type from
+ the variable below. If the key is {{{kbd(TAB)}}}, {{{kbd(RET)}}},
+ or {{{kbd(SPC)}}}, the user is prompted to enter a block type.
#+vindex: org-structure-template-alist
Available structure types are defined in
@@ -18271,7 +18396,7 @@ Org Tempo expands snippets to structures defined in
~org-structure-template-alist~ and ~org-tempo-keywords-alist~. For
example, {{{kbd(< s TAB)}}} creates a code block. Enable it by
customizing ~org-modules~ or add =(require 'org-tempo)= to your Emacs
-init file[fn:146].
+init file[fn:144].
#+attr_texinfo: :columns 0.1 0.9
| {{{kbd(a)}}} | =#+BEGIN_EXPORT ascii= ... =#+END_EXPORT= |
@@ -18285,24 +18410,6 @@ init file[fn:146].
| {{{kbd(s)}}} | =#+BEGIN_SRC= ... =#+END_SRC= |
| {{{kbd(v)}}} | =#+BEGIN_VERSE= ... =#+END_VERSE= |
-** Escape Character
-
-#+cindex: escape character
-#+cindex: zero width space
-You may sometimes want to write text that looks like Org syntax, but
-should really read as plain text. Org may use a specific escape
-character in some situations, e.g., a backslash in macros (see [[*Macro
-Replacement]]). In the general case, however, we suggest to use the
-zero width space. You can get it with one of the following:
-
-: C-x 8 <RET> zero width space <RET>
-: C-x 8 <RET> 200B <RET>
-
-For example, in order to write =[[1,2]]= as-is in your document, you can
-write this, where =X= denotes the zero width space character:
-
-: [[X1,2]]
-
** Speed Keys
:PROPERTIES:
:DESCRIPTION: Electric commands at the beginning of a headline.
@@ -18332,92 +18439,188 @@ activated, {{{kbd(M-x org-speed-command-help)}}}, or {{{kbd(?)}}} when
point is at the beginning of an Org headline, shows currently active
Speed Keys, including the user-defined ones.
-** Code Evaluation and Security Issues
+** A Cleaner Outline View
:PROPERTIES:
-:DESCRIPTION: Org files evaluate in-line code.
-:ALT_TITLE: Code Evaluation Security
+:DESCRIPTION: Getting rid of leading stars in the outline.
+:ALT_TITLE: Clean View
:END:
+#+cindex: hiding leading stars
+#+cindex: dynamic indentation
+#+cindex: odd-levels-only outlines
+#+cindex: clean outline view
-Unlike plain text, running code comes with risk. Each source code
-block, in terms of risk, is equivalent to an executable file. Org
-therefore puts a few confirmation prompts by default. This is to
-alert the casual user from accidentally running untrusted code.
+Org's outline with stars and no indents can look cluttered for short
+documents. For /book-like/ long documents, the effect is not as
+noticeable. Org provides an alternate stars and indentation scheme,
+as shown on the right in the following table. It displays only one
+star and indents text to line up with the heading:
-For users who do not run code blocks or write code regularly, Org's
-default settings should suffice. However, some users may want to
-tweak the prompts for fewer interruptions. To weigh the risks of
-automatic execution of code blocks, here are some details about code
-evaluation.
+#+begin_example
+,* Top level headline | * Top level headline
+,** Second level | * Second level
+,*** Third level | * Third level
+some text | some text
+,*** Third level | * Third level
+more text | more text
+,* Another top level headline | * Another top level headline
+#+end_example
-Org evaluates code in the following circumstances:
+Org can achieve this in two ways, (1) by just displaying the buffer in
+this way without changing it, or (2) by actually indenting every line
+in the desired amount with hard spaces and hiding leading stars.
-- /Source code blocks/ ::
+*** Org Indent Mode
- Org evaluates source code blocks in an Org file during export.
- Org also evaluates a source code block with the {{{kbd(C-c
- C-c)}}} key chord. Users exporting or running code blocks must
- load files only from trusted sources. Be wary of customizing
- variables that remove or alter default security measures.
-
- #+attr_texinfo: :options org-confirm-babel-evaluate
- #+begin_defopt
- When ~t~, Org prompts the user for confirmation before executing
- each code block. When ~nil~, Org executes code blocks without
- prompting the user for confirmation. When this option is set to
- a custom function, Org invokes the function with these two
- arguments: the source code language and the body of the code
- block. The custom function must return either a ~t~ or ~nil~,
- which determines if the user is prompted. Each source code
- language can be handled separately through this function
- argument.
- #+end_defopt
-
- For example, here is how to execute ditaa code blocks without
- prompting:
-
- #+begin_src emacs-lisp
- (defun my-org-confirm-babel-evaluate (lang body)
- (not (string= lang "ditaa"))) ;don't ask for ditaa
- (setq org-confirm-babel-evaluate #'my-org-confirm-babel-evaluate)
- #+end_src
+#+cindex: Indent mode
+#+findex: org-indent-mode
+To display the buffer in the indented view, activate Org Indent minor
+mode, using {{{kbd(M-x org-indent-mode)}}}. Text lines that are not
+headlines are prefixed with virtual spaces to vertically align with
+the headline text[fn:145].
-- /Following =shell= and =elisp= links/ ::
+#+vindex: org-indent-indentation-per-level
+To make more horizontal space, the headlines are shifted by two
+characters. Configure ~org-indent-indentation-per-level~ variable for
+a different number. Only one star on each headline is visible, the
+rest are masked with the same font color as the background[fn:146].
+
+#+vindex: org-startup-indented
+To globally turn on Org Indent mode for all files, customize the
+variable ~org-startup-indented~. To control it for individual files,
+use =STARTUP= keyword as follows:
- Org has two link types that can directly evaluate code (see
- [[*External Links]]). Because such code is not visible, these links
- have a potential risk. Org therefore prompts the user when it
- encounters such links. The customization variables are:
+: #+STARTUP: indent
+: #+STARTUP: noindent
- #+attr_texinfo: :options org-confirm-shell-link-function
- #+begin_defopt
- Function that prompts the user before executing a shell link.
- #+end_defopt
+*** Hard indentation
- #+attr_texinfo: :options org-confirm-elisp-link-function
- #+begin_defopt
- Function that prompts the user before executing an Emacs Lisp link.
- #+end_defopt
+It is possible to use hard spaces to achieve the indentation instead,
+if the bare ASCII file should have the indented look also outside
+Emacs[fn:147]. With Org's support, you have to indent all lines to
+line up with the outline headers. You would use these settings:
-- /Formulas in tables/ ::
+ #+begin_src emacs-lisp
+ (setq org-adapt-indentation t
+ org-hide-leading-stars t
+ org-odd-levels-only t)
+ #+end_src
+
+- /Indentation of text below headlines/ (~org-adapt-indentation~) ::
+
+ #+vindex: org-adapt-indentation
+ The first setting modifies paragraph filling, line wrapping, and
+ structure editing commands to preserving or adapting the indentation
+ as appropriate.
+
+- /Hiding leading stars/ (~org-hide-leading-stars~) ::
+
+ #+vindex: org-hide-leading-stars
+ #+vindex: org-hide, face
+ The second setting makes leading stars invisible by applying the
+ face ~org-hide~ to them. For per-file preference, use these file
+ =STARTUP= options:
- Formulas in tables (see [[*The Spreadsheet]]) are code that is
- evaluated either by the Calc interpreter, or by the Emacs Lisp
- interpreter.
+ #+begin_example
+ ,#+STARTUP: hidestars
+ ,#+STARTUP: showstars
+ #+end_example
-** Customization
+- /Odd levels/ (~org-odd-levels-only~) ::
+
+ #+vindex: org-odd-levels-only
+ The third setting makes Org use only odd levels, 1, 3, 5, ..., in
+ the outline to create more indentation. On a per-file level,
+ control this with:
+
+ #+begin_example
+ ,#+STARTUP: odd
+ ,#+STARTUP: oddeven
+ #+end_example
+
+ To convert a file between single and double stars layouts, use
+ {{{kbd(M-x org-convert-to-odd-levels)}}} and {{{kbd(M-x
+ org-convert-to-oddeven-levels)}}}.
+
+** Dynamic Headline Numbering
:PROPERTIES:
-:DESCRIPTION: Adapting Org to your taste.
+:DESCRIPTION: Display and update outline numbering.
:END:
-#+cindex: customization
-#+cindex: options, for customization
-#+cindex: variables, for customization
-Org has more than 500 variables for customization. They can be
-accessed through the usual {{{kbd(M-x org-customize)}}} command. Or
-through the Org menu: Org \rarr Customization \rarr Browse Org Group.
+#+cindex: Org Num mode
+#+cindex: number headlines
+The Org Num minor mode, toggled with {{{kbd(M-x org-num-mode)}}},
+displays outline numbering on top of headlines. It also updates it
+automatically upon changes to the structure of the document.
-Org also has per-file settings for some variables (see [[*Summary of
-In-Buffer Settings]]).
+#+vindex: org-num-max-level
+#+vindex: org-num-skip-tags
+#+vindex: org-num-skip-commented
+#+vindex: org-num-skip-unnumbered
+By default, all headlines are numbered. You can limit numbering to
+specific headlines according to their level, tags, =COMMENT= keyword,
+or =UNNUMBERED= property. Set ~org-num-max-level~,
+~org-num-skip-tags~, ~org-num-skip-commented~,
+~org-num-skip-unnumbered~, or ~org-num-skip-footnotes~ accordingly.
+
+#+vindex: org-num-skip-footnotes
+If ~org-num-skip-footnotes~ is non-~nil~, footnotes sections (see
+[[*Creating Footnotes]]) are not numbered either.
+
+#+vindex: org-num-face
+#+vindex: org-num-format-function
+You can control how the numbering is displayed by setting
+~org-num-face~ and ~org-num-format-function~.
+
+** The Very Busy {{{kbd(C-c C-c)}}} Key
+:PROPERTIES:
+:DESCRIPTION: When in doubt, press @kbd{C-c C-c}.
+:END:
+#+kindex: C-c C-c
+#+cindex: @kbd{C-c C-c}, overview
+
+The {{{kbd(C-c C-c)}}} key in Org serves many purposes depending on
+the context. It is probably the most over-worked, multi-purpose key
+combination in Org. Its uses are well documented throughout this
+manual, but here is a consolidated list for easy reference.
+
+- If any highlights shown in the buffer from the creation of a sparse
+ tree, or from clock display, remove such highlights.
+
+- If point is in one of the special =KEYWORD= lines, scan the buffer
+ for these lines and update the information. Also reset the Org file
+ cache used to temporary store the contents of URLs used as values
+ for keywords like =SETUPFILE=.
+
+- If point is inside a table, realign the table.
+
+- If point is on a =TBLFM= keyword, re-apply the formulas to the
+ entire table.
+
+- If the current buffer is a capture buffer, close the note and file
+ it. With a prefix argument, also jump to the target location after
+ saving the note.
+
+- If point is on a =<<<target>>>=, update radio targets and
+ corresponding links in this buffer.
+
+- If point is on a property line or at the start or end of a property
+ drawer, offer property commands.
+
+- If point is at a footnote reference, go to the corresponding
+ definition, and /vice versa/.
+
+- If point is on a statistics cookie, update it.
+
+- If point is in a plain list item with a checkbox, toggle the status
+ of the checkbox.
+
+- If point is on a numbered item in a plain list, renumber the ordered
+ list.
+
+- If point is on the =#+BEGIN= line of a dynamic block, the block is
+ updated.
+
+- If point is at a timestamp, fix the day name in the timestamp.
** Summary of In-Buffer Settings
:PROPERTIES:
@@ -18440,523 +18643,600 @@ changes.
#+attr_texinfo: :sep ,
- =#+ARCHIVE: %s_done= ::
- #+cindex: @samp{ARCHIVE}, keyword
- #+vindex: org-archive-location
- Sets the archive location of the agenda file. The corresponding
- variable is ~org-archive-location~.
+ #+cindex: @samp{ARCHIVE}, keyword
+ #+vindex: org-archive-location
+ Sets the archive location of the agenda file. The corresponding
+ variable is ~org-archive-location~.
- =#+CATEGORY= ::
- #+cindex: @samp{CATEGORY}, keyword
- Sets the category of the agenda file, which applies to the entire
- document.
+ #+cindex: @samp{CATEGORY}, keyword
+ Sets the category of the agenda file, which applies to the entire
+ document.
- =#+COLUMNS: %25ITEM ...= ::
- #+cindex: @samp{COLUMNS}, property
- Set the default format for columns view. This format applies
- when columns view is invoked in locations where no =COLUMNS=
- property applies.
+ #+cindex: @samp{COLUMNS}, property
+ Set the default format for columns view. This format applies when
+ columns view is invoked in locations where no =COLUMNS= property
+ applies.
- =#+CONSTANTS: name1=value1 ...= ::
- #+cindex: @samp{CONSTANTS}, keyword
- #+vindex: org-table-formula-constants
- #+vindex: org-table-formula
- Set file-local values for constants that table formulas can use.
- This line sets the local variable
- ~org-table-formula-constants-local~. The global version of this
- variable is ~org-table-formula-constants~.
+ #+cindex: @samp{CONSTANTS}, keyword
+ #+vindex: org-table-formula-constants
+ #+vindex: org-table-formula
+ Set file-local values for constants that table formulas can use.
+ This line sets the local variable
+ ~org-table-formula-constants-local~. The global version of this
+ variable is ~org-table-formula-constants~.
- =#+FILETAGS: :tag1:tag2:tag3:= ::
- #+cindex: @samp{FILETAGS}, keyword
- Set tags that all entries in the file inherit from, including the
- top-level entries.
+ #+cindex: @samp{FILETAGS}, keyword
+ Set tags that all entries in the file inherit from, including the
+ top-level entries.
- =#+LINK: linkword replace= ::
- #+cindex: @samp{LINK}, keyword
- #+vindex: org-link-abbrev-alist
- Each line specifies one abbreviation for one link. Use multiple
- =LINK= keywords for more, see [[*Link Abbreviations]]. The
- corresponding variable is ~org-link-abbrev-alist~.
+ #+cindex: @samp{LINK}, keyword
+ #+vindex: org-link-abbrev-alist
+ Each line specifies one abbreviation for one link. Use multiple
+ =LINK= keywords for more, see [[*Link Abbreviations]]. The
+ corresponding variable is ~org-link-abbrev-alist~.
- =#+PRIORITIES: highest lowest default= ::
- #+cindex: @samp{PRIORITIES}, keyword
- #+vindex: org-highest-priority
- #+vindex: org-lowest-priority
- #+vindex: org-default-priority
- This line sets the limits and the default for the priorities.
- All three must be either letters A--Z or numbers 0--9. The
- highest priority must have a lower ASCII number than the lowest
- priority.
+ #+cindex: @samp{PRIORITIES}, keyword
+ #+vindex: org-highest-priority
+ #+vindex: org-lowest-priority
+ #+vindex: org-default-priority
+ This line sets the limits and the default for the priorities. All
+ three must be either letters A--Z or numbers 0--9. The highest
+ priority must have a lower ASCII number than the lowest priority.
- =#+PROPERTY: Property_Name Value= ::
- #+cindex: @samp{PROPERTY}, keyword
- This line sets a default inheritance value for entries in the
- current buffer, most useful for specifying the allowed values of
- a property.
+ #+cindex: @samp{PROPERTY}, keyword
+ This line sets a default inheritance value for entries in the
+ current buffer, most useful for specifying the allowed values of
+ a property.
- =#+SETUPFILE: file= ::
- #+cindex: @samp{SETUPFILE}, keyword
- The setup file or a URL pointing to such file is for additional
- in-buffer settings. Org loads this file and parses it for any
- settings in it only when Org opens the main file. If URL is
- specified, the contents are downloaded and stored in a temporary
- file cache. {{{kbd(C-c C-c)}}} on the settings line parses and
- loads the file, and also resets the temporary file cache. Org
- also parses and loads the document during normal exporting
- process. Org parses the contents of this document as if it was
- included in the buffer. It can be another Org file. To visit
- the file---not a URL---use {{{kbd(C-c ')}}} while point is on the
- line with the file name.
+ #+cindex: @samp{SETUPFILE}, keyword
+ The setup file or a URL pointing to such file is for additional
+ in-buffer settings. Org loads this file and parses it for any
+ settings in it only when Org opens the main file. If URL is
+ specified, the contents are downloaded and stored in a temporary
+ file cache. {{{kbd(C-c C-c)}}} on the settings line parses and
+ loads the file, and also resets the temporary file cache. Org also
+ parses and loads the document during normal exporting process. Org
+ parses the contents of this document as if it was included in the
+ buffer. It can be another Org file. To visit the file---not
+ a URL---use {{{kbd(C-c ')}}} while point is on the line with the
+ file name.
- =#+STARTUP:= ::
- #+cindex: @samp{STARTUP}, keyword
- Startup options Org uses when first visiting a file.
-
- #+vindex: org-startup-folded
- The first set of options deals with the initial visibility of the
- outline tree. The corresponding variable for global default
- settings is ~org-startup-folded~ with a default value of ~t~,
- which is the same as ~overview~.
-
- - =overview= ::
-
- Top-level headlines only.
-
- - =content= ::
-
- All headlines.
-
- - =showall= ::
-
- No folding on any entry.
-
- - =showeverything= ::
-
- Show even drawer contents.
-
- #+vindex: org-startup-indented
- Dynamic virtual indentation is controlled by the variable
- ~org-startup-indented~[fn:147].
-
- - =indent= ::
-
- Start with ~org-indent-mode~ turned on.
-
- - =noindent= ::
-
- Start with ~org-indent-mode~ turned off.
-
- #+vindex: org-startup-align-all-tables
- Aligns tables consistently upon visiting a file. The corresponding
- variable is ~org-startup-align-all-tables~ with ~nil~ as default
- value.
-
- - =align= ::
-
- Align all tables.
-
- - =noalign= ::
-
- Do not align tables on startup.
-
- #+vindex: org-startup-shrink-all-tables
- Shrink table columns with a width cookie. The corresponding
- variable is ~org-startup-shrink-all-tables~ with ~nil~ as default
- value.
-
- #+vindex: org-startup-with-inline-images
- When visiting a file, inline images can be automatically displayed.
- The corresponding variable is ~org-startup-with-inline-images~,
- with a default value ~nil~ to avoid delays when visiting a file.
-
- - =inlineimages= ::
-
- Show inline images.
-
- - =noinlineimages= ::
-
- Do not show inline images on startup.
-
- #+vindex: org-log-done
- #+vindex: org-log-note-clock-out
- #+vindex: org-log-repeat
- Logging the closing and reopening of TODO items and clock
- intervals can be configured using these options (see variables
- ~org-log-done~, ~org-log-note-clock-out~, and ~org-log-repeat~).
-
- - =logdone= ::
-
- Record a timestamp when an item is marked DONE.
-
- - =lognotedone= ::
-
- Record timestamp and a note when DONE.
-
- - =nologdone= ::
-
- Do not record when items are marked DONE.
-
- - =logrepeat= ::
-
- Record a time when reinstating a repeating item.
-
- - =lognoterepeat= ::
-
- Record a note when reinstating a repeating item.
-
- - =nologrepeat= ::
-
- Do not record when reinstating repeating item.
-
- - =lognoteclock-out= ::
-
- Record a note when clocking out.
-
- - =nolognoteclock-out= ::
-
- Do not record a note when clocking out.
-
- - =logreschedule= ::
-
- Record a timestamp when scheduling time changes.
-
- - =lognotereschedule= ::
-
- Record a note when scheduling time changes.
-
- - =nologreschedule= ::
-
- Do not record when a scheduling date changes.
-
- - =logredeadline= ::
-
- Record a timestamp when deadline changes.
-
- - =lognoteredeadline= ::
-
- Record a note when deadline changes.
-
- - =nologredeadline= ::
-
- Do not record when a deadline date changes.
-
- - =logrefile= ::
-
- Record a timestamp when refiling.
-
- - =lognoterefile= ::
-
- Record a note when refiling.
-
- - =nologrefile= ::
-
- Do not record when refiling.
-
- #+vindex: org-hide-leading-stars
- #+vindex: org-odd-levels-only
- Here are the options for hiding leading stars in outline headings,
- and for indenting outlines. The corresponding variables are
- ~org-hide-leading-stars~ and ~org-odd-levels-only~, both with
- a default setting ~nil~ (meaning =showstars= and =oddeven=).
-
- - =hidestars= ::
+ #+cindex: @samp{STARTUP}, keyword
+ Startup options Org uses when first visiting a file.
- Make all but one of the stars starting a headline invisible.
-
- - =showstars= ::
-
- Show all stars starting a headline.
-
- - =indent= ::
-
- Virtual indentation according to outline level.
-
- - =noindent= ::
-
- No virtual indentation according to outline level.
-
- - =odd= ::
-
- Allow only odd outline levels (1, 3, ...).
-
- - =oddeven= ::
-
- Allow all outline levels.
-
- #+vindex: org-put-time-stamp-overlays
- #+vindex: org-time-stamp-overlay-formats
- To turn on custom format overlays over timestamps (variables
- ~org-put-time-stamp-overlays~ and ~org-time-stamp-overlay-formats~),
- use:
-
- - =customtime= ::
+ #+vindex: org-startup-folded
+ The first set of options deals with the initial visibility of the
+ outline tree. The corresponding variable for global default
+ settings is ~org-startup-folded~ with a default value of ~t~, which
+ is the same as ~overview~.
+
+ | =overview= | Top-level headlines only. |
+ | =content= | All headlines. |
+ | =showall= | No folding on any entry. |
+ | =showeverything= | Show even drawer contents. |
+
+ #+vindex: org-startup-indented
+ Dynamic virtual indentation is controlled by the variable
+ ~org-startup-indented~[fn:148].
+
+ | =indent= | Start with Org Indent mode turned on. |
+ | =noindent= | Start with Org Indent mode turned off. |
+
+ #+vindex: org-startup-align-all-tables
+ Aligns tables consistently upon visiting a file. The
+ corresponding variable is ~org-startup-align-all-tables~ with
+ ~nil~ as default value.
+
+ | =align= | Align all tables. |
+ | =noalign= | Do not align tables on startup. |
+
+ #+vindex: org-startup-shrink-all-tables
+ Shrink table columns with a width cookie. The corresponding
+ variable is ~org-startup-shrink-all-tables~ with ~nil~ as
+ default value.
+
+ #+vindex: org-startup-with-inline-images
+ When visiting a file, inline images can be automatically
+ displayed. The corresponding variable is
+ ~org-startup-with-inline-images~, with a default value ~nil~ to
+ avoid delays when visiting a file.
+
+ | =inlineimages= | Show inline images. |
+ | =noinlineimages= | Do not show inline images on startup. |
+
+ #+vindex: org-log-done
+ #+vindex: org-log-note-clock-out
+ #+vindex: org-log-repeat
+ Logging the closing and reopening of TODO items and clock
+ intervals can be configured using these options (see variables
+ ~org-log-done~, ~org-log-note-clock-out~, and ~org-log-repeat~).
+
+ | =logdone= | Record a timestamp when an item is marked as done. |
+ | =lognotedone= | Record timestamp and a note when DONE. |
+ | =nologdone= | Do not record when items are marked as done. |
+ | =logrepeat= | Record a time when reinstating a repeating item. |
+ | =lognoterepeat= | Record a note when reinstating a repeating item. |
+ | =nologrepeat= | Do not record when reinstating repeating item. |
+ | =lognoteclock-out= | Record a note when clocking out. |
+ | =nolognoteclock-out= | Do not record a note when clocking out. |
+ | =logreschedule= | Record a timestamp when scheduling time changes. |
+ | =lognotereschedule= | Record a note when scheduling time changes. |
+ | =nologreschedule= | Do not record when a scheduling date changes. |
+ | =logredeadline= | Record a timestamp when deadline changes. |
+ | =lognoteredeadline= | Record a note when deadline changes. |
+ | =nologredeadline= | Do not record when a deadline date changes. |
+ | =logrefile= | Record a timestamp when refiling. |
+ | =lognoterefile= | Record a note when refiling. |
+ | =nologrefile= | Do not record when refiling. |
+
+ #+vindex: org-hide-leading-stars
+ #+vindex: org-odd-levels-only
+ Here are the options for hiding leading stars in outline
+ headings, and for indenting outlines. The corresponding
+ variables are ~org-hide-leading-stars~ and
+ ~org-odd-levels-only~, both with a default setting ~nil~
+ (meaning =showstars= and =oddeven=).
+
+ | =hidestars= | Make all but one of the stars starting a headline invisible. |
+ | =showstars= | Show all stars starting a headline. |
+ | =indent= | Virtual indentation according to outline level. |
+ | =noindent= | No virtual indentation according to outline level. |
+ | =odd= | Allow only odd outline levels (1, 3, ...). |
+ | =oddeven= | Allow all outline levels. |
+
+ #+vindex: org-put-time-stamp-overlays
+ #+vindex: org-time-stamp-overlay-formats
+ To turn on custom format overlays over timestamps (variables
+ ~org-put-time-stamp-overlays~ and
+ ~org-time-stamp-overlay-formats~), use:
+
+ | =customtime= | Overlay custom time format. |
+
+ #+vindex: constants-unit-system
+ The following options influence the table spreadsheet (variable
+ ~constants-unit-system~).
+
+ | =constcgs= | =constants.el= should use the c-g-s unit system. |
+ | =constSI= | =constants.el= should use the SI unit system. |
+
+ #+vindex: org-footnote-define-inline
+ #+vindex: org-footnote-auto-label
+ #+vindex: org-footnote-auto-adjust
+ To influence footnote settings, use the following keywords. The
+ corresponding variables are ~org-footnote-define-inline~,
+ ~org-footnote-auto-label~, and ~org-footnote-auto-adjust~.
+
+ | =fninline= | Define footnotes inline. |
+ | =fnnoinline= | Define footnotes in separate section. |
+ | =fnlocal= | Define footnotes near first reference, but not inline. |
+ | =fnprompt= | Prompt for footnote labels. |
+ | =fnauto= | Create =[fn:1]=-like labels automatically (default). |
+ | =fnconfirm= | Offer automatic label for editing or confirmation. |
+ | =fnadjust= | Automatically renumber and sort footnotes. |
+ | =nofnadjust= | Do not renumber and sort automatically. |
+
+ #+vindex: org-hide-block-startup
+ To hide blocks on startup, use these keywords. The
+ corresponding variable is ~org-hide-block-startup~.
+
+ | =hideblocks= | Hide all begin/end blocks on startup. |
+ | =nohideblocks= | Do not hide blocks on startup. |
+
+ #+vindex: org-pretty-entities
+ The display of entities as UTF-8 characters is governed by the
+ variable ~org-pretty-entities~ and the keywords
+
+ | =entitiespretty= | Show entities as UTF-8 characters where possible. |
+ | =entitiesplain= | Leave entities plain. |
- Overlay custom time format.
+- =#+TAGS: TAG1(c1) TAG2(c2)= ::
- #+vindex: constants-unit-system
- The following options influence the table spreadsheet (variable
- ~constants-unit-system~).
+ #+cindex: @samp{TAGS}, keyword
+ #+vindex: org-tag-alist
+ These lines (several such lines are allowed) specify the valid tags
+ in this file, and (potentially) the corresponding /fast tag
+ selection/ keys. The corresponding variable is ~org-tag-alist~.
- - =constcgs= ::
+- =#+TODO:=, =#+SEQ_TODO:=, =#+TYP_TODO:= ::
- =constants.el= should use the c-g-s unit system.
+ #+cindex: @samp{SEQ_TODO}, keyword
+ #+cindex: @samp{TODO}, keyword
+ #+cindex: @samp{TYP_TODO}, keyword
+ #+vindex: org-todo-keywords
+ These lines set the TODO keywords and their interpretation in the
+ current file. The corresponding variable is ~org-todo-keywords~.
- - =constSI= ::
+** Org Syntax
+:PROPERTIES:
+:DESCRIPTION: Formal description of Org's syntax.
+:END:
- =constants.el= should use the SI unit system.
+A reference document providing a formal description of Org's syntax is
+available as [[https://orgmode.org/worg/dev/org-syntax.html][a draft on Worg]], written and maintained by Nicolas
+Goaziou. It defines Org's core internal concepts such as "headlines",
+"sections", "affiliated keywords", "(greater) elements" and "objects".
+Each part of an Org document belongs to one of the previous
+categories.
- #+vindex: org-footnote-define-inline
- #+vindex: org-footnote-auto-label
- #+vindex: org-footnote-auto-adjust
- To influence footnote settings, use the following keywords. The
- corresponding variables are ~org-footnote-define-inline~,
- ~org-footnote-auto-label~, and ~org-footnote-auto-adjust~.
+To explore the abstract structure of an Org buffer, run this in
+a buffer:
- - =fninline= ::
+: M-: (org-element-parse-buffer) <RET>
- Define footnotes inline.
+#+texinfo: @noindent
+It outputs a list containing the buffer's content represented as an
+abstract structure. The export engine relies on the information
+stored in this list. Most interactive commands---e.g., for structure
+editing---also rely on the syntactic meaning of the surrounding
+context.
- - =fnnoinline= ::
+#+cindex: syntax checker
+#+cindex: linter
+#+findex: org-lint
+You can probe the syntax of your documents with the command
- Define footnotes in separate section.
+: M-x org-lint <RET>
- - =fnlocal= ::
+#+texinfo: @noindent
+It runs a number of checks to find common mistakes. It then displays
+their location in a dedicated buffer, along with a description and
+a "trust level", since false-positive are possible. From there, you
+can operate on the reports with the following keys:
- Define footnotes near first reference, but not inline.
+#+attr_texinfo: :columns 0.22 0.78
+| {{{kbd(C-j)}}}, {{{kbd(TAB)}}} | Display the offending line |
+| {{{kbd(RET)}}} | Move point to the offending line |
+| {{{kbd(g)}}} | Check the document again |
+| {{{kbd(h)}}} | Hide all reports from the same checker |
+| {{{kbd(i)}}} | Also remove them from all subsequent checks |
+| {{{kbd(S)}}} | Sort reports by the column at point |
- - =fnprompt= ::
+** Context Dependent Documentation
+:PROPERTIES:
+:DESCRIPTION: Read documentation about current syntax.
+:ALT_TITLE: Documentation Access
+:END:
+#+cindex: documentation
+#+cindex: Info
- Prompt for footnote labels.
+#+findex: org-info-find-node
+#+kindex: C-c C-x I
+{{{kbd(C-c C-x I)}}} in an Org file tries to open a suitable section
+of the Org manual depending on the syntax at point. For example,
+using it on a headline displays "Document Structure" section.
- - =fnauto= ::
+{{{kbd(q)}}} closes the Info window.
- Create =[fn:1]=-like labels automatically (default).
+** Escape Character
- - =fnconfirm= ::
+#+cindex: escape character
+#+cindex: zero width space
+You may sometimes want to write text that looks like Org syntax, but
+should really read as plain text. Org may use a specific escape
+character in some situations, e.g., a backslash in macros (see [[*Macro
+Replacement]]) or a comma in source and example blocks (see [[*Literal
+Examples]]). In the general case, however, we suggest to use the zero
+width space. You can insert one with any of the following:
- Offer automatic label for editing or confirmation.
+: C-x 8 <RET> zero width space <RET>
+: C-x 8 <RET> 200B <RET>
- - =fnadjust= ::
+For example, in order to write =[[1,2]]= as-is in your document, you
+may write instead
- Automatically renumber and sort footnotes.
+: [X[1,2]]
- - =nofnadjust= ::
+where =X= denotes the zero width space character.
- Do not renumber and sort automatically.
+** Code Evaluation and Security Issues
+:PROPERTIES:
+:DESCRIPTION: Org files evaluate in-line code.
+:ALT_TITLE: Code Evaluation Security
+:END:
- #+vindex: org-hide-block-startup
- To hide blocks on startup, use these keywords. The corresponding
- variable is ~org-hide-block-startup~.
+Unlike plain text, running code comes with risk. Each source code
+block, in terms of risk, is equivalent to an executable file. Org
+therefore puts a few confirmation prompts by default. This is to
+alert the casual user from accidentally running untrusted code.
- - =hideblocks= ::
+For users who do not run code blocks or write code regularly, Org's
+default settings should suffice. However, some users may want to
+tweak the prompts for fewer interruptions. To weigh the risks of
+automatic execution of code blocks, here are some details about code
+evaluation.
- Hide all begin/end blocks on startup.
+Org evaluates code in the following circumstances:
- - =nohideblocks= ::
+- /Source code blocks/ ::
- Do not hide blocks on startup.
+ Org evaluates source code blocks in an Org file during export. Org
+ also evaluates a source code block with the {{{kbd(C-c C-c)}}} key
+ chord. Users exporting or running code blocks must load files only
+ from trusted sources. Be wary of customizing variables that remove
+ or alter default security measures.
+
+ #+attr_texinfo: :options org-confirm-babel-evaluate
+ #+begin_defopt
+ When ~t~, Org prompts the user for confirmation before executing
+ each code block. When ~nil~, Org executes code blocks without
+ prompting the user for confirmation. When this option is set to
+ a custom function, Org invokes the function with these two
+ arguments: the source code language and the body of the code block.
+ The custom function must return either a ~t~ or ~nil~, which
+ determines if the user is prompted. Each source code language can
+ be handled separately through this function argument.
+ #+end_defopt
+
+ For example, here is how to execute ditaa code blocks without
+ prompting:
- #+vindex: org-pretty-entities
- The display of entities as UTF-8 characters is governed by the
- variable ~org-pretty-entities~ and the keywords
+ #+begin_src emacs-lisp
+ (defun my-org-confirm-babel-evaluate (lang body)
+ (not (string= lang "ditaa"))) ;don't ask for ditaa
+ (setq org-confirm-babel-evaluate #'my-org-confirm-babel-evaluate)
+ #+end_src
- - =entitiespretty= ::
+- /Following =shell= and =elisp= links/ ::
- Show entities as UTF-8 characters where possible.
+ Org has two link types that can directly evaluate code (see
+ [[*External Links]]). Because such code is not visible, these links
+ have a potential risk. Org therefore prompts the user when it
+ encounters such links. The customization variables are:
- - =entitiesplain= ::
+ #+attr_texinfo: :options org-link-shell-confirm-function
+ #+begin_defopt
+ Function that prompts the user before executing a shell link.
+ #+end_defopt
- Leave entities plain.
+ #+attr_texinfo: :options org-link-elisp-confirm-function
+ #+begin_defopt
+ Function that prompts the user before executing an Emacs Lisp link.
+ #+end_defopt
-- =#+TAGS: TAG1(c1) TAG2(c2)= ::
+- /Formulas in tables/ ::
- #+cindex: @samp{TAGS}, keyword
- #+vindex: org-tag-alist
- These lines (several such lines are allowed) specify the valid
- tags in this file, and (potentially) the corresponding /fast tag
- selection/ keys. The corresponding variable is ~org-tag-alist~.
+ Formulas in tables (see [[*The Spreadsheet]]) are code that is evaluated
+ either by the Calc interpreter, or by the Emacs Lisp interpreter.
-- =#+TODO:=, =#+SEQ_TODO:=, =#+TYP_TODO:= ::
+** Interaction with Other Packages
+:PROPERTIES:
+:DESCRIPTION: With other Emacs packages.
+:ALT_TITLE: Interaction
+:END:
+#+cindex: packages, interaction with other
- #+cindex: @samp{SEQ_TODO}, keyword
- #+cindex: @samp{TODO}, keyword
- #+cindex: @samp{TYP_TODO}, keyword
- #+vindex: org-todo-keywords
- These lines set the TODO keywords and their interpretation in the
- current file. The corresponding variable is ~org-todo-keywords~.
+Org's compatibility and the level of interaction with other Emacs
+packages are documented here.
-** The Very Busy {{{kbd(C-c C-c)}}} Key
+*** Packages that Org cooperates with
:PROPERTIES:
-:DESCRIPTION: When in doubt, press @kbd{C-c C-c}.
+:DESCRIPTION: Packages Org cooperates with.
+:ALT_TITLE: Cooperation
:END:
-#+kindex: C-c C-c
-#+cindex: @kbd{C-c C-c}, overview
-The {{{kbd(C-c C-c)}}} key in Org serves many purposes depending on
-the context. It is probably the most over-worked, multi-purpose key
-combination in Org. Its uses are well documented throughout this
-manual, but here is a consolidated list for easy reference.
-
-- If any highlights shown in the buffer from the creation of a sparse
- tree, or from clock display, remove such highlights.
+- =calc.el= by Dave Gillespie ::
+ #+cindex: @file{calc.el}
-- If point is in one of the special =KEYWORD= lines, scan the buffer
- for these lines and update the information. Also reset the Org file
- cache used to temporary store the contents of URLs used as values
- for keywords like =SETUPFILE=.
+ Org uses the Calc package for implementing spreadsheet functionality
+ in its tables (see [[*The Spreadsheet]]). Org also uses Calc for
+ embedded calculations. See [[info:calc::Embedded Mode][GNU Emacs Calc Manual]].
-- If point is inside a table, realign the table. The table realigns
- even if automatic table editor is turned off.
+- =constants.el= by Carsten Dominik ::
+ #+cindex: @file{constants.el}
+ #+vindex: org-table-formula-constants
-- If point is on a =TBLFM= keyword, re-apply the formulas to the
- entire table.
+ Org can use names for constants in formulas in tables. Org can also
+ use calculation suffixes for units, such as =M= for =Mega=. For
+ a standard collection of such constants, install the =constants=
+ package. Install version 2.0 of this package, available at
+ [[http://www.astro.uva.nl/~dominik/Tools]]. Org checks if the function
+ ~constants-get~ has been autoloaded. Installation instructions are
+ in the file =constants.el=.
-- If the current buffer is a capture buffer, close the note and file
- it. With a prefix argument, also jump to the target location after
- saving the note.
+- =cdlatex.el= by Carsten Dominik ::
+ #+cindex: @file{cdlatex.el}
-- If point is on a =<<<target>>>=, update radio targets and
- corresponding links in this buffer.
+ Org mode can make use of the CDLaTeX package to efficiently enter
+ LaTeX fragments into Org files. See [[*Using CDLaTeX to enter math]].
-- If point is on a property line or at the start or end of a property
- drawer, offer property commands.
+- =imenu.el= by Ake Stenhoff and Lars Lindberg ::
+ #+cindex: @file{imenu.el}
-- If point is at a footnote reference, go to the corresponding
- definition, and /vice versa/.
+ Imenu creates dynamic menus based on an index of items in a file.
+ Org mode supports Imenu menus. Enable it with a mode hook as
+ follows:
-- If point is on a statistics cookie, update it.
+ #+begin_src emacs-lisp
+ (add-hook 'org-mode-hook
+ (lambda () (imenu-add-to-menubar "Imenu")))
+ #+end_src
-- If point is in a plain list item with a checkbox, toggle the status
- of the checkbox.
+ #+vindex: org-imenu-depth
+ By default the index is two levels deep---you can modify the
+ depth using the option ~org-imenu-depth~.
-- If point is on a numbered item in a plain list, renumber the ordered
- list.
+- =speedbar.el= by Eric\nbsp{}M.\nbsp{}Ludlam ::
+ #+cindex: @file{speedbar.el}
-- If point is on the =#+BEGIN= line of a dynamic block, the block is
- updated.
+ Speedbar package creates a special Emacs frame for displaying files
+ and index items in files. Org mode supports Speedbar; users can
+ drill into Org files directly from the Speedbar. The {{{kbd(<)}}}
+ in the Speedbar frame tweaks the agenda commands to that file or to
+ a subtree.
-- If point is at a timestamp, fix the day name in the timestamp.
+- =table.el= by Takaaki Ota ::
+ #+cindex: table editor, @file{table.el}
+ #+cindex: @file{table.el}
+
+ Complex ASCII tables with automatic line wrapping, column- and
+ row-spanning, and alignment can be created using the Emacs table
+ package by Takaaki Ota. Org mode recognizes such tables and exports
+ them properly. {{{kbd(C-c ')}}} to edit these tables in a special
+ buffer, much like Org's code blocks. Because of interference with
+ other Org mode functionality, Takaaki Ota tables cannot be edited
+ directly in the Org buffer.
+
+ - {{{kbd(C-c ')}}} (~org-edit-special~) ::
+
+ #+kindex: C-c '
+ #+findex: org-edit-special
+ Edit a =table.el= table. Works when point is in a =table.el=
+ table.
+
+ - {{{kbd(C-c ~​)}}} (~org-table-create-with-table.el~) ::
+
+ #+kindex: C-c ~
+ #+findex: org-table-create-with-table.el
+ Insert a =table.el= table. If there is already a table at point,
+ this command converts it between the =table.el= format and the Org
+ mode format. See the documentation string of the command
+ ~org-convert-table~ for the restrictions under which this is
+ possible.
-** A Cleaner Outline View
+*** Packages that conflict with Org mode
:PROPERTIES:
-:DESCRIPTION: Getting rid of leading stars in the outline.
-:ALT_TITLE: Clean View
+:DESCRIPTION: Packages that lead to conflicts.
+:ALT_TITLE: Conflicts
:END:
-#+cindex: hiding leading stars
-#+cindex: dynamic indentation
-#+cindex: odd-levels-only outlines
-#+cindex: clean outline view
-
-Org's default outline with stars and no indents can become too
-cluttered for short documents. For /book-like/ long documents, the
-effect is not as noticeable. Org provides an alternate stars and
-indentation scheme, as shown on the right in the following table. It
-uses only one star and indents text to line with the heading:
-#+begin_example
-,* Top level headline | * Top level headline
-,** Second level | * Second level
-,*** Third level | * Third level
- some text | some text
-,*** Third level | * Third level
- more text | more text
-,* Another top level headline | * Another top level headline
-#+end_example
+#+cindex: shift-selection
+#+vindex: org-support-shift-select
+In Emacs, shift-selection combines motions of point with shift key to
+enlarge regions. Emacs sets this mode by default. This conflicts
+with Org's use of {{{kbd(S-<cursor>)}}} commands to change timestamps,
+TODO keywords, priorities, and item bullet types, etc. Since
+{{{kbd(S-<cursor>)}}} commands outside of specific contexts do not do
+anything, Org offers the variable ~org-support-shift-select~ for
+customization. Org mode accommodates shift selection by (i) making it
+available outside of the special contexts where special commands
+apply, and (ii) extending an existing active region even if point
+moves across a special context.
-#+cindex: Indent mode
-#+findex: org-indent-mode
-To turn this mode on, use the minor mode, ~org-indent-mode~. Text
-lines that are not headlines are prefixed with spaces to vertically
-align with the headline text[fn:148].
+- =cua.el= by Kim\nbsp{}F.\nbsp{}Storm ::
-#+vindex: org-indent-indentation-per-level
-To make more horizontal space, the headlines are shifted by two stars.
-This can be configured by the ~org-indent-indentation-per-level~
-variable. Only one star on each headline is visible, the rest are
-masked with the same font color as the background.
+ #+cindex: @file{cua.el}
+ #+vindex: org-replace-disputed-keys
+ Org key bindings conflict with {{{kbd(S-<cursor>)}}} keys used by
+ CUA mode. For Org to relinquish these bindings to CUA mode,
+ configure the variable ~org-replace-disputed-keys~. When set, Org
+ moves the following key bindings in Org files, and in the agenda
+ buffer---but not during date selection.
-Note that turning on ~org-indent-mode~ sets ~org-hide-leading-stars~
-to ~t~ and ~org-adapt-indentation~ to ~nil~.
+ #+attr_texinfo: :columns 0.4 0.4
+ | {{{kbd(S-UP)}}} \rArr{} {{{kbd(M-p)}}} | {{{kbd(S-DOWN)}}} \rArr{} {{{kbd(M-n)}}} |
+ | {{{kbd(S-LEFT)}}} \rArr{} {{{kbd(M--)}}} | {{{kbd(S-RIGHT)}}} \rArr{} {{{kbd(M-+)}}} |
+ | {{{kbd(C-S-LEFT)}}} \rArr{} {{{kbd(M-S--)}}} | {{{kbd(C-S-RIGHT)}}} \rArr{} {{{kbd(M-S-+)}}} |
-#+vindex: org-startup-indented
-To globally turn on ~org-indent-mode~ for all files, customize the
-variable ~org-startup-indented~.
+ #+vindex: org-disputed-keys
+ Yes, these are unfortunately more difficult to remember. If you
+ want to have other replacement keys, look at the variable
+ ~org-disputed-keys~.
-To turn on indenting for individual files, use =STARTUP= keyword as
-follows:
+- =ecomplete.el= by Lars Magne Ingebrigtsen ::
-: #+STARTUP: indent
+ #+cindex: @file{ecomplete.el}
+ Ecomplete provides "electric" address completion in address header
+ lines in message buffers. Sadly Orgtbl mode cuts Ecomplete's power
+ supply: no completion happens when Orgtbl mode is enabled in message
+ buffers while entering text in address header lines. If one wants
+ to use ecomplete one should /not/ follow the advice to automagically
+ turn on Orgtbl mode in message buffers (see [[*The Orgtbl Minor Mode]]),
+ but instead---after filling in the message headers---turn on Orgtbl
+ mode manually when needed in the messages body.
-Indent on startup makes Org use hard spaces to align text with
-headings as shown in examples below.
+- =filladapt.el= by Kyle Jones ::
-- /Indentation of text below headlines/ ::
+ #+cindex: @file{filladapt.el}
+ Org mode tries to do the right thing when filling paragraphs, list
+ items and other elements. Many users reported problems using both
+ =filladapt.el= and Org mode, so a safe thing to do is to disable
+ filladapt like this:
- Indent text to align with the headline.
+ #+begin_src emacs-lisp
+ (add-hook 'org-mode-hook 'turn-off-filladapt-mode)
+ #+end_src
- #+begin_example
- ,*** Third level
- more text, now indented
- #+end_example
+- =viper.el= by Michael Kifer ::
+ #+cindex: @file{viper.el}
+ #+kindex: C-c /
- #+vindex: org-adapt-indentation
- Org supports this with paragraph filling, line wrapping, and
- structure editing, preserving or adapting the indentation as
- appropriate[fn:149].
+ Viper uses {{{kbd(C-c /)}}} and therefore makes this key not access
+ the corresponding Org mode command ~org-sparse-tree~. You need to
+ find another key for this command, or override the key in
+ ~viper-vi-global-user-map~ with
-- /Hiding leading stars/ ::
+ #+begin_src emacs-lisp
+ (define-key viper-vi-global-user-map "C-c /" 'org-sparse-tree)
+ #+end_src
- #+vindex: org-hide-leading-stars
- Org can make leading stars invisible. For global preference,
- configure the variable ~org-hide-leading-stars~. For per-file
- preference, use these file =STARTUP= options:
+- =windmove.el= by Hovav Shacham ::
+ #+cindex: @file{windmove.el}
- #+begin_example
- ,#+STARTUP: hidestars
- ,#+STARTUP: showstars
- #+end_example
+ This package also uses the {{{kbd(S-<cursor>)}}} keys, so everything
+ written in the paragraph above about CUA mode also applies here. If
+ you want to make the windmove function active in locations where Org
+ mode does not have special functionality on {{{kbd(S-<cursor>)}}},
+ add this to your configuration:
- With stars hidden, the tree is shown as:
+ #+begin_src emacs-lisp
+ ;; Make windmove work in Org mode:
+ (add-hook 'org-shiftup-final-hook 'windmove-up)
+ (add-hook 'org-shiftleft-final-hook 'windmove-left)
+ (add-hook 'org-shiftdown-final-hook 'windmove-down)
+ (add-hook 'org-shiftright-final-hook 'windmove-right)
+ #+end_src
- #+begin_example
- ,* Top level headline
- ,* Second level
- ,* Third level
- ...
- #+end_example
+- =yasnippet.el= ::
- #+vindex: org-hide, face
- Because Org makes the font color the same as the background color
- to hide to stars, sometimes ~org-hide~ face may need tweaking to
- get the effect right. For some black and white combinations,
- ~grey90~ on a white background might mask the stars better.
+ #+cindex: @file{yasnippet.el}
+ The way Org mode binds the {{{kbd(TAB)}}} key (binding to ~[tab]~
+ instead of ~"\t"~) overrules YASnippet's access to this key. The
+ following code fixed this problem:
-- /Odd levels/ ::
+ #+begin_src emacs-lisp
+ (add-hook 'org-mode-hook
+ (lambda ()
+ (setq-local yas/trigger-key [tab])
+ (define-key yas/keymap [tab] 'yas/next-field-or-maybe-expand)))
+ #+end_src
- #+vindex: org-odd-levels-only
- Using stars for only odd levels, 1, 3, 5, ..., can also clean up
- the clutter. This removes two stars from each level[fn:150].
- For Org to properly handle this cleaner structure during edits
- and exports, configure the variable ~org-odd-levels-only~. To
- set this per-file, use either one of the following lines:
+ The latest version of YASnippet does not play well with Org mode.
+ If the above code does not fix the conflict, start by defining
+ the following function:
- #+begin_example
- ,#+STARTUP: odd
- ,#+STARTUP: oddeven
- #+end_example
+ #+begin_src emacs-lisp
+ (defun yas/org-very-safe-expand ()
+ (let ((yas/fallback-behavior 'return-nil)) (yas/expand)))
+ #+end_src
- To switch between single and double stars layouts, use {{{kbd(M-x
- org-convert-to-odd-levels)}}} and {{{kbd(M-x
- org-convert-to-oddeven-levels)}}}.
+ Then, tell Org mode to use that function:
+ #+begin_src emacs-lisp
+ (add-hook 'org-mode-hook
+ (lambda ()
+ (make-variable-buffer-local 'yas/trigger-key)
+ (setq yas/trigger-key [tab])
+ (add-to-list 'org-tab-first-hook 'yas/org-very-safe-expand)
+ (define-key yas/keymap [tab] 'yas/next-field)))
+ #+end_src
** Using Org on a TTY
:PROPERTIES:
:DESCRIPTION: Using Org on a tty.
@@ -18994,246 +19274,195 @@ further based on their usage needs. For example, the normal
| {{{kbd(C-S-LEFT)}}} | {{{kbd(C-c C-x LEFT)}}} | | |
| {{{kbd(C-S-RIGHT)}}} | {{{kbd(C-c C-x RIGHT)}}} | | |
-** Context Dependent Documentation
+** Protocols for External Access
:PROPERTIES:
-:DESCRIPTION: Read documentation about current syntax.
-:ALT_TITLE: Documentation Access
+:DESCRIPTION: External access to Emacs and Org.
+:ALT_TITLE: Protocols
:END:
-#+cindex: documentation
-#+cindex: Info
+#+cindex: protocols, for external access
-#+findex: org-info-find-node
-#+kindex: C-c C-x I
-{{{kbd(C-c C-x I)}}} in an Org file tries to open a suitable section
-of the Org manual depending on the syntax at point. For example,
-using it on a headline displays "Document Structure" section.
+Org protocol is a tool to trigger custom actions in Emacs from
+external applications. Any application that supports calling external
+programs with an URL as argument may be used with this functionality.
+For example, you can configure bookmarks in your web browser to send a
+link to the current page to Org and create a note from it using
+capture (see [[*Capture]]). You can also create a bookmark that tells
+Emacs to open the local source file of a remote website you are
+browsing.
-{{{kbd(q)}}} closes the Info window.
+#+cindex: Org protocol, set-up
+#+cindex: Installing Org protocol
+In order to use Org protocol from an application, you need to register
+=org-protocol://= as a valid scheme-handler. External calls are
+passed to Emacs through the =emacsclient= command, so you also need to
+ensure an Emacs server is running. More precisely, when the
+application calls
-** Interaction with Other Packages
-:PROPERTIES:
-:DESCRIPTION: With other Emacs packages.
-:ALT_TITLE: Interaction
-:END:
-#+cindex: packages, interaction with other
+: emacsclient org-protocol://PROTOCOL?key1=val1&key2=val2
-Org's compatibility and the level of interaction with other Emacs
-packages are documented here.
+#+texinfo: @noindent
+Emacs calls the handler associated to {{{var(PROTOCOL)}}} with
+argument =(:key1 val1 :key2 val2)=.
-*** Packages that Org cooperates with
+#+cindex: protocol, new protocol
+#+cindex: defining new protocols
+Org protocol comes with three predefined protocols, detailed in the
+following sections. Configure ~org-protocol-protocol-alist~ to define
+your own.
+
+*** The ~store-link~ protocol
:PROPERTIES:
-:DESCRIPTION: Packages Org cooperates with.
-:ALT_TITLE: Cooperation
+:DESCRIPTION: Store a link, push URL to kill-ring.
:END:
+#+cindex: store-link protocol
+#+cindex: protocol, store-link
-- =calc.el= by Dave Gillespie ::
- #+cindex: @file{calc.el}
+Using the ~store-link~ handler, you can copy links, to that they can
+be inserted using {{{kbd(M-x org-insert-link)}}} or yanking. More
+precisely, the command
- Org uses the Calc package for implementing spreadsheet
- functionality in its tables (see [[*The Spreadsheet]]). Org also
- uses Calc for embedded calculations. See [[info:calc::Embedded%20Mode][GNU Emacs Calc Manual]].
+: emacsclient org-protocol://store-link?url=URL&title=TITLE
-- =constants.el= by Carsten Dominik ::
- #+cindex: @file{constants.el}
- #+vindex: org-table-formula-constants
+#+texinfo: @noindent
+stores the following link:
- Org can use names for constants in formulas in tables. Org can
- also use calculation suffixes for units, such as =M= for =Mega=.
- For a standard collection of such constants, install the
- =constants= package. Install version 2.0 of this package,
- available at [[http://www.astro.uva.nl/~dominik/Tools]]. Org checks
- if the function ~constants-get~ has been autoloaded.
- Installation instructions are in the file =constants.el=.
+: [[URL][TITLE]]
-- =cdlatex.el= by Carsten Dominik ::
- #+cindex: @file{cdlatex.el}
+In addition, {{{var(URL)}}} is pushed on the kill-ring for yanking.
+You need to encode {{{var(URL)}}} and {{{var(TITLE)}}} if they contain
+slashes, and probably quote those for the shell.
- Org mode can make use of the CDLaTeX package to efficiently enter
- LaTeX fragments into Org files. See [[*Using CDLaTeX to enter
- math]].
+To use this feature from a browser, add a bookmark with an arbitrary
+name, e.g., =Org: store-link= and enter this as /Location/:
-- =imenu.el= by Ake Stenhoff and Lars Lindberg ::
- #+cindex: @file{imenu.el}
+#+begin_example
+javascript:location.href='org-protocol://store-link?url='+
+ encodeURIComponent(location.href);
+#+end_example
- Imenu creates dynamic menus based on an index of items in a file.
- Org mode supports Imenu menus. Enable it with a mode hook as
- follows:
+*** The ~capture~ protocol
+:PROPERTIES:
+:DESCRIPTION: Fill a buffer with external information.
+:END:
+#+cindex: capture protocol
+#+cindex: protocol, capture
- #+begin_src emacs-lisp
- (add-hook 'org-mode-hook
- (lambda () (imenu-add-to-menubar "Imenu")))
- #+end_src
+Activating the "capture" handler pops up a =Capture= buffer in Emacs,
+using acapture template.
- #+vindex: org-imenu-depth
- By default the index is two levels deep---you can modify the
- depth using the option ~org-imenu-depth~.
+: emacsclient org-protocol://capture?template=X?url=URL?title=TITLE?body=BODY
-- =speedbar.el= by Eric\nbsp{}M.\nbsp{}Ludlam ::
- #+cindex: @file{speedbar.el}
+To use this feature, add a bookmark with an arbitrary name, e.g.,
+=Org: capture=, and enter this as =Location=:
- Speedbar package creates a special Emacs frame for displaying
- files and index items in files. Org mode supports Speedbar;
- users can drill into Org files directly from the Speedbar. The
- {{{kbd(<)}}} in the Speedbar frame tweaks the agenda commands to
- that file or to a subtree.
+#+begin_example
+javascript:location.href='org-protocol://capture?template=x'+
+ '&url='+encodeURIComponent(window.location.href)+
+ '&title='+encodeURIComponent(document.title)+
+ '&body='+encodeURIComponent(window.getSelection());
+#+end_example
-- =table.el= by Takaaki Ota ::
- #+cindex: table editor, @file{table.el}
- #+cindex: @file{table.el}
-
- Complex ASCII tables with automatic line wrapping, column- and
- row-spanning, and alignment can be created using the Emacs table
- package by Takaaki Ota. Org mode recognizes such tables and
- exports them properly. {{{kbd(C-c ')}}} to edit these tables in
- a special buffer, much like Org's code blocks. Because of
- interference with other Org mode functionality, Takaaki Ota
- tables cannot be edited directly in the Org buffer.
-
- - {{{kbd(C-c ')}}} (~org-edit-special~) ::
-
- #+kindex: C-c '
- #+findex: org-edit-special
- Edit a =table.el= table. Works when point is in
- a =table.el= table.
-
- - {{{kbd(C-c ~​)}}} (~org-table-create-with-table.el~) ::
-
- #+kindex: C-c ~
- #+findex: org-table-create-with-table.el
- Insert a =table.el= table. If there is already a table at
- point, this command converts it between the =table.el=
- format and the Org mode format. See the documentation
- string of the command ~org-convert-table~ for the
- restrictions under which this is possible.
+#+vindex: org-protocol-default-template-key
+The capture template to be used can be specified in the bookmark (like
+=X= above). If unspecified, the template key is set in the variable
+~org-protocol-default-template-key~. The following template
+placeholders are available:
-*** Packages that conflict with Org mode
+#+begin_example
+%:link The URL
+%:description The webpage title
+%:annotation Equivalent to [[%:link][%:description]]
+%i The selected text
+#+end_example
+
+*** The ~open-source~ protocol
:PROPERTIES:
-:DESCRIPTION: Packages that lead to conflicts.
-:ALT_TITLE: Conflicts
+:DESCRIPTION: Edit published contents.
:END:
+#+cindex: open-source protocol
+#+cindex: protocol, open-source
-#+cindex: shift-selection-mode
-#+vindex: org-support-shift-select
-In Emacs, ~shift-selection-mode~ combines motions of point with shift
-key to enlarge regions. Emacs sets this mode by default. This
-conflicts with Org's use of {{{kbd(S-<cursor>)}}} commands to change
-timestamps, TODO keywords, priorities, and item bullet types, etc.
-Since {{{kbd(S-<cursor>)}}} commands outside of specific contexts do
-not do anything, Org offers the variable ~org-support-shift-select~
-for customization. Org mode accommodates shift selection by (i)
-making it available outside of the special contexts where special
-commands apply, and (ii) extending an existing active region even if
-point moves across a special context.
-
-- =cua.el= by Kim\nbsp{}F.\nbsp{}Storm ::
-
- #+cindex: @file{cua.el}
- #+vindex: org-replace-disputed-keys
- Org key bindings conflict with {{{kbd(S-<cursor>)}}} keys used by
- CUA mode. For Org to relinquish these bindings to CUA mode,
- configure the variable ~org-replace-disputed-keys~. When set,
- Org moves the following key bindings in Org files, and in the
- agenda buffer---but not during date selection.
-
- #+attr_texinfo: :columns 0.4 0.4
- | {{{kbd(S-UP)}}} \rArr{} {{{kbd(M-p)}}} | {{{kbd(S-DOWN)}}} \rArr{} {{{kbd(M-n)}}} |
- | {{{kbd(S-LEFT)}}} \rArr{} {{{kbd(M--)}}} | {{{kbd(S-RIGHT)}}} \rArr{} {{{kbd(M-+)}}} |
- | {{{kbd(C-S-LEFT)}}} \rArr{} {{{kbd(M-S--)}}} | {{{kbd(C-S-RIGHT)}}} \rArr{} {{{kbd(M-S-+)}}} |
-
- #+vindex: org-disputed-keys
- Yes, these are unfortunately more difficult to remember. If you
- want to have other replacement keys, look at the variable
- ~org-disputed-keys~.
-
-- =ecomplete.el= by Lars Magne Ingebrigtsen ::
+The ~open-source~ handler is designed to help with editing local
+sources when reading a document. To that effect, you can use
+a bookmark with the following location:
- #+cindex: @file{ecomplete.el}
- Ecomplete provides "electric" address completion in address
- header lines in message buffers. Sadly Orgtbl mode cuts
- Ecomplete's power supply: no completion happens when Orgtbl mode
- is enabled in message buffers while entering text in address
- header lines. If one wants to use ecomplete one should /not/
- follow the advice to automagically turn on Orgtbl mode in message
- buffers (see [[*The Orgtbl Minor Mode]]), but instead---after
- filling in the message headers---turn on Orgtbl mode manually
- when needed in the messages body.
+#+begin_example
+javascript:location.href='org-protocol://open-source?&url='+
+ encodeURIComponent(location.href)
+#+end_example
-- =filladapt.el= by Kyle Jones ::
+#+vindex: org-protocol-project-alist
+The variable ~org-protocol-project-alist~ maps URLs to local file
+names, by stripping URL parameters from the end and replacing the
+~:base-url~ with ~:working-directory~ and ~:online-suffix~ with
+~:working-suffix~. For example, assuming you own a local copy of
+=https://orgmode.org/worg/= contents at =/home/user/worg=, you can set
+~org-protocol-project-alist~ to the following
- #+cindex: @file{filladapt.el}
- Org mode tries to do the right thing when filling paragraphs,
- list items and other elements. Many users reported problems
- using both =filladapt.el= and Org mode, so a safe thing to do is
- to disable filladapt like this:
+#+begin_src emacs-lisp
+(setq org-protocol-project-alist
+ '(("Worg"
+ :base-url "https://orgmode.org/worg/"
+ :working-directory "/home/user/worg/"
+ :online-suffix ".html"
+ :working-suffix ".org")))
+#+end_src
- #+begin_src emacs-lisp
- (add-hook 'org-mode-hook 'turn-off-filladapt-mode)
- #+end_src
+#+texinfo: @noindent
+If you are now browsing
+=https://orgmode.org/worg/org-contrib/org-protocol.html= and find
+a typo or have an idea about how to enhance the documentation, simply
+click the bookmark and start editing.
-- =viper.el= by Michael Kifer ::
- #+cindex: @file{viper.el}
- #+kindex: C-c /
+#+cindex: rewritten URL in open-source protocol
+#+cindex: protocol, open-source rewritten URL
+However, such mapping may not always yield the desired results.
+Suppose you maintain an online store located at =http://example.com/=.
+The local sources reside in =/home/user/example/=. It is common
+practice to serve all products in such a store through one file and
+rewrite URLs that do not match an existing file on the server. That
+way, a request to =http://example.com/print/posters.html= might be
+rewritten on the server to something like
+=http://example.com/shop/products.php/posters.html.php=. The
+~open-source~ handler probably cannot find a file named
+=/home/user/example/print/posters.html.php= and fails.
- Viper uses {{{kbd(C-c /)}}} and therefore makes this key not
- access the corresponding Org mode command ~org-sparse-tree~. You
- need to find another key for this command, or override the key in
- ~viper-vi-global-user-map~ with
+Such an entry in ~org-protocol-project-alist~ may hold an additional
+property ~:rewrites~. This property is a list of cons cells, each of
+which maps a regular expression to a path relative to the
+~:working-directory~.
- #+begin_src emacs-lisp
- (define-key viper-vi-global-user-map "C-c /" 'org-sparse-tree)
- #+end_src
+Now map the URL to the path =/home/user/example/products.php= by
+adding ~:rewrites~ rules like this:
-- =windmove.el= by Hovav Shacham ::
- #+cindex: @file{windmove.el}
-
- This package also uses the {{{kbd(S-<cursor>)}}} keys, so
- everything written in the paragraph above about CUA mode also
- applies here. If you want to make the windmove function active
- in locations where Org mode does not have special functionality
- on {{{kbd(S-<cursor>)}}}, add this to your configuration:
-
- #+begin_src emacs-lisp
- ;; Make windmove work in Org mode:
- (add-hook 'org-shiftup-final-hook 'windmove-up)
- (add-hook 'org-shiftleft-final-hook 'windmove-left)
- (add-hook 'org-shiftdown-final-hook 'windmove-down)
- (add-hook 'org-shiftright-final-hook 'windmove-right)
- #+end_src
+#+begin_src emacs-lisp
+(setq org-protocol-project-alist
+ '(("example.com"
+ :base-url "http://example.com/"
+ :working-directory "/home/user/example/"
+ :online-suffix ".php"
+ :working-suffix ".php"
+ :rewrites (("example.com/print/" . "products.php")
+ ("example.com/$" . "index.php")))))
+#+end_src
-- =yasnippet.el= ::
+#+texinfo: @noindent
+Since =example.com/$= is used as a regular expression, it maps
+=http://example.com/=, =https://example.com=,
+=http://www.example.com/= and similar to
+=/home/user/example/index.php=.
- #+cindex: @file{yasnippet.el}
- The way Org mode binds the {{{kbd(TAB)}}} key (binding to ~[tab]~
- instead of ~"\t"~) overrules YASnippet's access to this key. The
- following code fixed this problem:
-
- #+begin_src emacs-lisp
- (add-hook 'org-mode-hook
- (lambda ()
- (setq-local yas/trigger-key [tab])
- (define-key yas/keymap [tab] 'yas/next-field-or-maybe-expand)))
- #+end_src
-
- The latest version of YASnippet does not play well with Org mode.
- If the above code does not fix the conflict, start by defining
- the following function:
-
- #+begin_src emacs-lisp
- (defun yas/org-very-safe-expand ()
- (let ((yas/fallback-behavior 'return-nil)) (yas/expand)))
- #+end_src
-
- Then, tell Org mode to use that function:
-
- #+begin_src emacs-lisp
- (add-hook 'org-mode-hook
- (lambda ()
- (make-variable-buffer-local 'yas/trigger-key)
- (setq yas/trigger-key [tab])
- (add-to-list 'org-tab-first-hook 'yas/org-very-safe-expand)
- (define-key yas/keymap [tab] 'yas/next-field)))
- #+end_src
+The ~:rewrites~ rules are searched as a last resort if and only if no
+existing file name is matched.
+#+cindex: protocol, open-source, set-up mapping
+#+cindex: mappings in open-source protocol
+#+findex: org-protocol-create
+#+findex: org-protocol-create-for-org
+Two functions can help you filling ~org-protocol-project-alist~ with
+valid contents: ~org-protocol-create~ and
+~org-protocol-create-for-org~. The latter is of use if you're editing
+an Org file that is part of a publishing project.
** Org Crypt
:PROPERTIES:
:DESCRIPTION: Encrypting Org files.
@@ -19314,7 +19543,7 @@ these variables.
#+vindex: org-mobile-directory
The mobile application needs access to a file directory on
-a server[fn:151] to interact with Emacs. Pass its location through
+a server[fn:149] to interact with Emacs. Pass its location through
the ~org-mobile-directory~ variable. If you can mount that directory
locally just set the variable to point to that directory:
@@ -19335,7 +19564,7 @@ With a public server, consider encrypting the files. Org also
requires OpenSSL installed on the local computer. To turn on
encryption, set the same password in the mobile application and in
Emacs. Set the password in the variable
-~org-mobile-use-encryption~[fn:152]. Note that even after the mobile
+~org-mobile-use-encryption~[fn:150]. Note that even after the mobile
application encrypts the file contents, the file name remains visible
on the file systems of the local computer, the server, and the mobile
device.
@@ -19351,15 +19580,15 @@ The command ~org-mobile-push~ copies files listed in
~org-mobile-files~ into the staging area. Files include agenda files
(as listed in ~org-agenda-files~). Customize ~org-mobile-files~ to
add other files. File names are staged with paths relative to
-~org-directory~, so all files should be inside this directory[fn:153].
+~org-directory~, so all files should be inside this directory[fn:151].
Push creates a special Org file =agendas.org= with custom agenda views
-defined by the user[fn:154].
+defined by the user[fn:152].
Finally, Org writes the file =index.org=, containing links to other
files. The mobile application reads this file first from the server
to determine what other files to download for agendas. For faster
-downloads, it is expected to only read files whose checksums[fn:155]
+downloads, it is expected to only read files whose checksums[fn:153]
have changed.
*** Pulling from the mobile application
@@ -19376,7 +19605,7 @@ data in an inbox file format, through the following steps:
1.
#+vindex: org-mobile-inbox-for-pull
- Org moves all entries found in =mobileorg.org=[fn:156] and appends
+ Org moves all entries found in =mobileorg.org=[fn:154] and appends
them to the file pointed to by the variable
~org-mobile-inbox-for-pull~. It should reside neither in the
staging area nor on the server. Each captured entry and each
@@ -19398,13 +19627,13 @@ data in an inbox file format, through the following steps:
- {{{kbd(?)}}} ::
- Pressing {{{kbd(?)}}} displays the entire flagged note in
- another window. Org also pushes it to the kill ring. To
- store flagged note as a normal note, use {{{kbd(? z C-y C-c
- C-c)}}}. Pressing {{{kbd(?)}}} twice does these things: first
- it removes the =FLAGGED= tag; second, it removes the flagged
- note from the property drawer; third, it signals that manual
- editing of the flagged entry is now finished.
+ Pressing {{{kbd(?)}}} displays the entire flagged note in another
+ window. Org also pushes it to the kill ring. To store flagged
+ note as a normal note, use {{{kbd(? z C-y C-c C-c)}}}. Pressing
+ {{{kbd(?)}}} twice does these things: first it removes the
+ =FLAGGED= tag; second, it removes the flagged note from the
+ property drawer; third, it signals that manual editing of the
+ flagged entry is now finished.
#+kindex: ? @r{(Agenda dispatcher)}
From the agenda dispatcher, {{{kbd(?)}}} returns to the view to finish
@@ -19413,51 +19642,6 @@ most recent since the mobile application searches files that were last
pulled. To get an updated agenda view with changes since the last
pull, pull again.
-** Org Syntax
-:PROPERTIES:
-:DESCRIPTION: Formal description of Org's syntax.
-:END:
-
-A reference document providing a formal description of Org's syntax is
-available as [[https://orgmode.org/worg/dev/org-syntax.html][a draft on Worg]], written and maintained by Nicolas
-Goaziou. It defines Org's core internal concepts such as "headlines",
-"sections", "affiliated keywords", "(greater) elements" and "objects".
-Each part of an Org document belongs to one of the previous
-categories.
-
-To explore the abstract structure of an Org buffer, run this in
-a buffer:
-
-: M-: (org-element-parse-buffer) <RET>
-
-#+texinfo: @noindent
-It outputs a list containing the buffer's content represented as an
-abstract structure. The export engine relies on the information
-stored in this list. Most interactive commands---e.g., for structure
-editing---also rely on the syntactic meaning of the surrounding
-context.
-
-#+cindex: syntax checker
-#+cindex: linter
-#+findex: org-lint
-You can probe the syntax of your documents with the command
-
-: M-x org-lint <RET>
-
-#+texinfo: @noindent
-It runs a number of checks to find common mistakes. It then displays
-their location in a dedicated buffer, along with a description and
-a "trust level", since false-positive are possible. From there, you
-can operate on the reports with the following keys:
-
-#+attr_texinfo: :columns 0.22 0.78
-| {{{kbd(C-j)}}}, {{{kbd(TAB)}}} | Display the offending line |
-| {{{kbd(RET)}}} | Move point to the offending line |
-| {{{kbd(g)}}} | Check the document again |
-| {{{kbd(h)}}} | Hide all reports from the same checker |
-| {{{kbd(i)}}} | Also remove them from all subsequent checks |
-| {{{kbd(S)}}} | Sort reports by the column at point |
-
* Hacking
:PROPERTIES:
:DESCRIPTION: How to hack your way around.
@@ -19582,7 +19766,7 @@ A review of =org-man.el=:
For example, ~org-man-store-link~ is responsible for storing a link
when ~org-store-link~ (see [[*Handling Links]]) is called from a buffer
- displaying a man page. It first checks if the ~major-mode~ is
+ displaying a man page. It first checks if the major mode is
appropriate. If check fails, the function returns ~nil~, which
means it isn't responsible for creating a link to the current
buffer. Otherwise the function makes a link string by combining
@@ -19681,15 +19865,15 @@ called:
- =:skip N= ::
- Skip the first N lines of the table. Hlines do count; include
- them if they are to be skipped.
+ Skip the first N lines of the table. Hlines do count; include them
+ if they are to be skipped.
- =:skipcols (n1 n2 ...)= ::
- List of columns to be skipped. First Org automatically discards
- columns with calculation marks and then sends the table to the
- translator function, which then skips columns as specified in
- =skipcols=.
+ List of columns to be skipped. First Org automatically discards
+ columns with calculation marks and then sends the table to the
+ translator function, which then skips columns as specified in
+ =skipcols=.
To keep the source table intact in the buffer without being disturbed
when the source file is compiled or otherwise being worked on, use one
@@ -19712,9 +19896,9 @@ of these strategies:
#+cindex: @LaTeX{}, and Orgtbl mode
To wrap a source table in LaTeX, use the =comment= environment
-provided by =comment.sty=[fn:157]. To activate it, put
+provided by =comment.sty=[fn:155]. To activate it, put
~\usepackage{comment}~ in the document header. Orgtbl mode inserts
-a radio table skeleton[fn:158] with the command {{{kbd(M-x
+a radio table skeleton[fn:156] with the command {{{kbd(M-x
orgtbl-insert-radio-table)}}}, which prompts for a table name. For
example, if =salesfigures= is the name, the template inserts:
@@ -19733,7 +19917,7 @@ The line =#+ORGTBL: SEND= tells Orgtbl mode to use the function
~orgtbl-to-latex~ to convert the table to LaTeX format, then insert
the table at the target (receive) location named =salesfigures=. Now
the table is ready for data entry. It can even use spreadsheet
-features[fn:159]:
+features[fn:157]:
#+begin_example
% BEGIN RECEIVE ORGTBL salesfigures
@@ -19782,30 +19966,28 @@ control output, see [[*Translator functions]]:
- =:splice BOOLEAN= ::
- When {{{var(BOOLEAN}}} is non-~nil~, return only table body
- lines; i.e., not wrapped in =tabular= environment. Default is
- ~nil~.
+ When {{{var(BOOLEAN}}} is non-~nil~, return only table body lines;
+ i.e., not wrapped in =tabular= environment. Default is ~nil~.
- =:fmt FMT= ::
- Format string to warp each field. It should contain =%s= for the
- original field value. For example, to wrap each field value in
- dollar symbol, you could use =:fmt "$%s$"=. Format can also wrap
- a property list with column numbers and formats, for example
- =:fmt (2 "$%s$" 4 "%s\\%%")=. In place of a string, a function
- of one argument can be used; the function must return a formatted
- string.
+ Format string to warp each field. It should contain =%s= for the
+ original field value. For example, to wrap each field value in
+ dollar symbol, you could use =:fmt "$%s$"=. Format can also wrap
+ a property list with column numbers and formats, for example =:fmt
+ (2 "$%s$" 4 "%s\\%%")=. In place of a string, a function of one
+ argument can be used; the function must return a formatted string.
- =:efmt EFMT= ::
- Format numbers as exponentials. The spec should have =%s= twice
- for inserting mantissa and exponent, for example ="%s\\times10^{%s}"=.
- This may also be a property list with column numbers and formats,
- for example =:efmt (2 "$%s\\times10^{%s}$" 4 "$%s\\cdot10^{%s}$")=. After
- {{{var(EFMT)}}} has been applied to a value, {{{var(FMT)}}}---see
- above---is also applied. Functions with two arguments can be
- supplied instead of strings. By default, no special formatting
- is applied.
+ Format numbers as exponentials. The spec should have =%s= twice for
+ inserting mantissa and exponent, for example ="%s\\times10^{%s}"=. This
+ may also be a property list with column numbers and formats, for
+ example =:efmt (2 "$%s\\times10^{%s}$" 4 "$%s\\cdot10^{%s}$")=. After
+ {{{var(EFMT)}}} has been applied to a value, {{{var(FMT)}}}---see
+ above---is also applied. Functions with two arguments can be
+ supplied instead of strings. By default, no special formatting is
+ applied.
*** Translator functions
:PROPERTIES:
@@ -19874,9 +20056,14 @@ users mailing list, at mailto:emacs-orgmode@gnu.org.
Org supports /dynamic blocks/ in Org documents. They are inserted
with begin and end markers like any other code block, but the contents
-are updated automatically by a user function. For example, {{{kbd(C-c
-C-x C-r)}}} inserts a dynamic table that updates the work time (see
-[[*Clocking Work Time]]).
+are updated automatically by a user function.
+
+#+kindex: C-c C-x x
+#+findex: org-dynamic-block-insert-dblock
+You can insert a dynamic block with ~org-dynamic-block-insert-dblock~,
+which is bound to {{{kbd(C-c C-x x)}}} by default. For example,
+{{{kbd(C-c C-x x c l o c k t a b l e RET)}}} inserts a table that
+updates the work time (see [[*Clocking Work Time]]).
Dynamic blocks can have names and function parameters. The syntax is
similar to source code block specifications:
@@ -19891,24 +20078,23 @@ These commands update dynamic blocks:
- {{{kbd(C-c C-x C-u)}}} (~org-dblock-update~) ::
- #+kindex: C-c C-x C-u
- #+findex: org-dblock-update
- Update dynamic block at point.
+ #+kindex: C-c C-x C-u
+ #+findex: org-dblock-update
+ Update dynamic block at point.
- {{{kbd(C-u C-c C-x C-u)}}} ::
- #+kindex: C-u C-c C-x C-u
- Update all dynamic blocks in the current file.
+ #+kindex: C-u C-c C-x C-u
+ Update all dynamic blocks in the current file.
Before updating a dynamic block, Org removes content between the
=BEGIN= and =END= markers. Org then reads the parameters on the
-=BEGIN= line for passing to the writer function. If the function
-expects to access the removed content, then Org expects an extra
-parameter, =:content=, on the =BEGIN= line.
+=BEGIN= line for passing to the writer function as a plist. The
+previous content of the dynamic block becomes erased from the buffer
+and appended to the plist under ~:content~.
The syntax for naming a writer function with a dynamic block labelled
-=myblock= is: ~org-dblock-write:myblock~. Parameters come from the
-=BEGIN= line.
+=myblock= is: ~org-dblock-write:myblock~.
The following is an example of a dynamic block and a block writer function
that updates the time when the function was last run:
@@ -19947,7 +20133,7 @@ Dynamic blocks, like any other block, can be narrowed with
#+vindex: org-agenda-skip-function
#+vindex: org-agenda-skip-function-global
Org provides a special hook to further limit items in agenda views:
-~agenda~, ~agenda*~[fn:160], ~todo~, ~alltodo~, ~tags~, ~tags-todo~,
+~agenda~, ~agenda*~[fn:158], ~todo~, ~alltodo~, ~tags~, ~tags-todo~,
~tags-tree~. Specify a custom function that tests inclusion of every
matched item in the view. This function can also skip as much as is
needed.
@@ -19990,52 +20176,51 @@ meaningful string suitable for the agenda view.
#+vindex: org-agenda-skip-function
Search for entries with a limit set on levels for the custom search.
This is a general approach to creating custom searches in Org. To
-include all levels, use =LEVEL>0=[fn:161]. Then to selectively pick
+include all levels, use =LEVEL>0=[fn:159]. Then to selectively pick
the matched entries, use ~org-agenda-skip-function~, which also
accepts Lisp forms, such as ~org-agenda-skip-entry-if~ and
~org-agenda-skip-subtree-if~. For example:
- =(org-agenda-skip-entry-if 'scheduled)= ::
- Skip current entry if it has been scheduled.
+ Skip current entry if it has been scheduled.
- =(org-agenda-skip-entry-if 'notscheduled)= ::
- Skip current entry if it has not been scheduled.
+ Skip current entry if it has not been scheduled.
- =(org-agenda-skip-entry-if 'deadline)= ::
- Skip current entry if it has a deadline.
+ Skip current entry if it has a deadline.
- =(org-agenda-skip-entry-if 'scheduled 'deadline)= ::
- Skip current entry if it has a deadline, or if it is scheduled.
+ Skip current entry if it has a deadline, or if it is scheduled.
- =(org-agenda-skip-entry-if 'todo '("TODO" "WAITING"))= ::
- Skip current entry if the TODO keyword is TODO or WAITING.
+ Skip current entry if the TODO keyword is TODO or WAITING.
- =(org-agenda-skip-entry-if 'todo 'done)= ::
- Skip current entry if the TODO keyword marks a DONE state.
+ Skip current entry if the TODO keyword marks a DONE state.
- =(org-agenda-skip-entry-if 'timestamp)= ::
- Skip current entry if it has any timestamp, may also be deadline
- or scheduled.
+ Skip current entry if it has any timestamp, may also be deadline or
+ scheduled.
- =(org-agenda-skip-entry-if 'regexp "regular expression")= ::
- Skip current entry if the regular expression matches in the
- entry.
+ Skip current entry if the regular expression matches in the entry.
- =(org-agenda-skip-entry-if 'notregexp "regular expression")= ::
- Skip current entry unless the regular expression matches.
+ Skip current entry unless the regular expression matches.
- =(org-agenda-skip-subtree-if 'regexp "regular expression")= ::
- Same as above, but check and skip the entire subtree.
+ Same as above, but check and skip the entire subtree.
The following is an example of a search for =waiting= without the
special function:
@@ -20148,16 +20333,16 @@ with the following fields:
- head :: The headline, without TODO keyword, TAGS and PRIORITY
- type :: The type of the agenda entry, can be
- | ~todo~ | selected in TODO match |
- | ~tagsmatch~ | selected in tags match |
- | ~diary~ | imported from diary |
- | ~deadline~ | a deadline |
- | ~scheduled~ | scheduled |
- | ~timestamp~ | appointment, selected by timestamp |
- | ~closed~ | entry was closed on date |
- | ~upcoming-deadline~ | warning about nearing deadline |
- | ~past-scheduled~ | forwarded scheduled item |
- | ~block~ | entry has date block including date |
+ | ~todo~ | selected in TODO match |
+ | ~tagsmatch~ | selected in tags match |
+ | ~diary~ | imported from diary |
+ | ~deadline~ | a deadline |
+ | ~scheduled~ | scheduled |
+ | ~timestamp~ | appointment, selected by timestamp |
+ | ~closed~ | entry was closed on date |
+ | ~upcoming-deadline~ | warning about nearing deadline |
+ | ~past-scheduled~ | forwarded scheduled item |
+ | ~block~ | entry has date block including date |
- todo :: The TODO keyword, if any
- tags :: All tags including inherited ones, separated by colons
@@ -20340,35 +20525,35 @@ of:
- ~nil~ ::
- The current buffer, respecting the restriction, if any.
+ The current buffer, respecting the restriction, if any.
- ~tree~ ::
- The subtree started with the entry at point.
+ The subtree started with the entry at point.
- ~region~ ::
- The entries within the active region, if any.
+ The entries within the active region, if any.
- ~file~ ::
- The current buffer, without restriction.
+ The current buffer, without restriction.
- ~file-with-archives~ ::
- The current buffer, and any archives associated with it.
+ The current buffer, and any archives associated with it.
- ~agenda~ ::
- All agenda files.
+ All agenda files.
- ~agenda-with-archives~ ::
- All agenda files with any archive files associated with them.
+ All agenda files with any archive files associated with them.
- list of filenames ::
- If this is a list, all files in the list are scanned.
+ If this is a list, all files in the list are scanned.
#+texinfo: @noindent
The remaining arguments are treated as settings for the scanner's
@@ -20376,18 +20561,18 @@ skipping facilities. Valid arguments are:
- ~archive~ ::
- Skip trees with the =ARCHIVE= tag.
+ Skip trees with the =ARCHIVE= tag.
- ~comment~ ::
- Skip trees with the COMMENT keyword.
+ Skip trees with the COMMENT keyword.
- function or Lisp form ::
- #+vindex: org-agenda-skip-function
- Used as value for ~org-agenda-skip-function~, so whenever the
- function returns ~t~, {{{var(FUNC)}}} is called for that entry
- and search continues from the point where the function leaves it.
+ #+vindex: org-agenda-skip-function
+ Used as value for ~org-agenda-skip-function~, so whenever the
+ function returns ~t~, {{{var(FUNC)}}} is called for that entry and
+ search continues from the point where the function leaves it.
#+end_defun
The mapping routine can call any arbitrary function, even functions
@@ -20480,40 +20665,38 @@ Before I get to this list, a few special mentions are in order:
- Bastien Guerry ::
- Bastien has written a large number of extensions to Org (most of
- them integrated into the core by now), including the LaTeX
- exporter and the plain list parser. His support during the early
- days was central to the success of this project. Bastien also
- invented Worg, helped establishing the Web presence of Org, and
- sponsored hosting costs for the orgmode.org website. Bastien
- stepped in as maintainer of Org between 2011 and 2013, at a time
- when I desperately needed a break.
+ Bastien has written a large number of extensions to Org (most of
+ them integrated into the core by now), including the LaTeX exporter
+ and the plain list parser. His support during the early days was
+ central to the success of this project. Bastien also invented Worg,
+ helped establishing the Web presence of Org, and sponsored hosting
+ costs for the orgmode.org website. Bastien stepped in as maintainer
+ of Org between 2011 and 2013, at a time when I desperately needed
+ a break.
- Eric Schulte and Dan Davison ::
- Eric and Dan are jointly responsible for the Org Babel system,
- which turns Org into a multi-language environment for evaluating
- code and doing literate programming and reproducible research.
- This has become one of Org's killer features that define what Org
- is today.
+ Eric and Dan are jointly responsible for the Org Babel system, which
+ turns Org into a multi-language environment for evaluating code and
+ doing literate programming and reproducible research. This has
+ become one of Org's killer features that define what Org is today.
- John Wiegley ::
- John has contributed a number of great ideas and patches directly
- to Org, including the attachment system (=org-attach.el=),
- integration with Apple Mail (=org-mac-message.el=), hierarchical
- dependencies of TODO items, habit tracking (=org-habits.el=), and
- encryption (=org-crypt.el=). Also, the capture system is really
- an extended copy of his great =remember.el=.
+ John has contributed a number of great ideas and patches directly to
+ Org, including the attachment system (=org-attach.el=), integration
+ with Apple Mail (=org-mac-message.el=), hierarchical dependencies of
+ TODO items, habit tracking (=org-habits.el=), and encryption
+ (=org-crypt.el=). Also, the capture system is really an extended
+ copy of his great =remember.el=.
- Sebastian Rose ::
- Without Sebastian, the HTML/XHTML publishing of Org would be the
- pitiful work of an ignorant amateur. Sebastian has pushed this
- part of Org onto a much higher level. He also wrote
- =org-info.js=, a Java script for displaying webpages derived from
- Org using an Info-like or a folding interface with single-key
- navigation.
+ Without Sebastian, the HTML/XHTML publishing of Org would be the
+ pitiful work of an ignorant amateur. Sebastian has pushed this part
+ of Org onto a much higher level. He also wrote =org-info.js=,
+ a JavaScript program for displaying webpages derived from Org using
+ an Info-like or a folding interface with single-key navigation.
See below for the full list of contributions! Again, please let me
know what I am missing here!
@@ -20540,34 +20723,32 @@ considered co-maintainers, either of the code or the community:
- Eric Schulte ::
- Eric is maintaining the Babel parts of Org. His reactivity here
- kept me away from worrying about possible bugs here and let me
- focus on other parts.
+ Eric is maintaining the Babel parts of Org. His reactivity here
+ kept me away from worrying about possible bugs here and let me focus
+ on other parts.
- Nicolas Goaziou ::
- Nicolas is maintaining the consistency of the deepest parts of
- Org. His work on =org-element.el= and =ox.el= has been
- outstanding, and it opened the doors for many new ideas and
- features. He rewrote many of the old exporters to use the new
- export engine, and helped with documenting this major change.
- More importantly (if that's possible), he has been more than
- reliable during all the work done for Org 8.0, and always very
- reactive on the mailing list.
+ Nicolas is maintaining the consistency of the deepest parts of Org.
+ His work on =org-element.el= and =ox.el= has been outstanding, and
+ it opened the doors for many new ideas and features. He rewrote
+ many of the old exporters to use the new export engine, and helped
+ with documenting this major change. More importantly (if that's
+ possible), he has been more than reliable during all the work done
+ for Org 8.0, and always very reactive on the mailing list.
- Achim Gratz ::
- Achim rewrote the building process of Org, turning some /ad hoc/
- tools into a flexible and conceptually clean process. He
- patiently coped with the many hiccups that such a change can
- create for users.
+ Achim rewrote the building process of Org, turning some /ad hoc/
+ tools into a flexible and conceptually clean process. He patiently
+ coped with the many hiccups that such a change can create for users.
- Nick Dokos ::
- The Org mode mailing list would not be such a nice place without
- Nick, who patiently helped users so many times. It is impossible
- to overestimate such a great help, and the list would not be so
- active without him.
+ The Org mode mailing list would not be such a nice place without
+ Nick, who patiently helped users so many times. It is impossible to
+ overestimate such a great help, and the list would not be so active
+ without him.
I received support from so many users that it is clearly impossible to
be fair when shortlisting a few of them, but Org's history would not
@@ -20580,14 +20761,14 @@ be complete if the ones above were not mentioned in this manual.
- Russel Adams came up with the idea for drawers.
-- Thomas Baumann wrote =org-bbdb.el= and =org-mhe.el=.
+- Thomas Baumann wrote =ol-bbdb.el= and =ol-mhe.el=.
- Christophe Bataillon created the great unicorn logo that we use on
the Org mode website.
- Alex Bochannek provided a patch for rounding timestamps.
-- Jan Böcker wrote =org-docview.el=.
+- Jan Böcker wrote =ol-docview.el=.
- Brad Bozarth showed how to pull RSS feed data into Org files.
@@ -20664,7 +20845,7 @@ be complete if the ones above were not mentioned in this manual.
- Manuel Hermenegildo has contributed various ideas, small fixes and
patches.
-- Phil Jackson wrote =org-irc.el=.
+- Phil Jackson wrote =ol-irc.el=.
- Scott Jaderholm proposed footnotes, control over whitespace between
folded entries, and column view for properties.
@@ -20769,7 +20950,7 @@ be complete if the ones above were not mentioned in this manual.
- Ulf Stegemann created the table to translate special symbols to
HTML, LaTeX, UTF-8, Latin-1 and ASCII.
-- Andy Stewart contributed code to =org-w3m.el=, to copy
+- Andy Stewart contributed code to =ol-w3m.el=, to copy
HTML content with links transformation to Org syntax.
- David O'Toole wrote =org-publish.el= and drafted the
@@ -20803,7 +20984,7 @@ be complete if the ones above were not mentioned in this manual.
- Piotr Zielinski wrote =org-mouse.el=, proposed agenda
blocks and contributed various ideas and code snippets.
-- Marco Wahl wrote =org-eww.el=.
+- Marco Wahl wrote =ol-eww.el=.
* GNU Free Documentation License
:PROPERTIES:
@@ -20811,7 +20992,7 @@ be complete if the ones above were not mentioned in this manual.
:DESCRIPTION: The license for this documentation.
:END:
-#+texinfo: @include doclicense.texi
+#+include: fdl.org
* Main Index
:PROPERTIES:
@@ -20864,51 +21045,14 @@ modify this GNU manual."
* Export Setup :noexport:
-#+subtitle: Release {{{version}}}
-#+author: The Org Mode Developers
-#+date: {{{modification-time}}}
-#+language: en
-
-# XXX: We cannot use TODO keyword as a node starts with "TODO".
-#+todo: REVIEW FIXME | DONE
-#+property: header-args :eval no
-#+startup: overview nologdone
+#+setupfile: doc-setup.org
#+export_file_name: org.texi
-#+texinfo_dir_category: Emacs editing modes
+#+texinfo_dir_category: Emacs
#+texinfo_dir_title: Org Mode: (org)
#+texinfo_dir_desc: Outline-based notes management and organizer
-# Use proper quote and backtick for code sections in PDF output
-# Cf. Texinfo manual 14.2
-#+texinfo_header: @set txicodequoteundirected
-#+texinfo_header: @set txicodequotebacktick
-
-# Contact Info
-#+texinfo_header: @set MAINTAINERSITE @uref{https://orgmode.org,maintainers webpage}
-#+texinfo_header: @set MAINTAINER Carsten Dominik
-#+texinfo_header: @set MAINTAINEREMAIL @email{carsten at orgmode dot org}
-#+texinfo_header: @set MAINTAINERCONTACT @uref{mailto:carsten at orgmode dot org,contact the maintainer}
-
-#+options: H:4 num:t toc:t author:t \n:nil ::t |:t ^:nil -:t f:t *:t <:t e:t ':t
-#+options: d:nil todo:nil pri:nil tags:not-in-toc stat:nil broken-links:mark
-#+select_tags: export
-#+exclude_tags: noexport
-
-#+macro: cite @@texinfo:@cite{@@$1@@texinfo:}@@
-#+macro: var @@texinfo:@var{@@$1@@texinfo:}@@
-
-# The "version" macro extracts "Version" keyword from "org.el". It
-# returns major.minor version number. This is sufficient since bugfix
-# releases are not expected to add features and therefore imply manual
-# modifications.
-#+macro: version (eval (with-current-buffer (find-file-noselect "../lisp/org.el") (org-with-point-at 1 (if (re-search-forward "Version: +\\([0-9.]+\\)" nil t) (mapconcat #'identity (cl-subseq (split-string (match-string-no-properties 1) "\\.") 0 2) ".") (error "Missing \"Version\" keyword in \"org.el\"")))))
-
-# The "kbd" macro turns KBD into @kbd{KBD}. Additionnally, it
-# encloses case-sensitive special keys (SPC, RET...) within @key{...}.
-#+macro: kbd (eval (let ((case-fold-search nil) (regexp (regexp-opt '("SPC" "RET" "LFD" "TAB" "BS" "ESC" "DELETE" "SHIFT" "Ctrl" "Meta" "Alt" "Cmd" "Super" "UP" "LEFT" "RIGHT" "DOWN") 'words))) (format "@@texinfo:@kbd{@@%s@@texinfo:}@@" (replace-regexp-in-string regexp "@@texinfo:@key{@@\\&@@texinfo:}@@" $1 t))))
-
* Footnotes
[fn:1] If you do not use Font Lock globally turn it on in Org buffer
@@ -20928,7 +21072,7 @@ stars.
[fn:5] The indirect buffer contains the entire buffer, but is narrowed
to the current tree. Editing the indirect buffer also changes the
original buffer, but without affecting visibility in that buffer. For
-more information about indirect buffers, see [[info:emacs#Indirect%20Buffers][GNU Emacs Manual]].
+more information about indirect buffers, see [[info:emacs#Indirect Buffers][GNU Emacs Manual]].
[fn:6] When ~org-agenda-inhibit-startup~ is non-~nil~, Org does not
honor the default visibility state when first opening a file for the
@@ -20969,177 +21113,171 @@ variable ~org-M-RET-may-split-line~.
[fn:16] Many desktops intercept {{{kbd(M-TAB)}}} to switch windows.
Use {{{kbd(C-M-i)}}} or {{{kbd(ESC TAB)}}} instead.
-[fn:17] The corresponding in-buffer setting is: =#+STARTUP: fninline=
-or =#+STARTUP: nofninline=.
-
-[fn:18] The corresponding in-buffer options are =#+STARTUP: fnadjust=
-and =#+STARTUP: nofnadjust=.
-
-[fn:19] To insert a vertical bar into a table field, use =\vert= or,
+[fn:17] To insert a vertical bar into a table field, use =\vert= or,
inside a word =abc\vert{}def=.
-[fn:20] Org understands references typed by the user as =B4=, but it
+[fn:18] Org understands references typed by the user as =B4=, but it
does not use this syntax when offering a formula for editing. You can
customize this behavior using the variable
~org-table-use-standard-references~.
-[fn:21] The computation time scales as O(N^2) because table
+[fn:19] The computation time scales as O(N^2) because table
{{{var(FOO)}}} is parsed for each field to be copied.
-[fn:22] The file =constants.el= can supply the values of constants in
+[fn:20] The file =constants.el= can supply the values of constants in
two different unit systems, =SI= and =cgs=. Which one is used depends
on the value of the variable ~constants-unit-system~. You can use the
=STARTUP= options =constSI= and =constcgs= to set this value for the
current buffer.
-[fn:23] The printf reformatting is limited in precision because the
+[fn:21] The printf reformatting is limited in precision because the
value passed to it is converted into an "integer" or "double". The
"integer" is limited in size by truncating the signed value to 32
bits. The "double" is limited in precision to 64 bits overall which
leaves approximately 16 significant decimal digits.
-[fn:24] Such names must start with an alphabetic character and use
+[fn:22] Such names must start with an alphabetic character and use
only alphanumeric/underscore characters.
-[fn:25] Plain URIs are recognized only for a well-defined set of
+[fn:23] Plain URIs are recognized only for a well-defined set of
schemes. See [[*External Links]]. Unlike URI syntax, they cannot contain
parenthesis or white spaces, either. URIs within angle brackets have
no such limitation.
-[fn:26] More accurately, the precise behavior depends on how point
-arrived there---see [[info:elisp#Invisible%20Text][Invisible Text]].
+[fn:24] More accurately, the precise behavior depends on how point
+arrived there---see [[info:elisp#Invisible Text][Invisible Text]].
-[fn:27] To insert a link targeting a headline, in-buffer completion
+[fn:25] To insert a link targeting a headline, in-buffer completion
can be used. Just type a star followed by a few optional letters into
the buffer and press {{{kbd(M-TAB)}}}. All headlines in the current
buffer are offered as completions.
-[fn:28] When targeting a =NAME= keyword, the =CAPTION= keyword is
+[fn:26] When targeting a =NAME= keyword, the =CAPTION= keyword is
mandatory in order to get proper numbering (see [[*Captions]]).
-[fn:29] The actual behavior of the search depends on the value of the
+[fn:27] The actual behavior of the search depends on the value of the
variable ~org-link-search-must-match-exact-headline~. If its value is
~nil~, then a fuzzy text search is done. If it is ~t~, then only the
exact headline is matched, ignoring spaces and statistic cookies. If
the value is ~query-to-create~, then an exact headline is searched; if
it is not found, then the user is queried to create it.
-[fn:30] If the headline contains a timestamp, it is removed from the
+[fn:28] If the headline contains a timestamp, it is removed from the
link, which results in a wrong link---you should avoid putting
a timestamp in the headline.
-[fn:31] The Org Id library must first be loaded, either through
+[fn:29] The Org Id library must first be loaded, either through
~org-customize~, by enabling ~id~ in ~org-modules~, or by adding
=(require 'org-id)= in your Emacs init file.
-[fn:32] Note that you do not have to use this command to insert
+[fn:30] Note that you do not have to use this command to insert
a link. Links in Org are plain text, and you can type or paste them
straight into the buffer. By using this command, the links are
automatically enclosed in double brackets, and you will be asked for
the optional descriptive text.
-[fn:33] After insertion of a stored link, the link will be removed
+[fn:31] After insertion of a stored link, the link will be removed
from the list of stored links. To keep it in the list for later use,
use a triple {{{kbd(C-u)}}} prefix argument to {{{kbd(C-c C-l)}}}, or
-configure the option ~org-keep-stored-link-after-insertion~.
+configure the option ~org-link-keep-stored-after-insertion~.
-[fn:34] This works if a function has been defined in the ~:complete~
+[fn:32] This works if a function has been defined in the ~:complete~
property of a link in ~org-link-parameters~.
-[fn:35] See the variable ~org-display-internal-link-with-indirect-buffer~.
+[fn:33] See the variable ~org-link-use-indirect-buffer-for-internals~.
-[fn:36] For backward compatibility, line numbers can also follow a
+[fn:34] For backward compatibility, line numbers can also follow a
single colon.
-[fn:37] Of course, you can make a document that contains only long
+[fn:35] Of course, you can make a document that contains only long
lists of TODO items, but this is not required.
-[fn:38] Changing the variable ~org-todo-keywords~ only becomes
+[fn:36] Changing the variable ~org-todo-keywords~ only becomes
effective after restarting Org mode in a buffer.
-[fn:39] This is also true for the {{{kbd(t)}}} command in the agenda
+[fn:37] This is also true for the {{{kbd(t)}}} command in the agenda
buffer.
-[fn:40] All characters are allowed except =@=, =^= and =!=, which have
+[fn:38] All characters are allowed except =@=, =^= and =!=, which have
a special meaning here.
-[fn:41] Check also the variable ~org-fast-tag-selection-include-todo~,
+[fn:39] Check also the variable ~org-fast-tag-selection-include-todo~,
it allows you to change the TODO state through the tags interface (see
[[*Setting Tags]]), in case you like to mingle the two concepts. Note
that this means you need to come up with unique keys across both sets
of keywords.
-[fn:42] Org mode parses these lines only when Org mode is activated
+[fn:40] Org mode parses these lines only when Org mode is activated
after visiting a file. {{{kbd(C-c C-c)}}} with point in a line
starting with =#+= is simply restarting Org mode for the current
buffer.
-[fn:43] The corresponding in-buffer setting is: =#+STARTUP: logdone=.
+[fn:41] The corresponding in-buffer setting is: =#+STARTUP: logdone=.
-[fn:44] The corresponding in-buffer setting is: =#+STARTUP:
+[fn:42] The corresponding in-buffer setting is: =#+STARTUP:
lognotedone=.
-[fn:45] See the variable ~org-log-states-order-reversed~.
+[fn:43] See the variable ~org-log-states-order-reversed~.
-[fn:46] Note that the =LOGBOOK= drawer is unfolded when pressing
+[fn:44] Note that the =LOGBOOK= drawer is unfolded when pressing
{{{kbd(SPC)}}} in the agenda to show an entry---use {{{kbd(C-u
SPC)}}} to keep it folded here.
-[fn:47] It is possible that Org mode records two timestamps when you
+[fn:45] It is possible that Org mode records two timestamps when you
are using both ~org-log-done~ and state change logging. However, it
never prompts for two notes: if you have configured both, the state
change recording note takes precedence and cancel the closing note.
-[fn:48] See also the option ~org-priority-start-cycle-with-default~.
+[fn:46] See also the option ~org-priority-start-cycle-with-default~.
-[fn:49] To keep subtasks out of the global TODO list, see the option
+[fn:47] To keep subtasks out of the global TODO list, see the option
~org-agenda-todo-list-sublevels~.
-[fn:50] With the exception of description lists. But you can allow it
+[fn:48] With the exception of description lists. But you can allow it
by modifying ~org-list-automatic-rules~ accordingly.
-[fn:51] Set the variable ~org-hierarchical-checkbox-statistics~ if you
+[fn:49] Set the variable ~org-hierarchical-checkbox-statistics~ if you
want such cookies to count all checkboxes below the cookie, not just
those belonging to direct children.
-[fn:52] {{{kbd(C-u C-c C-c)}}} on the /first/ item of a list with no
+[fn:50] {{{kbd(C-u C-c C-c)}}} on the /first/ item of a list with no
checkbox adds checkboxes to the rest of the list.
-[fn:53] As with all these in-buffer settings, pressing {{{kbd(C-c
+[fn:51] As with all these in-buffer settings, pressing {{{kbd(C-c
C-c)}}} activates any changes in the line.
-[fn:54] This is only true if the search does not involve more complex
+[fn:52] This is only true if the search does not involve more complex
tests including properties (see [[*Property Searches]]).
-[fn:55] To extend this default list to all tags used in all agenda
+[fn:53] To extend this default list to all tags used in all agenda
files (see [[*Agenda Views]]), customize the variable
~org-complete-tags-always-offer-all-agenda-tags~.
-[fn:56] Keys are automatically assigned to tags that have no
+[fn:54] Keys are automatically assigned to tags that have no
configured keys.
-[fn:57] If more than one summary type applies to the same property,
+[fn:55] If more than one summary type applies to the same property,
the parent values are computed according to the first of them.
-[fn:58] An age can be defined as a duration, using units defined in
+[fn:56] An age can be defined as a duration, using units defined in
~org-duration-units~, e.g., =3d 1h=. If any value in the column is as
such, the summary is also expressed as a duration.
-[fn:59] Please note that the =COLUMNS= definition must be on a single
+[fn:57] Please note that the =COLUMNS= definition must be on a single
line; it is wrapped here only because of formatting constraints.
-[fn:60] Contributed packages are not part of Emacs, but are
+[fn:58] Contributed packages are not part of Emacs, but are
distributed with the main distribution of Org---visit
[[https://orgmode.org]].
-[fn:61] The Org date format is inspired by the standard ISO 8601
+[fn:59] The Org date format is inspired by the standard ISO 8601
date/time format. To use an alternative format, see [[*Custom time
format]]. The day name is optional when you type the date yourself.
However, any date inserted or modified by Org adds that day name, for
reading convenience.
-[fn:62] When working with the standard diary sexp functions, you need
-to be very careful with the order of the arguments. That order
+[fn:60] When working with the standard diary expression functions, you
+need to be very careful with the order of the arguments. That order
depends evilly on the variable ~calendar-date-style~. For example, to
specify a date December 12, 2005, the call might look like
=(diary-date 12 1 2005)= or =(diary-date 1 12 2005)= or =(diary-date
@@ -21150,70 +21288,70 @@ like the corresponding ~diary-~ functions, but with stable ISO order
of arguments (year, month, day) wherever applicable, independent of
the value of ~calendar-date-style~.
-[fn:63] See the variable ~org-read-date-prefer-future~. You may set
+[fn:61] See the variable ~org-read-date-prefer-future~. You may set
that variable to the symbol ~time~ to even make a time before now
shift the date to tomorrow.
-[fn:64] If you do not need/want the calendar, configure the variable
+[fn:62] If you do not need/want the calendar, configure the variable
~org-popup-calendar-for-date-prompt~.
-[fn:65] If you find this distracting, turn off the display with
+[fn:63] If you find this distracting, turn off the display with
~org-read-date-display-live~.
-[fn:66] It will still be listed on that date after it has been marked
-DONE. If you do not like this, set the variable
+[fn:64] It will still be listed on that date after it has been marked
+as done. If you do not like this, set the variable
~org-agenda-skip-scheduled-if-done~.
-[fn:67] The =SCHEDULED= and =DEADLINE= dates are inserted on the line
+[fn:65] The =SCHEDULED= and =DEADLINE= dates are inserted on the line
right below the headline. Do not put any text between this line and
the headline.
-[fn:68] Note the corresponding =STARTUP= options =logredeadline=,
+[fn:66] Note the corresponding =STARTUP= options =logredeadline=,
=lognoteredeadline=, and =nologredeadline=.
-[fn:69] Note the corresponding =STARTUP= options =logreschedule=,
+[fn:67] Note the corresponding =STARTUP= options =logreschedule=,
=lognotereschedule=, and =nologreschedule=.
-[fn:70] Org does not repeat inactive timestamps, however. See
-[[*Timestamps, Deadlines and Scheduling]].
+[fn:68] Org does not repeat inactive timestamps, however. See
+[[*Timestamps]].
-[fn:71] In fact, the target state is taken from, in this sequence, the
+[fn:69] In fact, the target state is taken from, in this sequence, the
=REPEAT_TO_STATE= property, the variable ~org-todo-repeat-to-state~ if
it is a string, the previous TODO state if ~org-todo-repeat-to-state~
is ~t~, or the first state of the TODO state sequence.
-[fn:72] You can change this using the option ~org-log-repeat~, or the
+[fn:70] You can change this using the option ~org-log-repeat~, or the
=STARTUP= options =logrepeat=, =lognoterepeat=, and =nologrepeat=.
With =lognoterepeat=, you will also be prompted for a note.
-[fn:73] Clocking only works if all headings are indented with less
+[fn:71] Clocking only works if all headings are indented with less
than 30 stars. This is a hard-coded limitation of ~lmax~ in
~org-clock-sum~.
-[fn:74] To resume the clock under the assumption that you have worked
+[fn:72] To resume the clock under the assumption that you have worked
on this task while outside Emacs, use =(setq org-clock-persist t)=.
-[fn:75] To add an effort estimate "on the fly", hook a function doing
+[fn:73] To add an effort estimate "on the fly", hook a function doing
this to ~org-clock-in-prepare-hook~.
-[fn:76] The last reset of the task is recorded by the =LAST_REPEAT=
+[fn:74] The last reset of the task is recorded by the =LAST_REPEAT=
property.
-[fn:77] See also the variable ~org-clock-mode-line-total~.
+[fn:75] See also the variable ~org-clock-mode-line-total~.
-[fn:78] The corresponding in-buffer setting is: =#+STARTUP:
+[fn:76] The corresponding in-buffer setting is: =#+STARTUP:
lognoteclock-out=.
-[fn:79] When using ~:step~, ~untilnow~ starts from the beginning of
+[fn:77] When using ~:step~, ~untilnow~ starts from the beginning of
2003, not the beginning of time.
-[fn:80] Language terms can be set through the variable
+[fn:78] Language terms can be set through the variable
~org-clock-clocktable-language-setup~.
-[fn:81] Note that all parameters must be specified in a single
+[fn:79] Note that all parameters must be specified in a single
line---the line is broken here only to fit it into the manual.
-[fn:82] On computers using macOS, idleness is based on actual user
+[fn:80] On computers using macOS, idleness is based on actual user
idleness, not just Emacs' idle time. For X11, you can install
a utility program =x11idle.c=, available in the =contrib/scripts/=
directory of the Org Git distribution, or install the xprintidle
@@ -21221,293 +21359,290 @@ package and set it to the variable ~org-clock-x11idle-program-name~ if
you are running Debian, to get the same general treatment of idleness.
On other systems, idle time refers to Emacs idle time only.
-[fn:83] Please note the pitfalls of summing hierarchical data in
+[fn:81] Please note the pitfalls of summing hierarchical data in
a flat list (see [[*Using Column View in the Agenda]]).
-[fn:84] Org used to offer four different targets for date/week tree
+[fn:82] Note the corresponding =STARTUP= options =logrefile=,
+=lognoterefile=, and =nologrefile=.
+
+[fn:83] Org used to offer four different targets for date/week tree
capture. Now, Org automatically translates these to use
~file+olp+datetree~, applying the ~:time-prompt~ and ~:tree-type~
properties. Please rewrite your date/week-tree targets using
~file+olp+datetree~ since the older targets are now deprecated.
-[fn:85] A date tree is an outline structure with years on the highest
+[fn:84] A date tree is an outline structure with years on the highest
level, months or ISO weeks as sublevels and then dates on the lowest
level. Tags are allowed in the tree structure.
-[fn:86] If you need one of these sequences literally, escape the =%=
+[fn:85] If you need one of these sequences literally, escape the =%=
with a backslash.
-[fn:87] If you define your own link types (see [[*Adding Hyperlink
+[fn:86] If you define your own link types (see [[*Adding Hyperlink
Types]]), any property you store with ~org-store-link-props~ can be
accessed in capture templates in a similar way.
-[fn:88] This is always the other, not the user. See the variable
-~org-from-is-user-regexp~.
+[fn:87] This is always the other, not the user. See the variable
+~org-link-from-user-regexp~.
-[fn:89] If you move entries or Org files from one directory to
-another, you may want to configure ~org-attach-directory~ to contain
+[fn:88] If you move entries or Org files from one directory to
+another, you may want to configure ~org-attach-id-dir~ to contain
an absolute path.
-[fn:90] Note the corresponding =STARTUP= options =logrefile=,
-=lognoterefile=, and =nologrefile=.
-
-[fn:91] If the value of that variable is not a list, but a single file
+[fn:89] If the value of that variable is not a list, but a single file
name, then the list of agenda files in maintained in that external
file.
-[fn:92] When using the dispatcher, pressing {{{kbd(<)}}} before
+[fn:90] When using the dispatcher, pressing {{{kbd(<)}}} before
selecting a command actually limits the command to the current file,
and ignores ~org-agenda-files~ until the next dispatcher command.
-[fn:93] For backward compatibility, you can also press {{{kbd(1)}}} to
+[fn:91] For backward compatibility, you can also press {{{kbd(1)}}} to
restrict to the current buffer.
-[fn:94] For backward compatibility, you can also press {{{kbd(0)}}} to
+[fn:92] For backward compatibility, you can also press {{{kbd(0)}}} to
restrict to the current region/subtree.
-[fn:95] For backward compatibility, the universal prefix argument
+[fn:93] For backward compatibility, the universal prefix argument
{{{kbd(C-u)}}} causes all TODO entries to be listed before the agenda.
This feature is deprecated, use the dedicated TODO list, or a block
agenda instead (see [[*Block agenda]]).
-[fn:96] The variable ~org-anniversary~ used in the example is just
+[fn:94] The variable ~org-anniversary~ used in the example is just
like ~diary-anniversary~, but the argument order is always according
to ISO and therefore independent of the value of
~calendar-date-style~.
-[fn:97] You can, however, disable this by setting
+[fn:95] You can, however, disable this by setting
~org-agenda-search-headline-for-time~ variable to a ~nil~ value.
-[fn:98] Custom commands can preset a filter by binding the variable
-~org-agenda-tag-filter-preset~ as an option. This filter is then
-applied to the view and persists as a basic filter through refreshes
-and more secondary filtering. The filter is a global property of the
-entire agenda view---in a block agenda, you should only set this in
-the global options section, not in the section of an individual block.
-
-[fn:99] Only tags filtering is respected here, effort filtering is
+[fn:96] Custom agenda commands can preset a filter by binding one of
+the variables ~org-agenda-tag-filter-preset~,
+~org-agenda-category-filter-preset~, ~org-agenda-effort-filter-preset~
+or ~org-agenda-regexp-filter-preset~ as an option. This filter is
+then applied to the view and persists as a basic filter through
+refreshes and more secondary filtering. The filter is a global
+property of the entire agenda view---in a block agenda, you should
+only set this in the global options section, not in the section of an
+individual block.
+
+[fn:97] Only tags filtering is respected here, effort filtering is
ignored.
-[fn:100] You can also create persistent custom functions through
+[fn:98] You can also create persistent custom functions through
~org-agenda-bulk-custom-functions~.
-[fn:101] This file is parsed for the agenda when
+[fn:99] This file is parsed for the agenda when
~org-agenda-include-diary~ is set.
-[fn:102] You can provide a description for a prefix key by inserting
+[fn:100] You can provide a description for a prefix key by inserting
a cons cell with the prefix and the description.
-[fn:103] /Planned/ means here that these entries have some planning
+[fn:101] /Planned/ means here that these entries have some planning
information attached to them, like a time-stamp, a scheduled or
a deadline string. See ~org-agenda-entry-types~ on how to set what
planning information is taken into account.
-[fn:104] For HTML you need to install Hrvoje Nikšić's =htmlize.el=
-from [[https://github.com/hniksic/emacs-htmlize][Hrvoje Nikšić's repository]].
+[fn:102] For HTML you need to install Hrvoje Nikšić's =htmlize.el=
+as an Emacs package from MELPA or from [[https://github.com/hniksic/emacs-htmlize][Hrvoje Nikšić's repository]].
-[fn:105] To create PDF output, the Ghostscript ps2pdf utility must be
+[fn:103] To create PDF output, the Ghostscript ps2pdf utility must be
installed on the system. Selecting a PDF file also creates the
postscript file.
-[fn:106] If you want to store standard views like the weekly agenda or
+[fn:104] If you want to store standard views like the weekly agenda or
the global TODO list as well, you need to define custom commands for
them in order to be able to specify file names.
-[fn:107] Quoting depends on the system you use, please check the FAQ
+[fn:105] Quoting depends on the system you use, please check the FAQ
for examples.
-[fn:108] You can turn this on by default by setting the variable
+[fn:106] You can turn this on by default by setting the variable
~org-pretty-entities~, or on a per-file base with the =STARTUP= option
=entitiespretty=.
-[fn:109] This behavior can be disabled with =-= export setting (see
+[fn:107] This behavior can be disabled with =-= export setting (see
[[*Export Settings]]).
-[fn:110] LaTeX is a macro system based on Donald\nbsp{}E.\nbsp{}Knuth's TeX
+[fn:108] LaTeX is a macro system based on Donald\nbsp{}E.\nbsp{}Knuth's TeX
system. Many of the features described here as "LaTeX" are really
from TeX, but for simplicity I am blurring this distinction.
-[fn:111] When MathJax is used, only the environments recognized by
+[fn:109] When MathJax is used, only the environments recognized by
MathJax are processed. When dvipng, dvisvgm, or ImageMagick suite is
used to create images, any LaTeX environment is handled.
-[fn:112] These are respectively available at
+[fn:110] These are respectively available at
[[http://sourceforge.net/projects/dvipng/]], [[http://dvisvgm.bplaced.net/]]
and from the ImageMagick suite. Choose the converter by setting the
variable ~org-preview-latex-default-process~ accordingly.
-[fn:113] Org mode has a method to test if point is inside such
+[fn:111] Org mode has a method to test if point is inside such
a fragment, see the documentation of the function
~org-inside-LaTeX-fragment-p~.
-[fn:114] This works automatically for the HTML backend (it requires
+[fn:112] This works automatically for the HTML backend (it requires
version 1.34 of the =htmlize.el= package, which you need to install).
Fontified code chunks in LaTeX can be achieved using either the
[[https://www.ctan.org/pkg/listings][listings]] package or the [[https://www.ctan.org/pkg/minted][minted]] package. Refer to
~org-export-latex-listings~ for details.
-[fn:115] Source code in code blocks may also be evaluated either
+[fn:113] Source code in code blocks may also be evaluated either
interactively or on export. See [[*Working with Source Code]] for more
information on evaluating code blocks.
-[fn:116] Adding =-k= to =-n -r= /keeps/ the labels in the source code
+[fn:114] Adding =-k= to =-n -r= /keeps/ the labels in the source code
while using line numbers for the links, which might be useful to
explain those in an Org mode example code.
-[fn:117] Upon exit, lines starting with =*=, =,*=, =#+= and =,#+= get
-a comma prepended, to keep them from being interpreted by Org as
-outline nodes or special syntax. These commas are stripped when
-editing with {{{kbd(C-c ')}}}, and also before export.
-
-[fn:118] You may select a different-mode with the variable
+[fn:115] You may select a different mode with the variable
~org-edit-fixed-width-region-mode~.
-[fn:119] What Emacs considers to be an image depends on
+[fn:116] What Emacs considers to be an image depends on
~image-file-name-extensions~ and ~image-file-name-regexps~.
-[fn:120] The variable ~org-startup-with-inline-images~ can be set
+[fn:117] The variable ~org-startup-with-inline-images~ can be set
within a buffer with the =STARTUP= options =inlineimages= and
=noinlineimages=.
-[fn:121] The variable ~org-export-date-timestamp-format~ defines how
+[fn:118] The corresponding in-buffer setting is: =#+STARTUP: fninline=
+or =#+STARTUP: nofninline=.
+
+[fn:119] The corresponding in-buffer options are =#+STARTUP: fnadjust=
+and =#+STARTUP: nofnadjust=.
+
+[fn:120] The variable ~org-export-date-timestamp-format~ defines how
this timestamp are exported.
-[fn:122] For export to LaTeX format---or LaTeX-related formats such as
+[fn:121] For export to LaTeX format---or LaTeX-related formats such as
Beamer---, the =org-latex-package-alist= variable needs further
configuration. See [[LaTeX specific export settings]].
-[fn:123] At the moment, some export back-ends do not obey this
+[fn:122] At the moment, some export back-ends do not obey this
specification. For example, LaTeX export excludes every unnumbered
headline from the table of contents.
-[fn:124] Note that ~org-link-search-must-match-exact-headline~ is
+[fn:123] Note that ~org-link-search-must-match-exact-headline~ is
locally bound to non-~nil~. Therefore, ~org-link-search~ only matches
headlines and named elements.
-[fn:125] Since commas separate the arguments, commas within arguments
+[fn:124] Since commas separate the arguments, commas within arguments
have to be escaped with the backslash character. So only those
backslash characters before a comma need escaping with another
backslash character.
-[fn:126] For a less drastic behavior, consider using a select tag (see
+[fn:125] For a less drastic behavior, consider using a select tag (see
[[*Export Settings]]) instead.
-[fn:127] If =BEAMER_ENV= is set, Org export adds =B_environment= tag
+[fn:126] If =BEAMER_ENV= is set, Org export adds =B_environment= tag
to make it visible. The tag serves as a visual aid and has no
semantic relevance.
-[fn:128] By default Org loads MathJax from [[https://cdnjs.com][cdnjs.com]] as recommended by
+[fn:127] By default Org loads MathJax from [[https://cdnjs.com][cdnjs.com]] as recommended by
[[http://www.mathjax.org][MathJax]].
-[fn:129] Please note that exported formulas are part of an HTML
+[fn:128] Please note that exported formulas are part of an HTML
document, and that signs such as =<=, =>=, or =&= have special
meanings. See [[http://docs.mathjax.org/en/latest/tex.html#tex-and-latex-in-html-documents][MathJax TeX and LaTeX support]].
-[fn:130] See [[http://docs.mathjax.org/en/latest/tex.html#tex-extensions][TeX and LaTeX extensions]] in the [[http://docs.mathjax.org][MathJax manual]] to learn
+[fn:129] See [[http://docs.mathjax.org/en/latest/tex.html#tex-extensions][TeX and LaTeX extensions]] in the [[http://docs.mathjax.org][MathJax manual]] to learn
about extensions.
-[fn:131] If the classes on TODO keywords and tags lead to conflicts,
+[fn:130] If the classes on TODO keywords and tags lead to conflicts,
use the variables ~org-html-todo-kwd-class-prefix~ and
~org-html-tag-class-prefix~ to make them unique.
-[fn:132] This does not allow setting different bibliography compilers
+[fn:131] This does not allow setting different bibliography compilers
for different files. However, "smart" LaTeX compilation systems, such
as latexmk, can select the correct bibliography compiler.
-[fn:133] See [[http://docs.oasis-open.org/office/v1.2/OpenDocument-v1.2.html][Open Document Format for Office Applications
+[fn:132] See [[http://docs.oasis-open.org/office/v1.2/OpenDocument-v1.2.html][Open Document Format for Office Applications
(OpenDocument) Version 1.2]].
-[fn:134] See [[http://www.mathtoweb.com/cgi-bin/mathtoweb_home.pl][MathToWeb]].
+[fn:133] See [[http://www.mathtoweb.com/cgi-bin/mathtoweb_home.pl][MathToWeb]].
-[fn:135] See [[http://dlmf.nist.gov/LaTeXML/]].
+[fn:134] See [[http://dlmf.nist.gov/LaTeXML/]].
-[fn:136] [[http://docs.oasis-open.org/office/v1.2/OpenDocument-v1.2.html][OpenDocument-v1.2 Specification]]
+[fn:135] [[http://docs.oasis-open.org/office/v1.2/OpenDocument-v1.2.html][OpenDocument-v1.2 Specification]]
-[fn:137] See the =<table:table-template>= element of the
+[fn:136] See the =<table:table-template>= element of the
OpenDocument-v1.2 specification.
-[fn:138] See the attributes =table:template-name=,
+[fn:137] See the attributes =table:template-name=,
=table:use-first-row-styles=, =table:use-last-row-styles=,
=table:use-first-column-styles=, =table:use-last-column-styles=,
=table:use-banding-rows-styles=, and =table:use-banding-column-styles=
of the =<table:table>= element in the OpenDocument-v1.2 specification.
-[fn:139] If the publishing directory is the same as the source
+[fn:138] If the publishing directory is the same as the source
directory, =file.org= is exported as =file.org.org=, so you probably
do not want to do this.
-[fn:140] The option ~org-babel-no-eval-on-ctrl-c-ctrl-c~ can be used
+[fn:139] The option ~org-babel-no-eval-on-ctrl-c-ctrl-c~ can be used
to remove code evaluation from the {{{kbd(C-c C-c)}}} key binding.
-[fn:141] Actually, the constructs =call_<name>()= and =src_<lang>{}=
+[fn:140] Actually, the constructs =call_<name>()= and =src_<lang>{}=
are not evaluated when they appear in a keyword (see [[*Summary of
In-Buffer Settings]]).
-[fn:142] Due to the way this header argument is implemented, it
-implies ":results file". Therefore if it is set for multiple blocks
-at once (by a subtree or buffer property for example), all blocks are
-forced to produce file results. This is seldom desired behavior, so
-it is recommended to set this header only on a per-block basis. It is
-possible that this aspect of the implementation might change in the
-future.
-
-[fn:143] C++ language is handled in =ob-C.el=. Even though the
+[fn:141] C++ language is handled in =ob-C.el=. Even though the
identifier for such source blocks is =C++=, you activate it by loading
the C language.
-[fn:144] D language is handled in =ob-C.el=. Even though the
+[fn:142] D language is handled in =ob-C.el=. Even though the
identifier for such source blocks is =D=, you activate it by loading
the C language.
-[fn:145] For Noweb literate programming details, see
+[fn:143] For Noweb literate programming details, see
http://www.cs.tufts.edu/~nr/noweb/.
-[fn:146] For more information, please refer to the commentary section
+[fn:144] For more information, please refer to the commentary section
in =org-tempo.el=.
-[fn:147] Note that ~org-indent-mode~ also sets the ~wrap-prefix~
-property, such that ~visual-line-mode~ (or purely setting ~word-wrap~)
-wraps long lines (including headlines) correctly indented.
-
-[fn:148] The ~org-indent-mode~ also sets the ~wrap-prefix~ correctly
-for indenting and wrapping long lines of headlines or text. This
-minor mode handles ~visual-line-mode~ and directly applied settings
+[fn:145] Org Indent mode also sets ~wrap-prefix~ correctly for
+indenting and wrapping long lines of headlines or text. This minor
+mode also handles Visual Line mode and directly applied settings
through ~word-wrap~.
-[fn:149] Also see the variable ~org-adapt-indentation~.
+[fn:146] Note that turning on Org Indent mode sets
+~org-hide-leading-stars~ to ~t~ and ~org-adapt-indentation~ to ~nil~.
+
+[fn:147] This works, but requires extra effort. Org Indent mode is
+more convenient for most applications.
-[fn:150] Because =LEVEL=2= has 3 stars, =LEVEL=3= has 5 stars, and so
-on.
+[fn:148] Note that Org Indent mode also sets the ~wrap-prefix~
+property, such that Visual Line mode (or purely setting ~word-wrap~)
+wraps long lines, including headlines, correctly indented.
-[fn:151] For a server to host files, consider using a WebDAV server,
+[fn:149] For a server to host files, consider using a WebDAV server,
such as [[https://nextcloud.com][Nextcloud]]. Additional help is at this [[https://orgmode.org/worg/org-faq.html#mobileorg_webdav][FAQ entry]].
-[fn:152] If Emacs is configured for safe storing of passwords, then
+[fn:150] If Emacs is configured for safe storing of passwords, then
configure the variable ~org-mobile-encryption-password~; please read
the docstring of that variable.
-[fn:153] Symbolic links in ~org-directory~ need to have the same name
+[fn:151] Symbolic links in ~org-directory~ need to have the same name
as their targets.
-[fn:154] While creating the agendas, Org mode forces =ID= properties
+[fn:152] While creating the agendas, Org mode forces =ID= properties
on all referenced entries, so that these entries can be uniquely
identified if Org Mobile flags them for further action. To avoid
setting properties configure the variable
~org-mobile-force-id-on-agenda-items~ to ~nil~. Org mode then relies
on outline paths, assuming they are unique.
-[fn:155] Checksums are stored automatically in the file
+[fn:153] Checksums are stored automatically in the file
=checksums.dat=.
-[fn:156] The file will be empty after this operation.
+[fn:154] The file will be empty after this operation.
-[fn:157] https://www.ctan.org/pkg/comment
+[fn:155] https://www.ctan.org/pkg/comment
-[fn:158] By default this works only for LaTeX, HTML, and Texinfo.
+[fn:156] By default this works only for LaTeX, HTML, and Texinfo.
Configure the variable ~orgtbl-radio-table-templates~ to install
templates for other modes.
-[fn:159] If the =TBLFM= keyword contains an odd number of dollar
+[fn:157] If the =TBLFM= keyword contains an odd number of dollar
characters, this may cause problems with Font Lock in LaTeX mode. As
shown in the example you can fix this by adding an extra line inside
the =comment= environment that is used to balance the dollar
@@ -21515,9 +21650,9 @@ expressions. If you are using AUCTeX with the font-latex library,
a much better solution is to add the =comment= environment to the
variable ~LaTeX-verbatim-environments~.
-[fn:160] The ~agenda*~ view is the same as ~agenda~ except that it
+[fn:158] The ~agenda*~ view is the same as ~agenda~ except that it
only considers /appointments/, i.e., scheduled and deadline items that
have a time specification =[h]h:mm= in their time-stamps.
-[fn:161] Note that, for ~org-odd-levels-only~, a level number
+[fn:159] Note that, for ~org-odd-levels-only~, a level number
corresponds to order in the hierarchy, not to the number of stars.
diff --git a/doc/orgcard.tex b/doc/orgcard.tex
index ac10d27..9e01ec3 100644
--- a/doc/orgcard.tex
+++ b/doc/orgcard.tex
@@ -271,8 +271,10 @@
\def\threecol#1#2#3{\hskip\keyindent\relax#1\hfil&\kbd{#2}\hfil\quad
&\kbd{#3}\hfil\quad\cr}
-\def\noteone{{\small \hfill [1]}}
-\def\notetwo{{\small \hfill [2]}}
+%\def\noteone{{\small \hfill [1]}}
+%\def\notetwo{{\small \hfill [2]}}
+\def\noteone{{\small [1]}}
+\def\notetwo{{\small [2]}}
%**end of header
@@ -292,6 +294,7 @@
\key{restore property-dependent startup visibility}{C-u C-u TAB}
\metax{show the whole file, including drawers}{C-u C-u C-u TAB}
\key{reveal context around point}{C-c C-r}
+\metax{toggle indented view}{M-x org-indent-mode}
\section{Motion}
@@ -458,7 +461,7 @@ formula, \kbd{:=} a field formula.
\key{go to the next code block}{C-c C-v n}
\key{go to the previous code block}{C-c C-v p}
\key{demarcate a code block}{C-c C-v d}
-\key{execute the next key sequence in the code edit buffer}{C-c C-v x}
+\key{execute next key sequence in code edit buffer}{C-c C-v x}
\key{execute all code blocks in current buffer}{C-c C-v b}
\key{execute all code blocks in current subtree}{C-c C-v s}
\key{tangle code blocks in current file}{C-c C-v t}
@@ -468,13 +471,14 @@ formula, \kbd{:=} a field formula.
\key{load the current code block into a session}{C-c C-v l}
\key{view sha1 hash of the current code block}{C-c C-v a}
-\section{Completion}
+\section{Completion and Template Insertion}
In-buffer completion completes TODO keywords at headline start, TeX
macros after ``{\tt \\}'', option keywords after ``{\tt \#-}'', TAGS
after ``{\tt :}'', and dictionary words elsewhere.
\key{complete word at point}{M-TAB}
+\key{structure template (insert or wrap region)}{C-c C-,}
\newcolumn
@@ -485,8 +489,8 @@ after ``{\tt :}'', and dictionary words elsewhere.
\section{TODO Items and Checkboxes}
\key{rotate the state of the current item}{C-c C-t}
-\metax{select next/previous state}{S-LEFT/RIGHT}
-\metax{select next/previous set}{C-S-LEFT/RIGHT}
+\metax{select next/previous state}{\quad\quad S-LEFT/RIGHT}
+\metax{select next/previous set}{\quad\quad\quad C-S-LEFT/RIGHT}
\key{toggle ORDERED property}{C-c C-x o}
\key{view TODO items in a sparse tree}{C-c / t}
@@ -512,19 +516,19 @@ after ``{\tt :}'', and dictionary words elsewhere.
\key{set property/effort}{C-c C-x p/e}
\key{special commands in property lines}{C-c C-c}
-\key{next/previous allowed value}{S-left/right}
+\key{next/previous allowed value}{S-LEFT/RIGHT}
\key{turn on column view}{C-c C-x C-c}
\key{capture columns view in dynamic block}{C-c C-x i}
\key{quit column view}{q}
\key{show full value}{v}
\key{edit value}{e}
-\metax{next/previous allowed value}{n/p or S-left/right}
+\metax{next/previous allowed value}{n/p or S-LEFT/RIGHT}
\key{edit allowed values list}{a}
\key{make column wider/narrower}{> / <}
-\key{move column left/right}{M-left/right}
-\key{add new column}{M-S-right}
-\key{Delete current column}{M-S-left}
+\key{move column left/right}{M-LEFT/RIGHT}
+\key{add new column}{M-S-RIGHT}
+\key{Delete current column}{M-S-LEFT}
\section{Timestamps}
@@ -536,8 +540,8 @@ after ``{\tt :}'', and dictionary words elsewhere.
\key{insert SCHEDULED timestamp}{C-c C-s}
\key{create sparse tree with all deadlines due}{C-c / d}
\key{the time between 2 dates in a time range}{C-c C-y}
-\metax{change timestamp at cursor $\pm 1$ day}{S-RIGHT/LEFT\notetwo}
-\key{change year/month/day at cursor by $\pm 1$}{S-UP/DOWN\notetwo}
+\metax{change timestamp at cursor $\pm 1$ day}{\quad\quad\quad\quad S-RIGHT/LEFT \notetwo}
+\key{change year/month/day at cursor by $\pm 1$}{S-UP/DOWN \notetwo}
\key{access the calendar for the current date}{C-c >}
\key{insert timestamp matching date in calendar}{C-c <}
\key{access agenda for current date}{C-c C-o}
@@ -666,8 +670,6 @@ some other place.
\key{toggle fixed width for entry or region}{C-c :}
\key{toggle pretty display of scripts, entities}{C-c C-x {\tt\char`\\}}
-{\bf Comments: Text not being exported}
-
Lines starting with \kbd{\#} and subtrees starting with COMMENT are
never exported.
diff --git a/doc/orgguide.texi b/doc/orgguide.texi
deleted file mode 100644
index 704f079..0000000
--- a/doc/orgguide.texi
+++ /dev/null
@@ -1,2693 +0,0 @@
-\input texinfo
-@c %**start of header
-@setfilename ../../info/orgguide
-@settitle The compact Org-mode Guide
-
-@include org-version.inc
-
-@c Use proper quote and backtick for code sections in PDF output
-@c Cf. Texinfo manual 14.2
-@set txicodequoteundirected
-@set txicodequotebacktick
-
-@c Version and Contact Info
-@set MAINTAINERSITE @uref{https://orgmode.org,maintainers webpage}
-@set AUTHOR Carsten Dominik
-@set MAINTAINER Carsten Dominik
-@set MAINTAINEREMAIL @email{carsten at orgmode dot org}
-@set MAINTAINERCONTACT @uref{mailto:carsten at orgmode dot org,contact the maintainer}
-@c %**end of header
-@finalout
-
-@c Macro definitions
-@iftex
-@c @hyphenation{time-stamp time-stamps time-stamp-ing time-stamp-ed}
-@end iftex
-
-@c Subheadings inside a table.
-@macro tsubheading{text}
-@ifinfo
-@subsubheading \text\
-@end ifinfo
-@ifnotinfo
-@item @b{\text\}
-@end ifnotinfo
-@end macro
-
-@macro seealso{text}
-@noindent
-@b{Further reading}@*@noindent \text\
-@end macro
-@copying
-
-Copyright @copyright{} 2010--2019 Free Software Foundation
-
-@quotation
-Permission is granted to copy, distribute and/or modify this document
-under the terms of the GNU Free Documentation License, Version 1.3 or
-any later version published by the Free Software Foundation; with no
-Invariant Sections, with the Front-Cover Texts being ``A GNU Manual,''
-and with the Back-Cover Texts as in (a) below. A copy of the license
-is included in the section entitled ``GNU Free Documentation License''
-in the full Org manual, which is distributed together with the compact
-guide.
-
-(a) The FSF's Back-Cover Text is: ``You have the freedom to copy and
-modify this GNU manual.''
-@end quotation
-@end copying
-
-@dircategory Emacs
-@direntry
-* Org Mode Guide: (orgguide). Abbreviated Org-mode Manual
-@end direntry
-
-@titlepage
-@title The compact Org-mode Guide
-
-@subtitle Release @value{VERSION}
-@author by Carsten Dominik
-
-@c The following two commands start the copyright page.
-@page
-@vskip 0pt plus 1filll
-@insertcopying
-@end titlepage
-
-@c Output the table of contents at the beginning.
-@shortcontents
-
-@ifnottex
-@node Top, Introduction, (dir), (dir)
-@top Org Mode Guide
-
-@insertcopying
-@end ifnottex
-
-@menu
-* Introduction:: Getting started
-* Document Structure:: A tree works like your brain
-* Tables:: Pure magic for quick formatting
-* Hyperlinks:: Notes in context
-* TODO Items:: Every tree branch can be a TODO item
-* Tags:: Tagging headlines and matching sets of tags
-* Properties:: Properties
-* Dates and Times:: Making items useful for planning
-* Capture - Refile - Archive:: The ins and outs for projects
-* Agenda Views:: Collecting information into views
-* Markup:: Prepare text for rich export
-* Exporting:: Sharing and publishing of notes
-* Publishing:: Create a web site of linked Org files
-* Working With Source Code:: Source code snippets embedded in Org
-* Miscellaneous:: All the rest which did not fit elsewhere
-
-* GNU Free Documentation License:: This manual license.
-
-@detailmenu
- --- The Detailed Node Listing ---
-
-Introduction
-
-* Preface:: Welcome
-* Installation:: How to install a downloaded version of Org
-* Activation:: How to activate Org for certain buffers
-* Feedback:: Bug reports, ideas, patches etc.
-
-Document Structure
-
-* Outlines:: Org is based on Outline mode
-* Headlines:: How to typeset Org tree headlines
-* Visibility cycling:: Show and hide, much simplified
-* Motion:: Jumping to other headlines
-* Structure editing:: Changing sequence and level of headlines
-* Sparse trees:: Matches embedded in context
-* Plain lists:: Additional structure within an entry
-* Footnotes:: How footnotes are defined in Org's syntax
-
-Hyperlinks
-
-* Link format:: How links in Org are formatted
-* Internal links:: Links to other places in the current file
-* External links:: URL-like links to the world
-* Handling links:: Creating, inserting and following
-* Targeted links:: Point at a location in a file
-
-TODO Items
-
-* Using TODO states:: Setting and switching states
-* Multi-state workflows:: More than just on/off
-* Progress logging:: Dates and notes for progress
-* Priorities:: Some things are more important than others
-* Breaking down tasks:: Splitting a task into manageable pieces
-* Checkboxes:: Tick-off lists
-
-Progress logging
-
-* Closing items:: When was this entry marked DONE?
-* Tracking TODO state changes:: When did the status change?
-
-Tags
-
-* Tag inheritance:: Tags use the tree structure of the outline
-* Setting tags:: How to assign tags to a headline
-* Tag groups:: Use one tag to search for several tags
-* Tag searches:: Searching for combinations of tags
-
-Dates and Times
-
-* Timestamps:: Assigning a time to a tree entry
-* Creating timestamps:: Commands which insert timestamps
-* Deadlines and scheduling:: Planning your work
-* Clocking work time:: Tracking how long you spend on a task
-
-Capture - Refile - Archive
-
-* Capture:: Capturing new stuff
-* Refile and copy:: Moving a tree from one place to another
-* Archiving:: What to do with finished projects
-
-Capture
-
-* Setting up a capture location:: Where notes will be stored
-* Using capture:: Commands to invoke and terminate capture
-* Capture templates:: Define the outline of different note types
-
-Agenda Views
-
-* Agenda files:: Files being searched for agenda information
-* Agenda dispatcher:: Keyboard access to agenda views
-* Built-in agenda views:: What is available out of the box?
-* Agenda commands:: Remote editing of Org trees
-* Custom agenda views:: Defining special searches and views
-
-The built-in agenda views
-
-* Weekly/daily agenda:: The calendar page with current tasks
-* Global TODO list:: All unfinished action items
-* Matching tags and properties:: Structured information with fine-tuned search
-* Search view:: Find entries by searching for text
-
-Markup for rich export
-
-* Structural markup elements:: The basic structure as seen by the exporter
-* Images and tables:: Images, tables and caption mechanism
-* Literal examples:: Source code examples with special formatting
-* Include files:: Include additional files into a document
-* Embedded @LaTeX{}:: @LaTeX{} can be freely used inside Org documents
-
-Structural markup elements
-
-* Document title:: Where the title is taken from
-* Headings and sections:: The document structure as seen by the exporter
-* Table of contents:: The if and where of the table of contents
-* Paragraphs:: Paragraphs
-* Emphasis and monospace:: Bold, italic, etc.
-* Comment lines:: What will *not* be exported
-
-Exporting
-
-* Export options:: Per-file export settings
-* The export dispatcher:: How to access exporter commands
-* ASCII/Latin-1/UTF-8 export:: Exporting to flat files with encoding
-* HTML export:: Exporting to HTML
-* @LaTeX{} and PDF export:: Exporting to @LaTeX{}, and processing to PDF
-* iCalendar export:: Exporting to iCalendar
-
-Miscellaneous
-
-* Completion:: M-TAB knows what you need
-* Clean view:: Getting rid of leading stars in the outline
-* MobileOrg:: Org-mode on the iPhone
-
-@end detailmenu
-@end menu
-
-@node Introduction, Document Structure, Top, Top
-@chapter Introduction
-
-@menu
-* Preface:: Welcome
-* Installation:: How to install a downloaded version of Org
-* Activation:: How to activate Org for certain buffers
-* Feedback:: Bug reports, ideas, patches etc.
-@end menu
-
-@node Preface, Installation, Introduction, Introduction
-@section Preface
-
-Org is a mode for keeping notes, maintaining TODO lists, and doing project
-planning with a fast and effective plain-text system. It is also an
-authoring and publishing system, and it supports working with source code for
-literal programming and reproducible research.
-
-@i{This document is a much compressed derivative of the
-@uref{https://orgmode.org/index.html#sec-4_1, comprehensive Org-mode manual}.
-It contains all basic features and commands, along with important hints for
-customization. It is intended for beginners who would shy back from a 200
-page manual because of sheer size.}
-
-@node Installation, Activation, Preface, Introduction
-@section Installation
-
-@b{Important:} @i{If you are using a version of Org that is part of the Emacs
-distribution, please skip this section and go directly to @ref{Activation}.}
-
-If you have downloaded Org from the Web, either as a distribution @file{.zip}
-or @file{.tar} file, or as a Git archive, it is best to run it directly from
-the distribution directory. You need to add the @file{lisp} subdirectories
-to the Emacs load path. To do this, add the following line to @file{.emacs}:
-
-@smallexample
-(setq load-path (cons "~/path/to/orgdir/lisp" load-path))
-(setq load-path (cons "~/path/to/orgdir/contrib/lisp" load-path))
-@end smallexample
-
-@noindent
-If you have been using git or a tar ball to get Org, you need to
-run the following command to generate autoload information.
-command:
-
-@smallexample
-make autoloads
-@end smallexample
-
-@node Activation, Feedback, Installation, Introduction
-@section Activation
-
-Add the following lines to your @file{.emacs} file. The last four lines
-define @emph{global} keys for some commands --- please choose suitable keys
-yourself.
-
-@smalllisp
-;; The following lines are always needed. Choose your own keys.
-(global-set-key "\C-cl" 'org-store-link)
-(global-set-key "\C-ca" 'org-agenda)
-(global-set-key "\C-cc" 'org-capture)
-(global-set-key "\C-cb" 'org-switchb)
-@end smalllisp
-
-Files with extension @samp{.org} will be put into Org mode automatically.
-
-@node Feedback, , Activation, Introduction
-@section Feedback
-
-If you find problems with Org, or if you have questions, remarks, or ideas
-about it, please mail to the Org mailing list @email{emacs-orgmode@@gnu.org}.
-For information on how to submit bug reports, see the main manual.
-
-@node Document Structure, Tables, Introduction, Top
-@chapter Document Structure
-
-Org is based on Outline mode and provides flexible commands to
-edit the structure of the document.
-
-@menu
-* Outlines:: Org is based on Outline mode
-* Headlines:: How to typeset Org tree headlines
-* Visibility cycling:: Show and hide, much simplified
-* Motion:: Jumping to other headlines
-* Structure editing:: Changing sequence and level of headlines
-* Sparse trees:: Matches embedded in context
-* Plain lists:: Additional structure within an entry
-* Footnotes:: How footnotes are defined in Org's syntax
-@end menu
-
-@node Outlines, Headlines, Document Structure, Document Structure
-@section Outlines
-
-Org is implemented on top of Outline mode. Outlines allow a
-document to be organized in a hierarchical structure, which (at least
-for me) is the best representation of notes and thoughts. An overview
-of this structure is achieved by folding (hiding) large parts of the
-document to show only the general document structure and the parts
-currently being worked on. Org greatly simplifies the use of
-outlines by compressing the entire show/hide functionality into a single
-command, @command{org-cycle}, which is bound to the @key{TAB} key.
-
-@node Headlines, Visibility cycling, Outlines, Document Structure
-@section Headlines
-
-Headlines define the structure of an outline tree. The headlines in
-Org start with one or more stars, on the left margin@footnote{See
-the variable @code{org-special-ctrl-a/e} to configure special behavior
-of @kbd{C-a} and @kbd{C-e} in headlines.}. For example:
-
-@smallexample
-* Top level headline
-** Second level
-*** 3rd level
- some text
-*** 3rd level
- more text
-
-* Another top level headline
-@end smallexample
-
-@noindent Note that a headline named after @code{org-footnote-section},
-which defaults to @samp{Footnotes}, is considered as special. A subtree with
-this headline will be silently ignored by exporting functions.
-
-Some people find the many stars too noisy and would prefer an
-outline that has whitespace followed by a single star as headline
-starters. @ref{Clean view}, describes a setup to realize this.
-
-@node Visibility cycling, Motion, Headlines, Document Structure
-@section Visibility cycling
-
-Outlines make it possible to hide parts of the text in the buffer.
-Org uses just two commands, bound to @key{TAB} and
-@kbd{S-@key{TAB}} to change the visibility in the buffer.
-
-@table @kbd
-@item @key{TAB}
-@emph{Subtree cycling}: Rotate current subtree among the states
-
-@smallexample
-,-> FOLDED -> CHILDREN -> SUBTREE --.
-'-----------------------------------'
-@end smallexample
-
-When called with a prefix argument (@kbd{C-u @key{TAB}}) or with the shift
-key, global cycling is invoked.
-
-@item S-@key{TAB} @r{and} C-u @key{TAB}
-@emph{Global cycling}: Rotate the entire buffer among the states
-
-@smallexample
-,-> OVERVIEW -> CONTENTS -> SHOW ALL --.
-'--------------------------------------'
-@end smallexample
-
-@item C-u C-u C-u @key{TAB}
-Show all, including drawers.
-@end table
-
-When Emacs first visits an Org file, the global state is set to
-OVERVIEW, i.e.@: only the top level headlines are visible. This can be
-configured through the variable @code{org-startup-folded}, or on a
-per-file basis by adding a startup keyword @code{overview}, @code{content},
-@code{showall}, like this:
-
-@smallexample
-#+STARTUP: content
-@end smallexample
-
-
-@node Motion, Structure editing, Visibility cycling, Document Structure
-@section Motion
-The following commands jump to other headlines in the buffer.
-
-@table @kbd
-@item C-c C-n
-Next heading.
-@item C-c C-p
-Previous heading.
-@item C-c C-f
-Next heading same level.
-@item C-c C-b
-Previous heading same level.
-@item C-c C-u
-Backward to higher level heading.
-@end table
-
-@node Structure editing, Sparse trees, Motion, Document Structure
-@section Structure editing
-
-@table @kbd
-@item M-@key{RET}
-Insert new heading with same level as current. If the cursor is in a plain
-list item, a new item is created (@pxref{Plain lists}). When this command is
-used in the middle of a line, the line is split and the rest of the line
-becomes the new headline@footnote{If you do not want the line to be split,
-customize the variable @code{org-M-RET-may-split-line}.}.
-@item M-S-@key{RET}
-Insert new TODO entry with same level as current heading.
-@item @key{TAB} @r{in new, empty entry}
-In a new entry with no text yet, @key{TAB} will cycle through reasonable
-levels.
-@item M-@key{left}@r{/}@key{right}
-Promote/demote current heading by one level.
-@item M-S-@key{left}@r{/}@key{right}
-Promote/demote the current subtree by one level.
-@item M-S-@key{up}@r{/}@key{down}
-Move subtree up/down (swap with previous/next subtree of same
-level).
-@item C-c C-w
-Refile entry or region to a different location. @xref{Refile and copy}.
-@item C-x n s/w
-Narrow buffer to current subtree / widen it again
-@end table
-
-When there is an active region (Transient Mark mode), promotion and
-demotion work on all headlines in the region.
-
-@node Sparse trees, Plain lists, Structure editing, Document Structure
-@section Sparse trees
-
-An important feature of Org mode is the ability to construct @emph{sparse
-trees} for selected information in an outline tree, so that the entire
-document is folded as much as possible, but the selected information is made
-visible along with the headline structure above it@footnote{See also the
-variable @code{org-show-context-detail} to decide how much context is shown
-around each match.}. Just try it out and you will see immediately how it
-works.
-
-Org mode contains several commands creating such trees, all these
-commands can be accessed through a dispatcher:
-
-@table @kbd
-@item C-c /
-This prompts for an extra key to select a sparse-tree creating command.
-@item C-c / r
-Occur. Prompts for a regexp and shows a sparse tree with all matches. Each
-match is also highlighted; the highlights disappear by pressing @kbd{C-c C-c}.
-@end table
-
-The other sparse tree commands select headings based on TODO keywords,
-tags, or properties and will be discussed later in this manual.
-
-@node Plain lists, Footnotes, Sparse trees, Document Structure
-@section Plain lists
-
-Within an entry of the outline tree, hand-formatted lists can provide
-additional structure. They also provide a way to create lists of
-checkboxes (@pxref{Checkboxes}). Org supports editing such lists,
-and the HTML exporter (@pxref{Exporting}) parses and formats them.
-
-Org knows ordered lists, unordered lists, and description lists.
-@itemize @bullet
-@item
-@emph{Unordered} list items start with @samp{-}, @samp{+}, or
-@samp{*} as bullets.
-@item
-@emph{Ordered} list items start with @samp{1.} or @samp{1)}.
-@item
-@emph{Description} list use @samp{ :: } to separate the @emph{term} from the
-description.
-@end itemize
-
-Items belonging to the same list must have the same indentation on the first
-line. An item ends before the next line that is indented like its
-bullet/number, or less. A list ends when all items are closed, or before two
-blank lines. An example:
-
-@smallexample
-@group
-** Lord of the Rings
- My favorite scenes are (in this order)
- 1. The attack of the Rohirrim
- 2. Eowyn's fight with the witch king
- + this was already my favorite scene in the book
- + I really like Miranda Otto.
- Important actors in this film are:
- - @b{Elijah Wood} :: He plays Frodo
- - @b{Sean Astin} :: He plays Sam, Frodo's friend.
-@end group
-@end smallexample
-
-The following commands act on items when the cursor is in the first line of
-an item (the line with the bullet or number).
-
-@table @kbd
-@item @key{TAB}
-Items can be folded just like headline levels.
-@item M-@key{RET}
-Insert new item at current level. With a prefix argument, force a new
-heading (@pxref{Structure editing}).
-@item M-S-@key{RET}
-Insert a new item with a checkbox (@pxref{Checkboxes}).
-@item M-S-@key{up}@r{/}@key{down}
-Move the item including subitems up/down (swap with previous/next item
-of same indentation). If the list is ordered, renumbering is
-automatic.
-@item M-@key{left}@r{/}M-@key{right}
-Decrease/increase the indentation of an item, leaving children alone.
-@item M-S-@key{left}@r{/}@key{right}
-Decrease/increase the indentation of the item, including subitems.
-@item C-c C-c
-If there is a checkbox (@pxref{Checkboxes}) in the item line, toggle the
-state of the checkbox. Also verify bullets and indentation consistency in
-the whole list.
-@item C-c -
-Cycle the entire list level through the different itemize/enumerate bullets
-(@samp{-}, @samp{+}, @samp{*}, @samp{1.}, @samp{1)}).
-@end table
-
-@node Footnotes, , Plain lists, Document Structure
-@section Footnotes
-
-A footnote is defined in a paragraph that is started by a footnote marker in
-square brackets in column 0, no indentation allowed. The footnote reference
-is simply the marker in square brackets, inside text. For example:
-
-@smallexample
-The Org homepage[fn:1] now looks a lot better than it used to.
-...
-[fn:1] The link is: https://orgmode.org
-@end smallexample
-
-@noindent
-The following commands handle footnotes:
-
-@table @kbd
-@item C-c C-x f
-The footnote action command. When the cursor is on a footnote reference,
-jump to the definition. When it is at a definition, jump to the (first)
-reference. Otherwise, create a new footnote. When this command is called
-with a prefix argument, a menu of additional options including renumbering is
-offered.
-
-@item C-c C-c
-Jump between definition and reference.
-@end table
-
-@seealso{
-@uref{https://orgmode.org/manual/Document-structure.html#Document-structure,
-Chapter 2 of the manual}@*
-@uref{http://sachachua.com/wp/2008/01/outlining-your-notes-with-org/,
-Sacha Chua's tutorial}}
-
-
-@node Tables, Hyperlinks, Document Structure, Top
-@chapter Tables
-
-Org comes with a fast and intuitive table editor. Spreadsheet-like
-calculations are supported in connection with the Emacs @file{calc}
-package
-@ifinfo
-(@pxref{Top,Calc,,Calc,Gnu Emacs Calculator Manual}).
-@end ifinfo
-@ifnotinfo
-(see the Emacs Calculator manual for more information about the Emacs
-calculator).
-@end ifnotinfo
-
-Org makes it easy to format tables in plain ASCII. Any line with
-@samp{|} as the first non-whitespace character is considered part of a
-table. @samp{|} is also the column separator. A table might look like
-this:
-
-@smallexample
-| Name | Phone | Age |
-|-------+-------+-----|
-| Peter | 1234 | 17 |
-| Anna | 4321 | 25 |
-@end smallexample
-
-A table is re-aligned automatically each time you press @key{TAB} or
-@key{RET} or @kbd{C-c C-c} inside the table. @key{TAB} also moves to
-the next field (@key{RET} to the next row) and creates new table rows
-at the end of the table or before horizontal lines. The indentation
-of the table is set by the first line. Any line starting with
-@samp{|-} is considered as a horizontal separator line and will be
-expanded on the next re-align to span the whole table width. So, to
-create the above table, you would only type
-
-@smallexample
-|Name|Phone|Age|
-|-
-@end smallexample
-
-@noindent
-and then press @key{TAB} to align the table and start filling in
-fields. Even faster would be to type @code{|Name|Phone|Age} followed by
-@kbd{C-c @key{RET}}.
-
-When typing text into a field, Org treats @key{DEL},
-@key{Backspace}, and all character keys in a special way, so that
-inserting and deleting avoids shifting other fields. Also, when
-typing @emph{immediately after the cursor was moved into a new field
-with @kbd{@key{TAB}}, @kbd{S-@key{TAB}} or @kbd{@key{RET}}}, the
-field is automatically made blank.
-
-@table @kbd
-@tsubheading{Creation and conversion}
-@item C-c |
-Convert the active region to table. If every line contains at least one TAB
-character, the function assumes that the material is tab separated. If every
-line contains a comma, comma-separated values (CSV) are assumed. If not,
-lines are split at whitespace into fields.
-@*
-If there is no active region, this command creates an empty Org
-table. But it's easier just to start typing, like
-@kbd{|Name|Phone|Age C-c @key{RET}}.
-
-@tsubheading{Re-aligning and field motion}
-@item C-c C-c
-Re-align the table without moving the cursor.
-@c
-@item @key{TAB}
-Re-align the table, move to the next field. Creates a new row if
-necessary.
-@c
-@item S-@key{TAB}
-Re-align, move to previous field.
-@c
-@item @key{RET}
-Re-align the table and move down to next row. Creates a new row if
-necessary.
-
-@tsubheading{Column and row editing}
-@item M-@key{left}
-@itemx M-@key{right}
-Move the current column left/right.
-@c
-@item M-S-@key{left}
-Kill the current column.
-@c
-@item M-S-@key{right}
-Insert a new column to the left of the cursor position.
-@c
-@item M-@key{up}
-@itemx M-@key{down}
-Move the current row up/down.
-@c
-@item M-S-@key{up}
-Kill the current row or horizontal line.
-@c
-@item M-S-@key{down}
-Insert a new row above the current row. With a prefix argument, the line is
-created below the current one.
-@c
-@item C-c -
-Insert a horizontal line below current row. With a prefix argument, the line
-is created above the current line.
-@c
-@item C-c @key{RET}
-Insert a horizontal line below current row, and move the cursor into the row
-below that line.
-@c
-@item C-c ^
-Sort the table lines in the region. The position of point indicates the
-column to be used for sorting, and the range of lines is the range
-between the nearest horizontal separator lines, or the entire table.
-
-@end table
-
-@seealso{
-@uref{https://orgmode.org/manual/Tables.html#Tables, Chapter 3 of the
-manual}@*
-@uref{https://orgmode.org/worg/org-tutorials/tables.html, Bastien's
-table tutorial}@*
-@uref{https://orgmode.org/worg/org-tutorials/org-spreadsheet-intro.html,
-Bastien's spreadsheet tutorial}@*
-@uref{https://orgmode.org/worg/org-tutorials/org-plot.html, Eric's plotting tutorial}}
-
-@node Hyperlinks, TODO Items, Tables, Top
-@chapter Hyperlinks
-
-Like HTML, Org provides links inside a file, external links to
-other files, Usenet articles, emails, and much more.
-
-@menu
-* Link format:: How links in Org are formatted
-* Internal links:: Links to other places in the current file
-* External links:: URL-like links to the world
-* Handling links:: Creating, inserting and following
-* Targeted links:: Point at a location in a file
-@end menu
-
-@node Link format, Internal links, Hyperlinks, Hyperlinks
-@section Link format
-
-Org will recognize plain URL-like links and activate them as
-clickable links. The general link format, however, looks like this:
-
-@smallexample
-[[link][description]] @r{or alternatively} [[link]]
-@end smallexample
-
-@noindent
-Once a link in the buffer is complete (all brackets present), Org will change
-the display so that @samp{description} is displayed instead of
-@samp{[[link][description]]} and @samp{link} is displayed instead of
-@samp{[[link]]}. To edit the invisible @samp{link} part, use @kbd{C-c
-C-l} with the cursor on the link.
-
-@node Internal links, External links, Link format, Hyperlinks
-@section Internal links
-
-If the link does not look like a URL, it is considered to be internal in the
-current file. The most important case is a link like
-@samp{[[#my-custom-id]]} which will link to the entry with the
-@code{CUSTOM_ID} property @samp{my-custom-id}.
-
-Links such as @samp{[[My Target]]} or @samp{[[My Target][Find my target]]}
-lead to a text search in the current file for the corresponding target which
-looks like @samp{<<My Target>>}.
-
-Internal links will be used to reference their destination, through links or
-numbers, when possible.
-
-@node External links, Handling links, Internal links, Hyperlinks
-@section External links
-
-Org supports links to files, websites, Usenet and email messages,
-BBDB database entries and links to both IRC conversations and their
-logs. External links are URL-like locators. They start with a short
-identifying string followed by a colon. There can be no space after
-the colon. Here are some examples:
-
-@smallexample
-http://www.astro.uva.nl/~dominik @r{on the web}
-file:/home/dominik/images/jupiter.jpg @r{file, absolute path}
-/home/dominik/images/jupiter.jpg @r{same as above}
-file:papers/last.pdf @r{file, relative path}
-file:projects.org @r{another Org file}
-docview:papers/last.pdf::NNN @r{open file in doc-view mode at page NNN}
-id:B7423F4D-2E8A-471B-8810-C40F074717E9 @r{Link to heading by ID}
-news:comp.emacs @r{Usenet link}
-mailto:adent@@galaxy.net @r{Mail link}
-vm:folder @r{VM folder link}
-vm:folder#id @r{VM message link}
-wl:folder#id @r{WANDERLUST message link}
-mhe:folder#id @r{MH-E message link}
-rmail:folder#id @r{RMAIL message link}
-gnus:group#id @r{Gnus article link}
-bbdb:R.*Stallman @r{BBDB link (with regexp)}
-irc:/irc.com/#emacs/bob @r{IRC link}
-info:org:External%20links @r{Info node link (with encoded space)}
-@end smallexample
-
-A link should be enclosed in double brackets and may contain a
-descriptive text to be displayed instead of the URL (@pxref{Link
-format}), for example:
-
-@smallexample
-[[http://www.gnu.org/software/emacs/][GNU Emacs]]
-@end smallexample
-
-@noindent
-If the description is a file name or URL that points to an image, HTML export
-(@pxref{HTML export}) will inline the image as a clickable button. If there
-is no description at all and the link points to an image, that image will be
-inlined into the exported HTML file.
-
-@node Handling links, Targeted links, External links, Hyperlinks
-@section Handling links
-
-Org provides methods to create a link in the correct syntax, to
-insert it into an Org file, and to follow the link.
-
-@table @kbd
-@item C-c l
-Store a link to the current location. This is a @emph{global} command (you
-must create the key binding yourself) which can be used in any buffer to
-create a link. The link will be stored for later insertion into an Org
-buffer (see below).
-@c
-@item C-c C-l
-Insert a link. This prompts for a link to be inserted into the buffer. You
-can just type a link, or use history keys @key{up} and @key{down} to access
-stored links. You will be prompted for the description part of the link.
-When called with a @kbd{C-u} prefix argument, file name completion is used to
-link to a file.
-@c
-@item C-c C-l @r{(with cursor on existing link)}
-When the cursor is on an existing link, @kbd{C-c C-l} allows you to edit the
-link and description parts of the link.
-@c
-@item C-c C-o @r{or} mouse-1 @r{or} mouse-2
-Open link at point.
-@item C-c &
-Jump back to a recorded position. A position is recorded by the
-commands following internal links, and by @kbd{C-c %}. Using this
-command several times in direct succession moves through a ring of
-previously recorded positions.
-@c
-@end table
-
-@node Targeted links, , Handling links, Hyperlinks
-@section Targeted links
-
-File links can contain additional information to make Emacs jump to a
-particular location in the file when following a link. This can be a
-line number or a search option after a double colon.
-
-Here is the syntax of the different ways to attach a search to a file
-link, together with an explanation:
-
-@smallexample
-[[file:~/code/main.c::255]] @r{Find line 255}
-[[file:~/xx.org::My Target]] @r{Find @samp{<<My Target>>}}
-[[file:~/xx.org::#my-custom-id]] @r{Find entry with custom id}
-@end smallexample
-
-@seealso{
-@uref{https://orgmode.org/manual/Hyperlinks.html#Hyperlinks, Chapter 4 of the
-manual}}
-
-@node TODO Items, Tags, Hyperlinks, Top
-@chapter TODO Items
-
-Org mode does not require TODO lists to live in separate documents. Instead,
-TODO items are part of a notes file, because TODO items usually
-come up while taking notes! With Org mode, simply mark any entry in a tree
-as being a TODO item. In this way, information is not duplicated, and TODO
-items remain in the context from which they emerged.
-
-Org mode provides methods to give you an overview of all the things that you
-have to do, collected from many files.
-
-@menu
-* Using TODO states:: Setting and switching states
-* Multi-state workflows:: More than just on/off
-* Progress logging:: Dates and notes for progress
-* Priorities:: Some things are more important than others
-* Breaking down tasks:: Splitting a task into manageable pieces
-* Checkboxes:: Tick-off lists
-@end menu
-
-@node Using TODO states, Multi-state workflows, TODO Items, TODO Items
-@section Using TODO states
-
-Any headline becomes a TODO item when it starts with the word
-@samp{TODO}, for example:
-
-@smallexample
-*** TODO Write letter to Sam Fortune
-@end smallexample
-
-@noindent
-The most important commands to work with TODO entries are:
-
-@table @kbd
-@item C-c C-t
-Rotate the TODO state of the current item among
-
-@smallexample
-(unmarked) -> TODO -> DONE -> (unmarked)
-@end smallexample
-
-The same rotation can also be done ``remotely'' from the agenda buffers with
-the @kbd{t} command key (@pxref{Agenda commands}).
-
-@item S-@key{right}@r{/}@key{left}
-Select the following/preceding TODO state, similar to cycling.
-@item C-c / t
-View TODO items in a @emph{sparse tree} (@pxref{Sparse trees}). Folds the
-buffer, but shows all TODO items and the headings hierarchy above
-them.
-@item C-c a t
-Show the global TODO list. Collects the TODO items from all agenda files
-(@pxref{Agenda Views}) into a single buffer. @xref{Global TODO list}, for
-more information.
-@item S-M-@key{RET}
-Insert a new TODO entry below the current one.
-@end table
-
-@noindent
-Changing a TODO state can also trigger tag changes. See the docstring of the
-option @code{org-todo-state-tags-triggers} for details.
-
-@node Multi-state workflows, Progress logging, Using TODO states, TODO Items
-@section Multi-state workflows
-
-You can use TODO keywords to indicate @emph{sequential} working progress
-states:
-
-@smalllisp
-(setq org-todo-keywords
- '((sequence "TODO" "FEEDBACK" "VERIFY" "|" "DONE" "DELEGATED")))
-@end smalllisp
-
-The vertical bar separates the TODO keywords (states that @emph{need action})
-from the DONE states (which need @emph{no further action}). If you don't
-provide the separator bar, the last state is used as the DONE state. With
-this setup, the command @kbd{C-c C-t} will cycle an entry from TODO to
-FEEDBACK, then to VERIFY, and finally to DONE and DELEGATED. Sometimes you
-may want to use different sets of TODO keywords in parallel. For example,
-you may want to have the basic @code{TODO}/@code{DONE}, but also a workflow
-for bug fixing. Your setup would then look like this:
-
-@smalllisp
-(setq org-todo-keywords
- '((sequence "TODO(t)" "|" "DONE(d)")
- (sequence "REPORT(r)" "BUG(b)" "KNOWNCAUSE(k)" "|" "FIXED(f)")))
-@end smalllisp
-
-The keywords should all be different, this helps Org mode to keep track of
-which subsequence should be used for a given entry. The example also shows
-how to define keys for fast access of a particular state, by adding a letter
-in parenthesis after each keyword---you will be prompted for the key after
-@kbd{C-c C-t}.
-
-To define TODO keywords that are valid only in a single file, use the
-following text anywhere in the file.
-
-@smallexample
-#+TODO: TODO(t) | DONE(d)
-#+TODO: REPORT(r) BUG(b) KNOWNCAUSE(k) | FIXED(f)
-#+TODO: | CANCELED(c)
-@end smallexample
-
-After changing one of these lines, use @kbd{C-c C-c} with the cursor still in
-the line to make the changes known to Org mode.
-
-@node Progress logging, Priorities, Multi-state workflows, TODO Items
-@section Progress logging
-
-Org mode can automatically record a timestamp and possibly a note when
-you mark a TODO item as DONE, or even each time you change the state of
-a TODO item. This system is highly configurable; settings can be on a
-per-keyword basis and can be localized to a file or even a subtree. For
-information on how to clock working time for a task, see @ref{Clocking
-work time}.
-
-@menu
-* Closing items:: When was this entry marked DONE?
-* Tracking TODO state changes:: When did the status change?
-@end menu
-
-@node Closing items, Tracking TODO state changes, Progress logging, Progress logging
-@unnumberedsubsec Closing items
-
-The most basic logging is to keep track of @emph{when} a certain TODO
-item was finished. This is achieved with@footnote{The corresponding
-in-buffer setting is: @code{#+STARTUP: logdone}}.
-
-@smalllisp
-(setq org-log-done 'time)
-@end smalllisp
-
-@noindent
-Then each time you turn an entry from a TODO (not-done) state into any of the
-DONE states, a line @samp{CLOSED: [timestamp]} will be inserted just after
-the headline. If you want to record a note along with the timestamp,
-use@footnote{The corresponding in-buffer setting is: @code{#+STARTUP:
-lognotedone}}
-
-@smalllisp
-(setq org-log-done 'note)
-@end smalllisp
-
-@noindent
-You will then be prompted for a note, and that note will be stored below
-the entry with a @samp{Closing Note} heading.
-
-@node Tracking TODO state changes, , Closing items, Progress logging
-@unnumberedsubsec Tracking TODO state changes
-
-You might want to keep track of TODO state changes. You can either record
-just a timestamp, or a time-stamped note for a change. These records will be
-inserted after the headline as an itemized list. When taking a lot of notes,
-you might want to get the notes out of the way into a drawer. Customize the
-variable @code{org-log-into-drawer} to get this behavior.
-
-For state logging, Org mode expects configuration on a per-keyword basis.
-This is achieved by adding special markers @samp{!} (for a timestamp) and
-@samp{@@} (for a note) in parentheses after each keyword. For example:
-@smallexample
-#+TODO: TODO(t) WAIT(w@@/!) | DONE(d!) CANCELED(c@@)
-@end smallexample
-@noindent
-will define TODO keywords and fast access keys, and also request that a time
-is recorded when the entry is set to DONE, and that a note is recorded when
-switching to WAIT or CANCELED. The same syntax works also when setting
-@code{org-todo-keywords}.
-
-@node Priorities, Breaking down tasks, Progress logging, TODO Items
-@section Priorities
-
-If you use Org mode extensively, you may end up with enough TODO items that
-it starts to make sense to prioritize them. Prioritizing can be done by
-placing a @emph{priority cookie} into the headline of a TODO item, like this
-
-@smallexample
-*** TODO [#A] Write letter to Sam Fortune
-@end smallexample
-
-@noindent
-Org mode supports three priorities: @samp{A}, @samp{B}, and @samp{C}.
-@samp{A} is the highest, @samp{B} the default if none is given. Priorities
-make a difference only in the agenda.
-
-@table @kbd
-@item @kbd{C-c ,}
-Set the priority of the current headline. Press @samp{A}, @samp{B} or
-@samp{C} to select a priority, or @key{SPC} to remove the cookie.
-@c
-@item S-@key{up}/@key{dwn}
-Increase/decrease priority of current headline
-@end table
-
-@node Breaking down tasks, Checkboxes, Priorities, TODO Items
-@section Breaking tasks down into subtasks
-
-It is often advisable to break down large tasks into smaller, manageable
-subtasks. You can do this by creating an outline tree below a TODO item,
-with detailed subtasks on the tree. To keep the overview over the fraction
-of subtasks that are already completed, insert either @samp{[/]} or
-@samp{[%]} anywhere in the headline. These cookies will be updated each time
-the TODO status of a child changes, or when pressing @kbd{C-c C-c} on the
-cookie. For example:
-
-@smallexample
-* Organize Party [33%]
-** TODO Call people [1/2]
-*** TODO Peter
-*** DONE Sarah
-** TODO Buy food
-** DONE Talk to neighbor
-@end smallexample
-
-@node Checkboxes, , Breaking down tasks, TODO Items
-@section Checkboxes
-
-Every item in a plain list (@pxref{Plain lists}) can be made into a checkbox
-by starting it with the string @samp{[ ]}. Checkboxes are not included in
-the global TODO list, so they are often great to split a task into a number
-of simple steps.
-Here is an example of a checkbox list.
-
-@smallexample
-* TODO Organize party [1/3]
- - [-] call people [1/2]
- - [ ] Peter
- - [X] Sarah
- - [X] order food
-@end smallexample
-
-Checkboxes work hierarchically, so if a checkbox item has children that
-are checkboxes, toggling one of the children checkboxes will make the
-parent checkbox reflect if none, some, or all of the children are
-checked.
-
-@noindent
-The following commands work with checkboxes:
-
-@table @kbd
-@item C-c C-c
-Toggle checkbox status or (with prefix arg) checkbox presence at point.
-@item M-S-@key{RET}
-Insert a new item with a checkbox.
-This works only if the cursor is already in a plain list item
-(@pxref{Plain lists}).
-@end table
-
-@seealso{
-@uref{https://orgmode.org/manual/TODO-items.html#TODO-items, Chapter 5 of the manual}@*
-@uref{https://orgmode.org/worg/org-tutorials/orgtutorial_dto.html, David
-O'Toole's introductory tutorial}@*
-@uref{http://members.optusnet.com.au/~charles57/GTD/gtd_workflow.html,
-Charles Cave's GTD setup}}
-
-@node Tags, Properties, TODO Items, Top
-@chapter Tags
-
-An excellent way to implement labels and contexts for cross-correlating
-information is to assign @i{tags} to headlines. Org mode has extensive
-support for tags.
-
-Every headline can contain a list of tags; they occur at the end of the
-headline. Tags are normal words containing letters, numbers, @samp{_}, and
-@samp{@@}. Tags must be preceded and followed by a single colon, e.g.,
-@samp{:work:}. Several tags can be specified, as in @samp{:work:urgent:}.
-Tags will by default be in bold face with the same color as the headline.
-
-@menu
-* Tag inheritance:: Tags use the tree structure of the outline
-* Setting tags:: How to assign tags to a headline
-* Tag groups:: Use one tag to search for several tags
-* Tag searches:: Searching for combinations of tags
-@end menu
-
-@node Tag inheritance, Setting tags, Tags, Tags
-@section Tag inheritance
-
-@i{Tags} make use of the hierarchical structure of outline trees. If a
-heading has a certain tag, all subheadings will inherit the tag as
-well. For example, in the list
-
-@smallexample
-* Meeting with the French group :work:
-** Summary by Frank :boss:notes:
-*** TODO Prepare slides for him :action:
-@end smallexample
-
-@noindent
-the final heading will have the tags @samp{:work:}, @samp{:boss:},
-@samp{:notes:}, and @samp{:action:} even though the final heading is not
-explicitly marked with those tags. You can also set tags that all entries in
-a file should inherit just as if these tags were defined in a hypothetical
-level zero that surrounds the entire file. Use a line like this@footnote{As
-with all these in-buffer settings, pressing @kbd{C-c C-c} activates any
-changes in the line.}:
-
-@smallexample
-#+FILETAGS: :Peter:Boss:Secret:
-@end smallexample
-
-@node Setting tags, Tag groups, Tag inheritance, Tags
-@section Setting tags
-
-Tags can simply be typed into the buffer at the end of a headline.
-After a colon, @kbd{M-@key{TAB}} offers completion on tags. There is
-also a special command for inserting tags:
-
-@table @kbd
-@item C-c C-q
-Enter new tags for the current headline. Org mode will either offer
-completion or a special single-key interface for setting tags, see
-below. After pressing @key{RET}, the tags will be inserted and aligned
-to @code{org-tags-column}. When called with a @kbd{C-u} prefix, all
-tags in the current buffer will be aligned to that column, just to make
-things look nice.
-@item C-c C-c
-When the cursor is in a headline, this does the same as @kbd{C-c C-q}.
-@end table
-
-Org will support tag insertion based on a @emph{list of tags}. By
-default this list is constructed dynamically, containing all tags
-currently used in the buffer. You may also globally specify a hard list
-of tags with the variable @code{org-tag-alist}. Finally you can set
-the default tags for a given file with lines like
-
-@smallexample
-#+TAGS: @@work @@home @@tennisclub
-#+TAGS: laptop car pc sailboat
-@end smallexample
-
-By default Org mode uses the standard minibuffer completion facilities for
-entering tags. However, it also implements another, quicker, tag selection
-method called @emph{fast tag selection}. This allows you to select and
-deselect tags with just a single key press. For this to work well you should
-assign unique letters to most of your commonly used tags. You can do this
-globally by configuring the variable @code{org-tag-alist} in your
-@file{.emacs} file. For example, you may find the need to tag many items in
-different files with @samp{:@@home:}. In this case you can set something
-like:
-
-@smalllisp
-(setq org-tag-alist '(("@@work" . ?w) ("@@home" . ?h) ("laptop" . ?l)))
-@end smalllisp
-
-@noindent
-If the tag is only relevant to the file you are working on, then you
-can instead set the TAGS option line as:
-
-@smallexample
-#+TAGS: @@work(w) @@home(h) @@tennisclub(t) laptop(l) pc(p)
-@end smallexample
-
-@node Tag groups, Tag searches, Setting tags, Tags
-@section Tag groups
-
-@cindex group tags
-@cindex tags, groups
-In a set of mutually exclusive tags, the first tag can be defined as a
-@emph{group tag}. When you search for a group tag, it will return matches
-for all members in the group. In an agenda view, filtering by a group tag
-will display headlines tagged with at least one of the members of the
-group. This makes tag searches and filters even more flexible.
-
-You can set group tags by inserting a colon between the group tag and other
-tags, like this:
-
-@example
-#+TAGS: @{ @@read : @@read_book @@read_ebook @}
-@end example
-
-In this example, @samp{@@read} is a @emph{group tag} for a set of three
-tags: @samp{@@read}, @samp{@@read_book} and @samp{@@read_ebook}.
-
-You can also use the @code{:grouptags} keyword directly when setting
-@var{org-tag-alist}, see the documentation of that variable.
-
-@kindex C-c C-x q
-@vindex org-group-tags
-If you want to ignore group tags temporarily, toggle group tags support
-with @command{org-toggle-tags-groups}, bound to @kbd{C-c C-x q}. If you
-want to disable tag groups completely, set @var{org-group-tags} to nil.
-
-@node Tag searches, , Tag groups, Tags
-@section Tag searches
-
-Once a system of tags has been set up, it can be used to collect related
-information into special lists.
-
-@table @kbd
-@item C-c \
-@itemx C-c / m
-Create a sparse tree with all headlines matching a tags search. With a
-@kbd{C-u} prefix argument, ignore headlines that are not a TODO line.
-@item C-c a m
-Create a global list of tag matches from all agenda files.
-@xref{Matching tags and properties}.
-@item C-c a M
-Create a global list of tag matches from all agenda files, but check
-only TODO items and force checking subitems (see variable
-@code{org-tags-match-list-sublevels}).
-@end table
-
-These commands all prompt for a match string which allows basic Boolean logic
-like @samp{+boss+urgent-project1}, to find entries with tags @samp{boss} and
-@samp{urgent}, but not @samp{project1}, or @samp{Kathy|Sally} to find entries
-which are tagged, like @samp{Kathy} or @samp{Sally}. The full syntax of the
-search string is rich and allows also matching against TODO keywords, entry
-levels and properties. For a complete description with many examples, see
-@ref{Matching tags and properties}.
-
-@seealso{
-@uref{https://orgmode.org/manual/Tags.html#Tags, Chapter 6 of the manual}@*
-@uref{http://sachachua.com/wp/2008/01/tagging-in-org-plus-bonus-code-for-timeclocks-and-tags/,
-Sacha Chua's article about tagging in Org-mode}}
-
-@node Properties, Dates and Times, Tags, Top
-@chapter Properties
-
-Properties are key-value pairs associated with an entry. They live in a
-special drawer with the name @code{PROPERTIES}. Each
-property is specified on a single line, with the key (surrounded by colons)
-first, and the value after it:
-
-@smallexample
-* CD collection
-** Classic
-*** Goldberg Variations
- :PROPERTIES:
- :Title: Goldberg Variations
- :Composer: J.S. Bach
- :Publisher: Deutsche Grammophon
- :NDisks: 1
- :END:
-@end smallexample
-
-You may define the allowed values for a particular property @samp{:Xyz:}
-by setting a property @samp{:Xyz_ALL:}. This special property is
-@emph{inherited}, so if you set it in a level 1 entry, it will apply to
-the entire tree. When allowed values are defined, setting the
-corresponding property becomes easier and is less prone to typing
-errors. For the example with the CD collection, we can predefine
-publishers and the number of disks in a box like this:
-
-@smallexample
-* CD collection
- :PROPERTIES:
- :NDisks_ALL: 1 2 3 4
- :Publisher_ALL: "Deutsche Grammophon" Philips EMI
- :END:
-@end smallexample
-or globally using @code{org-global-properties}, or file-wide like this:
-@smallexample
-#+PROPERTY: NDisks_ALL 1 2 3 4
-@end smallexample
-
-@table @kbd
-@item C-c C-x p
-Set a property. This prompts for a property name and a value.
-@item C-c C-c d
-Remove a property from the current entry.
-@end table
-
-To create sparse trees and special lists with selection based on properties,
-the same commands are used as for tag searches (@pxref{Tag searches}). The
-syntax for the search string is described in @ref{Matching tags and
-properties}.
-
-@table @kbd
-@end table
-
-@seealso{
-@uref{https://orgmode.org/manual/Properties-and-columns.html#Properties-and-columns,Chapter
-7 of the manual}@*
-@uref{https://orgmode.org/worg/org-tutorials/org-column-view-tutorial.html,Bastien's
-column view tutorial}}
-
-@node Dates and Times, Capture - Refile - Archive, Properties, Top
-@chapter Dates and Times
-
-To assist project planning, TODO items can be labeled with a date and/or
-a time. The specially formatted string carrying the date and time
-information is called a @emph{timestamp} in Org mode.
-
-@menu
-* Timestamps:: Assigning a time to a tree entry
-* Creating timestamps:: Commands which insert timestamps
-* Deadlines and scheduling:: Planning your work
-* Clocking work time:: Tracking how long you spend on a task
-@end menu
-
-
-@node Timestamps, Creating timestamps, Dates and Times, Dates and Times
-@section Timestamps
-
-A timestamp is a specification of a date (possibly with a time or a range of
-times) in a special format, either @samp{<2003-09-16 Tue>} or
-@samp{<2003-09-16 Tue 09:39>} or @samp{<2003-09-16 Tue 12:00-12:30>}. A
-timestamp can appear anywhere in the headline or body of an Org tree entry.
-Its presence causes entries to be shown on specific dates in the agenda
-(@pxref{Weekly/daily agenda}). We distinguish:
-
-@noindent
-@b{Plain timestamp; Event; Appointment}@*
-A simple timestamp just assigns a date/time to an item. This is just
-like writing down an appointment or event in a paper agenda.
-
-@smallexample
-* Meet Peter at the movies
- <2006-11-01 Wed 19:15>
-* Discussion on climate change
- <2006-11-02 Thu 20:00-22:00>
-@end smallexample
-
-@noindent
-@b{Timestamp with repeater interval}@*
-A timestamp may contain a @emph{repeater interval}, indicating that it
-applies not only on the given date, but again and again after a certain
-interval of N days (d), weeks (w), months (m), or years (y). The
-following will show up in the agenda every Wednesday:
-@smallexample
-* Pick up Sam at school
- <2007-05-16 Wed 12:30 +1w>
-@end smallexample
-
-@noindent
-@b{Diary-style sexp entries}@*
-For more complex date specifications, Org mode supports using the
-special sexp diary entries implemented in the Emacs calendar/diary
-package. For example
-@smallexample
-* The nerd meeting on every 2nd Thursday of the month
- <%%(diary-float t 4 2)>
-@end smallexample
-
-@noindent
-@b{Time/Date range}@*
-Two timestamps connected by @samp{--} denote a range.
-@smallexample
-** Meeting in Amsterdam
- <2004-08-23 Mon>--<2004-08-26 Thu>
-@end smallexample
-
-@noindent
-@b{Inactive timestamp}@*
-Just like a plain timestamp, but with square brackets instead of
-angular ones. These timestamps are inactive in the sense that they do
-@emph{not} trigger an entry to show up in the agenda.
-
-@smallexample
-* Gillian comes late for the fifth time
- [2006-11-01 Wed]
-@end smallexample
-
-
-@node Creating timestamps, Deadlines and scheduling, Timestamps, Dates and Times
-@section Creating timestamps
-
-For Org mode to recognize timestamps, they need to be in the specific
-format. All commands listed below produce timestamps in the correct
-format.
-
-@table @kbd
-@item C-c .
-Prompt for a date and insert a corresponding timestamp. When the cursor is
-at an existing timestamp in the buffer, the command is used to modify this
-timestamp instead of inserting a new one. When this command is used twice in
-succession, a time range is inserted. With a prefix, also add the current
-time.
-@c
-@item C-c !
-Like @kbd{C-c .}, but insert an inactive timestamp that will not cause
-an agenda entry.
-@c
-@item S-@key{left}@r{/}@key{right}
-Change date at cursor by one day.
-@c
-@item S-@key{up}@r{/}@key{down}
-Change the item under the cursor in a timestamp. The cursor can be on a
-year, month, day, hour or minute. When the timestamp contains a time range
-like @samp{15:30-16:30}, modifying the first time will also shift the second,
-shifting the time block with constant length. To change the length, modify
-the second time.
-@end table
-
-When Org mode prompts for a date/time, it will accept any string containing
-some date and/or time information, and intelligently interpret the string,
-deriving defaults for unspecified information from the current date and time.
-You can also select a date in the pop-up calendar. See the manual for more
-information on how exactly the date/time prompt works.
-
-@node Deadlines and scheduling, Clocking work time, Creating timestamps, Dates and Times
-@section Deadlines and scheduling
-
-A timestamp may be preceded by special keywords to facilitate planning:
-
-@noindent
-@b{DEADLINE}@*
-Meaning: the task (most likely a TODO item, though not necessarily) is supposed
-to be finished on that date.
-@table @kbd
-@item C-c C-d
-Insert @samp{DEADLINE} keyword along with a stamp, in the line following the
-headline.
-@end table
-
-On the deadline date, the task will be listed in the agenda. In
-addition, the agenda for @emph{today} will carry a warning about the
-approaching or missed deadline, starting
-@code{org-deadline-warning-days} before the due date, and continuing
-until the entry is marked DONE. An example:
-
-@smallexample
-*** TODO write article about the Earth for the Guide
- The editor in charge is [[bbdb:Ford Prefect]]
- DEADLINE: <2004-02-29 Sun>
-@end smallexample
-
-
-@noindent
-@b{SCHEDULED}@*
-Meaning: you are @i{planning to start working} on that task on the given
-date@footnote{This is quite different from what is normally understood by
-@i{scheduling a meeting}, which is done in Org-mode by just inserting a time
-stamp without keyword.}.
-
-@table @kbd
-@item C-c C-s
-Insert @samp{SCHEDULED} keyword along with a stamp, in the line following the
-headline.
-@end table
-
-The headline will be listed under the given date@footnote{It will still
-be listed on that date after it has been marked DONE. If you don't like
-this, set the variable @code{org-agenda-skip-scheduled-if-done}.}. In
-addition, a reminder that the scheduled date has passed will be present
-in the compilation for @emph{today}, until the entry is marked DONE.
-I.e.@: the task will automatically be forwarded until completed.
-
-@smallexample
-*** TODO Call Trillian for a date on New Years Eve.
- SCHEDULED: <2004-12-25 Sat>
-@end smallexample
-
-Some tasks need to be repeated again and again. Org mode helps to
-organize such tasks using a so-called repeater in a DEADLINE, SCHEDULED,
-or plain timestamp. In the following example
-@smallexample
-** TODO Pay the rent
- DEADLINE: <2005-10-01 Sat +1m>
-@end smallexample
-@noindent
-the @code{+1m} is a repeater; the intended interpretation is that the task
-has a deadline on <2005-10-01> and repeats itself every (one) month starting
-from that time.
-
-@node Clocking work time, , Deadlines and scheduling, Dates and Times
-@section Clocking work time
-
-Org mode allows you to clock the time you spend on specific tasks in a
-project.
-
-@table @kbd
-@item C-c C-x C-i
-Start the clock on the current item (clock-in). This inserts the CLOCK
-keyword together with a timestamp. When called with a @kbd{C-u} prefix
-argument, select the task from a list of recently clocked tasks.
-@c
-@item C-c C-x C-o
-Stop the clock (clock-out). This inserts another timestamp at the same
-location where the clock was last started. It also directly computes
-the resulting time in inserts it after the time range as @samp{=>
-HH:MM}.
-@item C-c C-x C-e
-Update the effort estimate for the current clock task.
-@item C-c C-x C-q
-Cancel the current clock. This is useful if a clock was started by
-mistake, or if you ended up working on something else.
-@item C-c C-x C-j
-Jump to the entry that contains the currently running clock. With a
-@kbd{C-u} prefix arg, select the target task from a list of recently clocked
-tasks.
-@item C-c C-x C-r
-Insert a dynamic block containing a clock
-report as an Org-mode table into the current file. When the cursor is
-at an existing clock table, just update it.
-@smallexample
-#+BEGIN: clocktable :maxlevel 2 :emphasize nil :scope file
-#+END: clocktable
-@end smallexample
-@noindent
-For details about how to customize this view, see @uref{https://orgmode.org/manual/Clocking-work-time.html#Clocking-work-time,the manual}.
-@item C-c C-c
-Update dynamic block at point. The cursor needs to be in the
-@code{#+BEGIN} line of the dynamic block.
-@end table
-
-The @kbd{l} key may be used in the agenda (@pxref{Weekly/daily agenda}) to
-show which tasks have been worked on or closed during a day.
-
-@seealso{
-@uref{https://orgmode.org/manual/Dates-and-times.html#Dates-and-times,
-Chapter 8 of the manual}@*
-@uref{http://members.optusnet.com.au/~charles57/GTD/org_dates/, Charles
-Cave's Date and Time tutorial}@*
-@uref{http://doc.norang.ca/org-mode.html#Clocking, Bernt Hansen's clocking workflow}}
-
-@node Capture - Refile - Archive, Agenda Views, Dates and Times, Top
-@chapter Capture - Refile - Archive
-
-An important part of any organization system is the ability to quickly
-capture new ideas and tasks, and to associate reference material with them.
-Org defines a capture process to create tasks. Once in the system, tasks and
-projects need to be moved around. Moving completed project trees to an
-archive file keeps the system compact and fast.
-
-@menu
-* Capture:: Capturing new stuff
-* Refile and copy:: Moving a tree from one place to another
-* Archiving:: What to do with finished projects
-@end menu
-
-@node Capture, Refile and copy, Capture - Refile - Archive, Capture - Refile - Archive
-@section Capture
-
-Org's lets you store quick notes with little interruption of your work flow.
-You can define templates for new entries and associate them with different
-targets for storing notes.
-
-@menu
-* Setting up a capture location:: Where notes will be stored
-* Using capture:: Commands to invoke and terminate capture
-* Capture templates:: Define the outline of different note types
-@end menu
-
-@node Setting up a capture location, Using capture, Capture, Capture
-@unnumberedsubsec Setting up a capture location
-
-The following customization sets a default target@footnote{Using capture
-templates, you get finer control over capture locations, see
-@ref{Capture templates}.} file for notes, and defines a global
-key for capturing new stuff.
-
-@example
-(setq org-default-notes-file (concat org-directory "/notes.org"))
-(define-key global-map "\C-cc" 'org-capture)
-@end example
-
-@node Using capture, Capture templates, Setting up a capture location, Capture
-@unnumberedsubsec Using capture
-
-@table @kbd
-@item C-c c
-Start a capture process, placing you into a narrowed indirect buffer to edit.
-@item C-c C-c
-Once you are done entering information into the capture buffer,
-@kbd{C-c C-c} will return you to the window configuration before the capture
-process, so that you can resume your work without further distraction.
-@item C-c C-w
-Finalize by moving the entry to a refile location (see section 9.2).
-@item C-c C-k
-Abort the capture process and return to the previous state.
-@end table
-
-@node Capture templates, , Using capture, Capture
-@unnumberedsubsec Capture templates
-
-You can use templates to generate different types of capture notes, and to
-store them in different places. For example, if you would like
-to store new tasks under a heading @samp{Tasks} in file @file{TODO.org}, and
-journal entries in a date tree in @file{journal.org} you could
-use:
-
-@smallexample
-(setq org-capture-templates
- '(("t" "Todo" entry (file+headline "~/org/gtd.org" "Tasks")
- "* TODO %?\n %i\n %a")
- ("j" "Journal" entry (file+datetree "~/org/journal.org")
- "* %?\nEntered on %U\n %i\n %a")))
-@end smallexample
-
-@noindent
-In these entries, the first string is the key to reach the
-template, the second is a short description. Then follows the type of the
-entry and a definition of the target location for storing the note. Finally,
-the template itself, a string with %-escapes to fill in information based on
-time and context.
-
-When you call @kbd{M-x org-capture}, Org will prompt for a key to select the
-template (if you have more than one template) and then prepare the buffer like
-@smallexample
-* TODO
- [[file:@var{link to where you were when initiating capture}]]
-@end smallexample
-
-@noindent
-During expansion of the template, special @kbd{%}-escapes@footnote{If you
-need one of these sequences literally, escape the @kbd{%} with a backslash.}
-allow dynamic insertion of content. Here is a small selection of the
-possibilities, consult the manual for more.
-@smallexample
-%a @r{annotation, normally the link created with @code{org-store-link}}
-%i @r{initial content, the region when capture is called with C-u.}
-%t, %T @r{timestamp, date only, or date and time}
-%u, %U @r{like above, but inactive timestamps}
-@end smallexample
-
-@node Refile and copy, Archiving, Capture, Capture - Refile - Archive
-@section Refile and copy
-
-When reviewing the captured data, you may want to refile or copy some of the
-entries into a different list, for example into a project. Cutting, finding
-the right location, and then pasting the note is cumbersome. To simplify
-this process, use the following commands:
-
-@table @kbd
-@item C-c M-w
-Copy the entry or region at point. This command behaves like
-@code{org-refile}, except that the original note will not be deleted.
-@item C-c C-w
-Refile the entry or region at point. This command offers possible locations
-for refiling the entry and lets you select one with completion. The item (or
-all items in the region) is filed below the target heading as a subitem.@*
-By default, all level 1 headlines in the current buffer are considered to be
-targets, but you can have more complex definitions across a number of files.
-See the variable @code{org-refile-targets} for details.
-@item C-u C-c C-w
-Use the refile interface to jump to a heading.
-@item C-u C-u C-c C-w
-Jump to the location where @code{org-refile} last moved a tree to.
-@end table
-
-@node Archiving, , Refile and copy, Capture - Refile - Archive
-@section Archiving
-
-When a project represented by a (sub)tree is finished, you may want
-to move the tree out of the way and to stop it from contributing to the
-agenda. Archiving is important to keep your working files compact and global
-searches like the construction of agenda views fast.
-The most common archiving action is to move a project tree to another file,
-the archive file.
-
-@table @kbd
-@item C-c C-x C-a
-Archive the current entry using @code{org-archive-default-command}.
-@item C-c C-x C-s@ @r{or short} @ C-c $
-Archive the subtree starting at the cursor position to the location
-given by @code{org-archive-location}.
-@end table
-
-The default archive location is a file in the same directory as the
-current file, with the name derived by appending @file{_archive} to the
-current file name. For information and examples on how to change this,
-see the documentation string of the variable
-@code{org-archive-location}. There is also an in-buffer option for
-setting this variable, for example
-
-@smallexample
-#+ARCHIVE: %s_done::
-@end smallexample
-
-@seealso{
-@uref{https://orgmode.org/manual/Capture-_002d-Refile-_002d-Archive.html#Capture-_002d-Refile-_002d-Archive,
-Chapter 9 of the manual}@*
-@uref{https://orgmode.org/worg/org-tutorials/org-protocol-custom-handler.html,
-Sebastian Rose's tutorial for capturing from a web browser}}@uref{}@*
-
-@node Agenda Views, Markup, Capture - Refile - Archive, Top
-@chapter Agenda Views
-
-Due to the way Org works, TODO items, time-stamped items, and tagged
-headlines can be scattered throughout a file or even a number of files. To
-get an overview of open action items, or of events that are important for a
-particular date, this information must be collected, sorted and displayed in
-an organized way. There are several different views, see below.
-
-The extracted information is displayed in a special @emph{agenda buffer}.
-This buffer is read-only, but provides commands to visit the corresponding
-locations in the original Org files, and even to edit these files remotely.
-Remote editing from the agenda buffer means, for example, that you can
-change the dates of deadlines and appointments from the agenda buffer.
-The commands available in the Agenda buffer are listed in @ref{Agenda
-commands}.
-
-@menu
-* Agenda files:: Files being searched for agenda information
-* Agenda dispatcher:: Keyboard access to agenda views
-* Built-in agenda views:: What is available out of the box?
-* Agenda commands:: Remote editing of Org trees
-* Custom agenda views:: Defining special searches and views
-@end menu
-
-@node Agenda files, Agenda dispatcher, Agenda Views, Agenda Views
-@section Agenda files
-
-The information to be shown is normally collected from all @emph{agenda
-files}, the files listed in the variable
-@code{org-agenda-files}.
-
-@table @kbd
-@item C-c [
-Add current file to the list of agenda files. The file is added to
-the front of the list. If it was already in the list, it is moved to
-the front. With a prefix argument, file is added/moved to the end.
-@item C-c ]
-Remove current file from the list of agenda files.
-@item C-,
-Cycle through agenda file list, visiting one file after the other.
-@end table
-
-@node Agenda dispatcher, Built-in agenda views, Agenda files, Agenda Views
-@section The agenda dispatcher
-The views are created through a dispatcher, which should be bound to a
-global key---for example @kbd{C-c a} (@pxref{Installation}). After
-pressing @kbd{C-c a}, an additional letter is required to execute a
-command:
-@table @kbd
-@item a
-The calendar-like agenda (@pxref{Weekly/daily agenda}).
-@item t @r{/} T
-A list of all TODO items (@pxref{Global TODO list}).
-@item m @r{/} M
-A list of headlines matching a TAGS expression (@pxref{Matching
-tags and properties}).
-@item s
-A list of entries selected by a boolean expression of keywords
-and/or regular expressions that must or must not occur in the entry.
-@end table
-
-@node Built-in agenda views, Agenda commands, Agenda dispatcher, Agenda Views
-@section The built-in agenda views
-
-@menu
-* Weekly/daily agenda:: The calendar page with current tasks
-* Global TODO list:: All unfinished action items
-* Matching tags and properties:: Structured information with fine-tuned search
-* Search view:: Find entries by searching for text
-@end menu
-
-@node Weekly/daily agenda, Global TODO list, Built-in agenda views, Built-in agenda views
-@subsection The weekly/daily agenda
-
-The purpose of the weekly/daily @emph{agenda} is to act like a page of a
-paper agenda, showing all the tasks for the current week or day.
-
-@table @kbd
-@item C-c a a
-Compile an agenda for the current week from a list of Org files. The agenda
-shows the entries for each day.
-@end table
-
-Emacs contains the calendar and diary by Edward M. Reingold. Org-mode
-understands the syntax of the diary and allows you to use diary sexp entries
-directly in Org files:
-
-@smallexample
-* Birthdays and similar stuff
-#+CATEGORY: Holiday
-%%(org-calendar-holiday) ; special function for holiday names
-#+CATEGORY: Ann
-%%(diary-anniversary 5 14 1956)@footnote{Note that the order of the arguments (month, day, year) depends on the setting of @code{calendar-date-style}.} Arthur Dent is %d years old
-%%(diary-anniversary 10 2 1869) Mahatma Gandhi would be %d years old
-@end smallexample
-
-Org can interact with Emacs appointments notification facility. To add all
-the appointments of your agenda files, use the command
-@code{org-agenda-to-appt}. See the docstring for details.
-
-@node Global TODO list, Matching tags and properties, Weekly/daily agenda, Built-in agenda views
-@subsection The global TODO list
-
-The global TODO list contains all unfinished TODO items formatted and
-collected into a single place. Remote editing of TODO items lets you
-can change the state of a TODO entry with a single key press. The commands
-available in the TODO list are described in @ref{Agenda commands}.
-
-@table @kbd
-@item C-c a t
-Show the global TODO list. This collects the TODO items from all
-agenda files (@pxref{Agenda Views}) into a single buffer.
-@item C-c a T
-Like the above, but allows selection of a specific TODO keyword.
-@end table
-
-@node Matching tags and properties, Search view, Global TODO list, Built-in agenda views
-@subsection Matching tags and properties
-
-If headlines in the agenda files are marked with @emph{tags} (@pxref{Tags}),
-or have properties (@pxref{Properties}), you can select headlines
-based on this metadata and collect them into an agenda buffer. The match
-syntax described here also applies when creating sparse trees with @kbd{C-c /
-m}. The commands available in the tags list are described in @ref{Agenda
-commands}.
-
-@table @kbd
-@item C-c a m
-Produce a list of all headlines that match a given set of tags. The
-command prompts for a selection criterion, which is a boolean logic
-expression with tags, like @samp{+work+urgent-withboss} or
-@samp{work|home} (@pxref{Tags}). If you often need a specific search,
-define a custom command for it (@pxref{Agenda dispatcher}).
-@item C-c a M
-Like @kbd{C-c a m}, but only select headlines that are also TODO items.
-@end table
-
-@subsubheading Match syntax
-
-A search string can use Boolean operators @samp{&} for AND and @samp{|} for
-OR. @samp{&} binds more strongly than @samp{|}. Parentheses are currently
-not implemented. Each element in the search is either a tag, a regular
-expression matching tags, or an expression like @code{PROPERTY OPERATOR
-VALUE} with a comparison operator, accessing a property value. Each element
-may be preceded by @samp{-}, to select against it, and @samp{+} is syntactic
-sugar for positive selection. The AND operator @samp{&} is optional when
-@samp{+} or @samp{-} is present. Here are some examples, using only tags.
-
-@table @samp
-@item +work-boss
-Select headlines tagged @samp{:work:}, but discard those also tagged
-@samp{:boss:}.
-@item work|laptop
-Selects lines tagged @samp{:work:} or @samp{:laptop:}.
-@item work|laptop+night
-Like before, but require the @samp{:laptop:} lines to be tagged also
-@samp{:night:}.
-@end table
-
-You may also test for properties at the same
-time as matching tags, see the manual for more information.
-
-@node Search view, , Matching tags and properties, Built-in agenda views
-@subsection Search view
-
-This agenda view is a general text search facility for Org mode entries.
-It is particularly useful to find notes.
-
-@table @kbd
-@item C-c a s
-This is a special search that lets you select entries by matching a substring
-or specific words using a boolean logic.
-@end table
-For example, the search string @samp{computer equipment} will find entries
-that contain @samp{computer equipment} as a substring.
-Search view can also search for specific keywords in the entry, using Boolean
-logic. The search string @samp{+computer +wifi -ethernet -@{8\.11[bg]@}}
-will search for note entries that contain the keywords @code{computer}
-and @code{wifi}, but not the keyword @code{ethernet}, and which are also
-not matched by the regular expression @code{8\.11[bg]}, meaning to
-exclude both 8.11b and 8.11g.
-
-Note that in addition to the agenda files, this command will also search
-the files listed in @code{org-agenda-text-search-extra-files}.
-
-@node Agenda commands, Custom agenda views, Built-in agenda views, Agenda Views
-@section Commands in the agenda buffer
-
-Entries in the agenda buffer are linked back to the Org file or diary
-file where they originate. Commands are provided to show and jump to the
-original entry location, and to edit the Org files ``remotely'' from
-the agenda buffer. This is just a selection of the many commands, explore
-the @code{Agenda} menu and the manual for a complete list.
-
-@table @kbd
-@tsubheading{Motion}
-@item n
-Next line (same as @key{up} and @kbd{C-p}).
-@item p
-Previous line (same as @key{down} and @kbd{C-n}).
-@tsubheading{View/Go to Org file}
-@item mouse-3
-@itemx @key{SPC}
-Display the original location of the item in another window.
-With prefix arg, make sure that the entire entry is made visible in the
-outline, not only the heading.
-@c
-@item @key{TAB}
-Go to the original location of the item in another window. Under Emacs
-22, @kbd{mouse-1} will also work for this.
-@c
-@item @key{RET}
-Go to the original location of the item and delete other windows.
-@c
-
-@tsubheading{Change display}
-@item o
-Delete other windows.
-@c
-@item d @r{/} w
-Switch to day/week view.
-@c
-@item f @r{and} b
-Go forward/backward in time to display the following
-@code{org-agenda-current-span} days. For example, if the display covers a
-week, switch to the following/previous week.
-@c
-@item .
-Go to today.
-@c
-@item j
-Prompt for a date and go there.
-@c
-@item v l @ @r{or short} @ l
-Toggle Logbook mode. In Logbook mode, entries that were marked DONE while
-logging was on (variable @code{org-log-done}) are shown in the agenda, as are
-entries that have been clocked on that day. When called with a @kbd{C-u}
-prefix, show all possible logbook entries, including state changes.
-@c
-@item r @r{or} g
-Recreate the agenda buffer, to reflect the changes.
-@item s
-Save all Org buffers in the current Emacs session, and also the locations of
-IDs.
-
-@tsubheading{Secondary filtering and query editing}
-
-@item /
-Filter the current agenda view with respect to a tag. You are prompted for a
-letter to select a tag. Press @samp{-} first to select against the tag.
-
-@item \
-Narrow the current agenda filter by an additional condition.
-
-@tsubheading{Remote editing (see the manual for many more commands)}
-
-@item 0--9
-Digit argument.
-@c
-@item t
-Change the TODO state of the item, in the agenda and in the
-org file.
-@c
-@item C-k
-Delete the current agenda item along with the entire subtree belonging
-to it in the original Org file.
-@c
-@item C-c C-w
-Refile the entry at point.
-@c
-@item C-c C-x C-a @ @r{or short} @ a
-Archive the subtree corresponding to the entry at point using the default
-archiving command set in @code{org-archive-default-command}.
-@c
-@item C-c C-x C-s @ @r{or short} @ $
-Archive the subtree corresponding to the current headline.
-@c
-@item C-c C-s
-Schedule this item, with prefix arg remove the scheduling timestamp
-@c
-@item C-c C-d
-Set a deadline for this item, with prefix arg remove the deadline.
-@c
-@item S-@key{right} @r{and} S-@key{left}
-Change the timestamp associated with the current line by one day.
-@c
-@item I
-Start the clock on the current item.
-@c
-@item O / X
-Stop/cancel the previously started clock.
-
-@item J
-Jump to the running clock in another window.
-@end table
-
-@node Custom agenda views, , Agenda commands, Agenda Views
-@section Custom agenda views
-
-The main application of custom searches is the definition of keyboard
-shortcuts for frequently used searches, either creating an agenda
-buffer, or a sparse tree (the latter covering of course only the current
-buffer).
-Custom commands are configured in the variable
-@code{org-agenda-custom-commands}. You can customize this variable, for
-example by pressing @kbd{C-c a C}. You can also directly set it with
-Emacs Lisp in @file{.emacs}. The following example contains all valid
-search types:
-
-@smalllisp
-@group
-(setq org-agenda-custom-commands
- '(("w" todo "WAITING")
- ("u" tags "+boss-urgent")
- ("v" tags-todo "+boss-urgent")))
-@end group
-@end smalllisp
-
-@noindent
-The initial string in each entry defines the keys you have to press after the
-dispatcher command @kbd{C-c a} in order to access the command. Usually this
-will be just a single character. The second parameter is the search type,
-followed by the string or regular expression to be used for the matching.
-The example above will therefore define:
-
-@table @kbd
-@item C-c a w
-as a global search for TODO entries with @samp{WAITING} as the TODO
-keyword
-@item C-c a u
-as a global tags search for headlines marked @samp{:boss:} but not
-@samp{:urgent:}
-@item C-c a v
-as the same search as @kbd{C-c a u}, but limiting the search to
-headlines that are also TODO items
-@end table
-
-@seealso{
-@uref{https://orgmode.org/manual/Agenda-views.html#Agenda-views, Chapter 10 of
-the manual}@*
-@uref{https://orgmode.org/worg/org-tutorials/org-custom-agenda-commands.html,
-Mat Lundin's tutorial about custom agenda commands}@*
-@uref{http://www.newartisans.com/2007/08/using-org-mode-as-a-day-planner.html,
-John Wiegley's setup}}
-
-@node Markup, Exporting, Agenda Views, Top
-@chapter Markup for rich export
-
-When exporting Org-mode documents, the exporter tries to reflect the
-structure of the document as accurately as possible in the backend. Since
-export targets like HTML, @LaTeX{}, or DocBook allow much richer formatting,
-Org mode has rules on how to prepare text for rich export. This section
-summarizes the markup rules used in an Org-mode buffer.
-
-@menu
-* Structural markup elements:: The basic structure as seen by the exporter
-* Images and tables:: Images, tables and caption mechanism
-* Literal examples:: Source code examples with special formatting
-* Include files:: Include additional files into a document
-* Embedded @LaTeX{}:: @LaTeX{} can be freely used inside Org documents
-@end menu
-
-@node Structural markup elements, Images and tables, Markup, Markup
-@section Structural markup elements
-
-@menu
-* Document title:: Where the title is taken from
-* Headings and sections:: The document structure as seen by the exporter
-* Table of contents:: The if and where of the table of contents
-* Paragraphs:: Paragraphs
-* Emphasis and monospace:: Bold, italic, etc.
-* Comment lines:: What will *not* be exported
-@end menu
-
-@node Document title, Headings and sections, Structural markup elements, Structural markup elements
-@subheading Document title
-
-@noindent
-The title of the exported document is taken from the special line
-
-@smallexample
-#+TITLE: This is the title of the document
-@end smallexample
-
-@node Headings and sections, Table of contents, Document title, Structural markup elements
-@subheading Headings and sections
-
-The outline structure of the document as described in @ref{Document
-Structure}, forms the basis for defining sections of the exported document.
-However, since the outline structure is also used for (for example) lists of
-tasks, only the first three outline levels will be used as headings. Deeper
-levels will become itemized lists. You can change the location of this
-switch globally by setting the variable @code{org-export-headline-levels}, or on a
-per-file basis with a line
-
-@smallexample
-#+OPTIONS: H:4
-@end smallexample
-
-@node Table of contents, Paragraphs, Headings and sections, Structural markup elements
-@subheading Table of contents
-
-The table of contents is normally inserted directly before the first headline
-of the file.
-
-@smallexample
-#+OPTIONS: toc:2 (only to two levels in TOC)
-#+OPTIONS: toc:nil (no TOC at all)
-@end smallexample
-
-@node Paragraphs, Emphasis and monospace, Table of contents, Structural markup elements
-@subheading Paragraphs, line breaks, and quoting
-
-Paragraphs are separated by at least one empty line. If you need to enforce
-a line break within a paragraph, use @samp{\\} at the end of a line.
-
-To keep the line breaks in a region, but otherwise use normal formatting, you
-can use this construct, which can also be used to format poetry.
-
-@smallexample
-#+BEGIN_VERSE
- Great clouds overhead
- Tiny black birds rise and fall
- Snow covers Emacs
-
- -- AlexSchroeder
-#+END_VERSE
-@end smallexample
-
-When quoting a passage from another document, it is customary to format this
-as a paragraph that is indented on both the left and the right margin. You
-can include quotations in Org-mode documents like this:
-
-@smallexample
-#+BEGIN_QUOTE
-Everything should be made as simple as possible,
-but not any simpler -- Albert Einstein
-#+END_QUOTE
-@end smallexample
-
-If you would like to center some text, do it like this:
-@smallexample
-#+BEGIN_CENTER
-Everything should be made as simple as possible, \\
-but not any simpler
-#+END_CENTER
-@end smallexample
-
-@node Emphasis and monospace, Comment lines, Paragraphs, Structural markup elements
-@subheading Emphasis and monospace
-
-You can make words @b{*bold*}, @i{/italic/}, _underlined_, @code{=verbatim=}
-and @code{~code~}, and, if you must, @samp{+strike-through+}. Text in the
-code and verbatim string is not processed for Org-mode specific syntax, it is
-exported verbatim. To insert a horizontal rules, use a line consisting of
-only dashes, and at least 5 of them.
-
-@node Comment lines, , Emphasis and monospace, Structural markup elements
-@subheading Comment lines
-
-Lines starting with zero or more whitespace characters followed by @samp{#}
-and a whitespace are treated as comments and, as such, are not exported.
-
-Likewise, regions surrounded by @samp{#+BEGIN_COMMENT}
-... @samp{#+END_COMMENT} are not exported.
-
-Finally, a @samp{COMMENT} keyword at the beginning of an entry, but after any
-other keyword or priority cookie, comments out the entire subtree. The
-command below helps changing the comment status of a headline.
-
-@table @kbd
-@item C-c ;
-Toggle the COMMENT keyword at the beginning of an entry.
-@end table
-
-@node Images and tables, Literal examples, Structural markup elements, Markup
-@section Images and Tables
-
-For Org mode tables, the lines before the first horizontal separator line
-will become table header lines. You can use the following lines somewhere
-before the table to assign a caption and a label for cross references, and in
-the text you can refer to the object with @code{[[tab:basic-data]]}:
-
-@smallexample
-#+CAPTION: This is the caption for the next table (or link)
-#+NAME: tbl:basic-data
- | ... | ...|
- |-----|----|
-@end smallexample
-
-Some backends allow you to directly include images into the exported
-document. Org does this, if a link to an image files does not have
-a description part, for example @code{[[./img/a.jpg]]}. If you wish to
-define a caption for the image and maybe a label for internal cross
-references, you sure that the link is on a line by itself precede it with:
-
-@smallexample
-#+CAPTION: This is the caption for the next figure link (or table)
-#+NAME: fig:SED-HR4049
-[[./img/a.jpg]]
-@end smallexample
-
-The same caption mechanism applies to other structures than images and tables
-(e.g., @LaTeX{} equations, source code blocks), provided the chosen export
-back-end supports them.
-
-@node Literal examples, Include files, Images and tables, Markup
-@section Literal examples
-
-You can include literal examples that should not be subjected to
-markup. Such examples will be typeset in monospace, so this is well suited
-for source code and similar examples.
-
-@smallexample
-#+BEGIN_EXAMPLE
-Some example from a text file.
-#+END_EXAMPLE
-@end smallexample
-
-For simplicity when using small examples, you can also start the example
-lines with a colon followed by a space. There may also be additional
-whitespace before the colon:
-
-@smallexample
-Here is an example
- : Some example from a text file.
-@end smallexample
-
-For source code from a programming language, or any other text
-that can be marked up by font-lock in Emacs, you can ask for it to
-look like the fontified Emacs buffer
-
-@smallexample
-#+BEGIN_SRC emacs-lisp
-(defun org-xor (a b)
- "Exclusive or."
- (if a (not b) b))
-#+END_SRC
-@end smallexample
-
-To edit the example in a special buffer supporting this language, use
-@kbd{C-c '} to both enter and leave the editing buffer.
-
-@node Include files, Embedded @LaTeX{}, Literal examples, Markup
-@section Include files
-
-During export, you can include the content of another file. For example, to
-include your @file{.emacs} file, you could use:
-
-@smallexample
-#+INCLUDE: "~/.emacs" src emacs-lisp
-@end smallexample
-@noindent
-The optional second and third parameter are the markup (i.e., @samp{example}
-or @samp{src}), and, if the markup is @samp{src}, the language for formatting
-the contents. The markup is optional, if it is not given, the text will be
-assumed to be in Org mode format and will be processed normally. File-links
-will be interpreted as well:
-@smallexample
-#+INCLUDE: "./otherfile.org::#my_custom_id" :only-contents t
-@end smallexample
-@noindent
-@kbd{C-c '} will visit the included file.
-
-@node Embedded @LaTeX{}, , Include files, Markup
-@section Embedded @LaTeX{}
-
-For scientific notes which need to be able to contain mathematical symbols
-and the occasional formula, Org-mode supports embedding @LaTeX{} code into
-its files. You can directly use TeX-like syntax for special symbols, enter
-formulas and entire @LaTeX{} environments.
-
-@smallexample
-Angles are written as Greek letters \alpha, \beta and \gamma. The mass of
-the sun is M_sun = 1.989 x 10^30 kg. The radius of the sun is R_@{sun@} =
-6.96 x 10^8 m. If $a^2=b$ and $b=2$, then the solution must be either
-$a=+\sqrt@{2@}$ or $a=-\sqrt@{2@}$.
-
-\begin@{equation@}
-x=\sqrt@{b@}
-\end@{equation@}
-@end smallexample
-@noindent
-With
-@uref{https://orgmode.org/manual/LaTeX-fragments.html#LaTeX-fragments,special
-setup}, @LaTeX{} snippets will be included as images when exporting to HTML.
-
-@seealso{
-@uref{https://orgmode.org/manual/Markup.html#Markup, Chapter 11 of the manual}}
-
-@node Exporting, Publishing, Markup, Top
-@chapter Exporting
-
-Org-mode documents can be exported into a variety of other formats: ASCII
-export for inclusion into emails, HTML to publish on the web, @LaTeX{}/PDF
-for beautiful printed documents and DocBook to enter the world of many other
-formats using DocBook tools. There is also export to iCalendar format so
-that planning information can be incorporated into desktop calendars.
-
-@menu
-* Export options:: Per-file export settings
-* The export dispatcher:: How to access exporter commands
-* ASCII/Latin-1/UTF-8 export:: Exporting to flat files with encoding
-* HTML export:: Exporting to HTML
-* @LaTeX{} and PDF export:: Exporting to @LaTeX{}, and processing to PDF
-* iCalendar export:: Exporting to iCalendar
-@end menu
-
-@node Export options, The export dispatcher, Exporting, Exporting
-@section Export options
-
-The exporter recognizes special lines in the buffer which provide additional
-information. These lines may be put anywhere in the file. The whole set of
-lines can be inserted into the buffer with @kbd{C-c C-e #}.
-
-@table @kbd
-@item C-c C-e #
-Insert template with export options, see example below.
-@end table
-
-@smallexample
-#+TITLE: the title to be shown
-#+AUTHOR: the author (default taken from @code{user-full-name})
-#+DATE: a date, fixed, or an Org timestamp
-#+EMAIL: his/her email address (default from @code{user-mail-address})
-#+LANGUAGE: language, e.g.@: @samp{en} (@code{org-export-default-language})
-#+OPTIONS: H:2 num:t toc:t \n:nil ::t |:t ^:t f:t tex:t ...
-@end smallexample
-
-@node The export dispatcher, ASCII/Latin-1/UTF-8 export, Export options, Exporting
-@section The export dispatcher
-
-All export commands can be reached using the export dispatcher, which is
-a prefix key that prompts for an additional key specifying the command.
-Normally the entire file is exported, but if a region is active, it will be
-exported instead.
-
-@table @kbd
-@item C-c C-e
-Dispatcher for export and publishing commands.
-@end table
-
-@node ASCII/Latin-1/UTF-8 export, HTML export, The export dispatcher, Exporting
-@section ASCII/Latin-1/UTF-8 export
-
-ASCII export produces a simple and very readable version of an Org-mode
-file, containing only plain ASCII. Latin-1 and UTF-8 export augment the file
-with special characters and symbols available in these encodings.
-
-@table @kbd
-@item C-c C-e t a @ @ @r{and} @ @ C-c C-e t A
-Export as ASCII file or temporary buffer.
-@item C-c C-e t n @ @ @r{and} @ @ C-c C-e t N
-Like the above commands, but use Latin-1 encoding.
-@item C-c C-e t u @ @ @r{and} @ @ C-c C-e t U
-Like the above commands, but use UTF-8 encoding.
-@end table
-
-@node HTML export, @LaTeX{} and PDF export, ASCII/Latin-1/UTF-8 export, Exporting
-@section HTML export
-
-@table @kbd
-@item C-c C-e h h
-Export as HTML file @file{myfile.html}.
-@item C-c C-e h o
-Export as HTML file and immediately open it with a browser.
-@end table
-
-To insert HTML that should be copied verbatim to
-the exported file use either
-
-@smallexample
-#+HTML: Literal HTML code for export
-@end smallexample
-@noindent
-or
-@smallexample
-#+BEGIN_EXPORT html
-All lines between these markers are exported literally
-#+END_HTML
-@end smallexample
-
-@node @LaTeX{} and PDF export, iCalendar export, HTML export, Exporting
-@section @LaTeX{} and PDF export
-
-@table @kbd
-@item C-c C-e l l
-Export as @LaTeX{} file @file{myfile.tex}.
-@item C-c C-e l p
-Export as @LaTeX{} and then process to PDF.
-@item C-c C-e l o
-Export as @LaTeX{} and then process to PDF, then open the resulting PDF file.
-@end table
-
-By default, the @LaTeX{} output uses the class @code{article}. You can
-change this by adding an option like @code{#+LATEX_CLASS: myclass} in your
-file. The class must be listed in @code{org-latex-classes}.
-
-Embedded @LaTeX{} as described in @ref{Embedded @LaTeX{}}, will be correctly
-inserted into the @LaTeX{} file. Similarly to the HTML exporter, you can use
-@code{#+LATEX:} and @code{#+BEGIN_EXPORT latex ... #+END_EXPORT} construct to
-add verbatim @LaTeX{} code.
-
-@node iCalendar export, , @LaTeX{} and PDF export, Exporting
-@section iCalendar export
-
-@table @kbd
-@item C-c C-e c f
-Create iCalendar entries for the current file in a @file{.ics} file.
-@item C-c C-e c c
-Create a single large iCalendar file from all files in
-@code{org-agenda-files} and write it to the file given by
-@code{org-icalendar-combined-agenda-file}.
-@end table
-
-@seealso{
-@uref{https://orgmode.org/manual/Exporting.html#Exporting, Chapter 12 of the manual}@*
-@uref{https://orgmode.org/worg/org-tutorials/images-and-xhtml-export.html,
-Sebastian Rose's image handling tutorial}@*
-@uref{https://orgmode.org/worg/org-tutorials/org-latex-export.html, Thomas
-Dye's LaTeX export tutorial}
-@uref{https://orgmode.org/worg/exporters/beamer/tutorial.html, Eric
-Fraga's BEAMER presentation tutorial}}
-
-@node Publishing, Working With Source Code, Exporting, Top
-@chapter Publishing
-
-Org includes a publishing management system that allows you to configure
-automatic HTML conversion of @emph{projects} composed of interlinked org
-files. You can also configure Org to automatically upload your exported HTML
-pages and related attachments, such as images and source code files, to a web
-server. For detailed instructions about setup, see the manual.
-
-Here is an example:
-
-@smalllisp
-(setq org-publish-project-alist
- '(("org"
- :base-directory "~/org/"
- :publishing-directory "~/public_html"
- :section-numbers nil
- :table-of-contents nil
- :style "<link rel=\"stylesheet\"
- href=\"../other/mystyle.css\"
- type=\"text/css\"/>")))
-@end smalllisp
-
-@table @kbd
-@item C-c C-e P x
-Prompt for a specific project and publish all files that belong to it.
-@item C-c C-e P p
-Publish the project containing the current file.
-@item C-c C-e P f
-Publish only the current file.
-@item C-c C-e P a
-Publish every project.
-@end table
-
-Org uses timestamps to track when a file has changed. The above functions
-normally only publish changed files. You can override this and force
-publishing of all files by giving a prefix argument to any of the commands
-above.
-
-@seealso{
-@uref{https://orgmode.org/manual/Publishing.html#Publishing, Chapter 13 of the
-manual}@*
-@uref{https://orgmode.org/worg/org-tutorials/org-publish-html-tutorial.html,
-Sebastian Rose's publishing tutorial}@*
-@uref{https://orgmode.org/worg/org-tutorials/org-jekyll.html, Ian Barton's
-Jekyll/blogging setup}}
-
-@node Working With Source Code, Miscellaneous, Publishing, Top
-@chapter Working with source code
-Org-mode provides a number of features for working with source code,
-including editing of code blocks in their native major-mode, evaluation of
-code blocks, tangling of code blocks, and exporting code blocks and their
-results in several formats.
-
-@subheading Structure of Code Blocks
-The structure of code blocks is as follows:
-
-@example
-#+NAME: <name>
-#+BEGIN_SRC <language> <switches> <header arguments>
- <body>
-#+END_SRC
-@end example
-
-Where @code{<name>} is a string used to name the code block,
-@code{<language>} specifies the language of the code block
-(e.g.@: @code{emacs-lisp}, @code{shell}, @code{R}, @code{python}, etc...),
-@code{<switches>} can be used to control export of the code block,
-@code{<header arguments>} can be used to control many aspects of code block
-behavior as demonstrated below, and @code{<body>} contains the actual source
-code.
-
-@subheading Editing source code
-Use @kbd{C-c '} to edit the current code block. This brings up a language
-major-mode edit buffer containing the body of the code block. Saving this
-buffer will write the new contents back to the Org buffer. Use @kbd{C-c '}
-again to exit the edit buffer.
-
-@subheading Evaluating code blocks
-Use @kbd{C-c C-c} to evaluate the current code block and insert its results
-in the Org-mode buffer. By default, evaluation is only turned on for
-@code{emacs-lisp} code blocks, however support exists for evaluating blocks
-in many languages. For a complete list of supported languages see the
-manual. The following shows a code block and its results.
-
-@example
-#+BEGIN_SRC emacs-lisp
- (+ 1 2 3 4)
-#+END_SRC
-
-#+RESULTS:
-: 10
-@end example
-
-@subheading Extracting source code
-Use @kbd{C-c C-v t} to create pure source code files by extracting code from
-source blocks in the current buffer. This is referred to as ``tangling''---a
-term adopted from the literate programming community. During ``tangling'' of
-code blocks their bodies are expanded using @code{org-babel-expand-src-block}
-which can expand both variable and ``noweb'' style references. In order to
-tangle a code block it must have a @code{:tangle} header argument, see the
-manual for details.
-
-@subheading Library of Babel
-Use @kbd{C-c C-v l} to load the code blocks from an Org-mode files into the
-``Library of Babel'', these blocks can then be evaluated from any Org-mode
-buffer. A collection of generally useful code blocks is accessible through
-Org-mode’s community-driven documentation on
-@uref{https://orgmode.org/worg/library-of-babel.html,Worg}.
-
-@subheading Header Arguments
-Many aspects of the evaluation and export of code blocks are controlled
-through header arguments. These can be specified globally, at the file
-level, at the outline subtree level, and at the individual code block level.
-The following describes some of the header arguments.
-@table @code
-@item :var
-The @code{:var} header argument is used to pass arguments to code blocks.
-The values passed to arguments can be literal values, values from org-mode
-tables and literal example blocks, or the results of other named code blocks.
-@item :results
-The @code{:results} header argument controls the @emph{collection},
-@emph{type}, and @emph{handling} of code block results. Values of
-@code{output} or @code{value} (the default) specify how results are collected
-from a code block's evaluation. Values of @code{vector}, @code{scalar}
-@code{file} @code{raw} @code{html} @code{latex} and @code{code} specify the
-type of the results of the code block which dictates how they will be
-incorporated into the Org-mode buffer. Values of @code{silent},
-@code{replace}, @code{prepend}, and @code{append} specify handling of code
-block results, specifically if and how the results should be inserted into
-the Org-mode buffer.
-@item :session
-A header argument of @code{:session} will cause the code block to be
-evaluated in a persistent interactive inferior process in Emacs. This allows
-for persisting state between code block evaluations, and for manual
-inspection of the results of evaluation.
-@item :exports
-Any combination of the @emph{code} or the @emph{results} of a block can be
-retained on export, this is specified by setting the @code{:results} header
-argument to @code{code} @code{results} @code{none} or @code{both}.
-@item :tangle
-A header argument of @code{:tangle yes} will cause a code block's contents to
-be tangled to a file named after the filename of the Org-mode buffer. An
-alternate file name can be specified with @code{:tangle filename}.
-@item :cache
-A header argument of @code{:cache yes} will cause associate a hash of the
-expanded code block with the results, ensuring that code blocks are only
-re-run when their inputs have changed.
-@item :noweb
-A header argument of @code{:noweb yes} will expand ``noweb'' style references
-on evaluation and tangling.
-@item :file
-Code blocks which output results to files (e.g.@: graphs, diagrams and figures)
-can accept a @code{:file filename} header argument in which case the results
-are saved to the named file, and a link to the file is inserted into the
-Org-mode buffer.
-@end table
-
-@seealso{
-@uref{https://orgmode.org/manual/Literal-examples.html#Literal-examples,
-Chapter 11 and section 5 of the manual}@*
-@uref{https://orgmode.org/worg/org-contrib/babel/,
-The Babel site on Worg}}
-
-@node Miscellaneous, GNU Free Documentation License, Working With Source Code, Top
-@chapter Miscellaneous
-
-@menu
-* Completion:: M-TAB knows what you need
-* Clean view:: Getting rid of leading stars in the outline
-* MobileOrg:: Org-mode on the iPhone
-@end menu
-
-@node Completion, Clean view, Miscellaneous, Miscellaneous
-@section Completion
-
-Org supports in-buffer completion with @kbd{M-@key{TAB}}. This type of
-completion does not make use of the minibuffer. You simply type a few
-letters into the buffer and use the key to complete text right there. For
-example, this command will complete @TeX{} symbols after @samp{\}, TODO
-keywords at the beginning of a headline, and tags after @samp{:} in a
-headline.
-
-@node Clean view, MobileOrg, Completion, Miscellaneous
-@section A cleaner outline view
-
-Some people find it noisy and distracting that the Org headlines start with a
-potentially large number of stars, and that text below the headlines is not
-indented. While this is no problem when writing a @emph{book-like} document
-where the outline headings are really section headings, in a more
-@emph{list-oriented} outline, indented structure is a lot cleaner:
-
-@smallexample
-@group
-* Top level headline | * Top level headline
-** Second level | * Second level
-*** 3rd level | * 3rd level
-some text | some text
-*** 3rd level | * 3rd level
-more text | more text
-* Another top level headline | * Another top level headline
-@end group
-@end smallexample
-
-@noindent
-This kind of view can be achieved dynamically at display time using
-@code{org-indent-mode}, which will prepend intangible space to each line.
-You can turn on @code{org-indent-mode} for all files by customizing the
-variable @code{org-startup-indented}, or you can turn it on for individual
-files using
-
-@smallexample
-#+STARTUP: indent
-@end smallexample
-
-If you want a similar effect in earlier version of Emacs and/or Org, or if
-you want the indentation to be hard space characters so that the plain text
-file looks as similar as possible to the Emacs display, Org supports you by
-helping to indent (with @key{TAB}) text below each headline, by hiding
-leading stars, and by only using levels 1, 3, etc to get two characters
-indentation for each level. To get this support in a file, use
-
-@smallexample
-#+STARTUP: hidestars odd
-@end smallexample
-
-@node MobileOrg, , Clean view, Miscellaneous
-@section MobileOrg
-
-@i{MobileOrg} is the name of the mobile companion app for Org mode, currently
-available for iOS and for Android. @i{MobileOrg} offers offline viewing and
-capture support for an Org mode system rooted on a ``real'' computer. It
-does also allow you to record changes to existing entries.
-
-The @uref{http://mobileorg.ncogni.to/, iOS implementation} for the
-@i{iPhone/iPod Touch/iPad} series of devices, was developed by Richard
-Moreland. Android users should check out
-@uref{http://wiki.github.com/matburt/mobileorg-android/, MobileOrg Android}
-by Matt Jones. The two implementations are not identical but offer similar
-features.
-
-@seealso{
-@uref{https://orgmode.org/manual/Miscellaneous.html#Miscellaneous, Chapter 15
-of the manual}@*
-@uref{https://orgmode.org/manual/MobileOrg.html#MobileOrg, Appendix B of the
-manual}@*
-@uref{https://orgmode.org/orgcard.pdf,Key reference card}}
-
-
-@node GNU Free Documentation License, , Miscellaneous, Top
-@appendix GNU Free Documentation License
-@include doclicense.texi
-
-
-@bye
-
-@c Local variables:
-@c fill-column: 77
-@c End:
-
-
-@c LocalWords: webdavhost pre
diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS
index 5ce1e79..c9722aa 100644
--- a/etc/ORG-NEWS
+++ b/etc/ORG-NEWS
@@ -10,6 +10,470 @@ See the end of the file for license conditions.
Please send Org bug reports to mailto:emacs-orgmode@gnu.org.
+* Version 9.3
+
+** Incompatible changes
+*** Change bracket link escaping syntax
+
+Org used to percent-encode sensitive characters in the URI part of the
+bracket links.
+
+Now, escaping mechanism uses the usual backslash character, according
+to the following rules, applied in order:
+
+1. All consecutive =\= characters at the end of the link must be
+ escaped;
+2. Any =]= character at the very end of the link must be escaped;
+3. All consecutive =\= characters preceding =][= or =]]= patterns must
+ be escaped;
+4. Any =]= character followed by either =[= or =]= must be escaped;
+5. Others =]= and =\= characters need not be escaped.
+
+When in doubt, use the function ~org-link-escape~ in order to turn
+a link string into its properly escaped form.
+
+The following function will help switching your links to the new
+syntax:
+
+#+begin_src emacs-lisp
+(defun org-update-link-syntax (&optional no-query)
+ "Update syntax for links in current buffer.
+Query before replacing a link, unless optional argument NO-QUERY
+is non-nil."
+ (interactive "P")
+ (org-with-point-at 1
+ (let ((case-fold-search t))
+ (while (re-search-forward "\\[\\[[^]]*?%\\(?:2[05]\\|5[BD]\\)" nil t)
+ (let ((object (save-match-data (org-element-context))))
+ (when (and (eq 'link (org-element-type object))
+ (= (match-beginning 0)
+ (org-element-property :begin object)))
+ (goto-char (org-element-property :end object))
+ (let* ((uri-start (+ 2 (match-beginning 0)))
+ (uri-end (save-excursion
+ (goto-char uri-start)
+ (re-search-forward "\\][][]" nil t)
+ (match-beginning 0)))
+ (uri (buffer-substring-no-properties uri-start uri-end)))
+ (when (or no-query
+ (y-or-n-p
+ (format "Possibly obsolete URI syntax: %S. Fix? "
+ uri)))
+ (setf (buffer-substring uri-start uri-end)
+ (org-link-escape (org-link-decode uri)))))))))))
+#+end_src
+
+The old ~org-link-escape~ and ~org-link-unescape~ functions have been
+renamed into ~org-link-encode~ and ~org-link-decode~.
+
+*** Change match group number in ~org-link-bracket-re~
+
+Link description, if any, is located in match group 2 instead of match
+group 3.
+
+*** ob-clojure does not auto prepend ~(ns ..)~ statement anymore
+
+When tangling, user usually just wants to tangle literally code instead
+of prepend inserting a ~(ns ..)~ statement before source block
+code. Now, when you have no ~:ns~ header argument specified, this
+behavior will not happen automatically.
+
+*** Change in behavior on exit from an Org edit buffer
+
+Org will no longer attempt to restore the window configuration in the
+frame to which the user returns after editing a source block with
+~org-edit-src-code~. Instead, the window configuration will remain as
+it is.
+
+*** Change default value for ~org-email-link-description-format~
+
+When linking from a mail buffer, Org used to truncate the subject of
+the message to 30 characters in order to build the description of the
+link. This behavior was considered as too surprising. As
+a consequence, Org no longer truncates subjects.
+
+You can get the old behaviour back with the following:
+
+: (setq org-email-link-description-format "Email %c: %.30s")
+
+*** ~:file~ header argument no longer assume "file" ~:results~
+
+The "file" ~:results~ value is now mandatory for a code block
+returning a link to a file. The ~:file~ or ~:file-ext~ header
+arguments no longer imply a "file" result is expected.
+
+*** Plain numbers are hours in Column View mode
+
+See [[git:3367ac9457]] for details.
+
+*** All LaTeX preview backends use now xcolor
+
+The dvipng backend was previously relying on fg and bg parameters to
+be passed to the CLI. This didn't work when xcolor was directly or
+indirectly used in the document (e.g. tkiz is a user of xcolor). Since
+every other backend was already using xcolor to set fg and bg, the CLI
+alternative was removed and there is no more a :use-xcolor options
+since now it's implicitly always true.
+
+*** Org-Attach Git commit
+
+[[*Org-Attach has been refactored and extended][Refactoring of Org-Attach]] affected the Git commit functionality. Not
+much, but the following changes are required if you still need to
+auto-commit attachments to git:
+
+- Customization of ~org-attach-annex-auto-get~ needs to be renamed to
+ ~org-attach-git-annex-auto-get~.
+
+- Customization of ~org-attach-commit~ is no longer needed. Instead
+ one need to require the =org-attach-git= module in the startup.
+
+** New features
+*** New option to wrap source code lines in HTML export
+
+When new option ~html-wrap-src-lines~ (with variable
+~org-html-wrap-src-lines~) is non-nil, HTML export wraps source code
+lines in HTML ~code~ elements.
+
+*** New option to handle schedules and deadlines in iCalendar export
+
+Export ignore done tasks with a deadline when
+~org-icalendar-use-deadline~ contains ~event-if-todo-not-done~.
+Likewise, scheduled done tasks are also ignored when
+~org-icalendar-use-scheduled~ contains the same symbol.
+
+*** Add split-window-right option for src block edit window placement
+
+Given the increasing popularity of wide screen monitors, splitting
+horizontally may make more sense than splitting vertically. An
+option, ~split-window-right~, to request horizontal splitting has been
+added to ~org-src-window-setup~.
+
+*** Org-Attach has been refactored and extended
+
+Org attach has been refactored and the functionality extended. It
+should now be easier to understand how it works. A few improvements
+and extra options have been added as well.
+
+From the initial comment in org-attach source-code:
+
+- Attachments are managed either by using a custom property DIR or by
+ using property ID from org-id. When DIR is defined, a location in
+ the filesystem is directly attached to the outline node. When
+ org-id is used, attachments are stored in a folder named after the
+ ID, in a location defined by ~org-attach-id-dir~. DIR has
+ precedence over ID when both parameters are defined for the current
+ outline node (also when inherited parameters are taken into
+ account).
+
+From now on inheritance requires no extra property and will adhere to
+~org-attach-use-inheritance~ by default. Inheritance can be
+customized to always be activated or never be activated in
+~org-attach-use-inheritance~.
+
+The ATTACH_DIR property is deprecated in favour of the shorter
+property DIR. Links to folders inside the DIR property can now be
+declared as relative links. This is not enabled by default, but can
+be set in ~org-attach-dir-relative~.
+
+When adding new attachment to the outline node the preferred way of
+doing so can be customized. Take a look at
+~org-attach-preferred-new-method~. It defaults to using ID since that
+was the behaviour before this change.
+
+If both DIR and ID properties are set on the same node, DIR has
+precedence and will be used.
+
+One can now also choose to build attachment-directory-paths in a
+customized way. This is an advanced topic, but in some case it makes
+sense to parse an ID in a different way than the default one. Create
+your own function and add it to the beginning of
+~org-attach-id-to-path-function~list~ if you want to customize the ID
+based folder structure.
+
+If you've used ATTACH_DIR properties to manage attachments, use the
+following code to rename that property to DIR which supports the same
+functionality. ATTACH_DIR_INHERIT is no longer supported and is
+removed.
+
+#+begin_src emacs-lisp
+ (defun org-update-attach-properties ()
+ "Change properties for Org-Attach."
+ (interactive)
+ (org-with-point-at 1
+ (while (outline-next-heading)
+ (let ((DIR (org--property-local-values "ATTACH_DIR" nil)))
+ (when DIR
+ (org-set-property "DIR" (car DIR))
+ (org-delete-property "ATTACH_DIR"))))
+ (org-delete-property-globally "ATTACH_DIR_INHERIT")))
+#+end_src
+
+For those who hate breaking changes, even though the changes are made
+to clean things up; fear not. ATTACH_DIR will still continue to work.
+It's just not documented any longer. When you get the chance, run the
+code above to clean things up anyways!
+
+**** New hooks
+Two hooks are added to org-attach:
+- org-attach-after-change-hook
+- org-attach-open-hook
+
+They are added mostly for internal restructuring purposes, but can
+ofc. be used for other things as well.
+
+*** New link-type: Attachment
+
+Attachment-links are now first-class citizens. They mimic file-links
+in everything they do but use the existing attachment-folder as a base
+when expanding the links. Both =DIR= and =ID= properties are used to
+try to resolve the links, in exactly the same way as Org-Attach uses
+those properties.
+
+*** Handle overlay specification for notes in Beamer export
+
+This aligns Beamer notes with slide overlays.
+
+*** Add support for lettered lists in Texinfo
+
+Using =:enum A= or =:enum a= Texinfo attribute switches an otherwise
+numbered list to a lettered list.
+
+*** Add a dispatcher command to insert dynamic blocks
+
+You can add new dynamic blocks with function
+~org-dynamic-block-define~. All such dynamic blocks can be used by
+~org-dynamic-block-insert-dblock~ command.
+
+*** Babel
+
+**** ob-emacs-lisp sets ~lexical-binding~ in Org edit buffers
+
+When editing an Elisp src block, the editing buffer's
+~lexical-binding~ is set according to the src block's =:lexical=
+parameter.
+
+**** Add LaTeX output support in PlantUML
+
+*** New minor mode to display headline numbering
+
+Use =<M-x org-num-mode>= to get a visual indication of the numbering
+in the outline. The numbering is also automatically updated upon
+changes in the buffer.
+
+*** New property =HTML_HEADLINE_CLASS= in HTML export
+
+The new property =HTML_HEADLINE_CLASS= assigns a class attribute to
+a headline.
+
+*** Allow LaTeX attributes and captions for "table.el" tables
+
+Supported LaTeX attributes are ~:float~, ~:center~, ~:font~ and
+~:caption~.
+
+*** Attach buffer contents to headline
+
+With =<b>= key from attachment dispatcher (=<C-c C-a>=), it is now
+possible to write the contents of a buffer to a file in the headline
+attachment directory.
+
+*** iCalendar export respects a =CLASS= property
+
+Set the =CLASS= property on an entry to specify a visibility class for
+that entry only during iCalendar export. The property can be set to
+anything the calendar server supports. The iCalendar standard defines
+the values =PUBLIC=, =CONFIDENTIAL=, =PRIVATE=, which can be
+interpreted as publicly visible, accessible to a specific group, and
+private respectively.
+
+This property can be inherited during iCalendar export, depending on
+the value of ~org-use-property-inheritance~.
+
+*** New parameter for =INCLUDE= keyword
+
+Add =:coding CODING-SYSTEM= to include files using a different coding
+system than the main Org document. For example:
+
+#+begin_example
+,#+INCLUDE: "myfile.cmd" src cmd :coding cp850-dos
+#+end_example
+
+*** New values in clock tables' step: =month= and =year=
+*** ODT export handles numbers cookies in lists
+*** New cell movement functions in tables
+
+~S-<UP>~, ~S-<DOWN>~, ~S-<RIGHT>~, and ~S-<LEFT>~ now move cells in
+the corresponding direction by swapping with the adjacent cell.
+
+*** New option to natively fontify LaTeX snippets and environments
+
+A 'native option was added to org-highlight-latex-and-related. It
+matches the same structures than 'latex but it calls
+org-src-font-lock-fontify-block instead, thus bringing about full
+LaTeX font locking.
+
+*** ~org-clone-subtree-with-time-shift~ learnt to shift backward in time
+
+=<C-c C-x c>= (~org-clone-subtree-with-time-shift~) now takes a
+negative value as a valid repeater to shift time stamps in backward
+in cloned subtrees. You can give, for example, ‘-3d’ to shift three
+days in the past.
+
+*** Toggle display of all vs. undone scheduled habits conveniently
+
+=<C-u K>= (~org-habit-toggle-display-in-agenda~) in an agenda toggles
+the display of all habits to those which are undone and scheduled.
+This is a function for convenience.
+
+*** New parameter for SQL Babel blocks: ~:dbconnection~
+
+The new parameter ~:dbconnection~ allows to specify a connection name
+in a SQL block header: this name is used to look up connection
+parameters in ~sql-connection-alist~.
+
+*** New =:scale= attribute supported by LaTeX exporters
+
+The builtin "latex" exporters now accept and use a =:scale= attribute,
+which scales an image by a given factor.
+
+This attribute is wrapped adound the =scale= parameter of LaTeX's
+=\includegraphics= (bitmap images) or a TiKZ's =\scalebox=.
+Therefore, its value should be some string palatable to LaTeX as
+a positive float Its default value is an empty string (i.e. disabled).
+
+This attribute overrides the =:width= and =:height= attributes.
+
+#+begin_example
+,#+name: Beastie
+,#+caption: I think I saw this curious horse already, but where ?
+,#+LATEX_ATTR: :scale 2
+[[https://orgmode.org/img/org-mode-unicorn-logo.png]]
+#+end_example
+
+*** Allow specifying the target for a table of contents
+
+The =+TOC= keyword now accepts a =:target:= attribute that specifies
+the headline to use for making the table of contents.
+
+#+begin_example
+,* Target
+ :PROPERTIES:
+ :CUSTOM_ID: TargetSection
+ :END:
+,** Heading A
+,** Heading B
+,* Another section
+,#+TOC: headlines 1 :target "#TargetSection"
+#+end_example
+
+** New functions
+*** ~org-dynamic-block-insert-dblock~
+
+Use default keybinding =<C-c C-x x>= to run command
+~org-dynamic-block-insert-dblock~. It will prompt user to select
+dynamic block in ~org-dynamic-block-alist~.
+
+*** ~org-table-cell-up~
+*** ~org-table-cell-down~
+*** ~org-table-cell-left~
+*** ~org-table-cell-right~
+*** ~org-habit-toggle-display-in-agenda~
+** Removed functions and variables
+*** Removed Org Drill
+
+You can install it back from MELPA.
+
+*** ~org-babel-set-current-result-hash~
+*** ~org-capture-insert-template-here~
+*** ~org-attach-directory~
+
+It has been deprecated in favour of ~org-attach-id-dir~ which is less
+ambiguous given the restructured org-attach.
+
+*** ~org-enable-fixed-width-editor~
+
+This variable was not used through the code base.
+
+** Miscellaneous
+*** Change signature for ~org-list-to-subtree~
+
+The function now accepts the level of the subtree as an optional
+argument. It no longer deduces it from the current level.
+
+*** LaTeX preview is simplified
+
+Function ~org-latex-preview~, formerly known as
+~org-toggle-latex-fragment~, has a hopefully simpler and more
+predictable behavior. See its docstring for details.
+
+*** ~org-table-copy-down~ supports patterns
+
+When ~org-table-copy-increment~ is non-nil, it is now possible to
+increment fields like =A1=, or =0A=, i.e., any string prefixed or
+suffixed with a whole number.
+
+*** No more special indentation for description items
+
+Descriptions items are indented like regular ones, i.e., text starts
+after the bullet. Special indentation used to introduce bugs when
+inserting sub-items in a description list.
+
+*** New hook: ~org-todo-repeat-hook~
+
+This hook was actually introduced in Org 9.2.1, but wasn't advertised.
+
+*** Org Table reads numbers starting with 0 as strings
+*** Disable fast tag selection interface via prefix arg
+
+A call of ~org-set-tags-command~ with prefix argument C-u C-u avoids
+the fast tag selection interface and instead offers the plain
+interface.
+
+*** ~:mkdirp~ now supports create directory for ~:dir~ path
+
+The ~:mkdirp~ header argument used to only work for ~:tangle~ tangle
+files. Now ~:mkdirp~ works for ~:dir~ too. This is more convenient for
+specify default directory and with ~:file~ header argument.
+
+*** New variable: ~org-agenda-breadcrumbs-separator~
+
+If breadcrumbs are showed in org-agenda with the help of "%b" format
+in ~org-agenda-prefix-format~, user can customize breadcrumbs's
+separator using ~org-agenda-breadcrumbs-separator~.
+
+*** New variable ~org-attach-commands~
+
+This variable makes it possible to customize the list of commands for
+the attachment dispatcher.
+
+*** New ID method based on timestamp
+
+If one chooses, it is now possible to create ID's based on timestamp
+(ISO8601) instead of UUID by changing org-id-method to ts.
+
+For an improved folder structure when using timestamp as ID, make sure
+to promote ~org-attach-id-ts-folder-format~ to the first element of
+~org-attach-id-to-path-function-list~ in your configuration at the
+same time.
+
+*** New customization: ~org-id-locations-relative~
+
+New customization to make the persisting of org-id-locations between
+sessions to store links to files as relative instead of absolute. The
+links will be stored as relative to the path of org-id-locations-file.
+
+*** ~org-ctrl-c-tab~ is functional before the first headline
+
+I.e. treat the whole file as if it was a subtree.
+
+Also fold everything below the chosen level. Former behavior was to
+leave unfolded subtrees unfolded.
+
+*** ~org-kill-note-or-show-branches~ is functional before the first headline
+
+I.e. treat the whole file as if it was a subtree.
+
+*** Respect narrowing when agenda command is restricted to buffer
+
* Version 9.2
** Incompatible changes
*** Removal of OrgStruct mode mode and radio lists
@@ -31,7 +495,7 @@ Org 9.2 comes with a new template expansion mechanism, combining
~org-insert-structure-template~ bound to ~C-c C-,~.
If you customized the ~org-structure-template-alist~ option manually,
-you probably need to udpate it, see the docstring for accepted values.
+you probably need to update it, see the docstring for accepted values.
If you prefer using previous patterns, e.g. =<s=, you can activate
them again by requiring Org Tempo library:
@@ -170,6 +634,17 @@ This is consistent with the naming of =org-dblock-write:columnview=
options, where =:match= is also used as a headlines filter.
** New features
+*** Add ~:session~ support of ob-clojure for CIDER
+You can initialize source block session with Babel default keybinding
+=[C-c C-v C-z]= to use =sesman= session manager to link current
+project, directory or buffer with specific Clojure session, or
+=cider-jack-in= a new CIDER REPL if no CIDER REPLs available. In older
+CIDER version which has not =sesman= integrated, only has
+=cider-jack-in= without Clojure project is supported.
+#+begin_src clojure :session
+(dissoc Clojure 'JVM)
+(conj clojurists "stardiviner")
+#+end_src
*** Add ~:results link~ support for Babel
With this output format, create a link to the file specified in
@@ -291,7 +766,7 @@ matcher.
=ob-sql= library already support running SQL blocks against an Oracle
database using ~sqlplus~. Now it's possible to use alias names
defined in =TNSNAMES= file instead of specifying full connection
-parameters. See example bellow.
+parameters. See example below.
#+BEGIN_SRC org
you can use the previous full connection parameters
@@ -312,6 +787,11 @@ beginning of a headline when using Org speed commands. Now, if there
is already a restriction at point, hitting =<= again (or =C-x C-x <=) will
remove it.
+*** Headlines can now link to themselves in HTML export
+
+When enabling ~org-html-self-link-headlines~ the headlines exported to
+HTML contain a hyperlink to themselves.
+
** New commands and functions
*** ~org-insert-structure-template~
@@ -340,7 +820,7 @@ will go back to the widen state.
*** ~org-browse-news~
-Browse https://orgmode.org/Changes.html to let users read informations
+Browse https://orgmode.org/Changes.html to let users read information
about the last major release.
There is a new menu entry for this in the "Documentation" menu item.
@@ -2158,7 +2638,7 @@ everywhere in the buffer, possibly corrupting URLs.
This undocumented option defaulted to the value of =shell-file-name= at
the time of loading =ob-shell=. The new behavior is to use the value
-of =shell-file-name= directly when the shell langage is =shell=. To chose
+of =shell-file-name= directly when the shell language is =shell=. To chose
a different shell, either customize =shell-file-name= or bind this
variable locally.
@@ -4236,7 +4716,7 @@ that Calc formulas can operate on them.
: Percent escaping is used in Org mode to escape certain characters
: in links that would either break the parser (e.g. square brackets
- : in link target oder description) or are not allowed to appear in
+ : in link target or description) or are not allowed to appear in
: a particular link type (e.g. non-ascii characters in a http:
: link).
:
diff --git a/lisp/Makefile b/lisp/Makefile
index 89f504d..f2a14b5 100644
--- a/lisp/Makefile
+++ b/lisp/Makefile
@@ -89,5 +89,5 @@ clean cleanall cleanelc::
clean-install:
if [ -d $(DESTDIR)$(lispdir) ] ; then \
- $(RM) $(DESTDIR)$(lispdir)/org*.el* $(DESTDIR)$(lispdir)/ob*.el* $(DESTDIR)$(lispdir)/ox*.el* ; \
+ $(RM) $(DESTDIR)$(lispdir)/org*.el* $(DESTDIR)$(lispdir)/ob*.el* $(DESTDIR)$(lispdir)/ol*.el* $(DESTDIR)$(lispdir)/ox*.el* ; \
fi ;
diff --git a/lisp/ob-C.el b/lisp/ob-C.el
index 92d034f..ca587cc 100644
--- a/lisp/ob-C.el
+++ b/lisp/ob-C.el
@@ -297,12 +297,12 @@ its header arguments."
(defun org-babel-prep-session:C (_session _params)
"This function does nothing as C is a compiled language with no
-support for sessions"
+support for sessions."
(error "C is a compiled language -- no support for sessions"))
(defun org-babel-load-session:C (_session _body _params)
"This function does nothing as C is a compiled language with no
-support for sessions"
+support for sessions."
(error "C is a compiled language -- no support for sessions"))
;; helper functions
@@ -393,9 +393,9 @@ of the same value."
(setq val (string-to-char val))))
(let* ((type-data (org-babel-C-val-to-C-type val))
(type (car type-data))
- (formated (org-babel-C-format-val type-data val))
- (suffix (car formated))
- (data (cdr formated)))
+ (formatted (org-babel-C-format-val type-data val))
+ (suffix (car formatted))
+ (data (cdr formatted)))
(format "%s %s%s = %s;"
type
var
diff --git a/lisp/ob-J.el b/lisp/ob-J.el
index 498cd59..b48562d 100644
--- a/lisp/ob-J.el
+++ b/lisp/ob-J.el
@@ -72,7 +72,7 @@ PROCESSED-PARAMS isn't used yet."
(defun org-babel-execute:J (body params)
"Execute a block of J code BODY.
PARAMS are given by org-babel.
-This function is called by `org-babel-execute-src-block'"
+This function is called by `org-babel-execute-src-block'."
(message "executing J source code block")
(let* ((processed-params (org-babel-process-params params))
(sessionp (cdr (assq :session params)))
diff --git a/lisp/ob-asymptote.el b/lisp/ob-asymptote.el
index 667d3e1..3fc0ceb 100644
--- a/lisp/ob-asymptote.el
+++ b/lisp/ob-asymptote.el
@@ -77,7 +77,7 @@ This function is called by `org-babel-execute-src-block'."
(defun org-babel-prep-session:asymptote (_session _params)
"Return an error if the :session header argument is set.
-Asymptote does not support sessions"
+Asymptote does not support sessions."
(error "Asymptote does not support sessions"))
(defun org-babel-variable-assignments:asymptote (params)
diff --git a/lisp/ob-awk.el b/lisp/ob-awk.el
index 4c0dbbc..0d5f47d 100644
--- a/lisp/ob-awk.el
+++ b/lisp/ob-awk.el
@@ -48,8 +48,8 @@
body)
(defun org-babel-execute:awk (body params)
- "Execute a block of Awk code with org-babel. This function is
-called by `org-babel-execute-src-block'"
+ "Execute a block of Awk code with org-babel.
+This function is called by `org-babel-execute-src-block'."
(message "executing Awk source code block")
(let* ((result-params (cdr (assq :result-params params)))
(cmd-line (cdr (assq :cmd-line params)))
diff --git a/lisp/ob-clojure.el b/lisp/ob-clojure.el
index 6407a67..0e5642a 100644
--- a/lisp/ob-clojure.el
+++ b/lisp/ob-clojure.el
@@ -43,8 +43,10 @@
(require 'ob)
(require 'org-macs)
+(declare-function cider-jack-in "ext:cider" (&optional prompt-project cljs-too))
(declare-function cider-current-connection "ext:cider-client" (&optional type))
(declare-function cider-current-ns "ext:cider-client" ())
+(declare-function cider-repls "ext:cider-connection" (&optional type ensure))
(declare-function nrepl--merge "ext:nrepl-client" (dict1 dict2))
(declare-function nrepl-dict-get "ext:nrepl-client" (dict key))
(declare-function nrepl-dict-put "ext:nrepl-client" (dict key value))
@@ -54,12 +56,15 @@
(defvar nrepl-sync-request-timeout)
(defvar cider-buffer-ns)
+(defvar sesman-system)
+(defvar cider-version)
(defvar org-babel-tangle-lang-exts)
(add-to-list 'org-babel-tangle-lang-exts '("clojure" . "clj"))
(defvar org-babel-default-header-args:clojure '())
-(defvar org-babel-header-args:clojure '((package . :any)))
+(defvar org-babel-header-args:clojure '((ns . :any)
+ (package . :any)))
(defcustom org-babel-clojure-sync-nrepl-timeout 10
"Timeout value, in seconds, of a Clojure sync call.
@@ -99,20 +104,19 @@ If the value is nil, timeout is disabled."
(result-params (cdr (assq :result-params params)))
(print-level nil)
(print-length nil)
- (body
- (org-trim
- (format "(ns %s)\n%s"
- ;; Source block specified namespace :ns.
- ns
- ;; Variables binding.
- (if (null vars) (org-trim body)
- (format "(let [%s]\n%s)"
- (mapconcat
- (lambda (var)
- (format "%S (quote %S)" (car var) (cdr var)))
- vars
- "\n ")
- body))))))
+ (body (org-trim
+ (concat
+ ;; Source block specified namespace :ns.
+ (and (cdr (assq :ns params)) (format "(ns %s)\n" ns))
+ ;; Variables binding.
+ (if (null vars) (org-trim body)
+ (format "(let [%s]\n%s)"
+ (mapconcat
+ (lambda (var)
+ (format "%S (quote %S)" (car var) (cdr var)))
+ vars
+ "\n ")
+ body))))))
(if (or (member "code" result-params)
(member "pp" result-params))
(format "(clojure.pprint/pprint (do %s))" body)
@@ -211,6 +215,69 @@ using the :show-process parameter."
(condition-case nil (org-babel-script-escape result)
(error result)))))
+(defun org-babel-clojure-initiate-session (&optional session _params)
+ "Initiate a session named SESSION according to PARAMS."
+ (when (and session (not (string= session "none")))
+ (save-window-excursion
+ (cond
+ ((org-babel-comint-buffer-livep session) nil)
+ ;; CIDER jack-in to the Clojure project directory.
+ ((eq org-babel-clojure-backend 'cider)
+ (require 'cider)
+ (let ((session-buffer
+ (save-window-excursion
+ (if (version< cider-version "0.18.0")
+ ;; Older CIDER (without sesman) still need to use
+ ;; old way.
+ (cider-jack-in nil) ;jack-in without project
+ ;; New CIDER (with sesman to manage sessions).
+ (unless (cider-repls)
+ (let ((sesman-system 'CIDER))
+ (call-interactively 'sesman-link-with-directory))))
+ (current-buffer))))
+ (when (org-babel-comint-buffer-livep session-buffer)
+ (sit-for .25)
+ session-buffer)))
+ ((eq org-babel-clojure-backend 'slime)
+ (error "Session evaluation with SLIME is not supported"))
+ (t
+ (error "Session initiate failed")))
+ (get-buffer session))))
+
+(defun org-babel-prep-session:clojure (session params)
+ "Prepare SESSION according to the header arguments specified in PARAMS."
+ (let ((session (org-babel-clojure-initiate-session session))
+ (var-lines (org-babel-variable-assignments:clojure params)))
+ (when session
+ (org-babel-comint-in-buffer session
+ (dolist (var var-lines)
+ (insert var)
+ (comint-send-input nil t)
+ (org-babel-comint-wait-for-output session)
+ (sit-for .1)
+ (goto-char (point-max)))))
+ session))
+
+(defun org-babel-clojure-var-to-clojure (var)
+ "Convert src block's VAR to Clojure variable."
+ (cond
+ ((listp var)
+ (replace-regexp-in-string "(" "'(" var))
+ ((stringp var)
+ ;; Wrap Babel passed-in header argument value with quotes in Clojure.
+ (format "\"%s\"" var))
+ (t
+ (format "%S" var))))
+
+(defun org-babel-variable-assignments:clojure (params)
+ "Return a list of Clojure statements assigning the block's variables in PARAMS."
+ (mapcar
+ (lambda (pair)
+ (format "(def %s %s)"
+ (car pair)
+ (org-babel-clojure-var-to-clojure (cdr pair))))
+ (org-babel--get-vars params)))
+
(provide 'ob-clojure)
;;; ob-clojure.el ends here
diff --git a/lisp/ob-core.el b/lisp/ob-core.el
index fe658ec..f877ff5 100644
--- a/lisp/ob-core.el
+++ b/lisp/ob-core.el
@@ -59,6 +59,7 @@
(declare-function org-element-type "org-element" (element))
(declare-function org-entry-get "org" (pom property &optional inherit literal-nil))
(declare-function org-escape-code-in-region "org-src" (beg end))
+(declare-function org-in-commented-heading-p "org" (&optional no-inheritance))
(declare-function org-indent-line "org" ())
(declare-function org-list-get-list-end "org-list" (item struct prevs))
(declare-function org-list-prevs-alist "org-list" (struct))
@@ -75,6 +76,7 @@
(declare-function org-show-context "org" (&optional key))
(declare-function org-src-coderef-format "org-src" (&optional element))
(declare-function org-src-coderef-regexp "org-src" (fmt &optional label))
+(declare-function org-src-get-lang-mode "org-src" (lang))
(declare-function org-table-align "org-table" ())
(declare-function org-table-end "org-table" (&optional table-type))
(declare-function org-table-import "org-table" (file arg))
@@ -526,7 +528,7 @@ to raise errors for all languages.")
"Hook for functions to be called after `org-babel-execute-src-block'")
(defun org-babel-named-src-block-regexp-for-name (&optional name)
- "This generates a regexp used to match a source block named NAME.
+ "Generate a regexp used to match a source block named NAME.
If NAME is nil, match any name. Matched name is then put in
match group 9. Other match groups are defined in
`org-babel-src-block-regexp'."
@@ -537,7 +539,7 @@ match group 9. Other match groups are defined in
(substring org-babel-src-block-regexp 1)))
(defun org-babel-named-data-regexp-for-name (name)
- "This generates a regexp used to match data named NAME."
+ "Generate a regexp used to match data named NAME."
(concat org-babel-name-regexp (regexp-quote name) "[ \t]*$"))
(defun org-babel--normalize-body (datum)
@@ -677,9 +679,16 @@ block."
(replace-regexp-in-string
(org-src-coderef-regexp coderef) "" expand nil nil 1))))
(dir (cdr (assq :dir params)))
+ (mkdirp (cdr (assq :mkdirp params)))
(default-directory
- (or (and dir (file-name-as-directory (expand-file-name dir)))
- default-directory))
+ (cond
+ ((not dir) default-directory)
+ ((member mkdirp '("no" "nil" nil))
+ (file-name-as-directory (expand-file-name dir)))
+ (t
+ (let ((d (file-name-as-directory (expand-file-name dir))))
+ (make-directory d 'parents)
+ d))))
(cmd (intern (concat "org-babel-execute:" lang)))
result)
(unless (fboundp cmd)
@@ -699,7 +708,8 @@ block."
(not (listp r)))
(list (list r))
r)))
- (let ((file (cdr (assq :file params))))
+ (let ((file (and (member "file" result-params)
+ (cdr (assq :file params)))))
;; If non-empty result and :file then write to :file.
(when file
;; If `:results' are special types like `link' or
@@ -1015,7 +1025,7 @@ evaluation mechanisms."
(call-interactively
(key-binding (or key (read-key-sequence nil))))))
-(defvar org-bracket-link-regexp)
+(defvar org-link-bracket-re)
(defun org-babel-active-location-p ()
(memq (org-element-type (save-match-data (org-element-context)))
@@ -1041,7 +1051,7 @@ exist."
(end-of-line)
(skip-chars-forward " \r\t\n")
;; Open the results.
- (if (looking-at org-bracket-link-regexp) (org-open-at-point)
+ (if (looking-at org-link-bracket-re) (org-open-at-point)
(let ((r (org-babel-format-result (org-babel-read-result)
(cdr (assq :sep arguments)))))
(pop-to-buffer (get-buffer-create "*Org Babel Results*"))
@@ -1296,19 +1306,6 @@ CONTEXT specifies the context of evaluation. It can be `:eval',
(looking-at org-babel-result-regexp)
(match-string-no-properties 1)))))
-(defun org-babel-set-current-result-hash (hash info)
- "Set the current in-buffer hash to HASH."
- (org-with-wide-buffer
- (goto-char (org-babel-where-is-src-block-result nil info))
- (looking-at org-babel-result-regexp)
- (goto-char (match-beginning 1))
- (mapc #'delete-overlay (overlays-at (point)))
- (forward-char org-babel-hash-show)
- (mapc #'delete-overlay (overlays-at (point)))
- (replace-match hash nil nil nil 1)
- (beginning-of-line)
- (org-babel-hide-hash)))
-
(defun org-babel-hide-hash ()
"Hide the hash in the current results line.
Only the initial `org-babel-hash-show' characters of the hash
@@ -1789,7 +1786,7 @@ to `org-babel-named-src-block-regexp'."
(ignore-errors (org-next-block 1 nil regexp))))))
(defun org-babel-src-block-names (&optional file)
- "Returns the names of source blocks in FILE or the current buffer."
+ "Return the names of source blocks in FILE or the current buffer."
(with-current-buffer (if file (find-file-noselect file) (current-buffer))
(org-with-point-at 1
(let ((regexp "^[ \t]*#\\+begin_src ")
@@ -1834,7 +1831,7 @@ buffer or nil if no such result exists."
(throw :found (line-beginning-position)))))))))
(defun org-babel-result-names (&optional file)
- "Returns the names of results in FILE or the current buffer."
+ "Return the names of results in FILE or the current buffer."
(save-excursion
(when file (find-file file)) (goto-char (point-min))
(let ((case-fold-search t) names)
@@ -2098,7 +2095,7 @@ Return nil if ELEMENT cannot be read."
(`paragraph
;; Treat paragraphs containing a single link specially.
(skip-chars-forward " \t")
- (if (and (looking-at org-bracket-link-regexp)
+ (if (and (looking-at org-link-bracket-re)
(save-excursion
(goto-char (match-end 0))
(skip-chars-forward " \r\t\n")
@@ -2140,7 +2137,7 @@ Return nil if ELEMENT cannot be read."
If the path of the link is a file path it is expanded using
`expand-file-name'."
(let* ((case-fold-search t)
- (raw (and (looking-at org-bracket-link-regexp)
+ (raw (and (looking-at org-link-bracket-re)
(org-no-properties (match-string 1))))
(type (and (string-match org-link-types-re raw)
(match-string 1 raw))))
@@ -2312,7 +2309,7 @@ INFO may provide the values of these header arguments (in the
(setq start inline-start)
(setq finish inline-finish)
(setq no-newlines t))
- (let ((before-finish (marker-position end)))
+ (let ((before-finish (copy-marker end)))
(goto-char end)
(insert (concat finish (unless no-newlines "\n")))
(goto-char beg)
@@ -2484,7 +2481,7 @@ in the buffer."
(defun org-babel-result-end ()
"Return the point at the end of the current set of results."
(cond ((looking-at-p "^[ \t]*$") (point)) ;no result
- ((looking-at-p (format "^[ \t]*%s[ \t]*$" org-bracket-link-regexp))
+ ((looking-at-p (format "^[ \t]*%s[ \t]*$" org-link-bracket-re))
(line-beginning-position 2))
(t
(let ((element (org-element-at-point)))
@@ -2641,19 +2638,6 @@ parameters when merging lists."
results
(split-string
(if (stringp value) value (eval value t))))))
- (`(,(or :file :file-ext) . ,value)
- ;; `:file' and `:file-ext' are regular keywords but they
- ;; imply a "file" `:results' and a "results" `:exports'.
- (when value
- (setq results
- (funcall merge results-exclusive-groups results '("file")))
- (unless (or (member "both" exports)
- (member "none" exports)
- (member "code" exports))
- (setq exports
- (funcall merge
- exports-exclusive-groups exports '("results"))))
- (push pair params)))
(`(:exports . ,value)
(setq exports (funcall merge
exports-exclusive-groups
@@ -2781,7 +2765,7 @@ block but are passed literally to the \"example-block\"."
;; Comment, according to LANG mode,
;; string S. Return new string.
(with-temp-buffer
- (funcall (intern (concat lang "-mode")))
+ (funcall (org-src-get-lang-mode lang))
(comment-region (point)
(progn (insert s) (point)))
(org-trim (buffer-string)))))
@@ -2797,7 +2781,8 @@ block but are passed literally to the \"example-block\"."
(concat (funcall c-wrap (car cs)) "\n"
b "\n"
(funcall c-wrap (cadr cs)))))))))
- (if (re-search-forward name-regexp nil t)
+ (if (and (re-search-forward name-regexp nil t)
+ (not (org-in-commented-heading-p)))
;; Found a source block named SOURCE-NAME.
;; Assume it is unique; do not look after
;; `:noweb-ref' header argument.
@@ -2808,14 +2793,16 @@ block but are passed literally to the \"example-block\"."
;; those with a matching Noweb reference.
(let ((expansion nil))
(org-babel-map-src-blocks nil
- (let* ((info (org-babel-get-src-block-info 'light))
- (parameters (nth 2 info)))
- (when (equal source-name
- (cdr (assq :noweb-ref parameters)))
- (push (funcall expand-body info) expansion)
- (push (or (cdr (assq :noweb-sep parameters))
- "\n")
- expansion))))
+ (unless (org-in-commented-heading-p)
+ (let* ((info
+ (org-babel-get-src-block-info 'light))
+ (parameters (nth 2 info)))
+ (when (equal source-name
+ (cdr (assq :noweb-ref parameters)))
+ (push (funcall expand-body info) expansion)
+ (push (or (cdr (assq :noweb-sep parameters))
+ "\n")
+ expansion)))))
(when expansion
(mapconcat #'identity
(nreverse (cdr expansion))
@@ -2944,7 +2931,7 @@ situations in which is it not appropriate."
(defun org-babel--string-to-number (string)
"If STRING represents a number return its value.
Otherwise return nil."
- (and (string-match-p "\\`-?[0-9]*\\.?[0-9]*\\'" string)
+ (and (string-match-p "\\`-?\\([0-9]\\|\\([1-9]\\|[0-9]*\\.\\)[0-9]*\\)\\'" string)
(string-to-number string)))
(defun org-babel-import-elisp-from-file (file-name &optional separator)
@@ -2992,7 +2979,7 @@ If NAME specifies a remote location, the remote portion of the
name is removed, since in that case the process will be executing
remotely. The file name is then processed by `expand-file-name'.
Unless second argument NO-QUOTE-P is non-nil, the file name is
-additionally processed by `shell-quote-argument'"
+additionally processed by `shell-quote-argument'."
(let ((f (org-babel-local-file-name (expand-file-name name))))
(if no-quote-p f (shell-quote-argument f))))
diff --git a/lisp/ob-ebnf.el b/lisp/ob-ebnf.el
index 5ed9319..c229228 100644
--- a/lisp/ob-ebnf.el
+++ b/lisp/ob-ebnf.el
@@ -49,8 +49,8 @@
;; Use ebnf-eps-buffer to produce an encapsulated postscript file.
;;
(defun org-babel-execute:ebnf (body params)
- "Execute a block of Ebnf code with org-babel. This function is
-called by `org-babel-execute-src-block'"
+ "Execute a block of Ebnf code with org-babel.
+This function is called by `org-babel-execute-src-block'."
(save-excursion
(let* ((dest-file (cdr (assq :file params)))
(dest-dir (file-name-directory dest-file))
diff --git a/lisp/ob-emacs-lisp.el b/lisp/ob-emacs-lisp.el
index cd86f4a..18b0d48 100644
--- a/lisp/ob-emacs-lisp.el
+++ b/lisp/ob-emacs-lisp.el
@@ -42,8 +42,9 @@
A value of \"yes\" or t causes source blocks to be eval'd using
lexical scoping. It can also be an alist mapping symbols to
-their value. It is used as the optional LEXICAL argument to
-`eval', which see.")
+their value. It is used both as the optional LEXICAL argument to
+`eval', and as the value for `lexical-binding' in buffers created
+by `org-edit-src-code'.")
(defun org-babel-expand-body:emacs-lisp (body params)
"Expand BODY according to PARAMS, return the expanded body."
@@ -71,9 +72,7 @@ their value. It is used as the optional LEXICAL argument to
(member "pp" result-params))
(concat "(pp " body ")")
body))
- (if (listp lexical)
- lexical
- (member lexical '("yes" "t"))))))
+ (org-babel-emacs-lisp-lexical lexical))))
(org-babel-result-cond result-params
(let ((print-level nil)
(print-length nil))
@@ -88,6 +87,23 @@ their value. It is used as the optional LEXICAL argument to
(org-babel-pick-name (cdr (assq :rowname-names params))
(cdr (assq :rownames params))))))))
+(defun org-babel-emacs-lisp-lexical (lexical)
+ "Interpret :lexical source block argument.
+Convert LEXICAL into the form appropriate for `lexical-binding'
+and the LEXICAL argument to `eval'."
+ (if (listp lexical)
+ lexical
+ (not (null (member lexical '("yes" "t"))))))
+
+(defun org-babel-edit-prep:emacs-lisp (info)
+ "Set `lexical-binding' in Org edit buffer.
+Set `lexical-binding' in Org edit buffer according to the
+corresponding :lexical source block argument."
+ (setq lexical-binding
+ (org-babel-emacs-lisp-lexical
+ (org-babel-read
+ (cdr (assq :lexical (nth 2 info)))))))
+
(org-babel-make-language-alias "elisp" "emacs-lisp")
(provide 'ob-emacs-lisp)
diff --git a/lisp/ob-eshell.el b/lisp/ob-eshell.el
new file mode 100644
index 0000000..800abce
--- /dev/null
+++ b/lisp/ob-eshell.el
@@ -0,0 +1,102 @@
+;;; ob-eshell.el --- Babel Functions for Eshell -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2018 Free Software Foundation, Inc.
+
+;; Author: stardiviner <numbchild@gmail.com>
+;; Keywords: literate programming, reproducible research
+;; Homepage: https://orgmode.org
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Org Babel support for evaluating Eshell source code.
+
+;;; Code:
+(require 'ob)
+(require 'eshell)
+
+(defvar org-babel-default-header-args:eshell '())
+
+(defun org-babel-execute:eshell (body params)
+ "Execute a block of Eshell code BODY with PARAMS.
+This function is called by `org-babel-execute-src-block'.
+
+The BODY can be any code which allowed executed in Eshell.
+Eshell allow to execute normal shell command and Elisp code.
+More details please reference Eshell Info.
+
+The PARAMS are variables assignments."
+ (let* ((session (org-babel-eshell-initiate-session
+ (cdr (assq :session params))))
+ (full-body (org-babel-expand-body:generic
+ body params (org-babel-variable-assignments:eshell params))))
+ (if session
+ (progn
+ (with-current-buffer session
+ (dolist (line (split-string full-body "\n"))
+ (goto-char eshell-last-output-end)
+ (insert line)
+ (eshell-send-input))
+ ;; get output of last input
+ ;; TODO: collect all output instead of last command's output.
+ (goto-char eshell-last-input-end)
+ (buffer-substring-no-properties (point) eshell-last-output-start)))
+ (with-temp-buffer
+ (eshell-command full-body t)
+ (buffer-string)))))
+
+(defun org-babel-prep-session:eshell (session params)
+ "Prepare SESSION according to the header arguments specified in PARAMS."
+ (let* ((session (org-babel-eshell-initiate-session session))
+ ;; Eshell session buffer is read from variable `eshell-buffer-name'.
+ (eshell-buffer-name session)
+ (var-lines (org-babel-variable-assignments:eshell params)))
+ (call-interactively #'eshell)
+ (mapc #'eshell-command var-lines)
+ session))
+
+(defun ob-eshell-session-live-p (session)
+ "Non-nil if Eshell SESSION exists."
+ (get-buffer session))
+
+(defun org-babel-eshell-initiate-session (&optional session _params)
+ "Initiate a session named SESSION."
+ (when (and session (not (string= session "none")))
+ (save-window-excursion
+ (unless (ob-eshell-session-live-p session)
+ (let ((eshell-buffer-name session)) (eshell))))
+ session))
+
+(defun org-babel-variable-assignments:eshell (params)
+ "Convert ob-eshell :var specified variables into Eshell variables assignments."
+ (mapcar
+ (lambda (pair)
+ (format "(setq %s %S)" (car pair) (cdr pair)))
+ (org-babel--get-vars params)))
+
+(defun org-babel-load-session:eshell (session body params)
+ "Load BODY into SESSION with PARAMS."
+ (save-window-excursion
+ (let ((buffer (org-babel-prep-session:eshell session params)))
+ (with-current-buffer buffer
+ (goto-char (point-max))
+ (insert (org-babel-chomp body)))
+ buffer)))
+
+(provide 'ob-eshell)
+
+;;; ob-eshell.el ends here
diff --git a/lisp/ob-exp.el b/lisp/ob-exp.el
index 177104b..c06e262 100644
--- a/lisp/ob-exp.el
+++ b/lisp/ob-exp.el
@@ -32,7 +32,6 @@
(declare-function org-element-type "org-element" (element))
(declare-function org-escape-code-in-string "org-src" (s))
(declare-function org-export-copy-buffer "ox" ())
-(declare-function org-fill-template "org" (template alist))
(declare-function org-in-commented-heading-p "org" (&optional no-inheritance))
(defvar org-src-preserve-indentation)
diff --git a/lisp/ob-forth.el b/lisp/ob-forth.el
index 2d61de3..5d4fe30 100644
--- a/lisp/ob-forth.el
+++ b/lisp/ob-forth.el
@@ -42,7 +42,7 @@
(defun org-babel-execute:forth (body params)
"Execute a block of Forth code with org-babel.
-This function is called by `org-babel-execute-src-block'"
+This function is called by `org-babel-execute-src-block'."
(if (string= "none" (cdr (assq :session params)))
(error "Non-session evaluation not supported for Forth code blocks")
(let ((all-results (org-babel-forth-session-execute body params)))
diff --git a/lisp/ob-fortran.el b/lisp/ob-fortran.el
index f1285f6..1431eb4 100644
--- a/lisp/ob-fortran.el
+++ b/lisp/ob-fortran.el
@@ -45,7 +45,7 @@
executable.")
(defun org-babel-execute:fortran (body params)
- "This function should only be called by `org-babel-execute:fortran'"
+ "This function should only be called by `org-babel-execute:fortran'."
(let* ((tmp-src-file (org-babel-temp-file "fortran-src-" ".F90"))
(tmp-bin-file (org-babel-temp-file "fortran-bin-" org-babel-exeext))
(cmdline (cdr (assq :cmdline params)))
@@ -114,12 +114,12 @@ its header arguments."
(defun org-babel-prep-session:fortran (_session _params)
"This function does nothing as fortran is a compiled language with no
-support for sessions"
+support for sessions."
(error "Fortran is a compiled languages -- no support for sessions"))
(defun org-babel-load-session:fortran (_session _body _params)
"This function does nothing as fortran is a compiled language with no
-support for sessions"
+support for sessions."
(error "Fortran is a compiled languages -- no support for sessions"))
;; helper functions
diff --git a/lisp/ob-groovy.el b/lisp/ob-groovy.el
index fe3a072..a22e21d 100644
--- a/lisp/ob-groovy.el
+++ b/lisp/ob-groovy.el
@@ -45,8 +45,8 @@ parameters may be used, like groovy -v"
:type 'string)
(defun org-babel-execute:groovy (body params)
- "Execute a block of Groovy code with org-babel. This function is
-called by `org-babel-execute-src-block'"
+ "Execute a block of Groovy code with org-babel.
+This function is called by `org-babel-execute-src-block'."
(message "executing Groovy source code block")
(let* ((processed-params (org-babel-process-params params))
(session (org-babel-groovy-initiate-session (nth 0 processed-params)))
diff --git a/lisp/ob-io.el b/lisp/ob-io.el
index b0d5b51..9817c64 100644
--- a/lisp/ob-io.el
+++ b/lisp/ob-io.el
@@ -41,8 +41,8 @@
"Name of the command to use for executing Io code.")
(defun org-babel-execute:io (body params)
- "Execute a block of Io code with org-babel. This function is
-called by `org-babel-execute-src-block'"
+ "Execute a block of Io code with org-babel.
+This function is called by `org-babel-execute-src-block'."
(message "executing Io source code block")
(let* ((processed-params (org-babel-process-params params))
(session (org-babel-io-initiate-session (nth 0 processed-params)))
diff --git a/lisp/ob-js.el b/lisp/ob-js.el
index 7b83c3e..dd53ef6 100644
--- a/lisp/ob-js.el
+++ b/lisp/ob-js.el
@@ -70,7 +70,7 @@
(defun org-babel-execute:js (body params)
"Execute a block of Javascript code with org-babel.
-This function is called by `org-babel-execute-src-block'"
+This function is called by `org-babel-execute-src-block'."
(let* ((org-babel-js-cmd (or (cdr (assq :cmd params)) org-babel-js-cmd))
(session (cdr (assq :session params)))
(result-type (cdr (assq :result-type params)))
diff --git a/lisp/ob-keys.el b/lisp/ob-keys.el
deleted file mode 100644
index 627648d..0000000
--- a/lisp/ob-keys.el
+++ /dev/null
@@ -1,106 +0,0 @@
-;;; ob-keys.el --- Key Bindings for Babel -*- lexical-binding: t; -*-
-
-;; Copyright (C) 2009-2019 Free Software Foundation, Inc.
-
-;; Author: Eric Schulte
-;; Keywords: literate programming, reproducible research
-;; Homepage: https://orgmode.org
-
-;; This file is part of GNU Emacs.
-
-;; GNU Emacs is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; Add Org Babel keybindings to the Org mode keymap for exposing
-;; Org Babel functions. These will all share a common prefix. See
-;; the value of `org-babel-key-bindings' for a list of interactive
-;; functions and their associated keys.
-
-;;; Code:
-(require 'ob-core)
-
-(defvar org-babel-key-prefix "\C-c\C-v"
- "The key prefix for Babel interactive key-bindings.
-See `org-babel-key-bindings' for the list of interactive babel
-functions which are assigned key bindings, and see
-`org-babel-map' for the actual babel keymap.")
-
-(defvar org-babel-map (make-sparse-keymap)
- "The keymap for interactive Babel functions.")
-
-;;;###autoload
-(defun org-babel-describe-bindings ()
- "Describe all keybindings behind `org-babel-key-prefix'."
- (interactive)
- (describe-bindings org-babel-key-prefix))
-
-(defvar org-babel-key-bindings
- '(("p" . org-babel-previous-src-block)
- ("\C-p" . org-babel-previous-src-block)
- ("n" . org-babel-next-src-block)
- ("\C-n" . org-babel-next-src-block)
- ("e" . org-babel-execute-maybe)
- ("\C-e" . org-babel-execute-maybe)
- ("o" . org-babel-open-src-block-result)
- ("\C-o" . org-babel-open-src-block-result)
- ("\C-v" . org-babel-expand-src-block)
- ("v" . org-babel-expand-src-block)
- ("u" . org-babel-goto-src-block-head)
- ("\C-u" . org-babel-goto-src-block-head)
- ("g" . org-babel-goto-named-src-block)
- ("r" . org-babel-goto-named-result)
- ("\C-r" . org-babel-goto-named-result)
- ("\C-b" . org-babel-execute-buffer)
- ("b" . org-babel-execute-buffer)
- ("\C-s" . org-babel-execute-subtree)
- ("s" . org-babel-execute-subtree)
- ("\C-d" . org-babel-demarcate-block)
- ("d" . org-babel-demarcate-block)
- ("\C-t" . org-babel-tangle)
- ("t" . org-babel-tangle)
- ("\C-f" . org-babel-tangle-file)
- ("f" . org-babel-tangle-file)
- ("\C-c" . org-babel-check-src-block)
- ("c" . org-babel-check-src-block)
- ("\C-j" . org-babel-insert-header-arg)
- ("j" . org-babel-insert-header-arg)
- ("\C-l" . org-babel-load-in-session)
- ("l" . org-babel-load-in-session)
- ("\C-i" . org-babel-lob-ingest)
- ("i" . org-babel-lob-ingest)
- ("\C-I" . org-babel-view-src-block-info)
- ("I" . org-babel-view-src-block-info)
- ("\C-z" . org-babel-switch-to-session)
- ("z" . org-babel-switch-to-session-with-code)
- ("\C-a" . org-babel-sha1-hash)
- ("a" . org-babel-sha1-hash)
- ("h" . org-babel-describe-bindings)
- ("\C-x" . org-babel-do-key-sequence-in-edit-buffer)
- ("x" . org-babel-do-key-sequence-in-edit-buffer)
- ("k" . org-babel-remove-result-one-or-many)
- ("\C-\M-h" . org-babel-mark-block))
- "Alist of key bindings and interactive Babel functions.
-This list associates interactive Babel functions
-with keys. Each element of this list will add an entry to the
-`org-babel-map' using the letter key which is the `car' of the
-a-list placed behind the generic `org-babel-key-prefix'.")
-
-(provide 'ob-keys)
-
-;; Local variables:
-;; generated-autoload-file: "org-loaddefs.el"
-;; End:
-
-;;; ob-keys.el ends here
diff --git a/lisp/ob-lilypond.el b/lisp/ob-lilypond.el
index c795d9c..4538ed5 100644
--- a/lisp/ob-lilypond.el
+++ b/lisp/ob-lilypond.el
@@ -43,20 +43,20 @@
(defvar org-babel-default-header-args:lilypond '()
"Default header arguments for lilypond code blocks.
NOTE: The arguments are determined at lilypond compile time.
-See (org-babel-lilypond-set-header-args)")
+See `org-babel-lilypond-set-header-args'.")
(defvar org-babel-lilypond-compile-post-tangle t
"Following the org-babel-tangle (C-c C-v t) command,
org-babel-lilypond-compile-post-tangle determines whether ob-lilypond should
automatically attempt to compile the resultant tangled file.
If the value is nil, no automated compilation takes place.
-Default value is t")
+Default value is t.")
(defvar org-babel-lilypond-display-pdf-post-tangle t
"Following a successful LilyPond compilation
org-babel-lilypond-display-pdf-post-tangle determines whether to automate the
drawing / redrawing of the resultant pdf. If the value is nil,
-the pdf is not automatically redrawn. Default value is t")
+the pdf is not automatically redrawn. Default value is t.")
(defvar org-babel-lilypond-play-midi-post-tangle t
"Following a successful LilyPond compilation
@@ -152,7 +152,7 @@ Depending on whether we are in arrange mode either:
(defun org-babel-lilypond-tangle ()
"ob-lilypond specific tangle, attempts to invoke
=ly-execute-tangled-ly= if tangle is successful. Also passes
-specific arguments to =org-babel-tangle="
+specific arguments to =org-babel-tangle=."
(interactive)
(if (org-babel-tangle nil "yes" "lilypond")
(org-babel-lilypond-execute-tangled-ly) nil))
@@ -189,7 +189,7 @@ specific arguments to =org-babel-tangle="
(defun org-babel-lilypond-execute-tangled-ly ()
"Compile result of block tangle with lilypond.
-If error in compilation, attempt to mark the error in lilypond org file"
+If error in compilation, attempt to mark the error in lilypond org file."
(when org-babel-lilypond-compile-post-tangle
(let ((org-babel-lilypond-tangled-file (org-babel-lilypond-switch-extension
(buffer-file-name) ".lilypond"))
@@ -212,8 +212,8 @@ If error in compilation, attempt to mark the error in lilypond org file"
(org-babel-lilypond-attempt-to-play-midi org-babel-lilypond-temp-file)))))
(defun org-babel-lilypond-compile-lilyfile (file-name &optional test)
- "Compile lilypond file and check for compile errors
-FILE-NAME is full path to lilypond (.ly) file"
+ "Compile lilypond file and check for compile errors.
+FILE-NAME is full path to lilypond (.ly) file."
(message "Compiling LilyPond...")
(let ((arg-1 org-babel-lilypond-ly-command) ;program
(arg-2 nil) ;infile
@@ -239,7 +239,7 @@ This is performed by parsing the *lilypond* buffer
containing the output message from the compilation.
FILE-NAME is full path to lilypond file.
If TEST is t just return nil if no error found, and pass
-nil as file-name since it is unused in this context"
+nil as file-name since it is unused in this context."
(let ((is-error (search-forward "error:" nil t)))
(if test
is-error
@@ -248,7 +248,7 @@ nil as file-name since it is unused in this context"
(defun org-babel-lilypond-process-compile-error (file-name)
"Process the compilation error that has occurred.
-FILE-NAME is full path to lilypond file"
+FILE-NAME is full path to lilypond file."
(let ((line-num (org-babel-lilypond-parse-line-num)))
(let ((error-lines (org-babel-lilypond-parse-error-line file-name line-num)))
(org-babel-lilypond-mark-error-line file-name error-lines)
@@ -257,7 +257,7 @@ FILE-NAME is full path to lilypond file"
(defun org-babel-lilypond-mark-error-line (file-name line)
"Mark the erroneous lines in the lilypond org buffer.
FILE-NAME is full path to lilypond file.
-LINE is the erroneous line"
+LINE is the erroneous line."
(switch-to-buffer-other-window
(concat (file-name-nondirectory
(org-babel-lilypond-switch-extension file-name ".org"))))
@@ -288,9 +288,9 @@ LINE is the erroneous line"
(and (numberp num) num)))))
(defun org-babel-lilypond-parse-error-line (file-name lineNo)
- "Extract the erroneous line from the tangled .ly file
+ "Extract the erroneous line from the tangled .ly file.
FILE-NAME is full path to lilypond file.
-LINENO is the number of the erroneous line"
+LINENO is the number of the erroneous line."
(with-temp-buffer
(insert-file-contents (org-babel-lilypond-switch-extension file-name ".ly")
nil nil nil t)
@@ -302,9 +302,9 @@ LINENO is the number of the erroneous line"
nil)))
(defun org-babel-lilypond-attempt-to-open-pdf (file-name &optional test)
- "Attempt to display the generated pdf file
-FILE-NAME is full path to lilypond file
-If TEST is non-nil, the shell command is returned and is not run"
+ "Attempt to display the generated pdf file.
+FILE-NAME is full path to lilypond file.
+If TEST is non-nil, the shell command is returned and is not run."
(when org-babel-lilypond-display-pdf-post-tangle
(let ((pdf-file (org-babel-lilypond-switch-extension file-name ".pdf")))
(if (file-exists-p pdf-file)
@@ -320,9 +320,9 @@ If TEST is non-nil, the shell command is returned and is not run"
(message "No pdf file generated so can't display!")))))
(defun org-babel-lilypond-attempt-to-play-midi (file-name &optional test)
- "Attempt to play the generated MIDI file
-FILE-NAME is full path to lilypond file
-If TEST is non-nil, the shell command is returned and is not run"
+ "Attempt to play the generated MIDI file.
+FILE-NAME is full path to lilypond file.
+If TEST is non-nil, the shell command is returned and is not run."
(when org-babel-lilypond-play-midi-post-tangle
(let ((midi-file (org-babel-lilypond-switch-extension file-name ".midi")))
(if (file-exists-p midi-file)
@@ -385,14 +385,13 @@ If TEST is non-nil, the shell command is returned and is not run"
(if org-babel-lilypond-arrange-mode "ENABLED." "DISABLED."))))
(defun org-babel-lilypond-switch-extension (file-name ext)
- "Utility command to swap current FILE-NAME extension with EXT"
+ "Utility command to swap current FILE-NAME extension with EXT."
(concat (file-name-sans-extension
file-name) ext))
(defun org-babel-lilypond-get-header-args (mode)
- "Default arguments to use when evaluating a lilypond
-source block. These depend upon whether we are in arrange
-mode i.e. ARRANGE-MODE is t"
+ "Default arguments to use when evaluating a lilypond source block.
+These depend upon whether we are in Arrange mode i.e. MODE is t."
(cond (mode
'((:tangle . "yes")
(:noweb . "yes")
@@ -405,7 +404,7 @@ mode i.e. ARRANGE-MODE is t"
(defun org-babel-lilypond-set-header-args (mode)
"Set org-babel-default-header-args:lilypond
-dependent on ORG-BABEL-LILYPOND-ARRANGE-MODE"
+dependent on ORG-BABEL-LILYPOND-ARRANGE-MODE."
(setq org-babel-default-header-args:lilypond
(org-babel-lilypond-get-header-args mode)))
diff --git a/lisp/ob-lisp.el b/lisp/ob-lisp.el
index e717fc3..398ed21 100644
--- a/lisp/ob-lisp.el
+++ b/lisp/ob-lisp.el
@@ -107,7 +107,7 @@ a property list containing the parameters of the block."
(point-min) (point-max)))))
(cdr (assq :package params)))))))
(org-babel-result-cond (cdr (assq :result-params params))
- result
+ (org-strip-quotes result)
(condition-case nil
(read (org-babel-lisp-vector-to-list result))
(error result))))
diff --git a/lisp/ob-lua.el b/lisp/ob-lua.el
index 70d328e..530376a 100644
--- a/lisp/ob-lua.el
+++ b/lisp/ob-lua.el
@@ -55,7 +55,7 @@
(defcustom org-babel-lua-mode 'lua-mode
"Preferred lua mode for use in running lua interactively.
-This will typically be 'lua-mode."
+This will typically be `lua-mode'."
:group 'org-babel
:version "26.1"
:package-version '(Org . "8.3")
@@ -69,7 +69,7 @@ This will typically be 'lua-mode."
:type 'string)
(defcustom org-babel-lua-None-to 'hline
- "Replace 'None' in lua tables with this before returning."
+ "Replace `None' in lua tables with this before returning."
:group 'org-babel
:version "26.1"
:package-version '(Org . "8.3")
@@ -100,7 +100,7 @@ This function is called by `org-babel-execute-src-block'."
(defun org-babel-prep-session:lua (session params)
"Prepare SESSION according to the header arguments in PARAMS.
-VARS contains resolved variable references"
+VARS contains resolved variable references."
(let* ((session (org-babel-lua-initiate-session session))
(var-lines
(org-babel-variable-assignments:lua params)))
@@ -284,8 +284,8 @@ fd:close()")
(defun org-babel-lua-evaluate-external-process
(body &optional result-type result-params preamble)
"Evaluate BODY in external lua process.
-If RESULT-TYPE equals 'output then return standard output as a
-string. If RESULT-TYPE equals 'value then return the value of the
+If RESULT-TYPE equals `output' then return standard output as a
+string. If RESULT-TYPE equals `value' then return the value of the
last statement in BODY, as elisp."
(let ((raw
(pcase result-type
@@ -316,8 +316,8 @@ last statement in BODY, as elisp."
(defun org-babel-lua-evaluate-session
(session body &optional result-type result-params)
"Pass BODY to the Lua process in SESSION.
-If RESULT-TYPE equals 'output then return standard output as a
-string. If RESULT-TYPE equals 'value then return the value of the
+If RESULT-TYPE equals `output' then return standard output as a
+string. If RESULT-TYPE equals `value' then return the value of the
last statement in BODY, as elisp."
(let* ((send-wait (lambda () (comint-send-input nil t) (sleep-for 0 5)))
(dump-last-value
diff --git a/lisp/ob-ocaml.el b/lisp/ob-ocaml.el
index 0c0ffe4..54bc49a 100644
--- a/lisp/ob-ocaml.el
+++ b/lisp/ob-ocaml.el
@@ -83,11 +83,11 @@
(raw (org-trim clean))
(result-params (cdr (assq :result-params params))))
(string-match
- "\\(\\(.*\n\\)*\\)[^:\n]+ : \\([^=\n]+\\) =\\(\n\\| \\)\\(.+\\)$"
+ "\\(\\(.*\n\\)*\\)[^:\n]+ : \\([^=\n]+\\) =[[:space:]]+\\(\\(.\\|\n\\)+\\)$"
raw)
(let ((output (match-string 1 raw))
(type (match-string 3 raw))
- (value (match-string 5 raw)))
+ (value (match-string 4 raw)))
(org-babel-reassemble-table
(org-babel-result-cond result-params
(cond
diff --git a/lisp/ob-picolisp.el b/lisp/ob-picolisp.el
index c0f0125..4f70252 100644
--- a/lisp/ob-picolisp.el
+++ b/lisp/ob-picolisp.el
@@ -94,8 +94,8 @@
body)))
(defun org-babel-execute:picolisp (body params)
- "Execute a block of Picolisp code with org-babel. This function is
- called by `org-babel-execute-src-block'"
+ "Execute a block of Picolisp code with org-babel.
+This function is called by `org-babel-execute-src-block'."
(message "executing Picolisp source code block")
(let* (
;; Name of the session or "none".
diff --git a/lisp/ob-plantuml.el b/lisp/ob-plantuml.el
index 91229a2..09c9a33 100644
--- a/lisp/ob-plantuml.el
+++ b/lisp/ob-plantuml.el
@@ -60,16 +60,19 @@ are expected to be scalar variables."
(defun org-babel-plantuml-make-body (body params)
"Return PlantUML input string.
+
BODY is the content of the source block and PARAMS is a property list
of source block parameters. This function relies on the
`org-babel-expand-body:generic' function to extract `:var' entries
from PARAMS and on the `org-babel-variable-assignments:plantuml'
-function to convert variables to PlantUML assignments."
- (concat
- "@startuml\n"
- (org-babel-expand-body:generic
- body params (org-babel-variable-assignments:plantuml params))
- "\n@enduml"))
+function to convert variables to PlantUML assignments.
+
+If BODY does not contain @startXXX ... @endXXX clauses, @startuml
+... @enduml will be added."
+ (let ((assignments (org-babel-variable-assignments:plantuml params)))
+ (if (string-prefix-p "@start" body t) assignments
+ (format "@startuml\n%s\n@enduml"
+ (org-babel-expand-body:generic body params assignments)))))
(defun org-babel-execute:plantuml (body params)
"Execute a block of plantuml code with org-babel.
@@ -93,6 +96,8 @@ This function is called by `org-babel-execute-src-block'."
" -teps" "")
(if (string= (file-name-extension out-file) "pdf")
" -tpdf" "")
+ (if (string= (file-name-extension out-file) "tex")
+ " -tlatex" "")
(if (string= (file-name-extension out-file) "vdx")
" -tvdx" "")
(if (string= (file-name-extension out-file) "xmi")
diff --git a/lisp/ob-processing.el b/lisp/ob-processing.el
index 97ab88c..7bb9fa1 100644
--- a/lisp/ob-processing.el
+++ b/lisp/ob-processing.el
@@ -135,7 +135,7 @@ This function is called by `org-babel-execute-src-block'."
(defun org-babel-prep-session:processing (_session _params)
"Return an error if the :session header argument is set.
-Processing does not support sessions"
+Processing does not support sessions."
(error "Processing does not support sessions"))
(defun org-babel-variable-assignments:processing (params)
diff --git a/lisp/ob-python.el b/lisp/ob-python.el
index d4ee230..c36bf2d 100644
--- a/lisp/ob-python.el
+++ b/lisp/ob-python.el
@@ -97,7 +97,7 @@ This function is called by `org-babel-execute-src-block'."
(defun org-babel-prep-session:python (session params)
"Prepare SESSION according to the header arguments in PARAMS.
-VARS contains resolved variable references"
+VARS contains resolved variable references."
(let* ((session (org-babel-python-initiate-session session))
(var-lines
(org-babel-variable-assignments:python params)))
diff --git a/lisp/ob-ruby.el b/lisp/ob-ruby.el
index 32af8c5..be76727 100644
--- a/lisp/ob-ruby.el
+++ b/lisp/ob-ruby.el
@@ -215,7 +215,7 @@ return the value of the last statement in BODY, as elisp."
(let ((eoe-string (format "puts \"%s\"" org-babel-ruby-eoe-indicator)))
;; Force the session to be ready before the actual session
;; code is run. There is some problem in comint that will
- ;; sometimes show the prompt after the the input has already
+ ;; sometimes show the prompt after the input has already
;; been inserted and that throws off the extraction of the
;; result for Babel.
(org-babel-comint-with-output
diff --git a/lisp/ob-scheme.el b/lisp/ob-scheme.el
index ceef8e3..21d9fad 100644
--- a/lisp/ob-scheme.el
+++ b/lisp/ob-scheme.el
@@ -102,7 +102,7 @@
(puthash session-name buffer org-babel-scheme-repl-map))
(defun org-babel-scheme-get-buffer-impl (buffer)
- "Returns the scheme implementation geiser associates with the buffer."
+ "Return the scheme implementation geiser associates with the buffer."
(with-current-buffer (set-buffer buffer)
geiser-impl--implementation))
@@ -131,7 +131,7 @@ org-babel-scheme-execute-with-geiser will use a temporary session."
(name)))
(defmacro org-babel-scheme-capture-current-message (&rest body)
- "Capture current message in both interactive and noninteractive mode"
+ "Capture current message in both interactive and noninteractive mode."
`(if noninteractive
(let ((original-message (symbol-function 'message))
(current-message nil))
@@ -147,10 +147,11 @@ org-babel-scheme-execute-with-geiser will use a temporary session."
(current-message))))
(defun org-babel-scheme-execute-with-geiser (code output impl repl)
- "Execute code in specified REPL. If the REPL doesn't exist, create it
-using the given scheme implementation.
+ "Execute code in specified REPL.
+If the REPL doesn't exist, create it using the given scheme
+implementation.
-Returns the output of executing the code if the output parameter
+Returns the output of executing the code if the OUTPUT parameter
is true; otherwise returns the last value."
(let ((result nil))
(with-temp-buffer
@@ -198,7 +199,7 @@ Emacs-lisp table, otherwise return the results as a string."
(defun org-babel-execute:scheme (body params)
"Execute a block of Scheme code with org-babel.
-This function is called by `org-babel-execute-src-block'"
+This function is called by `org-babel-execute-src-block'."
(let* ((source-buffer (current-buffer))
(source-buffer-name (replace-regexp-in-string ;; zap surrounding *
"^ ?\\*\\([^*]+\\)\\*" "\\1"
diff --git a/lisp/ob-shell.el b/lisp/ob-shell.el
index 66c28f7..88342ba 100644
--- a/lisp/ob-shell.el
+++ b/lisp/ob-shell.el
@@ -112,12 +112,12 @@ This function is called by `org-babel-execute-src-block'."
;;; Helper functions
(defun org-babel--variable-assignments:sh-generic
(varname values &optional sep hline)
- "Returns a list of statements declaring the values as a generic variable."
+ "Return a list of statements declaring the values as a generic variable."
(format "%s=%s" varname (org-babel-sh-var-to-sh values sep hline)))
(defun org-babel--variable-assignments:bash_array
(varname values &optional sep hline)
- "Returns a list of statements declaring the values as a bash array."
+ "Return a list of statements declaring the values as a bash array."
(format "unset %s\ndeclare -a %s=( %s )"
varname varname
(mapconcat
@@ -127,7 +127,7 @@ This function is called by `org-babel-execute-src-block'."
(defun org-babel--variable-assignments:bash_assoc
(varname values &optional sep hline)
- "Returns a list of statements declaring the values as bash associative array."
+ "Return a list of statements declaring the values as bash associative array."
(format "unset %s\ndeclare -A %s\n%s"
varname varname
(mapconcat
@@ -140,7 +140,7 @@ This function is called by `org-babel-execute-src-block'."
"\n")))
(defun org-babel--variable-assignments:bash (varname values &optional sep hline)
- "Represents the parameters as useful Bash shell variables."
+ "Represent the parameters as useful Bash shell variables."
(pcase values
(`((,_ ,_ . ,_) . ,_) ;two-dimensional array
(org-babel--variable-assignments:bash_assoc varname values sep hline))
diff --git a/lisp/ob-shen.el b/lisp/ob-shen.el
index af3bd2b..f2daa67 100644
--- a/lisp/ob-shen.el
+++ b/lisp/ob-shen.el
@@ -61,7 +61,7 @@
(defun org-babel-execute:shen (body params)
"Execute a block of Shen code with org-babel.
-This function is called by `org-babel-execute-src-block'"
+This function is called by `org-babel-execute-src-block'."
(require 'inf-shen)
(let* ((result-params (cdr (assq :result-params params)))
(full-body (org-babel-expand-body:shen body params)))
diff --git a/lisp/ob-sql.el b/lisp/ob-sql.el
index 2a58188..1bbfd44 100644
--- a/lisp/ob-sql.el
+++ b/lisp/ob-sql.el
@@ -39,6 +39,7 @@
;; - dbport
;; - dbuser
;; - dbpassword
+;; - dbconnection (to reference connections in sql-connection-alist)
;; - database
;; - colnames (default, nil, means "yes")
;; - result-params
@@ -73,6 +74,7 @@
(declare-function org-table-to-lisp "org-table" (&optional txt))
(declare-function cygwin-convert-file-name-to-windows "cygw32.c" (file &optional absolute-p))
+(defvar sql-connection-alist)
(defvar org-babel-default-header-args:sql '())
(defconst org-babel-header-args:sql
@@ -174,16 +176,35 @@ Otherwise, use Emacs' standard conversion function."
((string= "windows-nt" system-type) file)
(t (format "%S" (convert-standard-filename file)))))
+(defun org-babel-find-db-connection-param (params name)
+ "Return database connection parameter NAME.
+Given a parameter NAME, if :dbconnection is defined in PARAMS
+then look for the parameter into the corresponding connection
+defined in `sql-connection-alist`, otherwise look into PARAMS.
+Look `sql-connection-alist` (part of SQL mode) for how to define
+database connections."
+ (if (assq :dbconnection params)
+ (let* ((dbconnection (cdr (assq :dbconnection params)))
+ (name-mapping '((:dbhost . sql-server)
+ (:dbport . sql-port)
+ (:dbuser . sql-user)
+ (:dbpassword . sql-password)
+ (:database . sql-database)))
+ (mapped-name (cdr (assq name name-mapping))))
+ (cadr (assq mapped-name
+ (cdr (assoc dbconnection sql-connection-alist)))))
+ (cdr (assq name params))))
+
(defun org-babel-execute:sql (body params)
"Execute a block of Sql code with Babel.
This function is called by `org-babel-execute-src-block'."
(let* ((result-params (cdr (assq :result-params params)))
(cmdline (cdr (assq :cmdline params)))
- (dbhost (cdr (assq :dbhost params)))
- (dbport (cdr (assq :dbport params)))
- (dbuser (cdr (assq :dbuser params)))
- (dbpassword (cdr (assq :dbpassword params)))
- (database (cdr (assq :database params)))
+ (dbhost (org-babel-find-db-connection-param params :dbhost))
+ (dbport (org-babel-find-db-connection-param params :dbport))
+ (dbuser (org-babel-find-db-connection-param params :dbuser))
+ (dbpassword (org-babel-find-db-connection-param params :dbpassword))
+ (database (org-babel-find-db-connection-param params :database))
(engine (cdr (assq :engine params)))
(colnames-p (not (equal "no" (cdr (assq :colnames params)))))
(in-file (org-babel-temp-file "sql-in-"))
diff --git a/lisp/ob-sqlite.el b/lisp/ob-sqlite.el
index 04bf4fe..7522c83 100644
--- a/lisp/ob-sqlite.el
+++ b/lisp/ob-sqlite.el
@@ -28,7 +28,6 @@
;;; Code:
(require 'ob)
-(declare-function org-fill-template "org" (template alist))
(declare-function org-table-convert-region "org-table"
(beg0 end0 &optional separator))
(declare-function orgtbl-to-csv "org-table" (table params))
diff --git a/lisp/ob-tangle.el b/lisp/ob-tangle.el
index dbab56f..2ea3341 100644
--- a/lisp/ob-tangle.el
+++ b/lisp/ob-tangle.el
@@ -30,6 +30,7 @@
(require 'cl-lib)
(require 'org-src)
(require 'org-macs)
+(require 'ol)
(declare-function make-directory "files" (dir &optional parents))
(declare-function org-at-heading-p "org" (&optional ignored))
@@ -38,17 +39,10 @@
(declare-function org-before-first-heading-p "org" ())
(declare-function org-element-at-point "org-element" ())
(declare-function org-element-type "org-element" (element))
-(declare-function org-fill-template "org" (template alist))
(declare-function org-heading-components "org" ())
-(declare-function org-id-find "org-id" (id &optional markerp))
(declare-function org-in-commented-heading-p "org" (&optional no-inheritance))
-(declare-function org-link-escape "org" (text &optional table merge))
-(declare-function org-open-link-from-string "org" (s &optional arg reference-buffer))
-(declare-function org-store-link "org" (arg &optional interactive?))
(declare-function outline-previous-heading "outline" ())
-(defvar org-link-types-re)
-
(defcustom org-babel-tangle-lang-exts
'(("emacs-lisp" . "el")
("elisp" . "el"))
@@ -180,7 +174,7 @@ export file for all source blocks. Optional argument LANG can be
used to limit the exported source code blocks by language.
Return a list whose CAR is the tangled file name."
(interactive "fFile to tangle: \nP")
- (let ((visited-p (get-file-buffer (expand-file-name file)))
+ (let ((visited-p (find-buffer-visiting (expand-file-name file)))
to-be-removed)
(prog1
(save-window-excursion
@@ -234,13 +228,7 @@ used to limit the exported source code blocks by language."
(let* ((lang (car by-lang))
(specs (cdr by-lang))
(ext (or (cdr (assoc lang org-babel-tangle-lang-exts)) lang))
- (lang-f (intern
- (concat
- (or (and (cdr (assoc lang org-src-lang-modes))
- (symbol-name
- (cdr (assoc lang org-src-lang-modes))))
- lang)
- "-mode")))
+ (lang-f (org-src-get-lang-mode lang))
she-banged)
(mapc
(lambda (spec)
@@ -331,8 +319,6 @@ references."
(delete-region (save-excursion (beginning-of-line 1) (point))
(save-excursion (end-of-line 1) (forward-char 1) (point)))))
-(defvar org-stored-links)
-(defvar org-bracket-link-regexp)
(defun org-babel-spec-to-string (spec)
"Insert SPEC into the current file.
@@ -428,7 +414,7 @@ non-nil, return the full association list to be used by
(match-string 1 extra))
org-coderef-label-format))
(link (let ((l (org-no-properties (org-store-link nil))))
- (and (string-match org-bracket-link-regexp l)
+ (and (string-match org-link-bracket-re l)
(match-string 1 l))))
(source-name
(or (nth 4 info)
@@ -502,22 +488,21 @@ non-nil, return the full association list to be used by
result)))
(defun org-babel-tangle-comment-links (&optional info)
- "Return a list of begin and end link comments for the code block at point."
- (let ((link-data
- `(("start-line" . ,(number-to-string
- (org-babel-where-is-src-block-head)))
- ("file" . ,(buffer-file-name))
- ("link" . ,(org-link-escape
- (progn
- (call-interactively #'org-store-link)
- (org-no-properties (car (pop org-stored-links))))))
- ("source-name" .
- ,(nth 4 (or info (org-babel-get-src-block-info 'light)))))))
+ "Return a list of begin and end link comments for the code block at point.
+INFO, when non nil, is the source block information, as returned
+by `org-babel-get-src-block-info'."
+ (let ((link-data (pcase (or info (org-babel-get-src-block-info 'light))
+ (`(,_ ,_ ,_ ,_ ,name ,start ,_)
+ `(("start-line" . ,(org-with-point-at start
+ (number-to-string
+ (line-number-at-pos))))
+ ("file" . ,(buffer-file-name))
+ ("link" . ,(org-no-properties (org-store-link nil)))
+ ("source-name" . ,name))))))
(list (org-fill-template org-babel-tangle-comment-format-beg link-data)
(org-fill-template org-babel-tangle-comment-format-end link-data))))
;; de-tangling functions
-(defvar org-bracket-link-analytic-regexp)
(defun org-babel-detangle (&optional source-code-file)
"Propagate changes in source file back original to Org file.
This requires that code blocks were tangled with link comments
@@ -527,9 +512,9 @@ which enable the original code blocks to be found."
(when source-code-file (find-file source-code-file))
(goto-char (point-min))
(let ((counter 0) new-body end)
- (while (re-search-forward org-bracket-link-analytic-regexp nil t)
+ (while (re-search-forward org-link-bracket-re nil t)
(when (re-search-forward
- (concat " " (regexp-quote (match-string 5)) " ends here"))
+ (concat " " (regexp-quote (match-string 2)) " ends here"))
(setq end (match-end 0))
(forward-line -1)
(save-excursion
@@ -543,17 +528,15 @@ which enable the original code blocks to be found."
"Jump from a tangled code file to the related Org mode file."
(interactive)
(let ((mid (point))
- start body-start end
- target-buffer target-char link path block-name body)
+ start body-start end target-buffer target-char link block-name body)
(save-window-excursion
(save-excursion
- (while (and (re-search-backward org-bracket-link-analytic-regexp nil t)
+ (while (and (re-search-backward org-link-bracket-re nil t)
(not ; ever wider searches until matching block comments
(and (setq start (line-beginning-position))
(setq body-start (line-beginning-position 2))
(setq link (match-string 0))
- (setq path (match-string 3))
- (setq block-name (match-string 5))
+ (setq block-name (match-string 2))
(save-excursion
(save-match-data
(re-search-forward
@@ -563,12 +546,9 @@ which enable the original code blocks to be found."
(unless (and start (< start mid) (< mid end))
(error "Not in tangled code"))
(setq body (buffer-substring body-start end)))
- (when (string-match "::" path)
- (setq path (substring path 0 (match-beginning 0))))
- (find-file (or (car (org-id-find path)) path))
- (setq target-buffer (current-buffer))
;; Go to the beginning of the relative block in Org file.
- (org-open-link-from-string link)
+ (org-link-open-from-string link)
+ (setq target-buffer (current-buffer))
(if (string-match "[^ \t\n\r]:\\([[:digit:]]+\\)" block-name)
(let ((n (string-to-number (match-string 1 block-name))))
(if (org-before-first-heading-p) (goto-char (point-min))
diff --git a/lisp/ob.el b/lisp/ob.el
index 86d6928..6dffa23 100644
--- a/lisp/ob.el
+++ b/lisp/ob.el
@@ -24,11 +24,11 @@
;;; Code:
(require 'org-macs)
(require 'org-compat)
+(require 'org-keys)
(require 'ob-eval)
(require 'ob-core)
(require 'ob-comint)
(require 'ob-exp)
-(require 'ob-keys)
(require 'ob-table)
(require 'ob-lob)
(require 'ob-ref)
diff --git a/lisp/org-bbdb.el b/lisp/ol-bbdb.el
index c1f7973..bf99c61 100644
--- a/lisp/org-bbdb.el
+++ b/lisp/ol-bbdb.el
@@ -1,4 +1,4 @@
-;;; org-bbdb.el --- Support for links to BBDB entries -*- lexical-binding: t; -*-
+;;; ol-bbdb.el --- Links to BBDB entries -*- lexical-binding: t; -*-
;; Copyright (C) 2004-2019 Free Software Foundation, Inc.
@@ -93,23 +93,22 @@
;;
;;; Code:
-(require 'org)
(require 'cl-lib)
+(require 'org-compat)
+(require 'org-macs)
+(require 'ol)
-;; Declare external functions and variables
+;; Declare functions and variables
(declare-function bbdb "ext:bbdb-com" (string elidep))
(declare-function bbdb-company "ext:bbdb-com" (string elidep))
-(declare-function bbdb-current-record "ext:bbdb-com"
- (&optional planning-on-modifying))
+(declare-function bbdb-current-record "ext:bbdb-com" (&optional planning-on-modifying))
(declare-function bbdb-name "ext:bbdb-com" (string elidep))
-(declare-function bbdb-completing-read-record "ext:bbdb-com"
- (prompt &optional omit-records))
+(declare-function bbdb-completing-read-record "ext:bbdb-com" (prompt &optional omit-records))
(declare-function bbdb-record-field "ext:bbdb" (record field))
(declare-function bbdb-record-getprop "ext:bbdb" (record property))
(declare-function bbdb-record-name "ext:bbdb" (record))
-(declare-function bbdb-records "ext:bbdb"
- (&optional dont-check-disk already-in-db-buffer))
+(declare-function bbdb-records "ext:bbdb" (&optional dont-check-disk already-in-db-buffer))
(declare-function bbdb-split "ext:bbdb" (string separators))
(declare-function bbdb-string-trim "ext:bbdb" (string))
(declare-function bbdb-record-get-field "ext:bbdb" (record field))
@@ -121,10 +120,13 @@
;; `bbdb-record-xfield' replaces it in recent BBDB v3.x+
(declare-function bbdb-record-xfield "ext:bbdb" (record label))
+(declare-function calendar-absolute-from-gregorian "calendar" (date))
+(declare-function calendar-gregorian-from-absolute "calendar" (date))
(declare-function calendar-leap-year-p "calendar" (year))
+
(declare-function diary-ordinal-suffix "diary-lib" (n))
-(with-no-warnings (defvar date)) ;; unprefixed, from calendar.el
+(with-no-warnings (defvar date)) ;unprefixed, from calendar.el
;; Customization
@@ -230,7 +232,7 @@ date year)."
(bbdb-record-getprop rec 'company)
(car (bbdb-record-field rec 'organization))))
(link (concat "bbdb:" name)))
- (org-store-link-props :type "bbdb" :name name :company company
+ (org-link-store-props :type "bbdb" :name name :company company
:link link :description name)
link)))
@@ -532,10 +534,10 @@ END:VEVENT\n"
(concat (capitalize categ) " " (nth 1 rec))
categ)))))
-(provide 'org-bbdb)
+(provide 'ol-bbdb)
;; Local variables:
;; generated-autoload-file: "org-loaddefs.el"
;; End:
-;;; org-bbdb.el ends here
+;;; ol-bbdb.el ends here
diff --git a/lisp/org-bibtex.el b/lisp/ol-bibtex.el
index 9891012..78cdd04 100644
--- a/lisp/org-bibtex.el
+++ b/lisp/ol-bibtex.el
@@ -1,4 +1,4 @@
-;;; org-bibtex.el --- Org links to BibTeX entries -*- lexical-binding: t; -*-
+;;; ol-bibtex.el --- Links to BibTeX entries -*- lexical-binding: t; -*-
;;
;; Copyright (C) 2007-2019 Free Software Foundation, Inc.
;;
@@ -107,21 +107,37 @@
;;; Code:
-(require 'org)
(require 'bibtex)
(require 'cl-lib)
(require 'org-compat)
+(require 'org-macs)
+(require 'ol)
(defvar org-agenda-overriding-header)
(defvar org-agenda-search-view-always-boolean)
(defvar org-bibtex-description nil) ; dynamically scoped from org.el
(defvar org-id-locations)
+(defvar org-property-end-re)
+(defvar org-special-properties)
+(defvar org-window-config-before-follow-link)
(declare-function bibtex-beginning-of-entry "bibtex" ())
(declare-function bibtex-generate-autokey "bibtex" ())
(declare-function bibtex-parse-entry "bibtex" (&optional content))
(declare-function bibtex-url "bibtex" (&optional pos no-browse))
+(declare-function org-back-to-heading "org" (&optional invisible-ok))
+(declare-function org-entry-get "org" (pom property &optional inherit literal-nil))
+(declare-function org-entry-properties "org" (&optional pom which))
+(declare-function org-get-tags "org" (&optional pos local))
+(declare-function org-heading-components "org" ())
+(declare-function org-insert-heading "org" (&optional arg invisible-ok top))
+(declare-function org-map-entries "org" (func &optional match scope &rest skip))
+(declare-function org-narrow-to-subtree "org" ())
+(declare-function org-open-file "org" (path &optional in-emacs line search))
+(declare-function org-set-property "org" (property value))
+(declare-function org-toggle-tag "org" (tag &optional onoff))
+
;;; Bibtex data
(defvar org-bibtex-types
@@ -488,7 +504,7 @@ With optional argument OPTIONAL, also prompt for optional fields."
(save-excursion
(bibtex-beginning-of-entry)
(bibtex-parse-entry)))))
- (org-store-link-props
+ (org-link-store-props
:key (cdr (assoc "=key=" entry))
:author (or (cdr (assoc "author" entry)) "[no author]")
:editor (or (cdr (assoc "editor" entry)) "[no editor]")
@@ -742,6 +758,6 @@ This function relies `org-search-view' to locate results."
string (or org-bibtex-prefix "")
org-bibtex-type-property-name))))
-(provide 'org-bibtex)
+(provide 'ol-bibtex)
-;;; org-bibtex.el ends here
+;;; ol-bibtex.el ends here
diff --git a/lisp/org-docview.el b/lisp/ol-docview.el
index 40b06d3..0aadb9a 100644
--- a/lisp/org-docview.el
+++ b/lisp/ol-docview.el
@@ -1,4 +1,4 @@
-;;; org-docview.el --- Support for links to doc-view-mode buffers -*- lexical-binding: t; -*-
+;;; ol-docview.el --- Links to Docview mode buffers -*- lexical-binding: t; -*-
;; Copyright (C) 2009-2019 Free Software Foundation, Inc.
@@ -43,11 +43,12 @@
;;; Code:
-(require 'org)
(require 'doc-view)
+(require 'ol)
(declare-function doc-view-goto-page "doc-view" (page))
(declare-function image-mode-window-get "image-mode" (prop &optional winprops))
+(declare-function org-open-file "org" (path &optional in-emacs line search))
(org-link-set-parameters "docview"
:follow #'org-docview-open
@@ -84,7 +85,7 @@
(let* ((path buffer-file-name)
(page (image-mode-window-get 'page))
(link (concat "docview:" path "::" (number-to-string page))))
- (org-store-link-props
+ (org-link-store-props
:type "docview"
:link link
:description path))))
@@ -93,11 +94,11 @@
"Use the existing file name completion for file.
Links to get the file name, then ask the user for the page number
and append it."
- (concat (replace-regexp-in-string "^file:" "docview:" (org-file-complete-link))
+ (concat (replace-regexp-in-string "^file:" "docview:" (org-link-complete-file))
"::"
(read-from-minibuffer "Page:" "1")))
-(provide 'org-docview)
+(provide 'ol-docview)
-;;; org-docview.el ends here
+;;; ol-docview.el ends here
diff --git a/lisp/org-eshell.el b/lisp/ol-eshell.el
index be6db47..137e30f 100644
--- a/lisp/org-eshell.el
+++ b/lisp/ol-eshell.el
@@ -1,4 +1,4 @@
-;;; org-eshell.el - Support for Links to Working Directories in Eshell -*- lexical-binding: t; -*-
+;;; ol-eshell.el - Links to Working Directories in Eshell -*- lexical-binding: t; -*-
;; Copyright (C) 2011-2019 Free Software Foundation, Inc.
@@ -23,9 +23,11 @@
;;; Code:
-(require 'org)
(require 'eshell)
(require 'esh-mode)
+(require 'ol)
+
+(declare-function eshell/pwd "em-dirs.el" (&rest args))
(org-link-set-parameters "eshell"
:follow #'org-eshell-open
@@ -55,12 +57,12 @@
"Store a link that, when opened, switches back to the current eshell buffer
and the current working directory."
(when (eq major-mode 'eshell-mode)
- (let* ((command (concat "cd " dired-directory))
+ (let* ((command (concat "cd " (eshell/pwd)))
(link (concat (buffer-name) ":" command)))
- (org-store-link-props
+ (org-link-store-props
:link (concat "eshell:" link)
:description command))))
-(provide 'org-eshell)
+(provide 'ol-eshell)
-;;; org-eshell.el ends here
+;;; ol-eshell.el ends here
diff --git a/lisp/org-eww.el b/lisp/ol-eww.el
index 47f02a3..96357c4 100644
--- a/lisp/org-eww.el
+++ b/lisp/ol-eww.el
@@ -1,4 +1,4 @@
-;;; org-eww.el --- Store url and kill from Eww mode for Org -*- lexical-binding: t -*-
+;;; ol-eww.el --- Store URL and kill from Eww mode -*- lexical-binding: t -*-
;; Copyright (C) 2014-2019 Free Software Foundation, Inc.
@@ -44,7 +44,7 @@
;;; Code:
-(require 'org)
+(require 'ol)
(require 'cl-lib)
(defvar eww-current-title)
@@ -55,12 +55,12 @@
(declare-function eww-current-url "eww")
-;; Store Org-link in eww-mode buffer
+;; Store Org link in Eww mode buffer
(org-link-set-parameters "eww" :follow #'eww :store #'org-eww-store-link)
(defun org-eww-store-link ()
"Store a link to the url of an EWW buffer."
(when (eq major-mode 'eww-mode)
- (org-store-link-props
+ (org-link-store-props
:type "eww"
:link (if (< emacs-major-version 25)
eww-current-url
@@ -72,7 +72,7 @@
(eww-current-url))))))
-;; Some auxiliary functions concerning links in eww buffers
+;; Some auxiliary functions concerning links in Eww buffers
(defun org-eww-goto-next-url-property-change ()
"Move to the start of next link if exists.
Otherwise point is not moved. Return point."
@@ -93,7 +93,7 @@ Otherwise point is not moved. Return point."
(defun org-eww-copy-for-org-mode ()
"Copy current buffer content or active region with `org-mode' style links.
This will encode `link-title' and `link-location' with
-`org-make-link-string' and insert the transformed text into the
+`org-link-make-string' and insert the transformed text into the
kill ring, so that it can be yanked into an Org mode buffer with
links working correctly.
@@ -144,7 +144,7 @@ keep the structure of the Org file."
(if (org-string-nw-p link-location)
;; Hint: link-location is different
;; for form-elements.
- (org-make-link-string link-location link-title)
+ (org-link-make-string link-location link-title)
link-title))))
(goto-char temp-position) ; reset point before jump next anchor
(setq out-bound t))) ; for break out `while' loop
@@ -171,6 +171,6 @@ keep the structure of the Org file."
(add-hook 'eww-mode-hook #'org-eww-extend-eww-keymap)
-(provide 'org-eww)
+(provide 'ol-eww)
-;;; org-eww.el ends here
+;;; ol-eww.el ends here
diff --git a/lisp/org-gnus.el b/lisp/ol-gnus.el
index 9e07500..8ac36f0 100644
--- a/lisp/org-gnus.el
+++ b/lisp/ol-gnus.el
@@ -1,4 +1,4 @@
-;;; org-gnus.el --- Support for Links to Gnus Groups and Messages -*- lexical-binding: t; -*-
+;;; ol-gnus.el --- Links to Gnus Groups and Messages -*- lexical-binding: t; -*-
;; Copyright (C) 2004-2019 Free Software Foundation, Inc.
@@ -35,7 +35,7 @@
(require 'gnus-util)
(require 'nnheader)
(require 'nnir)
-(require 'org)
+(require 'ol)
;;; Declare external functions and variables
@@ -104,6 +104,7 @@ If `org-store-link' was called with a prefix arg the meaning of
(defun org-gnus-article-link (group newsgroups message-id x-no-archive)
"Create a link to a Gnus article.
+
The article is specified by its MESSAGE-ID. Additional
parameters are the Gnus GROUP, the NEWSGROUPS the article was
posted to and the X-NO-ARCHIVE header value of that article.
@@ -115,12 +116,12 @@ Otherwise create a link to the article inside Gnus.
If `org-store-link' was called with a prefix arg the meaning of
`org-gnus-prefer-web-links' is reversed."
(if (and (org-xor current-prefix-arg org-gnus-prefer-web-links)
- newsgroups ;; Make web links only for nntp groups
- (not x-no-archive)) ;; and if X-No-Archive isn't set.
- (format (if (string-match "gmane\\." newsgroups)
+ newsgroups ;make web links only for nntp groups
+ (not x-no-archive)) ;and if X-No-Archive isn't set
+ (format (if (string-match-p "gmane\\." newsgroups)
"http://mid.gmane.org/%s"
"http://groups.google.com/groups/search?as_umsgid=%s")
- (org-fixup-message-id-for-http message-id))
+ (url-encode-url message-id))
(concat "gnus:" group "#" message-id)))
(defun org-gnus-store-link ()
@@ -129,9 +130,9 @@ If `org-store-link' was called with a prefix arg the meaning of
(`gnus-group-mode
(let ((group (gnus-group-group-name)))
(when group
- (org-store-link-props :type "gnus" :group group)
+ (org-link-store-props :type "gnus" :group group)
(let ((description (org-gnus-group-link group)))
- (org-add-link-props :link description :description description)
+ (org-link-add-props :link description :description description)
description))))
((or `gnus-summary-mode `gnus-article-mode)
(let* ((group
@@ -169,12 +170,12 @@ If `org-store-link' was called with a prefix arg the meaning of
(setq to (or to (gnus-fetch-original-field "To")))
(setq newsgroups (gnus-fetch-original-field "Newsgroups"))
(setq x-no-archive (gnus-fetch-original-field "x-no-archive")))
- (org-store-link-props :type "gnus" :from from :date date :subject subject
+ (org-link-store-props :type "gnus" :from from :date date :subject subject
:message-id message-id :group group :to to)
(let ((link (org-gnus-article-link
group newsgroups message-id x-no-archive))
- (description (org-email-link-description)))
- (org-add-link-props :link link :description description)
+ (description (org-link-email-description)))
+ (org-link-add-props :link link :description description)
link)))
(`message-mode
(setq org-store-link-plist nil) ;reset
@@ -197,11 +198,11 @@ If `org-store-link' was called with a prefix arg the meaning of
(subject (mail-fetch-field "Subject"))
newsgroup xarchive) ;those are always nil for gcc
(unless gcc (error "Can not create link: No Gcc header found"))
- (org-store-link-props :type "gnus" :from from :subject subject
+ (org-link-store-props :type "gnus" :from from :subject subject
:message-id id :group gcc :to to)
(let ((link (org-gnus-article-link gcc newsgroup id xarchive))
- (description (org-email-link-description)))
- (org-add-link-props :link link :description description)
+ (description (org-link-email-description)))
+ (org-link-add-props :link link :description description)
link)))))))
(defun org-gnus-open-nntp (path)
@@ -264,7 +265,6 @@ If `org-store-link' was called with a prefix arg the meaning of
(org-gnus-no-server (gnus-no-server))
(t (gnus))))
-(provide 'org-gnus)
-
+(provide 'ol-gnus)
-;;; org-gnus.el ends here
+;;; ol-gnus.el ends here
diff --git a/lisp/org-info.el b/lisp/ol-info.el
index e21ac6b..d145eae 100644
--- a/lisp/org-info.el
+++ b/lisp/ol-info.el
@@ -1,4 +1,4 @@
-;;; org-info.el --- Support for Links to Info Nodes -*- lexical-binding: t; -*-
+;;; ol-info.el --- Links to Info Nodes -*- lexical-binding: t; -*-
;; Copyright (C) 2004-2019 Free Software Foundation, Inc.
@@ -30,7 +30,7 @@
;;; Code:
-(require 'org)
+(require 'ol)
;; Declare external functions and variables
@@ -54,7 +54,7 @@
"#" Info-current-node))
(desc (concat (file-name-nondirectory Info-current-file)
"#" Info-current-node)))
- (org-store-link-props :type "info" :file Info-current-file
+ (org-link-store-props :type "info" :file Info-current-file
:node Info-current-node
:link link :desc desc)
link)))
@@ -143,6 +143,6 @@ See `org-link-parameters' for details about PATH, DESC and FORMAT."
(format "@ref{%s,%s,,%s,}" node title manual)))
(_ nil))))
-(provide 'org-info)
+(provide 'ol-info)
-;;; org-info.el ends here
+;;; ol-info.el ends here
diff --git a/lisp/org-irc.el b/lisp/ol-irc.el
index dd8fd16..d39760b 100644
--- a/lisp/org-irc.el
+++ b/lisp/ol-irc.el
@@ -1,4 +1,4 @@
-;;; org-irc.el --- Store Links to IRC Sessions -*- lexical-binding: t; -*-
+;;; ol-irc.el --- Links to IRC Sessions -*- lexical-binding: t; -*-
;;
;; Copyright (C) 2008-2019 Free Software Foundation, Inc.
;;
@@ -48,7 +48,7 @@
;;; Code:
-(require 'org)
+(require 'ol)
(declare-function erc-buffer-filter "erc" (predicate &optional proc))
(declare-function erc-channel-p "erc" (channel))
@@ -155,7 +155,7 @@ the session itself."
(parsed-line (org-irc-erc-get-line-from-log erc-line)))
(if (erc-logging-enabled nil)
(progn
- (org-store-link-props
+ (org-link-store-props
:type "file"
:description (concat "'" (org-irc-ellipsify-description
(cadr parsed-line) 20)
@@ -168,7 +168,7 @@ the session itself."
(link (org-irc-parse-link link-text)))
(if link-text
(progn
- (org-store-link-props
+ (org-link-store-props
:type "irc"
:link (concat "irc:/" link-text)
:description (concat "irc session `" link-text "'")
@@ -260,10 +260,10 @@ FORMAT."
(`md (format "[%s](irc:%s)" desc link))
(_ nil))))
-(provide 'org-irc)
+(provide 'ol-irc)
;; Local variables:
;; generated-autoload-file: "org-loaddefs.el"
;; End:
-;;; org-irc.el ends here
+;;; ol-irc.el ends here
diff --git a/lisp/org-mhe.el b/lisp/ol-mhe.el
index a37c41a..b2c163c 100644
--- a/lisp/org-mhe.el
+++ b/lisp/ol-mhe.el
@@ -1,4 +1,4 @@
-;;; org-mhe.el --- Support for Links to MH-E Messages -*- lexical-binding: t; -*-
+;;; ol-mhe.el --- Links to MH-E Messages -*- lexical-binding: t; -*-
;; Copyright (C) 2004-2019 Free Software Foundation, Inc.
@@ -31,7 +31,7 @@
;;; Code:
(require 'org-macs)
-(require 'org)
+(require 'ol)
;; Customization variables
@@ -88,12 +88,12 @@ supported by MH-E."
(subject (org-mhe-get-header "Subject:"))
(date (org-mhe-get-header "Date:"))
link desc)
- (org-store-link-props :type "mh" :from from :to to :date date
+ (org-link-store-props :type "mh" :from from :to to :date date
:subject subject :message-id message-id)
- (setq desc (org-email-link-description))
+ (setq desc (org-link-email-description))
(setq link (concat "mhe:" (org-mhe-get-message-real-folder) "#"
(org-unbracket-string "<" ">" message-id)))
- (org-add-link-props :link link :description desc)
+ (org-link-add-props :link link :description desc)
link))))
(defun org-mhe-open (path)
@@ -199,7 +199,7 @@ folders."
(mh-search-choose)
(if (eq mh-searcher 'pick)
(progn
- (setq article (org-add-angle-brackets article))
+ (setq article (org-link-add-angle-brackets article))
(mh-search folder (list "--message-id" article))
(when (and org-mhe-search-all-folders
(not (org-mhe-get-message-real-folder)))
@@ -214,6 +214,6 @@ folders."
(kill-buffer)
(error "Message not found"))))
-(provide 'org-mhe)
+(provide 'ol-mhe)
-;;; org-mhe.el ends here
+;;; ol-mhe.el ends here
diff --git a/lisp/org-rmail.el b/lisp/ol-rmail.el
index c3d941e..a62b917 100644
--- a/lisp/org-rmail.el
+++ b/lisp/ol-rmail.el
@@ -1,4 +1,4 @@
-;;; org-rmail.el --- Support for Links to Rmail Messages -*- lexical-binding: t; -*-
+;;; ol-rmail.el --- Links to Rmail Messages -*- lexical-binding: t; -*-
;; Copyright (C) 2004-2019 Free Software Foundation, Inc.
@@ -30,7 +30,7 @@
;;; Code:
-(require 'org)
+(require 'ol)
;; Declare external functions and variables
(declare-function rmail-show-message "rmail" (&optional n no-summary))
@@ -65,13 +65,13 @@
(subject (mail-fetch-field "subject"))
(date (mail-fetch-field "date"))
desc link)
- (org-store-link-props
+ (org-link-store-props
:type "rmail" :from from :to to :date date
:subject subject :message-id message-id)
(setq message-id (org-unbracket-string "<" ">" message-id))
- (setq desc (org-email-link-description))
+ (setq desc (org-link-email-description))
(setq link (concat "rmail:" folder "#" message-id))
- (org-add-link-props :link link :description desc)
+ (org-link-add-props :link link :description desc)
(rmail-show-message rmail-current-message)
link)))))
@@ -89,7 +89,7 @@
(require 'rmail)
(cond ((null article) (setq article ""))
((stringp article)
- (setq article (org-add-angle-brackets article)))
+ (setq article (org-link-add-angle-brackets article)))
(t (user-error "Wrong RMAIL link format")))
(let (message-number)
(save-excursion
@@ -110,6 +110,6 @@
message-number)
(error "Message not found"))))
-(provide 'org-rmail)
+(provide 'ol-rmail)
-;;; org-rmail.el ends here
+;;; ol-rmail.el ends here
diff --git a/lisp/org-w3m.el b/lisp/ol-w3m.el
index 7db3473..046d3b6 100644
--- a/lisp/org-w3m.el
+++ b/lisp/ol-w3m.el
@@ -1,4 +1,4 @@
-;;; org-w3m.el --- Support from Copy and Paste From w3m -*- lexical-binding: t; -*-
+;;; ol-w3m.el --- Copy and Paste From W3M -*- lexical-binding: t; -*-
;; Copyright (C) 2008-2019 Free Software Foundation, Inc.
@@ -41,7 +41,7 @@
;;; Code:
-(require 'org)
+(require 'ol)
(defvar w3m-current-url)
(defvar w3m-current-title)
@@ -50,7 +50,7 @@
(defun org-w3m-store-link ()
"Store a link to a w3m buffer."
(when (eq major-mode 'w3m-mode)
- (org-store-link-props
+ (org-link-store-props
:type "w3m"
:link w3m-current-url
:url (url-view-url t)
@@ -59,7 +59,7 @@
(defun org-w3m-copy-for-org-mode ()
"Copy current buffer content or active region with Org style links.
This will encode `link-title' and `link-location' with
-`org-make-link-string', and insert the transformed test into the kill ring,
+`org-link-make-string', and insert the transformed test into the kill ring,
so that it can be yanked into an Org buffer with links working correctly."
(interactive)
(let* ((regionp (org-region-active-p))
@@ -98,7 +98,7 @@ so that it can be yanked into an Org buffer with links working correctly."
(setq return-content
(concat return-content
(if (org-string-nw-p link-location)
- (org-make-link-string link-location link-title)
+ (org-link-make-string link-location link-title)
link-title))))
(goto-char temp-position) ; reset point before jump next anchor
(setq out-bound t))) ; for break out `while' loop
@@ -179,6 +179,6 @@ Return t if there is no previous link; otherwise, return nil."
(define-key w3m-minor-mode-map "\C-c\C-x\M-w" 'org-w3m-copy-for-org-mode)
(define-key w3m-minor-mode-map "\C-c\C-x\C-w" 'org-w3m-copy-for-org-mode)))
-(provide 'org-w3m)
+(provide 'ol-w3m)
-;;; org-w3m.el ends here
+;;; ol-w3m.el ends here
diff --git a/lisp/ol.el b/lisp/ol.el
new file mode 100644
index 0000000..95a7e91
--- /dev/null
+++ b/lisp/ol.el
@@ -0,0 +1,1907 @@
+;;; ol.el --- Org links library -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2018 Free Software Foundation, Inc.
+
+;; Author: Carsten Dominik <carsten at orgmode dot org>
+;; Keywords: outlines, hypermedia, calendar, wp
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This library provides tooling to handle both external and internal
+;; links.
+
+;;; Code:
+
+(require 'org-compat)
+(require 'org-macs)
+
+(defvar clean-buffer-list-kill-buffer-names)
+(defvar org-agenda-buffer-name)
+(defvar org-comment-string)
+(defvar org-highlight-links)
+(defvar org-id-link-to-org-use-id)
+(defvar org-inhibit-startup)
+(defvar org-outline-regexp-bol)
+(defvar org-src-source-file-name)
+(defvar org-time-stamp-formats)
+(defvar org-ts-regexp)
+
+(declare-function calendar-cursor-to-date "calendar" (&optional error event))
+(declare-function dired-get-filename "dired" (&optional localp no-error-if-not-filep))
+(declare-function org-at-heading-p "org" (&optional _))
+(declare-function org-back-to-heading "org" (&optional invisible-ok))
+(declare-function org-do-occur "org" (regexp &optional cleanup))
+(declare-function org-element-at-point "org-element" ())
+(declare-function org-element-cache-refresh "org-element" (pos))
+(declare-function org-element-context "org-element" (&optional element))
+(declare-function org-element-lineage "org-element" (datum &optional types with-self))
+(declare-function org-element-link-parser "org-element" ())
+(declare-function org-element-property "org-element" (property element))
+(declare-function org-element-type "org-element" (element))
+(declare-function org-element-update-syntax "org-element" ())
+(declare-function org-entry-get "org" (pom property &optional inherit literal-nil))
+(declare-function org-find-property "org" (property &optional value))
+(declare-function org-get-heading "org" (&optional no-tags no-todo no-priority no-comment))
+(declare-function org-heading-components "org" ())
+(declare-function org-id-find-id-file "org-id" (id))
+(declare-function org-id-store-link "org-id" ())
+(declare-function org-insert-heading "org" (&optional arg invisible-ok top))
+(declare-function org-load-modules-maybe "org" (&optional force))
+(declare-function org-mark-ring-push "org" (&optional pos buffer))
+(declare-function org-occur "org" (regexp &optional keep-previous callback))
+(declare-function org-open-file "org" (path &optional in-emacs line search))
+(declare-function org-overview "org" ())
+(declare-function org-restart-font-lock "org" ())
+(declare-function org-show-context "org" (&optional key))
+(declare-function org-src-coderef-format "org-src" (&optional element))
+(declare-function org-src-coderef-regexp "org-src" (fmt &optional label))
+(declare-function org-src-edit-buffer-p "org-src" (&optional buffer))
+(declare-function org-src-source-buffer "org-src" ())
+(declare-function org-src-source-type "org-src" ())
+(declare-function org-time-stamp-format "org" (&optional long inactive))
+(declare-function outline-next-heading "outline" ())
+
+
+;;; Customization
+
+(defgroup org-link nil
+ "Options concerning links in Org mode."
+ :tag "Org Link"
+ :group 'org)
+
+(defcustom org-link-parameters nil
+ "An alist of properties that defines all the links in Org mode.
+The key in each association is a string of the link type.
+Subsequent optional elements make up a plist of link properties.
+
+:follow - A function that takes the link path as an argument.
+
+:export - A function that takes the link path, description and
+export-backend as arguments.
+
+:store - A function responsible for storing the link. See the
+function `org-store-link-functions'.
+
+:complete - A function that inserts a link with completion. The
+function takes one optional prefix argument.
+
+:face - A face for the link, or a function that returns a face.
+The function takes one argument which is the link path. The
+default face is `org-link'.
+
+:mouse-face - The mouse-face. The default is `highlight'.
+
+:display - `full' will not fold the link in descriptive
+display. Default is `org-link'.
+
+:help-echo - A string or function that takes (window object position)
+as arguments and returns a string.
+
+:keymap - A keymap that is active on the link. The default is
+`org-mouse-map'.
+
+:htmlize-link - A function for the htmlize-link. Defaults
+to (list :uri \"type:path\")
+
+:activate-func - A function to run at the end of font-lock
+activation. The function must accept (link-start link-end path bracketp)
+as arguments."
+ :group 'org-link
+ :package-version '(Org . "9.1")
+ :type '(alist :tag "Link display parameters"
+ :value-type plist)
+ :safe nil)
+
+(defcustom org-link-descriptive t
+ "Non-nil means Org displays descriptive links.
+
+E.g. [[https://orgmode.org][Org website]] is be displayed as
+\"Org Website\", hiding the link itself and just displaying its
+description. When set to nil, Org displays the full links
+literally.
+
+You can interactively set the value of this variable by calling
+`org-toggle-link-display' or from the \"Org > Hyperlinks\" menu."
+ :group 'org-link
+ :type 'boolean
+ :safe #'booleanp)
+
+(defcustom org-link-make-description-function nil
+ "Function to use for generating link descriptions from links.
+This function must take two parameters: the first one is the
+link, the second one is the description generated by
+`org-insert-link'. The function should return the description to
+use."
+ :group 'org-link
+ :type '(choice (const nil) (function))
+ :safe #'null)
+
+(defcustom org-link-file-path-type 'adaptive
+ "How the path name in file links should be stored.
+Valid values are:
+
+relative Relative to the current directory, i.e. the directory of the file
+ into which the link is being inserted.
+absolute Absolute path, if possible with ~ for home directory.
+noabbrev Absolute path, no abbreviation of home directory.
+adaptive Use relative path for files in the current directory and sub-
+ directories of it. For other files, use an absolute path."
+ :group 'org-link
+ :type '(choice
+ (const relative)
+ (const absolute)
+ (const noabbrev)
+ (const adaptive))
+ :safe #'symbolp)
+
+(defcustom org-link-abbrev-alist nil
+ "Alist of link abbreviations.
+The car of each element is a string, to be replaced at the start of a link.
+The cdrs are replacement values, like (\"linkkey\" . REPLACE). Abbreviated
+links in Org buffers can have an optional tag after a double colon, e.g.,
+
+ [[linkkey:tag][description]]
+
+The `linkkey' must be a single word, starting with a letter, followed
+by letters, numbers, `-' or `_'.
+
+If REPLACE is a string, the tag will simply be appended to create the link.
+If the string contains \"%s\", the tag will be inserted there. If the string
+contains \"%h\", it will cause a url-encoded version of the tag to be inserted
+at that point (see the function `url-hexify-string'). If the string contains
+the specifier \"%(my-function)\", then the custom function `my-function' will
+be invoked: this function takes the tag as its only argument and must return
+a string.
+
+REPLACE may also be a function that will be called with the tag as the
+only argument to create the link, which should be returned as a string.
+
+See the manual for examples."
+ :group 'org-link
+ :type '(repeat
+ (cons (string :tag "Protocol")
+ (choice
+ (string :tag "Format")
+ (function))))
+ :safe (lambda (val)
+ (pcase val
+ (`(,(pred stringp) . ,(pred stringp)) t)
+ (_ nil))))
+
+(defgroup org-link-follow nil
+ "Options concerning following links in Org mode."
+ :tag "Org Follow Link"
+ :group 'org-link)
+
+(defcustom org-link-translation-function nil
+ "Function to translate links with different syntax to Org syntax.
+This can be used to translate links created for example by the Planner
+or emacs-wiki packages to Org syntax.
+The function must accept two parameters, a TYPE containing the link
+protocol name like \"rmail\" or \"gnus\" as a string, and the linked path,
+which is everything after the link protocol. It should return a cons
+with possibly modified values of type and path.
+Org contains a function for this, so if you set this variable to
+`org-translate-link-from-planner', you should be able follow many
+links created by planner."
+ :group 'org-link-follow
+ :type '(choice (const nil) (function))
+ :safe #'null)
+
+(defcustom org-link-doi-server-url "https://doi.org/"
+ "The URL of the DOI server."
+ :group 'org-link-follow
+ :version "24.3"
+ :type 'string
+ :safe #'stringp)
+
+(defcustom org-link-frame-setup
+ '((vm . vm-visit-folder-other-frame)
+ (vm-imap . vm-visit-imap-folder-other-frame)
+ (gnus . org-gnus-no-new-news)
+ (file . find-file-other-window)
+ (wl . wl-other-frame))
+ "Setup the frame configuration for following links.
+When following a link with Emacs, it may often be useful to display
+this link in another window or frame. This variable can be used to
+set this up for the different types of links.
+For VM, use any of
+ `vm-visit-folder'
+ `vm-visit-folder-other-window'
+ `vm-visit-folder-other-frame'
+For Gnus, use any of
+ `gnus'
+ `gnus-other-frame'
+ `org-gnus-no-new-news'
+For FILE, use any of
+ `find-file'
+ `find-file-other-window'
+ `find-file-other-frame'
+For Wanderlust use any of
+ `wl'
+ `wl-other-frame'
+For the calendar, use the variable `calendar-setup'.
+For BBDB, it is currently only possible to display the matches in
+another window."
+ :group 'org-link-follow
+ :type '(list
+ (cons (const vm)
+ (choice
+ (const vm-visit-folder)
+ (const vm-visit-folder-other-window)
+ (const vm-visit-folder-other-frame)))
+ (cons (const vm-imap)
+ (choice
+ (const vm-visit-imap-folder)
+ (const vm-visit-imap-folder-other-window)
+ (const vm-visit-imap-folder-other-frame)))
+ (cons (const gnus)
+ (choice
+ (const gnus)
+ (const gnus-other-frame)
+ (const org-gnus-no-new-news)))
+ (cons (const file)
+ (choice
+ (const find-file)
+ (const find-file-other-window)
+ (const find-file-other-frame)))
+ (cons (const wl)
+ (choice
+ (const wl)
+ (const wl-other-frame))))
+ :safe nil)
+
+(defcustom org-link-search-must-match-exact-headline 'query-to-create
+ "Non-nil means internal fuzzy links can only match headlines.
+
+When nil, the a fuzzy link may point to a target or a named
+construct in the document. When set to the special value
+`query-to-create', offer to create a new headline when none
+matched.
+
+Spaces and statistics cookies are ignored during heading searches."
+ :group 'org-link-follow
+ :version "24.1"
+ :type '(choice
+ (const :tag "Use fuzzy text search" nil)
+ (const :tag "Match only exact headline" t)
+ (const :tag "Match exact headline or query to create it"
+ query-to-create))
+ :safe #'symbolp)
+
+(defcustom org-link-use-indirect-buffer-for-internals nil
+ "Non-nil means use indirect buffer to display infile links.
+Activating internal links (from one location in a file to another location
+in the same file) normally just jumps to the location. When the link is
+activated with a `\\[universal-argument]' prefix (or with mouse-3), the link \
+is displayed in
+another window. When this option is set, the other window actually displays
+an indirect buffer clone of the current buffer, to avoid any visibility
+changes to the current buffer."
+ :group 'org-link-follow
+ :type 'boolean
+ :safe #'booleanp)
+
+(defcustom org-link-shell-confirm-function 'yes-or-no-p
+ "Non-nil means ask for confirmation before executing shell links.
+
+Shell links can be dangerous: just think about a link
+
+ [[shell:rm -rf ~/*][Google Search]]
+
+This link would show up in your Org document as \"Google Search\",
+but really it would remove your entire home directory.
+Therefore we advise against setting this variable to nil.
+Just change it to `y-or-n-p' if you want to confirm with a
+single keystroke rather than having to type \"yes\"."
+ :group 'org-link-follow
+ :type '(choice
+ (const :tag "with yes-or-no (safer)" yes-or-no-p)
+ (const :tag "with y-or-n (faster)" y-or-n-p)
+ (const :tag "no confirmation (dangerous)" nil))
+ :safe nil)
+
+(defcustom org-link-shell-skip-confirm-regexp ""
+ "Regexp to skip confirmation for shell links."
+ :group 'org-link-follow
+ :version "24.1"
+ :type 'regexp
+ :safe nil)
+
+(defcustom org-link-elisp-confirm-function 'yes-or-no-p
+ "Non-nil means ask for confirmation before executing Emacs Lisp links.
+Elisp links can be dangerous: just think about a link
+
+ [[elisp:(shell-command \"rm -rf ~/*\")][Google Search]]
+
+This link would show up in your Org document as \"Google Search\",
+but really it would remove your entire home directory.
+Therefore we advise against setting this variable to nil.
+Just change it to `y-or-n-p' if you want to confirm with a
+single keystroke rather than having to type \"yes\"."
+ :group 'org-link-follow
+ :type '(choice
+ (const :tag "with yes-or-no (safer)" yes-or-no-p)
+ (const :tag "with y-or-n (faster)" y-or-n-p)
+ (const :tag "no confirmation (dangerous)" nil))
+ :safe nil)
+
+(defcustom org-link-elisp-skip-confirm-regexp ""
+ "A regexp to skip confirmation for Elisp links."
+ :group 'org-link-follow
+ :version "24.1"
+ :type 'regexp
+ :safe nil)
+
+(defgroup org-link-store nil
+ "Options concerning storing links in Org mode."
+ :tag "Org Store Link"
+ :group 'org-link)
+
+(defcustom org-link-context-for-files t
+ "Non-nil means file links from `org-store-link' contain context.
+\\<org-mode-map>
+A search string is added to the file name with \"::\" as separator
+and used to find the context when the link is activated by the command
+`org-open-at-point'. When this option is t, the entire active region
+is be placed in the search string of the file link. If set to a
+positive integer N, only the first N lines of context are stored.
+
+Using a prefix argument to the command `org-store-link' \
+\(`\\[universal-argument] \\[org-store-link]')
+negates this setting for the duration of the command."
+ :group 'org-link-store
+ :type '(choice boolean integer)
+ :safe (lambda (val) (or (booleanp val) (integerp val))))
+
+(defcustom org-link-email-description-format "Email %c: %s"
+ "Format of the description part of a link to an email or usenet message.
+The following %-escapes will be replaced by corresponding information:
+
+%F full \"From\" field
+%f name, taken from \"From\" field, address if no name
+%T full \"To\" field
+%t first name in \"To\" field, address if no name
+%c correspondent. Usually \"from NAME\", but if you sent it yourself, it
+ will be \"to NAME\". See also the variable `org-from-is-user-regexp'.
+%s subject
+%d date
+%m message-id.
+
+You may use normal field width specification between the % and the letter.
+This is for example useful to limit the length of the subject.
+
+Examples: \"%f on: %.30s\", \"Email from %f\", \"Email %c\""
+ :group 'org-link-store
+ :package-version '(Org . 9.3)
+ :type 'string
+ :safe #'stringp)
+
+(defcustom org-link-from-user-regexp
+ (let ((mail (and (org-string-nw-p user-mail-address)
+ (format "\\<%s\\>" (regexp-quote user-mail-address))))
+ (name (and (org-string-nw-p user-full-name)
+ (format "\\<%s\\>" (regexp-quote user-full-name)))))
+ (if (and mail name) (concat mail "\\|" name) (or mail name)))
+ "Regexp matched against the \"From:\" header of an email or Usenet message.
+It should match if the message is from the user him/herself."
+ :group 'org-link-store
+ :type 'regexp
+ :safe #'stringp)
+
+(defcustom org-link-keep-stored-after-insertion nil
+ "Non-nil means keep link in list for entire session.
+\\<org-mode-map>
+The command `org-store-link' adds a link pointing to the current
+location to an internal list. These links accumulate during a session.
+The command `org-insert-link' can be used to insert links into any
+Org file (offering completion for all stored links).
+
+When this option is nil, every link which has been inserted once using
+`\\[org-insert-link]' will be removed from the list, to make completing the \
+unused
+links more efficient."
+ :group 'org-link-store
+ :type 'boolean
+ :safe #'booleanp)
+
+;;; Public variables
+
+(defconst org-target-regexp (let ((border "[^<>\n\r \t]"))
+ (format "<<\\(%s\\|%s[^<>\n\r]*%s\\)>>"
+ border border border))
+ "Regular expression matching a link target.")
+
+(defconst org-radio-target-regexp (format "<%s>" org-target-regexp)
+ "Regular expression matching a radio target.")
+
+(defvar-local org-target-link-regexp nil
+ "Regular expression matching radio targets in plain text.")
+
+(defvar org-link-types-re nil
+ "Matches a link that has a url-like prefix like \"http:\"")
+
+(defvar org-link-angle-re nil
+ "Matches link with angular brackets, spaces are allowed.")
+
+(defvar org-link-plain-re nil
+ "Matches plain link, without spaces.")
+
+(defvar org-link-bracket-re nil
+ "Matches a link in double brackets.")
+
+(defvar org-link-any-re nil
+ "Regular expression matching any link.")
+
+(defvar-local org-link-abbrev-alist-local nil
+ "Buffer-local version of `org-link-abbrev-alist', which see.
+The value of this is taken from the LINK keywords.")
+
+(defvar org-stored-links nil
+ "Contains the links stored with `org-store-link'.")
+
+(defvar org-store-link-plist nil
+ "Plist with info about the most recently link created with `org-store-link'.")
+
+(defvar org-create-file-search-functions nil
+ "List of functions to construct the right search string for a file link.
+
+These functions are called in turn with point at the location to
+which the link should point.
+
+A function in the hook should first test if it would like to
+handle this file type, for example by checking the `major-mode'
+or the file extension. If it decides not to handle this file, it
+should just return nil to give other functions a chance. If it
+does handle the file, it must return the search string to be used
+when following the link. The search string will be part of the
+file link, given after a double colon, and `org-open-at-point'
+will automatically search for it. If special measures must be
+taken to make the search successful, another function should be
+added to the companion hook `org-execute-file-search-functions',
+which see.
+
+A function in this hook may also use `setq' to set the variable
+`description' to provide a suggestion for the descriptive text to
+be used for this link when it gets inserted into an Org buffer
+with \\[org-insert-link].")
+
+(defvar org-execute-file-search-functions nil
+ "List of functions to execute a file search triggered by a link.
+
+Functions added to this hook must accept a single argument, the
+search string that was part of the file link, the part after the
+double colon. The function must first check if it would like to
+handle this search, for example by checking the `major-mode' or
+the file extension. If it decides not to handle this search, it
+should just return nil to give other functions a chance. If it
+does handle the search, it must return a non-nil value to keep
+other functions from trying.
+
+Each function can access the current prefix argument through the
+variable `current-prefix-arg'. Note that a single prefix is used
+to force opening a link in Emacs, so it may be good to only use a
+numeric or double prefix to guide the search function.
+
+In case this is needed, a function in this hook can also restore
+the window configuration before `org-open-at-point' was called using:
+
+ (set-window-configuration org-window-config-before-follow-link)")
+
+(defvar org-open-link-functions nil
+ "Hook for functions finding a plain text link.
+These functions must take a single argument, the link content.
+They will be called for links that look like [[link text][description]]
+when LINK TEXT does not have a protocol like \"http:\" and does not look
+like a filename (e.g. \"./blue.png\").
+
+These functions will be called *before* Org attempts to resolve the
+link by doing text searches in the current buffer - so if you want a
+link \"[[target]]\" to still find \"<<target>>\", your function should
+handle this as a special case.
+
+When the function does handle the link, it must return a non-nil value.
+If it decides that it is not responsible for this link, it must return
+nil to indicate that that Org can continue with other options like
+exact and fuzzy text search.")
+
+
+;;; Internal Variables
+
+(defconst org-link--forbidden-chars "]\t\n\r<>"
+ "Characters forbidden within a link, as a string.")
+
+(defvar org-link--history nil
+ "History for inserted links.")
+
+(defvar org-link--insert-history nil
+ "Minibuffer history for links inserted with `org-insert-link'.")
+
+(defvar org-link--search-failed nil
+ "Non-nil when last link search failed.")
+
+
+;;; Internal Functions
+
+(defun org-link--try-special-completion (type)
+ "If there is completion support for link type TYPE, offer it."
+ (let ((fun (org-link-get-parameter type :complete)))
+ (if (functionp fun)
+ (funcall fun)
+ (read-string "Link (no completion support): " (concat type ":")))))
+
+(defun org-link--prettify (link)
+ "Return a human-readable representation of LINK.
+The car of LINK must be a raw link. The cdr of LINK must be
+either a link description or nil."
+ (let ((desc (or (cadr link) "<no description>")))
+ (concat (format "%-45s" (substring desc 0 (min (length desc) 40)))
+ "<" (car link) ">")))
+
+(defun org-link--decode-compound (hex)
+ "Unhexify Unicode hex-chars HEX.
+E.g. \"%C3%B6\" is the German o-Umlaut. Note: this function also
+decodes single byte encodings like \"%E1\" (a-acute) if not
+followed by another \"%[A-F0-9]{2}\" group."
+ (save-match-data
+ (let* ((bytes (cdr (split-string hex "%")))
+ (ret "")
+ (eat 0)
+ (sum 0))
+ (while bytes
+ (let* ((val (string-to-number (pop bytes) 16))
+ (shift-xor
+ (if (= 0 eat)
+ (cond
+ ((>= val 252) (cons 6 252))
+ ((>= val 248) (cons 5 248))
+ ((>= val 240) (cons 4 240))
+ ((>= val 224) (cons 3 224))
+ ((>= val 192) (cons 2 192))
+ (t (cons 0 0)))
+ (cons 6 128))))
+ (when (>= val 192) (setq eat (car shift-xor)))
+ (setq val (logxor val (cdr shift-xor)))
+ (setq sum (+ (lsh sum (car shift-xor)) val))
+ (when (> eat 0) (setq eat (- eat 1)))
+ (cond
+ ((= 0 eat) ;multi byte
+ (setq ret (concat ret (char-to-string sum)))
+ (setq sum 0))
+ ((not bytes) ; single byte(s)
+ (setq ret (org-link--decode-single-byte-sequence hex))))))
+ ret)))
+
+(defun org-link--decode-single-byte-sequence (hex)
+ "Unhexify hex-encoded single byte character sequence HEX."
+ (mapconcat (lambda (byte)
+ (char-to-string (string-to-number byte 16)))
+ (cdr (split-string hex "%"))
+ ""))
+
+(defun org-link--fontify-links-to-this-file ()
+ "Fontify links to the current file in `org-stored-links'."
+ (let ((f (buffer-file-name)) a b)
+ (setq a (mapcar (lambda(l)
+ (let ((ll (car l)))
+ (when (and (string-match "^file:\\(.+\\)::" ll)
+ (equal f (expand-file-name (match-string 1 ll))))
+ ll)))
+ org-stored-links))
+ (when (featurep 'org-id)
+ (setq b (mapcar (lambda(l)
+ (let ((ll (car l)))
+ (when (and (string-match "^id:\\(.+\\)$" ll)
+ (equal f (expand-file-name
+ (or (org-id-find-id-file
+ (match-string 1 ll)) ""))))
+ ll)))
+ org-stored-links)))
+ (mapcar (lambda(l)
+ (put-text-property 0 (length l) 'face 'font-lock-comment-face l))
+ (delq nil (append a b)))))
+
+(defun org-link--buffer-for-internals ()
+ "Return buffer used for displaying the target of internal links."
+ (cond
+ ((not org-link-use-indirect-buffer-for-internals) (current-buffer))
+ ((string-suffix-p "(Clone)" (buffer-name))
+ (message "Buffer is already a clone, not making another one")
+ ;; We also do not modify visibility in this case.
+ (current-buffer))
+ (t ;make a new indirect buffer for displaying the link
+ (let* ((indirect-buffer-name (concat (buffer-name) "(Clone)"))
+ (indirect-buffer
+ (or (get-buffer indirect-buffer-name)
+ (make-indirect-buffer (current-buffer)
+ indirect-buffer-name
+ 'clone))))
+ (with-current-buffer indirect-buffer (org-overview))
+ indirect-buffer))))
+
+(defun org-link--search-radio-target (target)
+ "Search a radio target matching TARGET in current buffer.
+White spaces are not significant."
+ (let ((re (format "<<<%s>>>"
+ (mapconcat #'regexp-quote
+ (split-string target)
+ "[ \t]+\\(?:\n[ \t]*\\)?")))
+ (origin (point)))
+ (goto-char (point-min))
+ (catch :radio-match
+ (while (re-search-forward re nil t)
+ (forward-char -1)
+ (let ((object (org-element-context)))
+ (when (eq (org-element-type object) 'radio-target)
+ (goto-char (org-element-property :begin object))
+ (org-show-context 'link-search)
+ (throw :radio-match nil))))
+ (goto-char origin)
+ (user-error "No match for radio target: %s" target))))
+
+
+;;; Public API
+
+(defun org-link-types ()
+ "Return a list of known link types."
+ (mapcar #'car org-link-parameters))
+
+(defun org-link-get-parameter (type key)
+ "Get TYPE link property for KEY.
+TYPE is a string and KEY is a plist keyword. See
+`org-link-parameters' for supported keywords."
+ (plist-get (cdr (assoc type org-link-parameters))
+ key))
+
+(defun org-link-set-parameters (type &rest parameters)
+ "Set link TYPE properties to PARAMETERS.
+PARAMETERS should be keyword value pairs. See
+`org-link-parameters' for supported keys."
+ (let ((data (assoc type org-link-parameters)))
+ (if data (setcdr data (org-combine-plists (cdr data) parameters))
+ (push (cons type parameters) org-link-parameters)
+ (org-link-make-regexps)
+ (when (featurep 'org-element) (org-element-update-syntax)))))
+
+(defun org-link-make-regexps ()
+ "Update the link regular expressions.
+This should be called after the variable `org-link-parameters' has changed."
+ (let ((types-re (regexp-opt (org-link-types) t)))
+ (setq org-link-types-re
+ (concat "\\`" types-re ":")
+ org-link-angle-re
+ (format "<%s:\\([^>\n]*\\(?:\n[ \t]*[^> \t\n][^>\n]*\\)*\\)>"
+ types-re)
+ org-link-plain-re
+ (concat
+ "\\<" types-re ":"
+ "\\([^][ \t\n()<>]+\\(?:([[:word:]0-9_]+)\\|\\([^[:punct:] \t\n]\\|/\\)\\)\\)")
+ ;; "\\([^]\t\n\r<>() ]+[^]\t\n\r<>,.;() ]\\)")
+ org-link-bracket-re
+ (rx (seq "[["
+ ;; URI part: match group 1.
+ (group
+ ;; Allow an even number of backslashes right
+ ;; before the closing bracket.
+ (or (one-or-more "\\\\")
+ (and (*? anything)
+ (not (any "\\"))
+ (zero-or-more "\\\\"))))
+ "]"
+ ;; Description (optional): match group 2.
+ (opt "[" (group (+? anything)) "]")
+ "]"))
+ org-link-any-re
+ (concat "\\(" org-link-bracket-re "\\)\\|\\("
+ org-link-angle-re "\\)\\|\\("
+ org-link-plain-re "\\)"))))
+
+(defun org-link-complete-file (&optional arg)
+ "Create a file link using completion."
+ (let ((file (read-file-name "File: "))
+ (pwd (file-name-as-directory (expand-file-name ".")))
+ (pwd1 (file-name-as-directory (abbreviate-file-name
+ (expand-file-name ".")))))
+ (cond ((equal arg '(16))
+ (concat "file:"
+ (abbreviate-file-name (expand-file-name file))))
+ ((string-match
+ (concat "^" (regexp-quote pwd1) "\\(.+\\)") file)
+ (concat "file:" (match-string 1 file)))
+ ((string-match
+ (concat "^" (regexp-quote pwd) "\\(.+\\)")
+ (expand-file-name file))
+ (concat "file:"
+ (match-string 1 (expand-file-name file))))
+ (t (concat "file:" file)))))
+
+(defun org-link-email-description (&optional fmt)
+ "Return the description part of an email link.
+This takes information from `org-store-link-plist' and formats it
+according to FMT (default from `org-link-email-description-format')."
+ (setq fmt (or fmt org-link-email-description-format))
+ (let* ((p org-store-link-plist)
+ (to (plist-get p :toaddress))
+ (from (plist-get p :fromaddress))
+ (table
+ (list
+ (cons "%c" (plist-get p :fromto))
+ (cons "%F" (plist-get p :from))
+ (cons "%f" (or (plist-get p :fromname) (plist-get p :fromaddress) "?"))
+ (cons "%T" (plist-get p :to))
+ (cons "%t" (or (plist-get p :toname) (plist-get p :toaddress) "?"))
+ (cons "%s" (plist-get p :subject))
+ (cons "%d" (plist-get p :date))
+ (cons "%m" (plist-get p :message-id)))))
+ (when (string-match "%c" fmt)
+ ;; Check if the user wrote this message
+ (if (and org-link-from-user-regexp from to
+ (save-match-data (string-match org-link-from-user-regexp from)))
+ (setq fmt (replace-match "to %t" t t fmt))
+ (setq fmt (replace-match "from %f" t t fmt))))
+ (org-replace-escapes fmt table)))
+
+(defun org-link-store-props (&rest plist)
+ "Store link properties.
+The properties are pre-processed by extracting names, addresses
+and dates."
+ (let ((x (plist-get plist :from)))
+ (when x
+ (let ((adr (mail-extract-address-components x)))
+ (setq plist (plist-put plist :fromname (car adr)))
+ (setq plist (plist-put plist :fromaddress (nth 1 adr))))))
+ (let ((x (plist-get plist :to)))
+ (when x
+ (let ((adr (mail-extract-address-components x)))
+ (setq plist (plist-put plist :toname (car adr)))
+ (setq plist (plist-put plist :toaddress (nth 1 adr))))))
+ (let ((x (ignore-errors (date-to-time (plist-get plist :date)))))
+ (when x
+ (setq plist (plist-put plist :date-timestamp
+ (format-time-string
+ (org-time-stamp-format t) x)))
+ (setq plist (plist-put plist :date-timestamp-inactive
+ (format-time-string
+ (org-time-stamp-format t t) x)))))
+ (let ((from (plist-get plist :from))
+ (to (plist-get plist :to)))
+ (when (and from to org-link-from-user-regexp)
+ (setq plist
+ (plist-put plist :fromto
+ (if (string-match org-link-from-user-regexp from)
+ (concat "to %t")
+ (concat "from %f"))))))
+ (setq org-store-link-plist plist))
+
+(defun org-link-add-props (&rest plist)
+ "Add these properties to the link property list."
+ (let (key value)
+ (while plist
+ (setq key (pop plist) value (pop plist))
+ (setq org-store-link-plist
+ (plist-put org-store-link-plist key value)))))
+
+(defun org-link-encode (text table)
+ "Return percent escaped representation of string TEXT.
+TEXT is a string with the text to escape. TABLE is a list of
+characters that should be escaped."
+ (mapconcat
+ (lambda (c)
+ (if (memq c table)
+ (mapconcat (lambda (e) (format "%%%.2X" e))
+ (or (encode-coding-char c 'utf-8)
+ (error "Unable to percent escape character: %c" c))
+ "")
+ (char-to-string c)))
+ text ""))
+
+(defun org-link-decode (s)
+ "Decode percent-encoded parts in string S.
+E.g. \"%C3%B6\" becomes the german o-Umlaut."
+ (replace-regexp-in-string "\\(%[0-9A-Za-z]\\{2\\}\\)+"
+ #'org-link--decode-compound s t t))
+
+(defun org-link-escape (link)
+ "Backslash-escape sensitive characters in string LINK."
+ ;; Escape closing square brackets followed by another square bracket
+ ;; or at the end of the link. Also escape final backslashes so that
+ ;; we do not escape inadvertently URI's closing bracket.
+ (with-temp-buffer
+ (insert link)
+ (insert (make-string (- (skip-chars-backward "\\\\"))
+ ?\\))
+ (while (search-backward "\]" nil t)
+ (when (looking-at-p "\\]\\(?:[][]\\|\\'\\)")
+ (insert (make-string (1+ (- (skip-chars-backward "\\\\")))
+ ?\\))))
+ (buffer-string)))
+
+(defun org-link-unescape (link)
+ "Remove escaping backslash characters from string LINK."
+ (with-temp-buffer
+ (save-excursion (insert link))
+ (while (re-search-forward "\\(\\\\+\\)\\]\\(?:[][]\\|\\'\\)" nil t)
+ (replace-match (make-string (/ (- (match-end 1) (match-beginning 1)) 2)
+ ?\\)
+ nil t nil 1))
+ (goto-char (point-max))
+ (delete-char (/ (- (skip-chars-backward "\\\\")) 2))
+ (buffer-string)))
+
+(defun org-link-make-string (link &optional description)
+ "Make a bracket link, consisting of LINK and DESCRIPTION.
+LINK is escaped with backslashes for inclusion in buffer."
+ (unless (org-string-nw-p link) (error "Empty link"))
+ (let* ((uri (org-link-escape link))
+ (zero-width-space (string ?\x200B))
+ (description
+ (and (org-string-nw-p description)
+ ;; Description cannot contain two consecutive square
+ ;; brackets, or end with a square bracket. To prevent
+ ;; this, insert a zero width space character between
+ ;; the brackets, or at the end of the description.
+ (replace-regexp-in-string
+ "\\(]\\)\\(]\\)"
+ (concat "\\1" zero-width-space "\\2")
+ (replace-regexp-in-string "]\\'"
+ (concat "\\&" zero-width-space)
+ (org-trim description))))))
+ (format "[[%s]%s]"
+ uri
+ (if description (format "[%s]" description) ""))))
+
+(defun org-store-link-functions ()
+ "List of functions that are called to create and store a link.
+
+The functions are defined in the `:store' property of
+`org-link-parameters'.
+
+Each function will be called in turn until one returns a non-nil
+value. Each function should check if it is responsible for
+creating this link (for example by looking at the major mode).
+If not, it must exit and return nil. If yes, it should return
+a non-nil value after calling `org-link-store-props' with a list
+of properties and values. Special properties are:
+
+:type The link prefix, like \"http\". This must be given.
+:link The link, like \"http://www.astro.uva.nl/~dominik\".
+ This is obligatory as well.
+:description Optional default description for the second pair
+ of brackets in an Org mode link. The user can still change
+ this when inserting this link into an Org mode buffer.
+
+In addition to these, any additional properties can be specified
+and then used in capture templates."
+ (cl-loop for link in org-link-parameters
+ with store-func
+ do (setq store-func (org-link-get-parameter (car link) :store))
+ if store-func
+ collect store-func))
+
+(defun org-link-expand-abbrev (link)
+ "Replace link abbreviations in LINK string.
+Abbreviations are defined in `org-link-abbrev-alist'."
+ (if (not (string-match "^\\([^:]*\\)\\(::?\\(.*\\)\\)?$" link)) link
+ (let* ((key (match-string 1 link))
+ (as (or (assoc key org-link-abbrev-alist-local)
+ (assoc key org-link-abbrev-alist)))
+ (tag (and (match-end 2) (match-string 3 link)))
+ rpl)
+ (if (not as)
+ link
+ (setq rpl (cdr as))
+ (cond
+ ((symbolp rpl) (funcall rpl tag))
+ ((string-match "%(\\([^)]+\\))" rpl)
+ (replace-match
+ (save-match-data
+ (funcall (intern-soft (match-string 1 rpl)) tag)) t t rpl))
+ ((string-match "%s" rpl) (replace-match (or tag "") t t rpl))
+ ((string-match "%h" rpl)
+ (replace-match (url-hexify-string (or tag "")) t t rpl))
+ (t (concat rpl tag)))))))
+
+(defun org-link-open (link &optional arg)
+ "Open a link object LINK.
+Optional argument is passed to `org-open-file' when S is
+a \"file\" link."
+ (let ((type (org-element-property :type link))
+ (path (org-element-property :path link)))
+ (cond
+ ((equal type "file")
+ (if (string-match "[*?{]" (file-name-nondirectory path))
+ (dired path)
+ ;; Look into `org-link-parameters' in order to find
+ ;; a DEDICATED-FUNCTION to open file. The function will be
+ ;; applied on raw link instead of parsed link due to the
+ ;; limitation in `org-add-link-type' ("open" function called
+ ;; with a single argument). If no such function is found,
+ ;; fallback to `org-open-file'.
+ (let* ((option (org-element-property :search-option link))
+ (app (org-element-property :application link))
+ (dedicated-function
+ (org-link-get-parameter (if app (concat type "+" app) type)
+ :follow)))
+ (if dedicated-function
+ (funcall dedicated-function
+ (concat path
+ (and option (concat "::" option))))
+ (apply #'org-open-file
+ path
+ (cond (arg)
+ ((equal app "emacs") 'emacs)
+ ((equal app "sys") 'system))
+ (cond ((not option) nil)
+ ((string-match-p "\\`[0-9]+\\'" option)
+ (list (string-to-number option)))
+ (t (list nil option))))))))
+ ((functionp (org-link-get-parameter type :follow))
+ (funcall (org-link-get-parameter type :follow) path))
+ ((member type '("coderef" "custom-id" "fuzzy" "radio"))
+ (unless (run-hook-with-args-until-success 'org-open-link-functions path)
+ (if (not arg) (org-mark-ring-push)
+ (switch-to-buffer-other-window (org-link--buffer-for-internals)))
+ (let ((destination
+ (org-with-wide-buffer
+ (if (equal type "radio")
+ (org-link--search-radio-target
+ (org-element-property :path link))
+ (org-link-search
+ (pcase type
+ ("custom-id" (concat "#" path))
+ ("coderef" (format "(%s)" path))
+ (_ path))
+ ;; Prevent fuzzy links from matching themselves.
+ (and (equal type "fuzzy")
+ (+ 2 (org-element-property :begin link)))))
+ (point))))
+ (unless (and (<= (point-min) destination)
+ (>= (point-max) destination))
+ (widen))
+ (goto-char destination))))
+ (t (browse-url-at-point)))))
+
+(defun org-link-open-from-string (s &optional arg)
+ "Open a link in the string S, as if it was in Org mode.
+Optional argument is passed to `org-open-file' when S is
+a \"file\" link."
+ (interactive "sLink: \nP")
+ (pcase (with-temp-buffer
+ (let ((org-inhibit-startup nil))
+ (insert s)
+ (org-mode)
+ (goto-char (point-min))
+ (org-element-link-parser)))
+ (`nil (user-error "No valid link in %S" s))
+ (link (org-link-open link arg))))
+
+(defun org-link-search (s &optional avoid-pos stealth)
+ "Search for a search string S.
+
+If S starts with \"#\", it triggers a custom ID search.
+
+If S is enclosed within parenthesis, it initiates a coderef
+search.
+
+If S is surrounded by forward slashes, it is interpreted as
+a regular expression. In Org mode files, this will create an
+`org-occur' sparse tree. In ordinary files, `occur' will be used
+to list matches. If the current buffer is in `dired-mode', grep
+will be used to search in all files.
+
+When AVOID-POS is given, ignore matches near that position.
+
+When optional argument STEALTH is non-nil, do not modify
+visibility around point, thus ignoring `org-show-context-detail'
+variable.
+
+Search is case-insensitive and ignores white spaces. Return type
+of matched result, which is either `dedicated' or `fuzzy'."
+ (unless (org-string-nw-p s) (error "Invalid search string \"%s\"" s))
+ (let* ((case-fold-search t)
+ (origin (point))
+ (normalized (replace-regexp-in-string "\n[ \t]*" " " s))
+ (starred (eq (string-to-char normalized) ?*))
+ (words (split-string (if starred (substring s 1) s)))
+ (s-multi-re (mapconcat #'regexp-quote words "\\(?:[ \t\n]+\\)"))
+ (s-single-re (mapconcat #'regexp-quote words "[ \t]+"))
+ type)
+ (cond
+ ;; Check if there are any special search functions.
+ ((run-hook-with-args-until-success 'org-execute-file-search-functions s))
+ ((eq (string-to-char s) ?#)
+ ;; Look for a custom ID S if S starts with "#".
+ (let* ((id (substring normalized 1))
+ (match (org-find-property "CUSTOM_ID" id)))
+ (if match (progn (goto-char match) (setf type 'dedicated))
+ (error "No match for custom ID: %s" id))))
+ ((string-match "\\`(\\(.*\\))\\'" normalized)
+ ;; Look for coderef targets if S is enclosed within parenthesis.
+ (let ((coderef (match-string-no-properties 1 normalized))
+ (re (substring s-single-re 1 -1)))
+ (goto-char (point-min))
+ (catch :coderef-match
+ (while (re-search-forward re nil t)
+ (let ((element (org-element-at-point)))
+ (when (and (memq (org-element-type element)
+ '(example-block src-block))
+ (org-match-line
+ (concat ".*?" (org-src-coderef-regexp
+ (org-src-coderef-format element)
+ coderef))))
+ (setq type 'dedicated)
+ (goto-char (match-beginning 2))
+ (throw :coderef-match nil))))
+ (goto-char origin)
+ (error "No match for coderef: %s" coderef))))
+ ((string-match "\\`/\\(.*\\)/\\'" normalized)
+ ;; Look for a regular expression.
+ (funcall (if (derived-mode-p 'org-mode) #'org-occur #'org-do-occur)
+ (match-string 1 s)))
+ ;; From here, we handle fuzzy links.
+ ;;
+ ;; Look for targets, only if not in a headline search.
+ ((and (not starred)
+ (let ((target (format "<<%s>>" s-multi-re)))
+ (catch :target-match
+ (goto-char (point-min))
+ (while (re-search-forward target nil t)
+ (backward-char)
+ (let ((context (org-element-context)))
+ (when (eq (org-element-type context) 'target)
+ (setq type 'dedicated)
+ (goto-char (org-element-property :begin context))
+ (throw :target-match t))))
+ nil))))
+ ;; Look for elements named after S, only if not in a headline
+ ;; search.
+ ((and (not starred)
+ (let ((name (format "^[ \t]*#\\+NAME: +%s[ \t]*$" s-single-re)))
+ (catch :name-match
+ (goto-char (point-min))
+ (while (re-search-forward name nil t)
+ (let ((element (org-element-at-point)))
+ (when (equal words
+ (split-string
+ (org-element-property :name element)))
+ (setq type 'dedicated)
+ (beginning-of-line)
+ (throw :name-match t))))
+ nil))))
+ ;; Regular text search. Prefer headlines in Org mode buffers.
+ ;; Ignore COMMENT keyword, TODO keywords, priority cookies,
+ ;; statistics cookies and tags.
+ ((and (derived-mode-p 'org-mode)
+ (let ((title-re
+ (format "%s.*\\(?:%s[ \t]\\)?.*%s"
+ org-outline-regexp-bol
+ org-comment-string
+ (mapconcat #'regexp-quote words ".+")))
+ (cookie-re "\\[[0-9]*\\(?:%\\|/[0-9]*\\)\\]")
+ (comment-re (format "\\`%s[ \t]+" org-comment-string)))
+ (goto-char (point-min))
+ (catch :found
+ (while (re-search-forward title-re nil t)
+ (when (equal words
+ (split-string
+ (replace-regexp-in-string
+ cookie-re ""
+ (replace-regexp-in-string
+ comment-re "" (org-get-heading t t t)))))
+ (throw :found t)))
+ nil)))
+ (beginning-of-line)
+ (setq type 'dedicated))
+ ;; Offer to create non-existent headline depending on
+ ;; `org-link-search-must-match-exact-headline'.
+ ((and (derived-mode-p 'org-mode)
+ (eq org-link-search-must-match-exact-headline 'query-to-create)
+ (yes-or-no-p "No match - create this as a new heading? "))
+ (goto-char (point-max))
+ (unless (bolp) (newline))
+ (org-insert-heading nil t t)
+ (insert s "\n")
+ (beginning-of-line 0))
+ ;; Only headlines are looked after. No need to process
+ ;; further: throw an error.
+ ((and (derived-mode-p 'org-mode)
+ (or starred org-link-search-must-match-exact-headline))
+ (goto-char origin)
+ (error "No match for fuzzy expression: %s" normalized))
+ ;; Regular text search.
+ ((catch :fuzzy-match
+ (goto-char (point-min))
+ (while (re-search-forward s-multi-re nil t)
+ ;; Skip match if it contains AVOID-POS or it is included in
+ ;; a link with a description but outside the description.
+ (unless (or (and avoid-pos
+ (<= (match-beginning 0) avoid-pos)
+ (> (match-end 0) avoid-pos))
+ (and (save-match-data
+ (org-in-regexp org-link-bracket-re))
+ (match-beginning 3)
+ (or (> (match-beginning 3) (point))
+ (<= (match-end 3) (point)))
+ (org-element-lineage
+ (save-match-data (org-element-context))
+ '(link) t)))
+ (goto-char (match-beginning 0))
+ (setq type 'fuzzy)
+ (throw :fuzzy-match t)))
+ nil))
+ ;; All failed. Throw an error.
+ (t (goto-char origin)
+ (error "No match for fuzzy expression: %s" normalized)))
+ ;; Disclose surroundings of match, if appropriate.
+ (when (and (derived-mode-p 'org-mode) (not stealth))
+ (org-show-context 'link-search))
+ type))
+
+(defun org-link-heading-search-string (&optional string)
+ "Make search string for the current headline or STRING."
+ (let ((s (or string
+ (and (derived-mode-p 'org-mode)
+ (save-excursion
+ (org-back-to-heading t)
+ (org-element-property :raw-value
+ (org-element-at-point))))))
+ (lines org-link-context-for-files))
+ (unless string (setq s (concat "*" s))) ;Add * for headlines
+ (setq s (replace-regexp-in-string "\\[[0-9]+%\\]\\|\\[[0-9]+/[0-9]+\\]" "" s))
+ (when (and string (integerp lines) (> lines 0))
+ (let ((slines (org-split-string s "\n")))
+ (when (< lines (length slines))
+ (setq s (mapconcat
+ #'identity
+ (reverse (nthcdr (- (length slines) lines)
+ (reverse slines))) "\n")))))
+ (mapconcat #'identity (split-string s) " ")))
+
+(defun org-link-display-format (s)
+ "Replace links in string S with their description.
+If there is no description, use the link target."
+ (save-match-data
+ (replace-regexp-in-string
+ org-link-bracket-re
+ (lambda (m) (or (match-string 2 m) (match-string 1 m)))
+ s nil t)))
+
+(defun org-link-add-angle-brackets (s)
+ "Wrap string S within angle brackets."
+ (unless (equal (substring s 0 1) "<") (setq s (concat "<" s)))
+ (unless (equal (substring s -1) ">") (setq s (concat s ">")))
+ s)
+
+
+;;; Built-in link types
+
+;;;; "doi" link type
+(defun org-link--open-doi (path)
+ "Open a \"doi\" type link.
+PATH is a the path to search for, as a string."
+ (browse-url (url-encode-url (concat org-link-doi-server-url path))))
+
+(org-link-set-parameters "doi" :follow #'org-link--open-doi)
+
+;;;; "elisp" link type
+(defun org-link--open-elisp (path)
+ "Open a \"elisp\" type link.
+PATH is the sexp to evaluate, as a string."
+ (if (or (and (org-string-nw-p org-link-elisp-skip-confirm-regexp)
+ (string-match-p org-link-elisp-skip-confirm-regexp path))
+ (not org-link-elisp-confirm-function)
+ (funcall org-link-elisp-confirm-function
+ (format "Execute %S as Elisp? "
+ (org-add-props path nil 'face 'org-warning))))
+ (message "%s => %s" path
+ (if (eq ?\( (string-to-char path))
+ (eval (read path))
+ (call-interactively (read path))))
+ (user-error "Abort")))
+
+(org-link-set-parameters "elisp" :follow #'org-link--open-elisp)
+
+;;;; "file" link type
+(org-link-set-parameters "file" :complete #'org-link-complete-file)
+
+;;;; "help" link type
+(defun org-link--open-help (path)
+ "Open a \"help\" type link.
+PATH is a symbol name, as a string."
+ (pcase (intern path)
+ ((and (pred fboundp) variable) (describe-function variable))
+ ((and (pred boundp) function) (describe-variable function))
+ (name (user-error "Unknown function or variable: %s" name))))
+
+(org-link-set-parameters "help" :follow #'org-link--open-help)
+
+;;;; "http", "https", "mailto", "ftp", and "news" link types
+(dolist (scheme '("ftp" "http" "https" "mailto" "news"))
+ (org-link-set-parameters scheme
+ :follow
+ (lambda (url) (browse-url (concat scheme ":" url)))))
+
+;;;; "shell" link type
+(defun org-link--open-shell (path)
+ "Open a \"shell\" type link.
+PATH is the command to execute, as a string."
+ (if (or (and (org-string-nw-p org-link-shell-skip-confirm-regexp)
+ (string-match-p org-link-shell-skip-confirm-regexp path))
+ (not org-link-shell-confirm-function)
+ (funcall org-link-shell-confirm-function
+ (format "Execute %S in shell? "
+ (org-add-props path nil 'face 'org-warning))))
+ (let ((buf (generate-new-buffer "*Org Shell Output*")))
+ (message "Executing %s" path)
+ (shell-command path buf)
+ (when (featurep 'midnight)
+ (setq clean-buffer-list-kill-buffer-names
+ (cons (buffer-name buf)
+ clean-buffer-list-kill-buffer-names))))
+ (user-error "Abort")))
+
+(org-link-set-parameters "shell" :follow #'org-link--open-shell)
+
+
+;;; Interactive Functions
+
+;;;###autoload
+(defun org-next-link (&optional search-backward)
+ "Move forward to the next link.
+If the link is in hidden text, expose it. When SEARCH-BACKWARD
+is non-nil, move backward."
+ (interactive)
+ (let ((pos (point))
+ (search-fun (if search-backward #'re-search-backward
+ #'re-search-forward)))
+ ;; Tweak initial position. If last search failed, wrap around.
+ ;; Otherwise, make sure we do not match current link.
+ (cond
+ ((not (and org-link--search-failed (eq this-command last-command)))
+ (cond
+ ((and (not search-backward) (looking-at org-link-any-re))
+ (goto-char (match-end 0)))
+ (search-backward
+ (pcase (org-in-regexp org-link-any-re nil t)
+ (`(,beg . ,_) (goto-char beg))
+ (_ nil)))
+ (t nil)))
+ (search-backward
+ (goto-char (point-max))
+ (message "Link search wrapped back to end of buffer"))
+ (t
+ (goto-char (point-min))
+ (message "Link search wrapped back to beginning of buffer")))
+ (setq org-link--search-failed nil)
+ (catch :found
+ (while (funcall search-fun org-link-any-re nil t)
+ (let ((context (save-excursion
+ (unless search-backward (forward-char -1))
+ (org-element-context))))
+ (pcase (org-element-lineage context '(link) t)
+ (`nil nil)
+ (link
+ (goto-char (org-element-property :begin link))
+ (when (org-invisible-p) (org-show-context))
+ (throw :found t)))))
+ (goto-char pos)
+ (setq org-link--search-failed t)
+ (message "No further link found"))))
+
+;;;###autoload
+(defun org-previous-link ()
+ "Move backward to the previous link.
+If the link is in hidden text, expose it."
+ (interactive)
+ (org-next-link t))
+
+;;;###autoload
+(defun org-toggle-link-display ()
+ "Toggle the literal or descriptive display of links."
+ (interactive)
+ (if org-link-descriptive (remove-from-invisibility-spec '(org-link))
+ (add-to-invisibility-spec '(org-link)))
+ (org-restart-font-lock)
+ (setq org-link-descriptive (not org-link-descriptive)))
+
+;;;###autoload
+(defun org-store-link (arg &optional interactive?)
+ "Store a link to the current location.
+\\<org-mode-map>
+This link is added to `org-stored-links' and can later be inserted
+into an Org buffer with `org-insert-link' (`\\[org-insert-link]').
+
+For some link types, a `\\[universal-argument]' prefix ARG is interpreted. \
+A single
+`\\[universal-argument]' negates `org-context-in-file-links' for file links or
+`org-gnus-prefer-web-links' for links to Usenet articles.
+
+A `\\[universal-argument] \\[universal-argument]' prefix ARG forces \
+skipping storing functions that are not
+part of Org core.
+
+A `\\[universal-argument] \\[universal-argument] \\[universal-argument]' \
+prefix ARG forces storing a link for each line in the
+active region.
+
+Assume the function is called interactively if INTERACTIVE? is
+non-nil."
+ (interactive "P\np")
+ (org-load-modules-maybe)
+ (if (and (equal arg '(64)) (org-region-active-p))
+ (save-excursion
+ (let ((end (region-end)))
+ (goto-char (region-beginning))
+ (set-mark (point))
+ (while (< (point-at-eol) end)
+ (move-end-of-line 1) (activate-mark)
+ (let (current-prefix-arg)
+ (call-interactively 'org-store-link))
+ (move-beginning-of-line 2)
+ (set-mark (point)))))
+ (setq org-store-link-plist nil)
+ (let (link cpltxt desc description search txt custom-id agenda-link)
+ (cond
+ ;; Store a link using an external link type, if any function is
+ ;; available. If more than one can generate a link from current
+ ;; location, ask which one to use.
+ ((and (not (equal arg '(16)))
+ (let ((results-alist nil))
+ (dolist (f (org-store-link-functions))
+ (when (funcall f)
+ ;; XXX: return value is not link's plist, so we
+ ;; store the new value before it is modified. It
+ ;; would be cleaner to ask store link functions to
+ ;; return the plist instead.
+ (push (cons f (copy-sequence org-store-link-plist))
+ results-alist)))
+ (pcase results-alist
+ (`nil nil)
+ (`((,_ . ,_)) t) ;single choice: nothing to do
+ (`((,name . ,_) . ,_)
+ ;; Reinstate link plist associated to the chosen
+ ;; function.
+ (apply #'org-link-store-props
+ (cdr (assoc-string
+ (completing-read
+ "Which function for creating the link? "
+ (mapcar #'car results-alist)
+ nil t (symbol-name name))
+ results-alist)))
+ t))))
+ (setq link (plist-get org-store-link-plist :link))
+ (setq desc (or (plist-get org-store-link-plist :description)
+ link)))
+
+ ;; Store a link from a remote editing buffer.
+ ((org-src-edit-buffer-p)
+ (let ((coderef-format (org-src-coderef-format))
+ (format-link
+ (lambda (label)
+ (if org-src-source-file-name
+ (format "file:%s::(%s)" org-src-source-file-name label)
+ (format "(%s)" label)))))
+ (cond
+ ;; Code references do not exist in this type of buffer.
+ ;; Pretend we're linking from the source buffer directly.
+ ((not (memq (org-src-source-type) '(example-block src-block)))
+ (with-current-buffer (org-src-source-buffer)
+ (org-store-link arg interactive?))
+ (setq link nil))
+ ;; A code reference exists. Use it.
+ ((save-excursion
+ (beginning-of-line)
+ (re-search-forward (org-src-coderef-regexp coderef-format)
+ (line-end-position)
+ t))
+ (setq link (funcall format-link (match-string-no-properties 3))))
+ ;; No code reference. Create a new one then store the link
+ ;; to it, but only in the function is called interactively.
+ (interactive?
+ (end-of-line)
+ (let* ((label (read-string "Code line label: "))
+ (reference (format coderef-format label))
+ (gc (- 79 (length reference))))
+ (if (< (current-column) gc)
+ (org-move-to-column gc t)
+ (insert " "))
+ (insert reference)
+ (setq link (funcall format-link label))))
+ ;; No code reference, and non-interactive call. Don't know
+ ;; what to do. Give up.
+ (t (setq link nil)))))
+
+ ;; We are in the agenda, link to referenced location
+ ((equal (bound-and-true-p org-agenda-buffer-name) (buffer-name))
+ (let ((m (or (get-text-property (point) 'org-hd-marker)
+ (get-text-property (point) 'org-marker))))
+ (when m
+ (org-with-point-at m
+ (setq agenda-link (org-store-link nil interactive?))))))
+
+ ((eq major-mode 'calendar-mode)
+ (let ((cd (calendar-cursor-to-date)))
+ (setq link
+ (format-time-string
+ (car org-time-stamp-formats)
+ (apply 'encode-time
+ (list 0 0 0 (nth 1 cd) (nth 0 cd) (nth 2 cd)
+ nil nil nil))))
+ (org-link-store-props :type "calendar" :date cd)))
+
+ ((eq major-mode 'help-mode)
+ (setq link (concat "help:" (save-excursion
+ (goto-char (point-min))
+ (looking-at "^[^ ]+")
+ (match-string 0))))
+ (org-link-store-props :type "help"))
+
+ ((eq major-mode 'w3-mode)
+ (setq cpltxt (if (and (buffer-name)
+ (not (string-match "Untitled" (buffer-name))))
+ (buffer-name)
+ (url-view-url t))
+ link (url-view-url t))
+ (org-link-store-props :type "w3" :url (url-view-url t)))
+
+ ((eq major-mode 'image-mode)
+ (setq cpltxt (concat "file:"
+ (abbreviate-file-name buffer-file-name))
+ link cpltxt)
+ (org-link-store-props :type "image" :file buffer-file-name))
+
+ ;; In dired, store a link to the file of the current line
+ ((derived-mode-p 'dired-mode)
+ (let ((file (dired-get-filename nil t)))
+ (setq file (if file
+ (abbreviate-file-name
+ (expand-file-name (dired-get-filename nil t)))
+ ;; otherwise, no file so use current directory.
+ default-directory))
+ (setq cpltxt (concat "file:" file)
+ link cpltxt)))
+
+ ((setq search (run-hook-with-args-until-success
+ 'org-create-file-search-functions))
+ (setq link (concat "file:" (abbreviate-file-name buffer-file-name)
+ "::" search))
+ (setq cpltxt (or description link)))
+
+ ((and (buffer-file-name (buffer-base-buffer)) (derived-mode-p 'org-mode))
+ (org-with-limited-levels
+ (setq custom-id (org-entry-get nil "CUSTOM_ID"))
+ (cond
+ ;; Store a link using the target at point
+ ((org-in-regexp "[^<]<<\\([^<>]+\\)>>[^>]" 1)
+ (setq cpltxt
+ (concat "file:"
+ (abbreviate-file-name
+ (buffer-file-name (buffer-base-buffer)))
+ "::" (match-string 1))
+ link cpltxt))
+ ((and (featurep 'org-id)
+ (or (eq org-id-link-to-org-use-id t)
+ (and interactive?
+ (or (eq org-id-link-to-org-use-id 'create-if-interactive)
+ (and (eq org-id-link-to-org-use-id
+ 'create-if-interactive-and-no-custom-id)
+ (not custom-id))))
+ (and org-id-link-to-org-use-id (org-entry-get nil "ID"))))
+ ;; Store a link using the ID at point
+ (setq link (condition-case nil
+ (prog1 (org-id-store-link)
+ (setq desc (or (plist-get org-store-link-plist
+ :description)
+ "")))
+ (error
+ ;; Probably before first headline, link only to file
+ (concat "file:"
+ (abbreviate-file-name
+ (buffer-file-name (buffer-base-buffer))))))))
+ (t
+ ;; Just link to current headline
+ (setq cpltxt (concat "file:"
+ (abbreviate-file-name
+ (buffer-file-name (buffer-base-buffer)))))
+ ;; Add a context search string
+ (when (org-xor org-link-context-for-files (equal arg '(4)))
+ (let* ((element (org-element-at-point))
+ (name (org-element-property :name element)))
+ (setq txt (cond
+ ((org-at-heading-p) nil)
+ (name)
+ ((org-region-active-p)
+ (buffer-substring (region-beginning) (region-end)))))
+ (when (or (null txt) (string-match "\\S-" txt))
+ (setq cpltxt
+ (concat cpltxt "::"
+ (condition-case nil
+ (org-link-heading-search-string txt)
+ (error "")))
+ desc (or name
+ (nth 4 (ignore-errors (org-heading-components)))
+ "NONE")))))
+ (when (string-match "::\\'" cpltxt)
+ (setq cpltxt (substring cpltxt 0 -2)))
+ (setq link cpltxt)))))
+
+ ((buffer-file-name (buffer-base-buffer))
+ ;; Just link to this file here.
+ (setq cpltxt (concat "file:"
+ (abbreviate-file-name
+ (buffer-file-name (buffer-base-buffer)))))
+ ;; Add a context string.
+ (when (org-xor org-link-context-for-files (equal arg '(4)))
+ (setq txt (if (org-region-active-p)
+ (buffer-substring (region-beginning) (region-end))
+ (buffer-substring (point-at-bol) (point-at-eol))))
+ ;; Only use search option if there is some text.
+ (when (string-match "\\S-" txt)
+ (setq cpltxt
+ (concat cpltxt "::" (org-link-heading-search-string txt))
+ desc "NONE")))
+ (setq link cpltxt))
+
+ (interactive?
+ (user-error "No method for storing a link from this buffer"))
+
+ (t (setq link nil)))
+
+ ;; We're done setting link and desc, clean up
+ (when (consp link) (setq cpltxt (car link) link (cdr link)))
+ (setq link (or link cpltxt)
+ desc (or desc cpltxt))
+ (cond ((not desc))
+ ((equal desc "NONE") (setq desc nil))
+ (t (setq desc (org-link-display-format desc))))
+ ;; Return the link
+ (if (not (and interactive? link))
+ (or agenda-link (and link (org-link-make-string link desc)))
+ (push (list link desc) org-stored-links)
+ (message "Stored: %s" (or desc link))
+ (when custom-id
+ (setq link (concat "file:" (abbreviate-file-name
+ (buffer-file-name)) "::#" custom-id))
+ (push (list link desc) org-stored-links))
+ (car org-stored-links)))))
+
+;;;###autoload
+(defun org-insert-link (&optional complete-file link-location description)
+ "Insert a link. At the prompt, enter the link.
+
+Completion can be used to insert any of the link protocol prefixes in use.
+
+The history can be used to select a link previously stored with
+`org-store-link'. When the empty string is entered (i.e. if you just
+press `RET' at the prompt), the link defaults to the most recently
+stored link. As `SPC' triggers completion in the minibuffer, you need to
+use `M-SPC' or `C-q SPC' to force the insertion of a space character.
+
+You will also be prompted for a description, and if one is given, it will
+be displayed in the buffer instead of the link.
+
+If there is already a link at point, this command will allow you to edit
+link and description parts.
+
+With a `\\[universal-argument]' prefix, prompts for a file to link to. The \
+file name can be
+selected using completion. The path to the file will be relative to the
+current directory if the file is in the current directory or a subdirectory.
+Otherwise, the link will be the absolute path as completed in the minibuffer
+\(i.e. normally ~/path/to/file). You can configure this behavior using the
+option `org-link-file-path-type'.
+
+With a `\\[universal-argument] \\[universal-argument]' prefix, enforce an \
+absolute path even if the file is in
+the current directory or below.
+
+A `\\[universal-argument] \\[universal-argument] \\[universal-argument]' \
+prefix negates `org-link-keep-stored-after-insertion'.
+
+If the LINK-LOCATION parameter is non-nil, this value will be used as
+the link location instead of reading one interactively.
+
+If the DESCRIPTION parameter is non-nil, this value will be used as the
+default description. Otherwise, if `org-link-make-description-function'
+is non-nil, this function will be called with the link target, and the
+result will be the default link description. When called non-interactively,
+don't allow to edit the default description."
+ (interactive "P")
+ (let* ((wcf (current-window-configuration))
+ (origbuf (current-buffer))
+ (region (when (org-region-active-p)
+ (buffer-substring (region-beginning) (region-end))))
+ (remove (and region (list (region-beginning) (region-end))))
+ (desc region)
+ (link link-location)
+ (abbrevs org-link-abbrev-alist-local)
+ entry all-prefixes auto-desc)
+ (cond
+ (link-location) ; specified by arg, just use it.
+ ((org-in-regexp org-link-bracket-re 1)
+ ;; We do have a link at point, and we are going to edit it.
+ (setq remove (list (match-beginning 0) (match-end 0)))
+ (setq desc (when (match-end 2) (match-string-no-properties 2)))
+ (setq link (read-string "Link: "
+ (org-link-unescape
+ (match-string-no-properties 1)))))
+ ((or (org-in-regexp org-link-angle-re)
+ (org-in-regexp org-link-plain-re))
+ ;; Convert to bracket link
+ (setq remove (list (match-beginning 0) (match-end 0))
+ link (read-string "Link: "
+ (org-unbracket-string "<" ">" (match-string 0)))))
+ ((member complete-file '((4) (16)))
+ ;; Completing read for file names.
+ (setq link (org-link-complete-file complete-file)))
+ (t
+ ;; Read link, with completion for stored links.
+ (org-link--fontify-links-to-this-file)
+ (org-switch-to-buffer-other-window "*Org Links*")
+ (with-current-buffer "*Org Links*"
+ (erase-buffer)
+ (insert "Insert a link.
+Use TAB to complete link prefixes, then RET for type-specific completion support\n")
+ (when org-stored-links
+ (insert "\nStored links are available with <up>/<down> or M-p/n \
+\(most recent with RET):\n\n")
+ (insert (mapconcat #'org-link--prettify
+ (reverse org-stored-links)
+ "\n")))
+ (goto-char (point-min)))
+ (let ((cw (selected-window)))
+ (select-window (get-buffer-window "*Org Links*" 'visible))
+ (with-current-buffer "*Org Links*" (setq truncate-lines t))
+ (unless (pos-visible-in-window-p (point-max))
+ (org-fit-window-to-buffer))
+ (and (window-live-p cw) (select-window cw)))
+ (setq all-prefixes (append (mapcar #'car abbrevs)
+ (mapcar #'car org-link-abbrev-alist)
+ (org-link-types)))
+ (unwind-protect
+ ;; Fake a link history, containing the stored links.
+ (let ((org-link--history
+ (append (mapcar #'car org-stored-links)
+ org-link--insert-history)))
+ (setq link
+ (org-completing-read
+ "Link: "
+ (append
+ (mapcar (lambda (x) (concat x ":")) all-prefixes)
+ (mapcar #'car org-stored-links))
+ nil nil nil
+ 'org-link--history
+ (caar org-stored-links)))
+ (unless (org-string-nw-p link) (user-error "No link selected"))
+ (dolist (l org-stored-links)
+ (when (equal link (cadr l))
+ (setq link (car l))
+ (setq auto-desc t)))
+ (when (or (member link all-prefixes)
+ (and (equal ":" (substring link -1))
+ (member (substring link 0 -1) all-prefixes)
+ (setq link (substring link 0 -1))))
+ (setq link (with-current-buffer origbuf
+ (org-link--try-special-completion link)))))
+ (set-window-configuration wcf)
+ (kill-buffer "*Org Links*"))
+ (setq entry (assoc link org-stored-links))
+ (or entry (push link org-link--insert-history))
+ (setq desc (or desc (nth 1 entry)))))
+
+ (when (funcall (if (equal complete-file '(64)) 'not 'identity)
+ (not org-link-keep-stored-after-insertion))
+ (setq org-stored-links (delq (assoc link org-stored-links)
+ org-stored-links)))
+
+ (when (and (string-match org-link-plain-re link)
+ (not (string-match org-ts-regexp link)))
+ ;; URL-like link, normalize the use of angular brackets.
+ (setq link (org-unbracket-string "<" ">" link)))
+
+ ;; Check if we are linking to the current file with a search
+ ;; option If yes, simplify the link by using only the search
+ ;; option.
+ (when (and buffer-file-name
+ (let ((case-fold-search nil))
+ (string-match "\\`file:\\(.+?\\)::" link)))
+ (let ((path (match-string-no-properties 1 link))
+ (search (substring-no-properties link (match-end 0))))
+ (save-match-data
+ (when (equal (file-truename buffer-file-name) (file-truename path))
+ ;; We are linking to this same file, with a search option
+ (setq link search)))))
+
+ ;; Check if we can/should use a relative path. If yes, simplify
+ ;; the link.
+ (let ((case-fold-search nil))
+ (when (string-match "\\`\\(file\\|docview\\):" link)
+ (let* ((type (match-string-no-properties 0 link))
+ (path-start (match-end 0))
+ (search (and (string-match "::\\(.*\\)\\'" link)
+ (match-string 1 link)))
+ (path
+ (if search
+ (substring-no-properties
+ link path-start (match-beginning 0))
+ (substring-no-properties link (match-end 0))))
+ (origpath path))
+ (cond
+ ((or (eq org-link-file-path-type 'absolute)
+ (equal complete-file '(16)))
+ (setq path (abbreviate-file-name (expand-file-name path))))
+ ((eq org-link-file-path-type 'noabbrev)
+ (setq path (expand-file-name path)))
+ ((eq org-link-file-path-type 'relative)
+ (setq path (file-relative-name path)))
+ (t
+ (save-match-data
+ (if (string-match (concat "^" (regexp-quote
+ (expand-file-name
+ (file-name-as-directory
+ default-directory))))
+ (expand-file-name path))
+ ;; We are linking a file with relative path name.
+ (setq path (substring (expand-file-name path)
+ (match-end 0)))
+ (setq path (abbreviate-file-name (expand-file-name path)))))))
+ (setq link (concat type path (and search (concat "::" search))))
+ (when (equal desc origpath)
+ (setq desc path)))))
+
+ (unless auto-desc
+ (let ((initial-input
+ (cond
+ (description)
+ ((not org-link-make-description-function) desc)
+ (t (condition-case nil
+ (funcall org-link-make-description-function link desc)
+ (error
+ (message "Can't get link description from %S"
+ (symbol-name org-link-make-description-function))
+ (sit-for 2)
+ nil))))))
+ (setq desc (if (called-interactively-p 'any)
+ (read-string "Description: " initial-input)
+ initial-input))))
+
+ (unless (org-string-nw-p desc) (setq desc nil))
+ (when remove (apply #'delete-region remove))
+ (insert (org-link-make-string link desc))
+ ;; Redisplay so as the new link has proper invisible characters.
+ (sit-for 0)))
+
+;;;###autoload
+(defun org-insert-all-links (arg &optional pre post)
+ "Insert all links in `org-stored-links'.
+When a universal prefix, do not delete the links from `org-stored-links'.
+When `ARG' is a number, insert the last N link(s).
+`PRE' and `POST' are optional arguments to define a string to
+prepend or to append."
+ (interactive "P")
+ (let ((org-link-keep-stored-after-insertion (equal arg '(4)))
+ (links (copy-sequence org-stored-links))
+ (pr (or pre "- "))
+ (po (or post "\n"))
+ (cnt 1) l)
+ (if (null org-stored-links)
+ (message "No link to insert")
+ (while (and (or (listp arg) (>= arg cnt))
+ (setq l (if (listp arg)
+ (pop links)
+ (pop org-stored-links))))
+ (setq cnt (1+ cnt))
+ (insert pr)
+ (org-insert-link nil (car l) (or (cadr l) "<no description>"))
+ (insert po)))))
+
+;;;###autoload
+(defun org-insert-last-stored-link (arg)
+ "Insert the last link stored in `org-stored-links'."
+ (interactive "p")
+ (org-insert-all-links arg "" "\n"))
+
+;;;###autoload
+(defun org-insert-link-global ()
+ "Insert a link like Org mode does.
+This command can be called in any mode to insert a link in Org syntax."
+ (interactive)
+ (org-load-modules-maybe)
+ (org-run-like-in-org-mode 'org-insert-link))
+
+;;;###autoload
+(defun org-update-radio-target-regexp ()
+ "Find all radio targets in this file and update the regular expression.
+Also refresh fontification if needed."
+ (interactive)
+ (let ((old-regexp org-target-link-regexp)
+ ;; Some languages, e.g., Chinese, do not use spaces to
+ ;; separate words. Also allow to surround radio targets with
+ ;; line-breakable characters.
+ (before-re "\\(?:^\\|[^[:alnum:]]\\|\\c|\\)\\(")
+ (after-re "\\)\\(?:$\\|[^[:alnum:]]\\|\\c|\\)")
+ (targets
+ (org-with-wide-buffer
+ (goto-char (point-min))
+ (let (rtn)
+ (while (re-search-forward org-radio-target-regexp nil t)
+ ;; Make sure point is really within the object.
+ (backward-char)
+ (let ((obj (org-element-context)))
+ (when (eq (org-element-type obj) 'radio-target)
+ (cl-pushnew (org-element-property :value obj) rtn
+ :test #'equal))))
+ rtn))))
+ (setq org-target-link-regexp
+ (and targets
+ (concat before-re
+ (mapconcat
+ (lambda (x)
+ (replace-regexp-in-string
+ " +" "\\s-+" (regexp-quote x) t t))
+ targets
+ "\\|")
+ after-re)))
+ (unless (equal old-regexp org-target-link-regexp)
+ ;; Clean-up cache.
+ (let ((regexp (cond ((not old-regexp) org-target-link-regexp)
+ ((not org-target-link-regexp) old-regexp)
+ (t
+ (concat before-re
+ (mapconcat
+ (lambda (re)
+ (substring re (length before-re)
+ (- (length after-re))))
+ (list old-regexp org-target-link-regexp)
+ "\\|")
+ after-re)))))
+ (when (featurep 'org-element)
+ (org-with-point-at 1
+ (while (re-search-forward regexp nil t)
+ (org-element-cache-refresh (match-beginning 1))))))
+ ;; Re fontify buffer.
+ (when (memq 'radio org-highlight-links)
+ (org-restart-font-lock)))))
+
+
+;;; Initialize Regexps
+
+(org-link-make-regexps)
+
+
+(provide 'ol)
+
+;;; ol.el ends here
diff --git a/lisp/org-agenda.el b/lisp/org-agenda.el
index 76ff2d9..090e632 100644
--- a/lisp/org-agenda.el
+++ b/lisp/org-agenda.el
@@ -46,6 +46,7 @@
;;; Code:
(require 'cl-lib)
+(require 'ol)
(require 'org)
(require 'org-macs)
@@ -90,6 +91,7 @@
(defvar org-habit-show-habits)
(defvar org-habit-show-habits-only-for-today)
(defvar org-habit-show-all-today)
+(defvar org-habit-scheduled-past-days)
;; Defined somewhere in this file, but used before definition.
(defvar org-agenda-buffer-name "*Org Agenda*")
@@ -267,7 +269,7 @@ you can \"misuse\" it to also add other text to the header."
"List of types searched for when creating the daily/weekly agenda.
This variable is a list of symbols that controls the types of
items that appear in the daily/weekly agenda. Allowed symbols in this
-list are are
+list are
:timestamp List items containing a date stamp or date range matching
the selected date. This includes sexp entries in angular
@@ -381,6 +383,9 @@ the daily/weekly agenda, see `org-agenda-skip-function'.")
(const :scheduled*)
(const :timestamp)
(const :sexp))))
+ (list :tag "Columns format"
+ (const org-overriding-columns-format)
+ (string :tag "Format"))
(list :tag "Standard skipping condition"
:value (org-agenda-skip-function '(org-agenda-skip-entry-if))
(const org-agenda-skip-function)
@@ -461,7 +466,7 @@ type The command type, any of the following symbols:
... A user-defined function.
match What to search for:
- a single keyword for TODO keyword searches
- - a tags match expression for tags searches
+ - a tags/property/todo match expression for searches
- a word search expression for text searches.
- a regular expression for occur searches
For all other commands, this should be the empty string.
@@ -548,11 +553,11 @@ should provide a description for the prefix, like
(const :format "" stuck)
(const :tag "" :format "" "")
,org-agenda-custom-commands-local-options)
- (list :tag "Tags search"
+ (list :tag "Tags/Property match (all agenda files)"
(const :format "" tags)
(string :tag "Match")
,org-agenda-custom-commands-local-options)
- (list :tag "Tags search, TODO entries only"
+ (list :tag "Tags/Property match of TODO entries (all agenda files)"
(const :format "" tags-todo)
(string :tag "Match")
,org-agenda-custom-commands-local-options)
@@ -1225,7 +1230,7 @@ These days get the special face `org-agenda-date-weekend' in the agenda."
(defcustom org-agenda-move-date-from-past-immediately-to-today t
"Non-nil means jump to today when moving a past date forward in time.
-When using S-right in the agenda to move a a date forward, and the date
+When using S-right in the agenda to move a date forward, and the date
stamp currently points to the past, the first key press will move it
to today. When nil, just move one day forward even if the date stays
in the past."
@@ -1498,7 +1503,7 @@ The third item is a string which will be placed right after the
times that have a grid line.
The fourth item is a string placed after the grid times. This
-will align with agenda items"
+will align with agenda items."
:group 'org-agenda-time-grid
:type
'(list
@@ -1542,18 +1547,18 @@ This is a list of symbols which will be used in sequence to determine
if an entry should be listed before another entry. The following
symbols are recognized:
-time-up Put entries with time-of-day indications first, early first
-time-down Put entries with time-of-day indications first, late first
-timestamp-up Sort by any timestamp, early first
-timestamp-down Sort by any timestamp, late first
-scheduled-up Sort by scheduled timestamp, early first
-scheduled-down Sort by scheduled timestamp, late first
-deadline-up Sort by deadline timestamp, early first
-deadline-down Sort by deadline timestamp, late first
-ts-up Sort by active timestamp, early first
-ts-down Sort by active timestamp, late first
-tsia-up Sort by inactive timestamp, early first
-tsia-down Sort by inactive timestamp, late first
+time-up Put entries with time-of-day indications first, early first.
+time-down Put entries with time-of-day indications first, late first.
+timestamp-up Sort by any timestamp, early first.
+timestamp-down Sort by any timestamp, late first.
+scheduled-up Sort by scheduled timestamp, early first.
+scheduled-down Sort by scheduled timestamp, late first.
+deadline-up Sort by deadline timestamp, early first.
+deadline-down Sort by deadline timestamp, late first.
+ts-up Sort by active timestamp, early first.
+ts-down Sort by active timestamp, late first.
+tsia-up Sort by inactive timestamp, early first.
+tsia-down Sort by inactive timestamp, late first.
category-keep Keep the default order of categories, corresponding to the
sequence in `org-agenda-files'.
category-up Sort alphabetically by category, A-Z.
@@ -1568,10 +1573,10 @@ effort-up Sort numerically by estimated effort, high effort last.
effort-down Sort numerically by estimated effort, high effort first.
user-defined-up Sort according to `org-agenda-cmp-user-defined', high last.
user-defined-down Sort according to `org-agenda-cmp-user-defined', high first.
-habit-up Put entries that are habits first
-habit-down Put entries that are habits last
-alpha-up Sort headlines alphabetically
-alpha-down Sort headlines alphabetically, reversed
+habit-up Put entries that are habits first.
+habit-down Put entries that are habits last.
+alpha-up Sort headlines alphabetically.
+alpha-down Sort headlines alphabetically, reversed.
The different possibilities will be tried in sequence, and testing stops
if one comparison returns a \"not-equal\". For example, the default
@@ -1706,6 +1711,13 @@ Custom commands can set this variable in the options section."
:version "26.1"
:package-version '(Org . "9.1"))
+(defcustom org-agenda-breadcrumbs-separator "->"
+ "The separator of breadcrumbs in agenda lines."
+ :group 'org-agenda-line-format
+ :package-version '(Org . "9.3")
+ :type 'string
+ :safe #'stringp)
+
(defvar org-prefix-format-compiled nil
"The compiled prefix format and associated variables.
This is a list where first element is a list of variable bindings, and second
@@ -2021,7 +2033,8 @@ estimate."
The sole argument to the function, which is called once for each
possible tag, is a string giving the name of the tag. The
function should return either nil if the tag should be included
-as normal, or \"-<TAG>\" to exclude the tag.
+as normal, \"-<TAG>\" to exclude the tag, or \"+<TAG>\" to exclude
+lines not carrying this tag.
Note that for the purpose of tag filtering, only the lower-case version of
all tags will be considered, so that this function will only ever see
the lower-case version of all tags."
@@ -2387,9 +2400,10 @@ The following commands are available:
(org-defkey org-agenda-mode-map "]" 'org-agenda-manipulate-query-subtract)
(org-defkey org-agenda-mode-map "{" 'org-agenda-manipulate-query-add-re)
(org-defkey org-agenda-mode-map "}" 'org-agenda-manipulate-query-subtract-re)
-(org-defkey org-agenda-mode-map "/" 'org-agenda-filter-by-tag)
+(org-defkey org-agenda-mode-map "\\" 'org-agenda-filter-by-tag)
(org-defkey org-agenda-mode-map "_" 'org-agenda-filter-by-effort)
(org-defkey org-agenda-mode-map "=" 'org-agenda-filter-by-regexp)
+(org-defkey org-agenda-mode-map "/" 'org-agenda-filter)
(org-defkey org-agenda-mode-map "|" 'org-agenda-filter-remove-all)
(org-defkey org-agenda-mode-map "~" 'org-agenda-limit-interactively)
(org-defkey org-agenda-mode-map "<" 'org-agenda-filter-by-category)
@@ -2470,8 +2484,20 @@ The following commands are available:
:keys "v A"]
"--"
["Remove Restriction" org-agenda-remove-restriction-lock org-agenda-restrict])
- ["Write view to file" org-agenda-write t]
+ ("Filter current view"
+ ["with generic interface" org-agenda-filter t]
+ "--"
+ ["by category at cursor" org-agenda-filter-by-category t]
+ ["by tag" org-agenda-filter-by-tag t]
+ ["by effort" org-agenda-filter-by-effort t]
+ ["by regexp" org-agenda-filter-by-regexp t]
+ ["by top-level headline" org-agenda-filter-by-top-headline t]
+ "--"
+ ["Remove all filtering" org-agenda-filter-remove-all t]
+ "--"
+ ["limit" org-agenda-limit-interactively t])
["Rebuild buffer" org-agenda-redo t]
+ ["Write view to file" org-agenda-write t]
["Save all Org buffers" org-save-all-org-buffers t]
"--"
["Show original entry" org-agenda-show t]
@@ -2839,7 +2865,13 @@ Pressing `<' twice means to restrict to the current subtree or region
(org-back-to-heading t)
(move-marker org-agenda-restrict-begin (point))
(move-marker org-agenda-restrict-end
- (progn (org-end-of-subtree t)))))))
+ (progn (org-end-of-subtree t)))))
+ ((and (eq restriction 'buffer)
+ (or (< 1 (point-min))
+ (< (point-max) (1+ (buffer-size)))))
+ (setq org-agenda-restrict (current-buffer))
+ (move-marker org-agenda-restrict-begin (point-min))
+ (move-marker org-agenda-restrict-end (point-max)))))
;; For example the todo list should not need it (but does...)
(cond
@@ -3077,16 +3109,42 @@ s Search for keywords M Like m, but only TODO entries
(setq second-time t)
(org-fit-window-to-buffer))
+ ;; Hint to navigation if window too small for all information
+ (setq header-line-format
+ (when (not (pos-visible-in-window-p (point-max)))
+ "Use SPC, DEL, C-n or C-p to navigate."))
+
;; Ask for selection
- (message "Press key for agenda command%s:"
- (if (or restrict-ok org-agenda-overriding-restriction)
- (if org-agenda-overriding-restriction
- " (restriction lock active)"
- (if restriction
- (format " (restricted to %s)" restriction)
- " (unrestricted)"))
- ""))
- (setq c (read-char-exclusive))
+ (cl-loop
+ do (progn
+ (message "Press key for agenda command%s:"
+ (if (or restrict-ok org-agenda-overriding-restriction)
+ (if org-agenda-overriding-restriction
+ " (restriction lock active)"
+ (if restriction
+ (format " (restricted to %s)" restriction)
+ " (unrestricted)"))
+ ""))
+ (setq c (read-char-exclusive)))
+ until (not (memq c '(14 16 ?\s ?\d)))
+ do (cl-case c
+ (14 (if (not (pos-visible-in-window-p (point-max)))
+ (ignore-errors (scroll-up 1))
+ (message "End of buffer")
+ (sit-for 1)))
+ (16 (if (not (pos-visible-in-window-p (point-min)))
+ (ignore-errors (scroll-down 1))
+ (message "Beginning of buffer")
+ (sit-for 1)))
+ (?\s (if (not (pos-visible-in-window-p (point-max)))
+ (scroll-up nil)
+ (message "End of buffer")
+ (sit-for 1)))
+ (?\d (if (not (pos-visible-in-window-p (point-min)))
+ (scroll-down nil)
+ (message "Beginning of buffer")
+ (sit-for 1)))))
+
(message "")
(cond
((assoc (char-to-string c) custom)
@@ -3259,7 +3317,7 @@ todo The todo keyword, if any
tags All tags including inherited ones, separated by colons
date The relevant date, like 2007-2-14
time The time, like 15:00-16:50
-extra Sting with extra planning info
+extra String with extra planning info
priority-l The priority letter if any was given
priority-n The computed numerical priority
agenda-day The day in the agenda where this is listed"
@@ -3535,7 +3593,7 @@ removed from the entry content. Currently only `planning' is allowed here."
(add-text-properties (match-beginning 0) (match-end 0)
'(face org-link))))
(goto-char (point-min))
- (while (re-search-forward org-bracket-link-regexp (point-max) t)
+ (while (re-search-forward org-link-bracket-re (point-max) t)
(set-text-properties (match-beginning 0) (match-end 0)
nil))
(goto-char (point-min))
@@ -3608,6 +3666,11 @@ removed from the entry content. Currently only `planning' is allowed here."
(defvar org-agenda-regexp-filter nil)
(defvar org-agenda-effort-filter nil)
(defvar org-agenda-top-headline-filter nil)
+
+(defvar org-agenda-represented-categories nil
+ "Cache for the list of all categories in the agenda.")
+(defvar org-agenda-represented-tags nil
+ "Cache for the list of all categories in the agenda.")
(defvar org-agenda-tag-filter-preset nil
"A preset of the tags filter used for secondary agenda filtering.
This must be a list of strings, each string must be a single tag preceded
@@ -3618,6 +3681,20 @@ the entire agenda view. In a block agenda, it will not work reliably to
define a filter for one of the individual blocks. You need to set it in
the global options and expect it to be applied to the entire view.")
+(defconst org-agenda-filter-variables
+ '((category . org-agenda-category-filter)
+ (tag . org-agenda-tag-filter)
+ (effort . org-agenda-effort-filter)
+ (regexp . org-agenda-regexp-filter))
+ "Alist of filter types and associated variables")
+(defun org-agenda-filter-any ()
+ "Is any filter active?"
+ (let ((form (cons 'or (mapcar (lambda (x)
+ (if (or (symbol-value (cdr x))
+ (get :preset-filter x))
+ t nil))
+ org-agenda-filter-variables))))
+ (eval form)))
(defvar org-agenda-category-filter-preset nil
"A preset of the category filter used for secondary agenda filtering.
This must be a list of strings, each string must be a single category
@@ -3715,6 +3792,7 @@ FILTER-ALIST is an alist of filters we need to apply when
(put 'org-agenda-tag-filter :preset-filter nil)
(put 'org-agenda-category-filter :preset-filter nil)
(put 'org-agenda-regexp-filter :preset-filter nil)
+ (put 'org-agenda-effort-filter :preset-filter nil)
;; Popup existing buffer
(org-agenda-prepare-window (get-buffer org-agenda-buffer-name)
filter-alist)
@@ -3816,6 +3894,8 @@ FILTER-ALIST is an alist of filters we need to apply when
(org-with-point-at mrk
(mapcar #'downcase (org-get-tags)))))))))
(run-hooks 'org-agenda-finalize-hook)
+ (setq org-agenda-represented-tags nil
+ org-agenda-represented-categories nil)
(when org-agenda-top-headline-filter
(org-agenda-filter-top-headline-apply
org-agenda-top-headline-filter))
@@ -3941,7 +4021,7 @@ dimming them."
the header at `org-hd-marker' is blocked according to
`org-entry-blocked-p', then if `org-agenda-dim-blocked-tasks' is
'invisible and the header is not blocked by checkboxes, set the
-text property `org-todo-blocked' to 'invisible, otherwise set it
+text property `org-todo-blocked' to `invisible', otherwise set it
to t."
(when (get-text-property 0 'todo-state entry)
(let ((entry-marker (get-text-property 0 'org-hd-marker entry))
@@ -4125,6 +4205,9 @@ items if they have an hour specification like [h]h:mm."
span (nth 2 org-agenda-overriding-arguments)))
(when (and (integerp arg) (> arg 0))
(setq span arg arg nil))
+ (when (numberp span)
+ (unless (< 0 span)
+ (user-error "Agenda creation impossible for this span(=%d days)." span)))
(catch 'exit
(setq org-agenda-buffer-name
(or org-agenda-buffer-tmp-name
@@ -4627,7 +4710,7 @@ Press `\\[org-agenda-manipulate-query-add]', \
`\\[org-agenda-manipulate-query-subtract]' to add/sub word, \
`\\[org-agenda-manipulate-query-add-re]', \
`\\[org-agenda-manipulate-query-subtract-re]' to add/sub regexp, \
-`\\[universal-argument] \\[org-agenda-redo]' to edit\n"))
+`\\[universal-argument] \\[org-agenda-redo]' for a fresh search\n"))
(add-text-properties pos (1- (point))
(list 'face 'org-agenda-structure)))
(buffer-string)))
@@ -5201,7 +5284,7 @@ function from a program - use `org-agenda-get-day-entries' instead."
(when results
(setq results
(mapcar (lambda (i) (replace-regexp-in-string
- org-bracket-link-regexp "\\3" i)) results))
+ org-link-bracket-re "\\2" i)) results))
(concat (org-agenda-finalize-entries results) "\n"))))
;;; Agenda entry finders
@@ -5867,7 +5950,14 @@ See also the user option `org-agenda-clock-consistency-checks'."
(error "No valid Clock line")
(throw 'next t))
(unless (match-end 3)
- (setq issue "No end time"
+ (setq issue
+ (format
+ "No end time: (%s)"
+ (org-duration-from-minutes
+ (floor
+ (- (float-time (org-current-time))
+ (float-time (org-time-string-to-time (match-string 1))))
+ 60)))
face (or (plist-get pl :no-end-time-face) face))
(throw 'next t))
(setq ts (match-string 1)
@@ -6164,6 +6254,7 @@ scheduled items with an hour specification like [h]h:mm."
(diff (- current schedule))
(warntime (get-text-property (point) 'org-appt-warntime))
(pastschedp (< schedule today))
+ (futureschedp (> schedule today))
(habitp (and (fboundp 'org-is-habit-p) (org-is-habit-p)))
(suppress-delay
(let ((deadline (and org-agenda-skip-scheduled-delay-if-deadline
@@ -6201,7 +6292,8 @@ scheduled items with an hour specification like [h]h:mm."
habitp
(bound-and-true-p org-habit-show-all-today))
(when (or (and (> ddays 0) (< diff ddays))
- (> diff org-scheduled-past-days)
+ (> diff (or (and habitp org-habit-scheduled-past-days)
+ org-scheduled-past-days))
(> schedule current)
(and (/= current schedule)
(/= current today)
@@ -6255,9 +6347,17 @@ scheduled items with an hour specification like [h]h:mm."
(head (buffer-substring (point) (line-end-position)))
(time
(cond
- ;; No time of day designation if it is only
- ;; a reminder.
- ((and (/= current schedule) (/= current repeat)) nil)
+ ;; No time of day designation if it is only a
+ ;; reminder, except for habits, which always show
+ ;; the time of day. Habits are an exception
+ ;; because if there is a time of day, that is
+ ;; interpreted to mean they should usually happen
+ ;; then, even if doing the habit was missed.
+ ((and
+ (not habitp)
+ (/= current schedule)
+ (/= current repeat))
+ nil)
((string-match " \\([012]?[0-9]:[0-9][0-9]\\)" s)
(concat (substring s (match-beginning 1)) " "))
(t 'time)))
@@ -6271,6 +6371,8 @@ scheduled items with an hour specification like [h]h:mm."
head level category tags time nil habitp))
(face (cond ((and (not habitp) pastschedp)
'org-scheduled-previously)
+ ((and habitp futureschedp)
+ 'org-agenda-done)
(todayp 'org-scheduled-today)
(t 'org-scheduled)))
(habitp (and habitp (org-habit-parse-todo))))
@@ -6540,8 +6642,8 @@ Any match of REMOVE-RE will be removed from TXT."
(setq breadcrumbs (org-with-point-at (org-get-at-bol 'org-marker)
(let ((s (org-format-outline-path (org-get-outline-path)
(1- (frame-width))
- nil "->")))
- (if (eq "" s) "" (concat s "->"))))))
+ nil org-agenda-breadcrumbs-separator)))
+ (if (eq "" s) "" (concat s org-agenda-breadcrumbs-separator))))))
(setq time (cond (s2 (concat
(org-agenda-time-of-day-to-ampm-maybe s1)
"-" (org-agenda-time-of-day-to-ampm-maybe s2)
@@ -6555,11 +6657,9 @@ Any match of REMOVE-RE will be removed from TXT."
extra (or (and (not habitp) extra) "")
category (if (symbolp category) (symbol-name category) category)
level (or level ""))
- (if (string-match org-bracket-link-regexp category)
+ (if (string-match org-link-bracket-re category)
(progn
- (setq l (if (match-end 3)
- (- (match-end 3) (match-beginning 3))
- (- (match-end 1) (match-beginning 1))))
+ (setq l (string-width (or (match-string 2) (match-string 1))))
(when (< l (or org-prefix-category-length 0))
(setq category (copy-sequence category))
(org-add-props category nil
@@ -6709,8 +6809,9 @@ and stored in the variable `org-prefix-format-compiled'."
(floor (abs (string-to-number (match-string 2 s)))))
(setq org-prefix-category-max-length
(let ((x (match-string 2 s)))
- (when (string-match-p "\\.[0-9]+" x)
- (string-to-number (substring (match-string 0 x) 1))))))
+ (save-match-data
+ (and (string-match "\\.[0-9]+" x)
+ (string-to-number (substring (match-string 0 x) 1)))))))
(if (eq var 'eval)
(setq varform `(format ,f (org-eval ,(read (match-string 4 s)))))
(if opt
@@ -7207,14 +7308,14 @@ subtree."
;;; Agenda commands
(defun org-agenda-check-type (error &rest types)
- "Check if agenda buffer is of allowed type.
+ "Check if agenda buffer or component is of allowed type.
If ERROR is non-nil, throw an error, otherwise just return nil.
Allowed types are `agenda' `todo' `tags' `search'."
(cond ((not org-agenda-type)
(error "No Org agenda currently displayed"))
((memq org-agenda-type types) t)
(error
- (error "Not allowed in %s-type agenda buffers" org-agenda-type))
+ (error "Not allowed in '%s'-type agenda buffer or component" org-agenda-type))
(t nil)))
(defun org-agenda-Quit ()
@@ -7393,14 +7494,13 @@ With a prefix argument, do so in all agenda buffers."
(defun org-agenda-filter-by-category (strip)
"Filter lines in the agenda buffer that have a specific category.
The category is that of the current line.
-Without prefix argument, keep only the lines of that category.
-With a prefix argument, exclude the lines of that category.
-"
+With a `\\[universal-argument]' prefix argument, exclude the lines of that category.
+When there is already a category filter in place, this command removes the filter."
(interactive "P")
(if (and org-agenda-filtered-by-category
org-agenda-category-filter)
(org-agenda-filter-show-all-cat)
- (let ((cat (org-no-properties (org-agenda-get-category))))
+ (let ((cat (org-no-properties (org-get-at-eol 'org-category 1))))
(cond
((and cat strip)
(org-agenda-filter-apply
@@ -7425,7 +7525,8 @@ search from."
(defvar org-agenda-filtered-by-top-headline nil)
(defun org-agenda-filter-by-top-headline (strip)
"Keep only those lines that are descendants from the same top headline.
-The top headline is that of the current line."
+The top headline is that of the current line. With prefix arg STRIP, hide
+all lines of the category at point."
(interactive "P")
(if org-agenda-filtered-by-top-headline
(progn
@@ -7437,47 +7538,60 @@ The top headline is that of the current line."
(error "No top-level headline at point")))))
(defvar org-agenda-regexp-filter nil)
-(defun org-agenda-filter-by-regexp (strip)
- "Filter agenda entries by regular expressions.
-
-With one prefix argument, filter out entries matching the regexp.
-If there is already a regexp filter, remove it unless called with
-two prefix arguments."
+(defun org-agenda-filter-by-regexp (strip-or-accumulate)
+ "Filter agenda entries by a regular expressions.
+You will be prompted for the regular expression, and the agenda
+view will only show entries that are matched by that expression.
+
+With one `\\[universal-argument]' prefix argument, hide entries matching the regexp.
+When there is already a regexp filter active, this command removed the
+filter. However, with two `\\[universal-argument]' prefix arguments, add a new condition to
+an already existing regexp filter."
(interactive "P")
- (cond
- ((and org-agenda-regexp-filter (not (equal strip '(16))))
- (org-agenda-filter-show-all-re)
- (message "Regexp filter removed"))
- (t (let ((flt (concat (if (equal strip '(4)) "-" "+")
- (read-from-minibuffer
- (if (equal strip '(4))
- "Filter out entries matching regexp: "
- "Narrow to entries matching regexp: ")))))
- (push flt org-agenda-regexp-filter)
- (org-agenda-filter-apply org-agenda-regexp-filter 'regexp)))))
+ (let* ((strip (equal strip-or-accumulate '(4)))
+ (accumulate (equal strip-or-accumulate '(16))))
+ (cond
+ ((and org-agenda-regexp-filter (not accumulate))
+ (org-agenda-filter-show-all-re)
+ (message "Regexp filter removed"))
+ (t (let ((flt (concat (if strip "-" "+")
+ (read-from-minibuffer
+ (if strip
+ "Hide entries matching regexp: "
+ "Narrow to entries matching regexp: ")))))
+ (push flt org-agenda-regexp-filter)
+ (org-agenda-filter-apply org-agenda-regexp-filter 'regexp))))))
(defvar org-agenda-effort-filter nil)
-(defun org-agenda-filter-by-effort (strip)
+(defun org-agenda-filter-by-effort (strip-or-accumulate)
"Filter agenda entries by effort.
-With no prefix argument, keep entries matching the effort condition.
-With one prefix argument, filter out entries matching the condition.
-With two prefix arguments, remove the effort filters."
+With no `\\[universal-argument]' prefix argument, keep entries matching the effort condition.
+With one `\\[universal-argument]' prefix argument, filter out entries matching the condition.
+With two `\\[universal-argument]' prefix arguments, add a second condition to the existing filter.
+This last option is in practice not very useful, but it is available for
+consistency with the other filter commands."
(interactive "P")
- (cond
- ((member strip '(nil 4))
- (let* ((efforts (split-string
- (or (cdr (assoc (concat org-effort-property "_ALL")
- org-global-properties))
- "0 0:10 0:30 1:00 2:00 3:00 4:00 5:00 6:00 7:00")))
- ;; XXX: the following handles only up to 10 different
- ;; effort values.
- (allowed-keys (if (null efforts) nil
- (mapcar (lambda (n) (mod n 10)) ;turn 10 into 0
- (number-sequence 1 (length efforts)))))
- (op nil))
- (while (not (memq op '(?< ?> ?=)))
- (setq op (read-char-exclusive "Effort operator? (> = or <)")))
- ;; Select appropriate duration. Ignore non-digit characters.
+ (let* ((efforts (split-string
+ (or (cdr (assoc (concat org-effort-property "_ALL")
+ org-global-properties))
+ "0 0:10 0:30 1:00 2:00 3:00 4:00 5:00 6:00 7:00")))
+ ;; XXX: the following handles only up to 10 different
+ ;; effort values.
+ (allowed-keys (if (null efforts) nil
+ (mapcar (lambda (n) (mod n 10)) ;turn 10 into 0
+ (number-sequence 1 (length efforts)))))
+ (keep (equal strip-or-accumulate '(16)))
+ (negative (equal strip-or-accumulate '(4)))
+ (current org-agenda-effort-filter)
+ (op nil))
+ (while (not (memq op '(?< ?> ?= ?_)))
+ (setq op (read-char-exclusive
+ "Effort operator? (> = or <) or press `_' again to remove filter")))
+ ;; Select appropriate duration. Ignore non-digit characters.
+ (if (eq op ?_)
+ (progn
+ (org-agenda-filter-show-all-effort)
+ (message "Effort filter removed"))
(let ((prompt
(apply #'format
(concat "Effort %c "
@@ -7489,15 +7603,149 @@ With two prefix arguments, remove the effort filters."
(while (not (memq eff allowed-keys))
(message prompt)
(setq eff (- (read-char-exclusive) 48)))
+ (org-agenda-filter-show-all-effort)
(setq org-agenda-effort-filter
- (list (concat (if strip "-" "+")
- (char-to-string op)
- ;; Numbering is 1 2 3 ... 9 0, but we want
- ;; 0 1 2 ... 8 9.
- (nth (mod (1- eff) 10) efforts)))))
- (org-agenda-filter-apply org-agenda-effort-filter 'effort)))
- (t (org-agenda-filter-show-all-effort)
- (message "Effort filter removed"))))
+ (append
+ (list (concat (if negative "-" "+")
+ (char-to-string op)
+ ;; Numbering is 1 2 3 ... 9 0, but we want
+ ;; 0 1 2 ... 8 9.
+ (nth (mod (1- eff) 10) efforts)))
+ (if keep current nil)))
+ (org-agenda-filter-apply org-agenda-effort-filter 'effort)))))
+
+
+(defun org-agenda-filter (&optional strip-or-accumulate)
+ "Prompt for a general filter string and apply it to the agenda.
+
+The string may contain filter elements like
+
++category
++tag
++<effort > and = are also allowed as effort operators
++/regexp/
+
+Instead of `+', `-' is allowed to strip the agenda of matching entries.
+`+' is optional if it is not required to separate two string parts.
+Multiple filter elements can be concatenated without spaces, for example
+
+ +work-John<0:10-/plot/
+
+selects entries with category `work' and effort estimates below 10 minutes,
+and deselects entries with tag `John' or matching the regexp `plot'.
+
+During entry of the filter, completion for tags, categories and effort
+values is offered. Since the syntax for categories and tags is identical
+there should be no overlap between categoroes and tags. If there is, tags
+get priority.
+
+A single `\\[universal-argument]' prefix arg STRIP-OR-ACCUMULATE will negate the
+entire filter, which can be useful in connection with the prompt history.
+
+A double `\\[universal-argument] \\[universal-argument]' prefix arg will add the new filter elements to the
+existing ones. A shortcut for this is to add an additional `+' at the
+beginning of the string, like `+-John'.
+
+With a triple prefix argument, execute the computed filtering defined in
+the variable `org-agenda-auto-exclude-function'."
+ (interactive "P")
+ (if (equal strip-or-accumulate '(64))
+ ;; Execute the auto-exclude action
+ (if (not org-agenda-auto-exclude-function)
+ (user-error "`org-agenda-auto-exclude-function' is undefined")
+ (org-agenda-filter-show-all-tag)
+ (setq org-agenda-tag-filter nil)
+ (dolist (tag (org-agenda-get-represented-tags))
+ (let ((modifier (funcall org-agenda-auto-exclude-function tag)))
+ (when modifier
+ (push modifier org-agenda-tag-filter))))
+ (unless (null org-agenda-tag-filter)
+ (org-agenda-filter-apply org-agenda-tag-filter 'tag 'expand)))
+ ;; Prompt for a filter and act
+ (let* ((tag-list (org-agenda-get-represented-tags))
+ (category-list (org-agenda-get-represented-categories))
+ (negate (equal strip-or-accumulate '(4)))
+ (f-string (completing-read
+ (concat
+ (if negate "Negative filter" "Filter")
+ " [+cat-tag<0:10-/regexp/]: ")
+ 'org-agenda-filter-completion-function))
+ (keep (or (if (string-match "^+[-+]" f-string)
+ (progn (setq f-string (substring f-string 1)) t))
+ (equal strip-or-accumulate '(16))))
+ (fc (if keep org-agenda-category-filter))
+ (ft (if keep org-agenda-tag-filter))
+ (fe (if keep org-agenda-effort-filter))
+ (fr (if keep org-agenda-regexp-filter))
+ pm s)
+ (while (string-match "^[ \t]*\\([-+]\\)?\\(\\([^-+<>=/ \t]+\\)\\|\\([<>=][0-9:]+\\)\\|\\(/\\([^/]+\\)/?\\)\\)" f-string)
+ (setq pm (if (match-beginning 1) (match-string 1 f-string) "+"))
+ (when negate
+ (setq pm (if (equal pm "+") "-" "+")))
+ (cond
+ ((match-beginning 3)
+ ;; category or tag
+ (setq s (match-string 3 f-string))
+ (cond
+ ((member s tag-list)
+ (add-to-list 'ft (concat pm s) 'append 'equal))
+ ((member s category-list)
+ (add-to-list 'fc (concat pm s) 'append 'equal))
+ (t (message
+ "`%s%s' filter ignored because tag/category is not represented"
+ pm s))))
+ ((match-beginning 4)
+ ;; effort
+ (add-to-list 'fe (concat pm (match-string 4 f-string)) t 'equal))
+ ((match-beginning 5)
+ ;; regexp
+ (add-to-list 'fr (concat pm (match-string 6 f-string)) t 'equal)))
+ (setq f-string (substring f-string (match-end 0))))
+ (org-agenda-filter-remove-all)
+ (and fc (org-agenda-filter-apply
+ (setq org-agenda-category-filter fc) 'category))
+ (and ft (org-agenda-filter-apply
+ (setq org-agenda-tag-filter ft) 'tag))
+ (and fe (org-agenda-filter-apply
+ (setq org-agenda-effort-filter fe) 'effort))
+ (and fr (org-agenda-filter-apply
+ (setq org-agenda-regexp-filter fr) 'regexp))
+ )))
+
+(defun org-agenda-filter-completion-function (string _predicate &optional flag)
+ "Complete a complex filter string
+FLAG specifies the type of completion operation to perform. This
+function is passed as a collection function to `completing-read',
+which see."
+ (let ((completion-ignore-case t) ;tags are case-sensitive
+ (confirm (lambda (x) (stringp x)))
+ (prefix "")
+ (operator "")
+ table)
+ (when (string-match "^\\(.*\\([-+<>=]\\)\\)\\([^-+<>=]*\\)$" string)
+ (setq prefix (match-string 1 string)
+ operator (match-string 2 string)
+ string (match-string 3 string)))
+ (cond
+ ((member operator '("+" "-" "" nil))
+ (setq table (append (org-agenda-get-represented-categories)
+ (org-agenda-get-represented-tags))))
+ ((member operator '("<" ">" "="))
+ (setq table (split-string
+ (or (cdr (assoc (concat org-effort-property "_ALL")
+ org-global-properties))
+ "0 0:10 0:30 1:00 2:00 3:00 4:00 5:00 6:00 7:00")
+ " +")))
+ (t (setq table nil)))
+ (pcase flag
+ (`t (all-completions string table confirm))
+ (`lambda (assoc string table)) ;exact match?
+ (`nil
+ (pcase (try-completion string table confirm)
+ ((and completion (pred stringp))
+ (concat prefix completion))
+ (completion completion)))
+ (_ nil))))
(defun org-agenda-filter-remove-all ()
"Remove all filters from the current agenda buffer."
@@ -7514,14 +7762,17 @@ With two prefix arguments, remove the effort filters."
(org-agenda-filter-show-all-effort))
(org-agenda-finalize))
-(defun org-agenda-filter-by-tag (arg &optional char exclude)
+(defun org-agenda-filter-by-tag (strip-or-accumulate &optional char exclude)
"Keep only those lines in the agenda buffer that have a specific tag.
The tag is selected with its fast selection letter, as configured.
-With a `\\[universal-argument]' prefix, exclude the agenda search.
+With a `\\[universal-argument]' prefix, apply the filter negatively, stripping all matches.
-With a `\\[universal-argument] \\[universal-argument]' prefix, filter the literal tag, \
+With a `\\[universal-argument] \\[universal-argument]' prefix, add the new tag to the existing filter
+instead of replacing it.
+
+With a `\\[universal-argument] \\[universal-argument] \\[universal-argument]' prefix, filter the literal tag, \
i.e. don't
filter on all its group members.
@@ -7530,33 +7781,38 @@ should be used to exclude the search - the interactive user can
also press `-' or `+' to switch between filtering and excluding."
(interactive "P")
(let* ((alist org-tag-alist-for-agenda)
+ (seen-chars nil)
(tag-chars (mapconcat
(lambda (x) (if (and (not (symbolp (car x)))
- (cdr x))
- (char-to-string (cdr x))
+ (cdr x)
+ (not (member (cdr x) seen-chars)))
+ (progn
+ (push (cdr x) seen-chars)
+ (char-to-string (cdr x)))
""))
org-tag-alist-for-agenda ""))
- (valid-char-list (append '(?\t ?\r ?/ ?. ?\s ?q)
+ (valid-char-list (append '(?\t ?\r ?\\ ?. ?\s ?q)
(string-to-list tag-chars)))
- (exclude (or exclude (equal arg '(4))))
- (expand (not (equal arg '(16))))
+ (exclude (or exclude (equal strip-or-accumulate '(4))))
+ (accumulate (equal strip-or-accumulate '(16)))
+ (expand (not (equal strip-or-accumulate '(64))))
(inhibit-read-only t)
(current org-agenda-tag-filter)
a n tag)
(unless char
(while (not (memq char valid-char-list))
(org-unlogged-message
- "%s by tag [%s ]:tag-char, [TAB]:tag, %s[/]:off, [+/-]:filter/exclude%s, [q]:quit"
- (if exclude "Exclude" "Filter")
+ "%s by tag%s: [%s ]tag-char [TAB]tag %s[\\]off [q]uit"
+ (if exclude "Exclude[+]" "Filter[-]")
+ (if expand "" " (no grouptag expand)")
tag-chars
- (if org-agenda-auto-exclude-function "[RET], " "")
- (if expand "" ", no grouptag expand"))
+ (if org-agenda-auto-exclude-function "[RET] " ""))
(setq char (read-char-exclusive))
;; Excluding or filtering down
(cond ((eq char ?-) (setq exclude t))
((eq char ?+) (setq exclude nil)))))
(when (eq char ?\t)
- (unless (local-variable-p 'org-global-tags-completion-table (current-buffer))
+ (unless (local-variable-p 'org-global-tags-completion-table)
(setq-local org-global-tags-completion-table
(org-global-tags-completion-table)))
(let ((completion-ignore-case t))
@@ -7573,7 +7829,7 @@ also press `-' or `+' to switch between filtering and excluding."
(push modifier org-agenda-tag-filter))))
(unless (null org-agenda-tag-filter)
(org-agenda-filter-apply org-agenda-tag-filter 'tag expand))))
- ((eq char ?/)
+ ((eq char ?\\)
(org-agenda-filter-show-all-tag)
(when (get 'org-agenda-tag-filter :preset-filter)
(org-agenda-filter-apply org-agenda-tag-filter 'tag expand)))
@@ -7590,21 +7846,36 @@ also press `-' or `+' to switch between filtering and excluding."
(setq tag (car a))
(setq org-agenda-tag-filter
(cons (concat (if exclude "-" "+") tag)
- current))
+ (if accumulate current nil)))
(org-agenda-filter-apply org-agenda-tag-filter 'tag expand))
(t (error "Invalid tag selection character %c" char)))))
-(defun org-agenda-get-represented-tags ()
- "Get a list of all tags currently represented in the agenda."
- (let (p tags)
- (save-excursion
- (goto-char (point-min))
- (while (setq p (next-single-property-change (point) 'tags))
- (goto-char p)
- (mapc (lambda (x) (add-to-list 'tags x))
- (get-text-property (point) 'tags))))
- tags))
+(defun org-agenda-get-represented-categories ()
+ "Return a list of all categories used in this agenda buffer."
+ (or org-agenda-represented-categories
+ (when (derived-mode-p 'org-agenda-mode)
+ (let ((pos (point-min)) categories)
+ (while (and (< pos (point-max))
+ (setq pos (next-single-property-change
+ pos 'org-category nil (point-max))))
+ (push (get-text-property pos 'org-category) categories))
+ (setq org-agenda-represented-categories
+ (nreverse (org-uniquify (delq nil categories))))))))
+(defun org-agenda-get-represented-tags ()
+ "Return a list of all tags used in this agenda buffer.
+These will be lower-case, for filtering."
+ (or org-agenda-represented-tags
+ (when (derived-mode-p 'org-agenda-mode)
+ (let ((pos (point-min)) tags-lists tt)
+ (while (and (< pos (point-max))
+ (setq pos (next-single-property-change
+ pos 'tags nil (point-max))))
+ (setq tt (get-text-property pos 'tags))
+ (if tt (push tt tags-lists)))
+ (setq org-agenda-represented-tags
+ (nreverse (org-uniquify
+ (delq nil (apply 'append tags-lists)))))))))
(defun org-agenda-filter-make-matcher (filter type &optional expand)
"Create the form that tests a line for agenda filter. Optional
@@ -7667,7 +7938,7 @@ function to set the right switches in the returned form."
(dolist (x tags (cons (if (eq op ?-) 'and 'or) form))
(let* ((tag (substring x 1))
(f (cond
- ((string= "" tag) '(not tags))
+ ((string= "" tag) 'tags)
((and (string-match-p "\\`{" tag) (string-match-p "}\\'" tag))
;; TAG is a regexp.
(list 'org-match-any-p (substring tag 1 -1) 'tags))
@@ -7722,7 +7993,8 @@ tags in the FILTER if any of the tags in FILTER are grouptags."
;; Deactivate `org-agenda-entry-text-mode' when filtering
(when org-agenda-entry-text-mode (org-agenda-entry-text-mode))
(let (tags cat txt)
- (setq org-agenda-filter-form (org-agenda-filter-make-matcher filter type expand))
+ (setq org-agenda-filter-form (org-agenda-filter-make-matcher
+ filter type expand))
;; Only set `org-agenda-filtered-by-category' to t when a unique
;; category is used as the filter:
(setq org-agenda-filtered-by-category
@@ -7732,7 +8004,7 @@ tags in the FILTER if any of the tags in FILTER are grouptags."
(save-excursion
(goto-char (point-min))
(while (not (eobp))
- (if (org-get-at-bol 'org-marker)
+ (if (org-get-at-bol 'org-hd-marker)
(progn
(setq tags (org-get-at-bol 'tags)
cat (org-agenda-get-category)
@@ -7775,7 +8047,8 @@ tags in the FILTER if any of the tags in FILTER are grouptags."
(save-excursion
(goto-char (point-min))
(let ((inhibit-read-only t) pos)
- (while (setq pos (text-property-any (point) (point-max) 'org-filter-type type))
+ (while (setq pos (text-property-any (point) (point-max)
+ 'org-filter-type type))
(goto-char pos)
(remove-text-properties
(point) (next-single-property-change (point) 'org-filter-type)
@@ -7912,7 +8185,7 @@ Negative selection means regexp must not match for selection of an entry."
(defun org-agenda-forward-block (&optional backward)
"Move forward by one agenda block.
-When optional argument BACKWARD is set, go backward"
+When optional argument BACKWARD is set, go backward."
(interactive)
(cond ((not (derived-mode-p 'org-agenda-mode))
(user-error
@@ -8307,56 +8580,51 @@ When called with a prefix argument, include all archive files as well."
((eq org-agenda-show-log 'clockcheck) " ClkCk")
(org-agenda-show-log " Log")
(t ""))
+ (if (org-agenda-filter-any) " " "")
(if (or org-agenda-category-filter
(get 'org-agenda-category-filter :preset-filter))
'(:eval (propertize
- (concat " <"
+ (concat "["
(mapconcat
'identity
(append
(get 'org-agenda-category-filter :preset-filter)
org-agenda-category-filter)
"")
- ">")
+ "]")
'face 'org-agenda-filter-category
'help-echo "Category used in filtering")) "")
(if (or org-agenda-tag-filter
(get 'org-agenda-tag-filter :preset-filter))
'(:eval (propertize
- (concat " {"
- (mapconcat
+ (concat (mapconcat
'identity
(append
(get 'org-agenda-tag-filter :preset-filter)
org-agenda-tag-filter)
- "")
- "}")
+ ""))
'face 'org-agenda-filter-tags
'help-echo "Tags used in filtering")) "")
(if (or org-agenda-effort-filter
(get 'org-agenda-effort-filter :preset-filter))
'(:eval (propertize
- (concat " {"
- (mapconcat
+ (concat (mapconcat
'identity
(append
(get 'org-agenda-effort-filter :preset-filter)
org-agenda-effort-filter)
- "")
- "}")
+ ""))
'face 'org-agenda-filter-effort
'help-echo "Effort conditions used in filtering")) "")
(if (or org-agenda-regexp-filter
(get 'org-agenda-regexp-filter :preset-filter))
'(:eval (propertize
- (concat " ["
- (mapconcat
- 'identity
+ (concat (mapconcat
+ (lambda (x) (concat (substring x 0 1) "/" (substring x 1) "/"))
(append
(get 'org-agenda-regexp-filter :preset-filter)
org-agenda-regexp-filter)
- "")
- "]")
+ ""))
'face 'org-agenda-filter-regexp
'help-echo "Regexp used in filtering")) "")
(if org-agenda-archives-mode
@@ -8463,7 +8731,7 @@ Point is in the buffer where the item originated.")
(buffer (marker-buffer marker))
(pos (marker-position marker))
(type (org-get-at-bol 'type))
- dbeg dend (n 0) conf)
+ dbeg dend (n 0))
(org-with-remote-undo buffer
(with-current-buffer buffer
(save-excursion
@@ -8475,14 +8743,20 @@ Point is in the buffer where the item originated.")
dend (min (point-max) (1+ (point-at-eol)))))
(goto-char dbeg)
(while (re-search-forward "^[ \t]*\\S-" dend t) (setq n (1+ n)))))
- (setq conf (or (eq t org-agenda-confirm-kill)
- (and (numberp org-agenda-confirm-kill)
- (> n org-agenda-confirm-kill))))
- (and conf
- (not (y-or-n-p
- (format "Delete entry with %d lines in buffer \"%s\"? "
- n (buffer-name buffer))))
- (error "Abort"))
+ (when (or (eq t org-agenda-confirm-kill)
+ (and (numberp org-agenda-confirm-kill)
+ (> n org-agenda-confirm-kill)))
+ (let ((win-conf (current-window-configuration)))
+ (unwind-protect
+ (and
+ (prog2
+ (org-agenda-tree-to-indirect-buffer nil)
+ (not (y-or-n-p
+ (format "Delete entry with %d lines in buffer \"%s\"? "
+ n (buffer-name buffer))))
+ (kill-buffer org-last-indirect-buffer))
+ (error "Abort"))
+ (set-window-configuration win-conf))))
(let ((org-agenda-buffer-name bufname-orig))
(org-remove-subtree-entries-from-agenda buffer dbeg dend))
(with-current-buffer buffer (delete-region dbeg dend))
@@ -8616,9 +8890,9 @@ It also looks at the text of the entry itself."
((and buffer lk)
(mapcar (lambda(l)
(with-current-buffer buffer
- (setq trg (and (string-match org-bracket-link-regexp l)
+ (setq trg (and (string-match org-link-bracket-re l)
(match-string 1 l)))
- (if (or (not trg) (string-match org-any-link-re trg))
+ (if (or (not trg) (string-match org-link-any-re trg))
(org-with-wide-buffer
(goto-char marker)
(when (search-forward l nil lkend)
@@ -8632,11 +8906,11 @@ It also looks at the text of the entry itself."
(goto-char (match-beginning 0))
(org-open-at-point)))))
lk))
- ((or (org-in-regexp (concat "\\(" org-bracket-link-regexp "\\)"))
+ ((or (org-in-regexp (concat "\\(" org-link-bracket-re "\\)"))
(save-excursion
(beginning-of-line 1)
- (looking-at (concat ".*?\\(" org-bracket-link-regexp "\\)"))))
- (org-open-link-from-string (match-string 1)))
+ (looking-at (concat ".*?\\(" org-link-bracket-re "\\)"))))
+ (org-link-open-from-string (match-string 1)))
(t (message "No link to open here")))))
(defun org-agenda-copy-local-variable (var)
@@ -8654,8 +8928,8 @@ displayed Org file fills the frame."
(interactive)
(if (and org-return-follows-link
(not (org-get-at-bol 'org-marker))
- (org-in-regexp org-bracket-link-regexp))
- (org-open-link-from-string (match-string 0))
+ (org-in-regexp org-link-bracket-re))
+ (org-link-open-from-string (match-string 0))
(let* ((marker (or (org-get-at-bol 'org-marker)
(org-agenda-error)))
(buffer (marker-buffer marker))
@@ -8739,7 +9013,7 @@ if it was hidden in the outline."
(set-window-start (selected-window) (point-at-bol))
(cond
((= more 0)
- (outline-hide-subtree)
+ (org-flag-subtree t)
(save-excursion
(org-back-to-heading)
(run-hook-with-args 'org-cycle-hook 'folded))
@@ -8888,6 +9162,7 @@ the same tree node, and the headline of the tree node in the Org file."
(hdmarker (org-get-at-bol 'org-hd-marker))
(todayp (org-agenda-today-p (org-get-at-bol 'day)))
(inhibit-read-only t)
+ org-loop-over-headlines-in-active-region
org-agenda-headline-snapshot-before-repeat newhead just-one)
(org-with-remote-undo buffer
(with-current-buffer buffer
@@ -8943,7 +9218,7 @@ The new content of the line will be NEWHEAD (as modified by
If FIXFACE is non-nil, the face of each item is modified according to
the new TODO state.
If JUST-THIS is non-nil, change just the current line, not all.
-If FORCE-TAGS is non nil, the car of it returns the new tags."
+If FORCE-TAGS is non-nil, the car of it returns the new tags."
(let* ((inhibit-read-only t)
(line (org-current-line))
(org-agenda-buffer (current-buffer))
@@ -9879,9 +10154,9 @@ The prefix arg is passed through to the command if possible."
;; Prompt for the bulk command.
(org-unlogged-message
- (concat (if org-agenda-persistent-marks "Bulk (persistent): " "Bulk: ")
+ (concat "Bulk (" (if org-agenda-persistent-marks "" "don't ") "[p]ersist marks): "
"[$]arch [A]rch->sib [t]odo [+/-]tag [s]chd [d]eadline [r]efile "
- "[S]catter [f]unction [p]ersist-toggle "
+ "[S]catter [f]unction "
(and org-agenda-bulk-custom-functions
(format " Custom: [%s]"
(mapconcat (lambda (f) (char-to-string (car f)))
@@ -10219,12 +10494,12 @@ to override `appt-message-warning-time'."
(append entries
(apply 'org-agenda-get-day-entries
file today scope)))))
- ;; Map thru entries and find if we should filter them out
+ ;; Map through entries and find if we should filter them out
(mapc
(lambda (x)
(let* ((evt (org-trim
(replace-regexp-in-string
- org-bracket-link-regexp "\\3"
+ org-link-bracket-re "\\2"
(or (get-text-property 1 'txt x) ""))))
(cat (get-text-property (1- (length x)) 'org-category x))
(tod (get-text-property 1 'time-of-day x))
@@ -10256,7 +10531,7 @@ to override `appt-message-warning-time'."
(message "Added %d event%s for today" cnt (if (> cnt 1) "s" "")))))
(defun org-agenda-today-p (date)
- "Non nil when DATE means today.
+ "Non-nil when DATE means today.
DATE is either a list of the form (month day year) or a number of
days as returned by `calendar-absolute-from-gregorian' or
`org-today'. This function considers `org-extend-today-until'
diff --git a/lisp/org-archive.el b/lisp/org-archive.el
index 55c5681..4721ef7 100644
--- a/lisp/org-archive.el
+++ b/lisp/org-archive.el
@@ -450,7 +450,7 @@ Archiving time is retained in the ARCHIVE_TIME node property."
(format-time-string
(substring (cdr org-time-stamp-formats) 1 -1)))
(outline-up-heading 1 t)
- (outline-hide-subtree)
+ (org-flag-subtree t)
(org-cycle-show-empty-lines 'folded)
(when org-provide-todo-statistics
;; Update TODO statistics of parent.
diff --git a/lisp/org-attach-git.el b/lisp/org-attach-git.el
new file mode 100644
index 0000000..525495f
--- /dev/null
+++ b/lisp/org-attach-git.el
@@ -0,0 +1,119 @@
+;;; org-attach-git.el --- Automatic git commit extension to org-attach -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2019 Free Software Foundation, Inc.
+
+;; Original Author: John Wiegley <johnw@newartisans.com>
+;; Restructurer: Gustav Wikström <gustav@whil.se>
+;; Keywords: org data git
+
+;; This file is part of GNU Emacs.
+;;
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; An extension to org-attach. If `org-attach-id-dir' is initialized
+;; as a Git repository, then org-attach-git will automatically commit
+;; changes when it sees them. Requires git-annex.
+
+;;; Code:
+
+(require 'org-attach)
+(require 'vc-git)
+
+(defcustom org-attach-git-annex-cutoff (* 32 1024)
+ "If non-nil, files larger than this will be annexed instead of stored."
+ :group 'org-attach
+ :version "24.4"
+ :package-version '(Org . "8.0")
+ :type '(choice
+ (const :tag "None" nil)
+ (integer :tag "Bytes")))
+
+(defcustom org-attach-git-annex-auto-get 'ask
+ "Confirmation preference for automatically getting annex files.
+If \\='ask, prompt using `y-or-n-p'. If t, always get. If nil, never get."
+ :group 'org-attach
+ :package-version '(Org . "9.0")
+ :version "26.1"
+ :type '(choice
+ (const :tag "confirm with `y-or-n-p'" ask)
+ (const :tag "always get from annex if necessary" t)
+ (const :tag "never get from annex" nil)))
+
+(defun org-attach-git-use-annex ()
+ "Return non-nil if git annex can be used."
+ (let ((git-dir (vc-git-root (expand-file-name org-attach-id-dir))))
+ (and org-attach-git-annex-cutoff
+ (or (file-exists-p (expand-file-name "annex" git-dir))
+ (file-exists-p (expand-file-name ".git/annex" git-dir))))))
+
+(defun org-attach-git-annex-get-maybe (path)
+ "Call git annex get PATH (via shell) if using git annex.
+Signals an error if the file content is not available and it was not retrieved."
+ (let* ((default-directory (expand-file-name org-attach-id-dir))
+ (path-relative (file-relative-name path)))
+ (when (and (org-attach-git-use-annex)
+ (not
+ (string-equal
+ "found"
+ (shell-command-to-string
+ (format "git annex find --format=found --in=here %s"
+ (shell-quote-argument path-relative))))))
+ (let ((should-get
+ (if (eq org-attach-git-annex-auto-get 'ask)
+ (y-or-n-p (format "Run git annex get %s? " path-relative))
+ org-attach-git-annex-auto-get)))
+ (unless should-get
+ (error "File %s stored in git annex but unavailable" path))
+ (message "Running git annex get \"%s\"." path-relative)
+ (call-process "git" nil nil nil "annex" "get" path-relative)))))
+
+(defun org-attach-git-commit (&optional _)
+ "Commit changes to git if `org-attach-id-dir' is properly initialized.
+This checks for the existence of a \".git\" directory in that directory.
+
+Takes an unused optional argument for the sake of being compatible
+with hook `org-attach-after-change-hook'."
+ (let* ((dir (expand-file-name org-attach-id-dir))
+ (git-dir (vc-git-root dir))
+ (use-annex (org-attach-git-use-annex))
+ (changes 0))
+ (when (and git-dir (executable-find "git"))
+ (with-temp-buffer
+ (cd dir)
+ (dolist (new-or-modified
+ (split-string
+ (shell-command-to-string
+ "git ls-files -zmo --exclude-standard") "\0" t))
+ (if (and use-annex
+ (>= (file-attribute-size (file-attributes new-or-modified))
+ org-attach-git-annex-cutoff))
+ (call-process "git" nil nil nil "annex" "add" new-or-modified)
+ (call-process "git" nil nil nil "add" new-or-modified))
+ (cl-incf changes))
+ (dolist (deleted
+ (split-string
+ (shell-command-to-string "git ls-files -z --deleted") "\0" t))
+ (call-process "git" nil nil nil "rm" deleted)
+ (cl-incf changes))
+ (when (> changes 0)
+ (shell-command "git commit -m 'Synchronized attachments'"))))))
+
+(add-hook 'org-attach-after-change-hook 'org-attach-git-commit)
+(add-hook 'org-attach-open-hook 'org-attach-git-annex-get-maybe)
+
+(provide 'org-attach-git)
+
+;;; org-attach-git.el ends here
diff --git a/lisp/org-attach.el b/lisp/org-attach.el
index 4100d6f..bc49be7 100644
--- a/lisp/org-attach.el
+++ b/lisp/org-attach.el
@@ -1,9 +1,9 @@
-;;; org-attach.el --- Manage file attachments to Org tasks -*- lexical-binding: t; -*-
+;;; org-attach.el --- Manage file attachments to Org outlines -*- lexical-binding: t; -*-
;; Copyright (C) 2008-2019 Free Software Foundation, Inc.
;; Author: John Wiegley <johnw@newartisans.com>
-;; Keywords: org data task
+;; Keywords: org data attachment
;; This file is part of GNU Emacs.
;;
@@ -24,32 +24,30 @@
;; See the Org manual for information on how to use it.
;;
-;; Attachments are managed in a special directory called "data", which
-;; lives in the same directory as the org file itself. If this data
-;; directory is initialized as a Git repository, then org-attach will
-;; automatically commit changes when it sees them.
-;;
-;; Attachment directories are identified using a UUID generated for the
-;; task which has the attachments. These are added as property to the
-;; task when necessary, and should not be deleted or changed by the
-;; user, ever. UUIDs are generated by a mechanism defined in the variable
-;; `org-id-method'.
+;; Attachments are managed either by using a custom property DIR or by
+;; using property ID from org-id. When DIR is defined, a location in
+;; the filesystem is directly attached to the outline node. When
+;; org-id is used, attachments are stored in a folder named after the
+;; ID, in a location defined by `org-attach-id-dir'. DIR has
+;; precedence over ID when both parameters are defined for the current
+;; outline node (also when inherited parameters are taken into
+;; account).
;;; Code:
(require 'cl-lib)
(require 'org)
+(require 'ol)
(require 'org-id)
-(require 'vc-git)
(declare-function dired-dwim-target-directory "dired-aux")
(defgroup org-attach nil
- "Options concerning entry attachments in Org mode."
+ "Options concerning attachments in Org mode."
:tag "Org Attach"
:group 'org)
-(defcustom org-attach-directory "data/"
+(defcustom org-attach-id-dir "data/"
"The directory where attachments are stored.
If this is a relative path, it will be interpreted relative to the directory
where the Org file lives."
@@ -57,22 +55,13 @@ where the Org file lives."
:type 'directory
:safe #'stringp)
-(defcustom org-attach-commit t
- "If non-nil commit attachments with git.
-This is only done if the Org file is in a git repository."
+(defcustom org-attach-dir-relative nil
+ "Non-nil means directories in DIR property are added as relative links.
+Defaults to absolute location."
:group 'org-attach
:type 'boolean
- :version "26.1"
- :package-version '(Org . "9.0"))
-
-(defcustom org-attach-git-annex-cutoff (* 32 1024)
- "If non-nil, files larger than this will be annexed instead of stored."
- :group 'org-attach
- :version "24.4"
- :package-version '(Org . "8.0")
- :type '(choice
- (const :tag "None" nil)
- (integer :tag "Bytes")))
+ :package-version '(Org . "9.3")
+ :safe #'booleanp)
(defcustom org-attach-auto-tag "ATTACH"
"Tag that will be triggered automatically when an entry has an attachment."
@@ -81,15 +70,27 @@ This is only done if the Org file is in a git repository."
(const :tag "None" nil)
(string :tag "Tag")))
-(defcustom org-attach-file-list-property "Attachments"
- "The property used to keep a list of attachment belonging to this entry.
-This is not really needed, so you may set this to nil if you don't want it.
-Also, for entries where children inherit the directory, the list of
-attachments is not kept in this property."
+(defcustom org-attach-preferred-new-method 'id
+ "Preferred way to attach to nodes without existing ID and DIR property.
+This choice is used when adding attachments to nodes without ID
+and DIR properties.
+
+Allowed values are:
+
+id Create and use an ID parameter
+dir Create and use a DIR parameter
+ask Ask the user for input of which method to choose
+nil Prefer to not create a new parameter
+
+ nil means that ID or DIR has to be created explicitly
+ before attaching files."
:group 'org-attach
+ :package-version '(org . "9.3")
:type '(choice
- (const :tag "None" nil)
- (string :tag "Tag")))
+ (const :tag "ID parameter" id)
+ (const :tag "DIR parameter" dir)
+ (const :tag "Ask user" ask)
+ (const :tag "Don't create" nil)))
(defcustom org-attach-method 'cp
"The preferred method to attach a file.
@@ -113,14 +114,24 @@ lns create a symbol link. Note that this is not supported
:group 'org-attach
:type 'boolean)
-(defcustom org-attach-allow-inheritance t
- "Non-nil means allow attachment directories be inherited."
+(defcustom org-attach-use-inheritance 'selective
+ "Attachment inheritance for the outline.
+
+Enabling inheritance for org-attach implies two things. First,
+that attachment links will look through all parent headings until
+it finds the linked attachment. Second, that running org-attach
+inside a node without attachments will make org-attach operate on
+the first parent heading it finds with an attachment.
+
+Selective means to respect the inheritance setting in
+`org-use-property-inheritance'."
:group 'org-attach
+ :type '(choice
+ (const :tag "Don't use inheritance" nil)
+ (const :tag "Inherit parent node attachments" t)
+ (const :tag "Respect org-use-property-inheritance" selective))
:type 'boolean)
-(defvar org-attach-inherited nil
- "Indicates if the last access to the attachment directory was inherited.")
-
(defcustom org-attach-store-link-p nil
"Non-nil means store a link to a file when attaching it."
:group 'org-attach
@@ -141,28 +152,108 @@ When set to `query', ask the user instead."
(const :tag "Always delete attachments" t)
(const :tag "Query the user" query)))
-(defcustom org-attach-annex-auto-get 'ask
- "Confirmation preference for automatically getting annex files.
-If \\='ask, prompt using `y-or-n-p'. If t, always get. If nil, never get."
+(defun org-attach-id-uuid-folder-format (id)
+ "Translate an UUID ID into a folder-path.
+Default format for how Org translates ID properties to a path for
+attachments. Useful if ID is generated with UUID."
+ (format "%s/%s"
+ (substring id 0 2)
+ (substring id 2)))
+
+(defun org-attach-id-ts-folder-format (id)
+ "Translate an ID based on a timestamp to a folder-path.
+Useful way of translation if ID is generated based on ISO8601
+timestamp. Splits the attachment folder hierarchy into
+year-month, the rest."
+ (format "%s/%s"
+ (substring id 0 6)
+ (substring id 6)))
+
+(defcustom org-attach-id-to-path-function-list '(org-attach-id-uuid-folder-format
+ org-attach-id-ts-folder-format)
+ "List of functions parsing an ID string into a folder-path.
+The first function in this list defines the preferred function
+which will be used when creating new attachment folders. All
+functions of this list will be tried when looking for existing
+attachment folders based on ID."
:group 'org-attach
- :package-version '(Org . "9.0")
- :version "26.1"
- :type '(choice
- (const :tag "confirm with `y-or-n-p'" ask)
- (const :tag "always get from annex if necessary" t)
- (const :tag "never get from annex" nil)))
+ :package-version '(Org . "9.3")
+ :type '(repeat (function :tag "Function with ID as input")))
+
+(defvar org-attach-after-change-hook nil
+ "Hook to be called when files have been added or removed to the attachment folder.")
+
+(defvar org-attach-open-hook nil
+ "Hook that is invoked by `org-attach-open'.
+
+Created mostly to be compatible with org-attach-git after removing
+git-funtionality from this file.")
+
+(defcustom org-attach-commands
+ '(((?a ?\C-a) org-attach-attach
+ "Select a file and attach it to the task, using `org-attach-method'.")
+ ((?c ?\C-c) org-attach-attach-cp
+ "Attach a file using copy method.")
+ ((?m ?\C-m) org-attach-attach-mv
+ "Attach a file using move method.")
+ ((?l ?\C-l) org-attach-attach-ln
+ "Attach a file using link method.")
+ ((?y ?\C-y) org-attach-attach-lns
+ "Attach a file using symbolic-link method.")
+ ((?u ?\C-u) org-attach-url
+ "Attach a file from URL (downloading it).")
+ ((?b) org-attach-buffer
+ "Select a buffer and attach its contents to the task.")
+ ((?n ?\C-n) org-attach-new
+ "Create a new attachment, as an Emacs buffer.")
+ ((?z ?\C-z) org-attach-sync
+ "Synchronize the current node with its attachment\n directory, in case \
+you added attachments yourself.\n")
+ ((?o ?\C-o) org-attach-open
+ "Open current node's attachments.")
+ ((?O) org-attach-open-in-emacs
+ "Like \"o\", but force opening in Emacs.")
+ ((?f ?\C-f) org-attach-reveal
+ "Open current node's attachment directory. Create if missing.")
+ ((?F) org-attach-reveal-in-emacs
+ "Like \"f\", but force using Dired in Emacs.\n")
+ ((?d ?\C-d) org-attach-delete-one
+ "Delete one attachment, you will be prompted for a file name.")
+ ((?D) org-attach-delete-all
+ "Delete all of a node's attachments. A safer way is\n to open the \
+directory in dired and delete from there.\n")
+ ((?s ?\C-s) org-attach-set-directory
+ "Set a specific attachment directory for this entry. Sets DIR property.")
+ ((?S ?\C-S) org-attach-unset-directory
+ "Unset the attachment directory for this entry. Removes DIR property.")
+ ((?q) (lambda () (interactive) (message "Abort")) "Abort."))
+ "The list of commands for the attachment dispatcher.
+Each entry in this list is a list of three elements:
+- A list of keys (characters) to select the command (the fist
+ character in the list is shown in the attachment dispatcher's
+ splash buffer and minubuffer prompt).
+- A command that is called interactively when one of these keys
+ is pressed.
+- A docstring for this command in the attachment dispatcher's
+ splash buffer."
+ :group 'org-attach
+ :package-version '(Org . "9.3")
+ :type '(repeat (list (repeat :tag "Keys" character)
+ (function :tag "Command")
+ (string :tag "Docstring"))))
;;;###autoload
(defun org-attach ()
"The dispatcher for attachment commands.
Shows a list of commands and prompts for another key to execute a command."
(interactive)
- (let (c marker)
+ (let ((dir (org-attach-dir nil 'no-fs-check))
+ c marker)
(when (eq major-mode 'org-agenda-mode)
(setq marker (or (get-text-property (point) 'org-hd-marker)
(get-text-property (point) 'org-marker)))
(unless marker
- (error "No task in current line")))
+ (error "No item in current line")))
(save-excursion
(when marker
(set-buffer (marker-buffer marker))
@@ -172,201 +263,189 @@ Shows a list of commands and prompts for another key to execute a command."
(save-window-excursion
(unless org-attach-expert
(with-output-to-temp-buffer "*Org Attach*"
- (princ "Select an Attachment Command:
-
-a Select a file and attach it to the task, using `org-attach-method'.
-c/m/l/y Attach a file using copy/move/link/symbolic-link method.
-u Attach a file from URL (downloading it).
-n Create a new attachment, as an Emacs buffer.
-z Synchronize the current task with its attachment
- directory, in case you added attachments yourself.
-
-o Open current task's attachments.
-O Like \"o\", but force opening in Emacs.
-f Open current task's attachment directory.
-F Like \"f\", but force using dired in Emacs.
-
-d Delete one attachment, you will be prompted for a file name.
-D Delete all of a task's attachments. A safer way is
- to open the directory in dired and delete from there.
-
-s Set a specific attachment directory for this entry or reset to default.
-i Make children of the current entry inherit its attachment directory.")))
+ (princ
+ (concat "Attachment folder:\n"
+ (or dir
+ "Can't find an existing attachment-folder")
+ (unless (and dir (file-directory-p dir))
+ "\n(Not yet created)")
+ "\n\n"
+ (format "Select an Attachment Command:\n\n%s"
+ (mapconcat
+ (lambda (entry)
+ (pcase entry
+ (`((,key . ,_) ,_ ,docstring)
+ (format "%c %s"
+ key
+ (replace-regexp-in-string "\n\\([\t ]*\\)"
+ " "
+ docstring
+ nil nil 1)))
+ (_
+ (user-error
+ "Invalid `org-attach-commands' item: %S"
+ entry))))
+ org-attach-commands
+ "\n"))))))
(org-fit-window-to-buffer (get-buffer-window "*Org Attach*"))
- (message "Select command: [acmlyunzoOfFdD]")
+ (message "Select command: [%s]"
+ (concat (mapcar #'caar org-attach-commands)))
(setq c (read-char-exclusive))
(and (get-buffer "*Org Attach*") (kill-buffer "*Org Attach*"))))
- (cond
- ((memq c '(?a ?\C-a)) (call-interactively 'org-attach-attach))
- ((memq c '(?c ?\C-c))
- (let ((org-attach-method 'cp)) (call-interactively 'org-attach-attach)))
- ((memq c '(?m ?\C-m))
- (let ((org-attach-method 'mv)) (call-interactively 'org-attach-attach)))
- ((memq c '(?l ?\C-l))
- (let ((org-attach-method 'ln)) (call-interactively 'org-attach-attach)))
- ((memq c '(?y ?\C-y))
- (let ((org-attach-method 'lns)) (call-interactively 'org-attach-attach)))
- ((memq c '(?u ?\C-u))
- (let ((org-attach-method 'url)) (call-interactively 'org-attach-url)))
- ((memq c '(?n ?\C-n)) (call-interactively 'org-attach-new))
- ((memq c '(?z ?\C-z)) (call-interactively 'org-attach-sync))
- ((memq c '(?o ?\C-o)) (call-interactively 'org-attach-open))
- ((eq c ?O) (call-interactively 'org-attach-open-in-emacs))
- ((memq c '(?f ?\C-f)) (call-interactively 'org-attach-reveal))
- ((memq c '(?F)) (call-interactively 'org-attach-reveal-in-emacs))
- ((memq c '(?d ?\C-d)) (call-interactively
- 'org-attach-delete-one))
- ((eq c ?D) (call-interactively 'org-attach-delete-all))
- ((eq c ?q) (message "Abort"))
- ((memq c '(?s ?\C-s)) (call-interactively
- 'org-attach-set-directory))
- ((memq c '(?i ?\C-i)) (call-interactively
- 'org-attach-set-inherit))
- (t (error "No such attachment command %c" c))))))
-
-(defun org-attach-dir (&optional create-if-not-exists-p)
- "Return the directory associated with the current entry.
-This first checks for a local property ATTACH_DIR, and then for an inherited
-property ATTACH_DIR_INHERIT. If neither exists, the default mechanism
-using the entry ID will be invoked to access the unique directory for the
-current entry.
-If the directory does not exist and CREATE-IF-NOT-EXISTS-P is non-nil,
-the directory and (if necessary) the corresponding ID will be created."
- (let (attach-dir uuid)
- (setq org-attach-inherited (org-entry-get nil "ATTACH_DIR_INHERIT"))
+ (let ((command (cl-some (lambda (entry)
+ (and (memq c (nth 0 entry)) (nth 1 entry)))
+ org-attach-commands)))
+ (if (commandp command t)
+ (call-interactively command)
+ (error "No such attachment command: %c" c))))))
+
+(defun org-attach-dir (&optional create-if-not-exists-p no-fs-check)
+ "Return the directory associated with the current outline node.
+First check for DIR property, then ID property.
+`org-attach-use-inheritance' determines whether inherited
+properties also will be considered.
+
+If an ID property is found the default mechanism using that ID
+will be invoked to access the directory for the current entry.
+Note that this method returns the directory as declared by ID or
+DIR even if the directory doesn't exist in the filesystem.
+
+If CREATE-IF-NOT-EXIST-P is non-nil, `org-attach-dir-get-create'
+is run. If NO-FS-CHECK is non-nil, the function returns the path
+to the attachment even if it has not yet been initialized in the
+filesystem.
+
+If no attachment directory can be derived, return nil."
+ (let (attach-dir id)
(cond
- ((setq attach-dir (org-entry-get nil "ATTACH_DIR"))
+ (create-if-not-exists-p
+ (setq attach-dir (org-attach-dir-get-create)))
+ ((setq attach-dir (org-entry-get nil "DIR" org-attach-use-inheritance))
+ (org-attach-check-absolute-path attach-dir))
+ ;; Deprecated and removed from documentation, but still
+ ;; works. FIXME: Remove after major nr change.
+ ((setq attach-dir (org-entry-get nil "ATTACH_DIR" org-attach-use-inheritance))
(org-attach-check-absolute-path attach-dir))
- ((and org-attach-allow-inheritance
- (org-entry-get nil "ATTACH_DIR_INHERIT" t))
- (setq attach-dir
- (org-with-wide-buffer
- (if (marker-position org-entry-property-inherited-from)
- (goto-char org-entry-property-inherited-from)
- (org-back-to-heading t))
- (let (org-attach-allow-inheritance)
- (org-attach-dir create-if-not-exists-p))))
- (org-attach-check-absolute-path attach-dir)
- (setq org-attach-inherited t))
- (t ; use the ID
+ ((setq id (org-entry-get nil "ID" org-attach-use-inheritance))
(org-attach-check-absolute-path nil)
- (setq uuid (org-id-get (point) create-if-not-exists-p))
- (when (or uuid create-if-not-exists-p)
- (unless uuid (error "ID retrieval/creation failed"))
- (setq attach-dir (expand-file-name
- (format "%s/%s"
- (substring uuid 0 2)
- (substring uuid 2))
- (expand-file-name org-attach-directory))))))
- (when attach-dir
- (if (and create-if-not-exists-p
- (not (file-directory-p attach-dir)))
- (make-directory attach-dir t))
- (and (file-exists-p attach-dir)
- attach-dir))))
+ (setq attach-dir (org-attach-dir-from-id id 'try-all))))
+ (if no-fs-check
+ attach-dir
+ (when (and attach-dir (file-directory-p attach-dir))
+ attach-dir))))
+
+(defun org-attach-dir-get-create ()
+ "Return existing or new directory associated with the current outline node.
+`org-attach-preferred-new-method' decides how to attach new
+directory if neither ID nor DIR property exist.
+
+If the attachment by some reason cannot be created an error will be raised."
+ (interactive)
+ (let ((attach-dir (org-attach-dir nil 'no-fs-check)))
+ (unless attach-dir
+ (let (answer)
+ (when (eq org-attach-preferred-new-method 'ask)
+ (message "Create new ID [1] property or DIR [2] property for attachments?")
+ (setq answer (read-char-exclusive)))
+ (cond
+ ((or (eq org-attach-preferred-new-method 'id) (eq answer ?1))
+ (setq attach-dir (org-attach-dir-from-id (org-id-get nil t))))
+ ((or (eq org-attach-preferred-new-method 'dir) (eq answer ?2))
+ (setq attach-dir (org-attach-set-directory)))
+ ((eq org-attach-preferred-new-method 'nil)
+ (error "No existing directory. DIR or ID property has to be explicitly created")))))
+ (unless attach-dir
+ (error "No attachment directory is associated with the current node"))
+ (unless (file-directory-p attach-dir)
+ (make-directory attach-dir t))
+ attach-dir))
+
+(defun org-attach-dir-from-id (id &optional try-all)
+ "Returns a folder path based on `org-attach-id-dir' and ID.
+If TRY-ALL is non-nil, try all id-to-path functions in
+`org-attach-id-to-path-function-list' and return the first path
+that exist in the filesystem, or the first one if none exist.
+Otherwise only use the first function in that list."
+ (let ((attach-dir-preferred (expand-file-name
+ (funcall (car org-attach-id-to-path-function-list) id)
+ (expand-file-name org-attach-id-dir))))
+ (if try-all
+ (let ((attach-dir attach-dir-preferred)
+ (fun-list (cdr org-attach-id-to-path-function-list)))
+ (while (and fun-list (not (file-directory-p attach-dir)))
+ (setq attach-dir (expand-file-name
+ (funcall (car fun-list) id)
+ (expand-file-name org-attach-id-dir)))
+ (setq fun-list (cdr fun-list)))
+ (if (file-directory-p attach-dir)
+ attach-dir
+ attach-dir-preferred))
+ attach-dir-preferred)))
(defun org-attach-check-absolute-path (dir)
"Check if we have enough information to root the attachment directory.
When DIR is given, check also if it is already absolute. Otherwise,
-assume that it will be relative, and check if `org-attach-directory' is
+assume that it will be relative, and check if `org-attach-id-dir' is
absolute, or if at least the current buffer has a file name.
Throw an error if we cannot root the directory."
(or (and dir (file-name-absolute-p dir))
- (file-name-absolute-p org-attach-directory)
+ (file-name-absolute-p org-attach-id-dir)
(buffer-file-name (buffer-base-buffer))
- (error "Need absolute `org-attach-directory' to attach in buffers without filename")))
+ (error "Need absolute `org-attach-id-dir' to attach in buffers without filename")))
-(defun org-attach-set-directory (&optional arg)
- "Set the ATTACH_DIR node property and ask to move files there.
+(defun org-attach-set-directory ()
+ "Set the DIR node property and ask to move files there.
The property defines the directory that is used for attachments
-of the entry. When called with `\\[universal-argument]', reset \
-the directory to
-the default ID based one."
- (interactive "P")
+of the entry. Creates relative links if `org-attach-dir-relative'
+is non-nil.
+
+Return the directory."
+ (interactive)
(let ((old (org-attach-dir))
- (new
- (progn
- (if arg (org-entry-delete nil "ATTACH_DIR")
- (let ((dir (read-directory-name
- "Attachment directory: "
- (org-entry-get nil
- "ATTACH_DIR"
- (and org-attach-allow-inheritance t)))))
- (org-entry-put nil "ATTACH_DIR" dir)))
- (org-attach-dir t))))
+ (new
+ (let* ((attach-dir (read-directory-name
+ "Attachment directory: "
+ (org-entry-get nil "DIR")))
+ (current-dir (file-name-directory (or default-directory
+ buffer-file-name)))
+ (attach-dir-relative (file-relative-name attach-dir current-dir)))
+ (org-entry-put nil "DIR" (if org-attach-dir-relative
+ attach-dir-relative
+ attach-dir))
+ attach-dir)))
(unless (or (string= old new)
(not old))
(when (yes-or-no-p "Copy over attachments from old directory? ")
+ (copy-directory old new t t t))
+ (when (yes-or-no-p (concat "Delete " old))
+ (delete-directory old t)))
+ new))
+
+(defun org-attach-unset-directory ()
+ "Removes DIR node property.
+If attachment folder is changed due to removal of DIR-property
+ask to move attachments to new location and ask to delete old
+attachment-folder.
+
+Change of attachment-folder due to unset might be if an ID
+property is set on the node, or if a separate inherited
+DIR-property exists (that is different than the unset one)."
+ (interactive)
+ (let ((old (org-attach-dir))
+ (new
+ (progn
+ (org-entry-delete nil "DIR")
+ ;; ATTACH-DIR is deprecated and removed from documentation,
+ ;; but still works. Remove code for it after major nr change.
+ (org-entry-delete nil "ATTACH_DIR")
+ (org-attach-dir))))
+ (unless (or (string= old new)
+ (not old))
+ (when (and new (yes-or-no-p "Copy over attachments from old directory? "))
(copy-directory old new t nil t))
(when (yes-or-no-p (concat "Delete " old))
(delete-directory old t)))))
-(defun org-attach-set-inherit ()
- "Set the ATTACH_DIR_INHERIT property of the current entry.
-The property defines the directory that is used for attachments
-of the entry and any children that do not explicitly define (by setting
-the ATTACH_DIR property) their own attachment directory."
- (interactive)
- (org-entry-put nil "ATTACH_DIR_INHERIT" "t")
- (message "Children will inherit attachment directory"))
-
-(defun org-attach-use-annex ()
- "Return non-nil if git annex can be used."
- (let ((git-dir (vc-git-root (expand-file-name org-attach-directory))))
- (and org-attach-git-annex-cutoff
- (or (file-exists-p (expand-file-name "annex" git-dir))
- (file-exists-p (expand-file-name ".git/annex" git-dir))))))
-
-(defun org-attach-annex-get-maybe (path)
- "Call git annex get PATH (via shell) if using git annex.
-Signals an error if the file content is not available and it was not retrieved."
- (let* ((default-directory (expand-file-name org-attach-directory))
- (path-relative (file-relative-name path)))
- (when (and (org-attach-use-annex)
- (not
- (string-equal
- "found"
- (shell-command-to-string
- (format "git annex find --format=found --in=here %s"
- (shell-quote-argument path-relative))))))
- (let ((should-get
- (if (eq org-attach-annex-auto-get 'ask)
- (y-or-n-p (format "Run git annex get %s? " path-relative))
- org-attach-annex-auto-get)))
- (if should-get
- (progn (message "Running git annex get \"%s\"." path-relative)
- (call-process "git" nil nil nil "annex" "get" path-relative))
- (error "File %s stored in git annex but it is not available, and was not retrieved"
- path))))))
-
-(defun org-attach-commit ()
- "Commit changes to git if `org-attach-directory' is properly initialized.
-This checks for the existence of a \".git\" directory in that directory."
- (let* ((dir (expand-file-name org-attach-directory))
- (git-dir (vc-git-root dir))
- (use-annex (org-attach-use-annex))
- (changes 0))
- (when (and git-dir (executable-find "git"))
- (with-temp-buffer
- (cd dir)
- (dolist (new-or-modified
- (split-string
- (shell-command-to-string
- "git ls-files -zmo --exclude-standard") "\0" t))
- (if (and use-annex
- (>= (file-attribute-size (file-attributes new-or-modified))
- org-attach-git-annex-cutoff))
- (call-process "git" nil nil nil "annex" "add" new-or-modified)
- (call-process "git" nil nil nil "add" new-or-modified))
- (cl-incf changes))
- (dolist (deleted
- (split-string
- (shell-command-to-string "git ls-files -z --deleted") "\0" t))
- (call-process "git" nil nil nil "rm" deleted)
- (cl-incf changes))
- (when (> changes 0)
- (shell-command "git commit -m 'Synchronized attachments'"))))))
-
(defun org-attach-tag (&optional off)
"Turn the autotag on or (if OFF is set) off."
(when org-attach-auto-tag
@@ -388,10 +467,25 @@ Only do this when `org-attach-store-link-p' is non-nil."
(defun org-attach-url (url)
(interactive "MURL of the file to attach: \n")
- (org-attach-attach url))
+ (let ((org-attach-method 'url))
+ (org-attach-attach url)))
+
+(defun org-attach-buffer (buffer-name)
+ "Attach BUFFER-NAME's contents to current outline node.
+BUFFER-NAME is a string. Signals a `file-already-exists' error
+if it would overwrite an existing filename."
+ (interactive "bBuffer whose contents should be attached: ")
+ (let* ((attach-dir (org-attach-dir 'get-create))
+ (output (expand-file-name buffer-name attach-dir)))
+ (when (file-exists-p output)
+ (signal 'file-already-exists (list "File exists" output)))
+ (run-hook-with-args 'org-attach-after-change-hook attach-dir)
+ (org-attach-tag)
+ (with-temp-file output
+ (insert-buffer-substring buffer-name))))
(defun org-attach-attach (file &optional visit-dir method)
- "Move/copy/link FILE into the attachment directory of the current task.
+ "Move/copy/link FILE into the attachment directory of the current outline node.
If VISIT-DIR is non-nil, visit the directory with dired.
METHOD may be `cp', `mv', `ln', `lns' or `url' default taken from
`org-attach-method'."
@@ -406,10 +500,7 @@ METHOD may be `cp', `mv', `ln', `lns' or `url' default taken from
nil))
(setq method (or method org-attach-method))
(let ((basename (file-name-nondirectory file)))
- (when (and org-attach-file-list-property (not org-attach-inherited))
- (org-entry-add-to-multivalued-property
- (point) org-attach-file-list-property basename))
- (let* ((attach-dir (org-attach-dir t))
+ (let* ((attach-dir (org-attach-dir 'get-create))
(fname (expand-file-name basename attach-dir)))
(cond
((eq method 'mv) (rename-file file fname))
@@ -417,8 +508,7 @@ METHOD may be `cp', `mv', `ln', `lns' or `url' default taken from
((eq method 'ln) (add-name-to-file file fname))
((eq method 'lns) (make-symbolic-link file fname))
((eq method 'url) (url-copy-file file fname)))
- (when org-attach-commit
- (org-attach-commit))
+ (run-hook-with-args 'org-attach-after-change-hook attach-dir)
(org-attach-tag)
(cond ((eq org-attach-store-link-p 'attached)
(org-attach-store-link fname))
@@ -426,7 +516,7 @@ METHOD may be `cp', `mv', `ln', `lns' or `url' default taken from
(org-attach-store-link file)))
(if visit-dir
(dired attach-dir)
- (message "File %S is now a task attachment." basename)))))
+ (message "File %S is now an attachment." basename)))))
(defun org-attach-attach-cp ()
"Attach a file by copying it."
@@ -451,13 +541,10 @@ On some systems, this apparently does copy the file instead."
(let ((org-attach-method 'lns)) (call-interactively 'org-attach-attach)))
(defun org-attach-new (file)
- "Create a new attachment FILE for the current task.
+ "Create a new attachment FILE for the current outline node.
The attachment is created as an Emacs buffer."
(interactive "sCreate attachment named: ")
- (when (and org-attach-file-list-property (not org-attach-inherited))
- (org-entry-add-to-multivalued-property
- (point) org-attach-file-list-property file))
- (let ((attach-dir (org-attach-dir t)))
+ (let ((attach-dir (org-attach-dir 'get-create)))
(org-attach-tag)
(find-file (expand-file-name file attach-dir))
(message "New attachment %s" file)))
@@ -465,7 +552,7 @@ The attachment is created as an Emacs buffer."
(defun org-attach-delete-one (&optional file)
"Delete a single attachment."
(interactive)
- (let* ((attach-dir (org-attach-dir t))
+ (let* ((attach-dir (org-attach-dir))
(files (org-attach-file-list attach-dir))
(file (or file
(completing-read
@@ -477,44 +564,32 @@ The attachment is created as an Emacs buffer."
(unless (file-exists-p file)
(error "No such attachment: %s" file))
(delete-file file)
- (when org-attach-commit
- (org-attach-commit))))
+ (run-hook-with-args 'org-attach-after-change-hook attach-dir)))
(defun org-attach-delete-all (&optional force)
- "Delete all attachments from the current task.
+ "Delete all attachments from the current outline node.
This actually deletes the entire attachment directory.
A safer way is to open the directory in dired and delete from there."
(interactive "P")
- (when (and org-attach-file-list-property (not org-attach-inherited))
- (org-entry-delete (point) org-attach-file-list-property))
(let ((attach-dir (org-attach-dir)))
- (when
- (and attach-dir
- (or force
- (y-or-n-p "Are you sure you want to remove all attachments of this entry? ")))
- (shell-command (format "rm -fr %s" attach-dir))
+ (when (and attach-dir
+ (or force
+ (yes-or-no-p "Really remove all attachments of this entry? ")))
+ (delete-directory attach-dir (yes-or-no-p "Recursive?") t)
(message "Attachment directory removed")
- (when org-attach-commit
- (org-attach-commit))
+ (run-hook-with-args 'org-attach-after-change-hook attach-dir)
(org-attach-untag))))
(defun org-attach-sync ()
- "Synchronize the current tasks with its attachments.
+ "Synchronize the current outline node with its attachments.
This can be used after files have been added externally."
(interactive)
- (when org-attach-commit
- (org-attach-commit))
- (when (and org-attach-file-list-property (not org-attach-inherited))
- (org-entry-delete (point) org-attach-file-list-property))
(let ((attach-dir (org-attach-dir)))
(when attach-dir
+ (run-hook-with-args 'org-attach-after-change-hook attach-dir)
(let ((files (org-attach-file-list attach-dir)))
- (org-attach-tag (not files))
- (when org-attach-file-list-property
- (dolist (file files)
- (unless (string-match "^\\.\\.?\\'" file)
- (org-entry-add-to-multivalued-property
- (point) org-attach-file-list-property file))))))))
+ (org-attach-tag (not files))))
+ (unless attach-dir (org-attach-tag t))))
(defun org-attach-file-list (dir)
"Return a list of files in the attachment directory.
@@ -523,35 +598,38 @@ This ignores files ending in \"~\"."
(mapcar (lambda (x) (if (string-match "^\\.\\.?\\'" x) nil x))
(directory-files dir nil "[^~]\\'"))))
-(defun org-attach-reveal (&optional if-exists)
- "Show the attachment directory of the current task.
-This will attempt to use an external program to show the directory."
- (interactive "P")
- (let ((attach-dir (org-attach-dir (not if-exists))))
- (and attach-dir (org-open-file attach-dir))))
+(defun org-attach-reveal ()
+ "Show the attachment directory of the current outline node.
+This will attempt to use an external program to show the
+directory. Will create an attachment and folder if it doesn't
+exist yet. Respects `org-attach-preferred-new-method'."
+ (interactive)
+ (org-open-file (org-attach-dir-get-create)))
(defun org-attach-reveal-in-emacs ()
- "Show the attachment directory of the current task in dired."
+ "Show the attachment directory of the current outline node in dired.
+Will create an attachment and folder if it doesn't exist yet.
+Respects `org-attach-preferred-new-method'."
(interactive)
- (let ((attach-dir (org-attach-dir t)))
- (dired attach-dir)))
+ (dired (org-attach-dir-get-create)))
(defun org-attach-open (&optional in-emacs)
- "Open an attachment of the current task.
+ "Open an attachment of the current outline node.
If there are more than one attachment, you will be prompted for the file name.
This command will open the file using the settings in `org-file-apps'
and in the system-specific variants of this variable.
If IN-EMACS is non-nil, force opening in Emacs."
(interactive "P")
- (let* ((attach-dir (org-attach-dir t))
- (files (org-attach-file-list attach-dir))
- (file (if (= (length files) 1)
- (car files)
- (completing-read "Open attachment: "
- (mapcar #'list files) nil t)))
- (path (expand-file-name file attach-dir)))
- (org-attach-annex-get-maybe path)
- (org-open-file path in-emacs)))
+ (let ((attach-dir (org-attach-dir)))
+ (if attach-dir
+ (let* ((file (pcase (org-attach-file-list attach-dir)
+ (`(,file) file)
+ (files (completing-read "Open attachment: "
+ (mapcar #'list files) nil t))))
+ (path (expand-file-name file attach-dir)))
+ (run-hook-with-args 'org-attach-open-hook path)
+ (org-open-file path in-emacs))
+ (error "No attachment directory exist"))))
(defun org-attach-open-in-emacs ()
"Open attachment, force opening in Emacs.
@@ -570,6 +648,69 @@ Basically, this adds the path to the attachment directory, and a \"file:\"
prefix."
(concat "file:" (org-attach-expand file)))
+(org-link-set-parameters "attachment"
+ :follow #'org-attach-open-link
+ :export #'org-attach-export-link
+ :complete #'org-attach-complete-link)
+
+(defun org-attach-open-link (link &optional in-emacs)
+ "Attachment link type LINK is expanded with the attached directory and opened.
+
+With optional prefix argument IN-EMACS, Emacs will visit the file.
+With a double \\[universal-argument] \\[universal-argument] \
+prefix arg, Org tries to avoid opening in Emacs
+and to use an external application to visit the file."
+ (interactive "P")
+ (let (line search)
+ (cond
+ ((string-match "::\\([0-9]+\\)\\'" link)
+ (setq line (string-to-number (match-string 1 link))
+ link (substring link 0 (match-beginning 0))))
+ ((string-match "::\\(.+\\)\\'" link)
+ (setq search (match-string 1 link)
+ link (substring link 0 (match-beginning 0)))))
+ (if (string-match "[*?{]" (file-name-nondirectory link))
+ (dired (org-attach-expand link))
+ (org-open-file (org-attach-expand link) in-emacs line search))))
+
+(defun org-attach-complete-link ()
+ "Advise the user with the available files in the attachment directory."
+ (let ((attach-dir (org-attach-dir)))
+ (if attach-dir
+ (let* ((attached-dir (expand-file-name attach-dir))
+ (file (read-file-name "File: " attached-dir))
+ (pwd (file-name-as-directory attached-dir))
+ (pwd-relative (file-name-as-directory
+ (abbreviate-file-name attached-dir))))
+ (cond
+ ((string-match (concat "^" (regexp-quote pwd-relative) "\\(.+\\)") file)
+ (concat "attachment:" (match-string 1 file)))
+ ((string-match (concat "^" (regexp-quote pwd) "\\(.+\\)")
+ (expand-file-name file))
+ (concat "attachment:" (match-string 1 (expand-file-name file))))
+ (t (concat "attachment:" file))))
+ (error "No attachment directory exist"))))
+
+(defun org-attach-export-link (link description format)
+ "Translate attachment LINK from Org mode format to exported FORMAT.
+Also includes the DESCRIPTION of the link in the export."
+ (save-excursion
+ (let (path desc)
+ (cond
+ ((string-match "::\\([0-9]+\\)\\'" link)
+ (setq link (substring link 0 (match-beginning 0))))
+ ((string-match "::\\(.+\\)\\'" link)
+ (setq link (substring link 0 (match-beginning 0)))))
+ (setq path (file-relative-name (org-attach-expand link))
+ desc (or description link))
+ (pcase format
+ (`html (format "<a target=\"_blank\" href=\"%s\">%s</a>" path desc))
+ (`latex (format "\\href{%s}{%s}" path desc))
+ (`texinfo (format "@uref{%s,%s}" path desc))
+ (`ascii (format "%s (%s)" desc path))
+ (`md (format "[%s](%s)" desc path))
+ (_ path)))))
+
(defun org-attach-archive-delete-maybe ()
"Maybe delete subtree attachments when archiving.
This function is called by `org-archive-hook'. The option
@@ -597,7 +738,7 @@ Idea taken from `gnus-dired-attach'."
(interactive
(list (dired-get-marked-files)))
(unless (eq major-mode 'dired-mode)
- (user-error "This command must be triggered in a dired buffer."))
+ (user-error "This command must be triggered in a dired buffer"))
(let ((start-win (selected-window))
(other-win
(get-window-with-predicate
@@ -610,7 +751,9 @@ Idea taken from `gnus-dired-attach'."
(select-window other-win)
(dolist (file files)
(org-attach-attach file))
- (select-window start-win)))
+ (select-window start-win)
+ (when (eq 'mv org-attach-method)
+ (revert-buffer))))
diff --git a/lisp/org-capture.el b/lisp/org-capture.el
index d24045f..4f97e17 100644
--- a/lisp/org-capture.el
+++ b/lisp/org-capture.el
@@ -51,10 +51,16 @@
(require 'org)
(declare-function org-at-encrypted-entry-p "org-crypt" ())
+(declare-function org-at-table-p "org-table" (&optional table-type))
(declare-function org-clock-update-mode-line "org-clock" (&optional refresh))
(declare-function org-datetree-find-date-create "org-datetree" (date &optional keep-restriction))
(declare-function org-decrypt-entry "org-crypt" ())
+(declare-function org-element-at-point "org-element" ())
+(declare-function org-element-lineage "org-element" (datum &optional types with-self))
+(declare-function org-element-property "org-element" (property element))
(declare-function org-encrypt-entry "org-crypt" ())
+(declare-function org-insert-link "ol" (&optional complete-file link-location default-description))
+(declare-function org-link-make-string "ol" (link &optional description))
(declare-function org-table-analyze "org-table" ())
(declare-function org-table-current-dline "org-table" ())
(declare-function org-table-fix-formulas "org-table" (key replace &optional limit delta remove))
@@ -64,9 +70,12 @@
(defvar org-end-time-was-given)
(defvar org-remember-default-headline)
(defvar org-remember-templates)
+(defvar org-store-link-plist)
(defvar org-table-border-regexp)
(defvar org-table-current-begin-pos)
+(defvar org-table-dataline-regexp)
(defvar org-table-fix-formulas-confirm)
+(defvar org-table-hline-regexp)
(defvar org-table-hlines)
(defvar org-capture-clock-was-started nil
@@ -654,10 +663,9 @@ of the day at point (if any) or the current HH:MM time."
:annotation annotation
:initial initial
:return-to-wconf (current-window-configuration)
- :default-time
- (or org-overriding-default-time
- (org-current-time)))
- (org-capture-set-target-location)
+ :default-time (or org-overriding-default-time
+ (org-current-time)))
+ (org-capture-set-target-location (and (equal goto 0) 'here))
(condition-case error
(org-capture-put :template (org-capture-fill-template))
((error quit)
@@ -665,31 +673,28 @@ of the day at point (if any) or the current HH:MM time."
(error "Capture abort: %s" (error-message-string error))))
(setq org-capture-clock-keep (org-capture-get :clock-keep))
- (if (equal goto 0)
- ;;insert at point
- (org-capture-insert-template-here)
- (condition-case error
- (org-capture-place-template
- (eq (car (org-capture-get :target)) 'function))
- ((error quit)
- (when (and (buffer-base-buffer (current-buffer))
- (string-prefix-p "CAPTURE-" (buffer-name)))
- (kill-buffer (current-buffer)))
- (set-window-configuration (org-capture-get :return-to-wconf))
- (error "Capture template `%s': %s"
- (org-capture-get :key)
- (error-message-string error))))
- (when (and (derived-mode-p 'org-mode) (org-capture-get :clock-in))
- (condition-case nil
- (progn
- (when (org-clock-is-active)
- (org-capture-put :interrupted-clock
- (copy-marker org-clock-marker)))
- (org-clock-in)
- (setq-local org-capture-clock-was-started t))
- (error "Could not start the clock in this capture buffer")))
- (when (org-capture-get :immediate-finish)
- (org-capture-finalize)))))))))
+ (condition-case error
+ (org-capture-place-template
+ (eq (car (org-capture-get :target)) 'function))
+ ((error quit)
+ (when (and (buffer-base-buffer (current-buffer))
+ (string-prefix-p "CAPTURE-" (buffer-name)))
+ (kill-buffer (current-buffer)))
+ (set-window-configuration (org-capture-get :return-to-wconf))
+ (error "Capture template `%s': %s"
+ (org-capture-get :key)
+ (error-message-string error))))
+ (when (and (derived-mode-p 'org-mode) (org-capture-get :clock-in))
+ (condition-case nil
+ (progn
+ (when (org-clock-is-active)
+ (org-capture-put :interrupted-clock
+ (copy-marker org-clock-marker)))
+ (org-clock-in)
+ (setq-local org-capture-clock-was-started t))
+ (error "Could not start the clock in this capture buffer")))
+ (when (org-capture-get :immediate-finish)
+ (org-capture-finalize))))))))
(defun org-capture-get-template ()
"Get the template from a file or a function if necessary."
@@ -918,6 +923,8 @@ Store them in the capture property list."
(let ((target-entry-p t))
(save-excursion
(pcase (or target (org-capture-get :target))
+ (`here
+ (org-capture-put :exact-position (point) :insert-here t))
(`(file ,path)
(set-buffer (org-capture-target-buffer path))
(org-capture-put-target-region-and-position)
@@ -1115,11 +1122,14 @@ may have been stored before."
"Place the template as a new Org entry."
(let ((template (org-capture-get :template))
(reversed? (org-capture-get :prepend))
+ (exact-position (org-capture-get :exact-position))
+ (insert-here? (org-capture-get :insert-here))
(level 1))
(org-capture-verify-tree template)
- (when (org-capture-get :exact-position)
- (goto-char (org-capture-get :exact-position)))
+ (when exact-position (goto-char exact-position))
(cond
+ ;; Force insertion at point.
+ ((org-capture-get :insert-here) nil)
;; Insert as a child of the current entry.
((org-capture-get :target-entry-p)
(setq level (org-get-valid-level
@@ -1136,7 +1146,9 @@ may have been stored before."
(unless (bolp) (insert "\n"))
(org-capture-empty-lines-before)
(let ((beg (point)))
- (org-paste-subtree level template 'for-yank)
+ (save-restriction
+ (when insert-here? (narrow-to-region beg beg))
+ (org-paste-subtree level template 'for-yank))
(org-capture-position-for-last-stored beg)
(let ((end (if (org-at-heading-p) (line-end-position 0) (point))))
(org-capture-empty-lines-after)
@@ -1163,10 +1175,11 @@ may have been stored before."
(cond ((org-capture-get :exact-position)
;; User gave a specific position. Start
;; looking for lists from here.
- (cons (save-excursion
- (goto-char (org-capture-get :exact-position))
- (line-beginning-position))
- (org-entry-end-position)))
+ (org-with-point-at (org-capture-get :exact-position)
+ (cons (line-beginning-position)
+ (if (org-capture-get :insert-here)
+ (line-beginning-position)
+ (org-entry-end-position)))))
((org-capture-get :target-entry-p)
;; At a heading, limit search to its body.
(cons (line-beginning-position 2)
@@ -1189,7 +1202,8 @@ may have been stored before."
;; No list found. Move to the location when to insert
;; template. Skip planning info and properties drawers, if
;; any.
- (goto-char (cond ((not prepend?) end)
+ (goto-char (cond ((org-capture-get :insert-here) beg)
+ ((not prepend?) end)
((org-before-first-heading-p) beg)
(t (max (save-excursion
(org-end-of-meta-data)
@@ -1271,8 +1285,10 @@ may have been stored before."
beg end)
(cond
((org-capture-get :exact-position)
- (setq beg (org-capture-get :exact-position))
- (setq end (save-excursion (outline-next-heading) (point))))
+ (org-with-point-at (org-capture-get :exact-position)
+ (setq beg (line-beginning-position))
+ (setq end (if (org-capture-get :insert-here) beg
+ (org-entry-end-position)))))
((not (org-capture-get :target-entry-p))
;; Table is not necessarily under a heading. Find first table
;; in the buffer.
@@ -1298,10 +1314,11 @@ may have been stored before."
(goto-char end)
(unless (bolp) (insert "\n"))
(let ((origin (point)))
- (insert "| |\n|----|\n")
+ (insert "| |\n|---|\n")
(narrow-to-region origin (point))))
;; In the current table, find the appropriate location for TEXT.
(cond
+ ((org-capture-get :insert-here) nil)
((and table-line-pos
(string-match "\\(I+\\)\\([-+][0-9]+\\)" table-line-pos))
(goto-char (point-min))
@@ -1447,44 +1464,6 @@ Point will remain at the first line after the inserted text."
(defvar org-clock-marker) ; Defined in org.el
-(defun org-capture-insert-template-here ()
- "Insert the capture template at point."
- (let* ((template (org-capture-get :template))
- (type (org-capture-get :type))
- beg end pp)
- (unless (bolp) (insert "\n"))
- (setq beg (point))
- (cond
- ((and (eq type 'entry) (derived-mode-p 'org-mode))
- (org-capture-verify-tree (org-capture-get :template))
- (org-paste-subtree nil template t))
- ((and (memq type '(item checkitem))
- (derived-mode-p 'org-mode)
- (save-excursion (skip-chars-backward " \t\n")
- (setq pp (point))
- (org-in-item-p)))
- (goto-char pp)
- (org-insert-item)
- (skip-chars-backward " ")
- (skip-chars-backward "-+*0123456789).")
- (delete-region (point) (point-at-eol))
- (setq beg (point))
- (org-remove-indentation template)
- (insert template)
- (org-capture-empty-lines-after)
- (goto-char beg)
- (org-list-repair)
- (org-end-of-item))
- (t
- (insert template)
- (org-capture-empty-lines-after)
- (skip-chars-forward " \t\n")
- (unless (eobp) (beginning-of-line))))
- (setq end (point))
- (goto-char beg)
- (when (re-search-forward "%\\?" end t)
- (replace-match ""))))
-
(defun org-capture-set-plist (entry)
"Initialize the property list from the template definition."
(setq org-capture-plist (copy-sequence (nthcdr 5 entry)))
@@ -1592,14 +1571,14 @@ The template may still contain \"%?\" for cursor positioning."
(replace-match "[[\\1][%^{Link description}]]" nil nil v-a)
v-a))
(v-l (if (and v-a (string-match l-re v-a))
- (replace-match "\\1" nil nil v-a)
+ (replace-match "[[\\1]]" nil nil v-a)
v-a))
(v-n user-full-name)
(v-k (if (marker-buffer org-clock-marker)
(org-no-properties org-clock-heading)
""))
(v-K (if (marker-buffer org-clock-marker)
- (org-make-link-string
+ (org-link-make-string
(format "%s::*%s"
(buffer-file-name (marker-buffer org-clock-marker))
v-k)
diff --git a/lisp/org-clock.el b/lisp/org-clock.el
index d0548d0..df4ba62 100644
--- a/lisp/org-clock.el
+++ b/lisp/org-clock.el
@@ -35,13 +35,17 @@
(declare-function notifications-notify "notifications" (&rest params))
(declare-function org-element-property "org-element" (property element))
(declare-function org-element-type "org-element" (element))
+(declare-function org-link-display-format "ol" (s))
+(declare-function org-link-heading-search-string "ol" (&optional string))
+(declare-function org-link-make-string "ol" (link &optional description))
(declare-function org-table-goto-line "org-table" (n))
+(declare-function org-dynamic-block-define "org" (type func))
-(defvar org-frame-title-format-backup frame-title-format)
+(defvar org-frame-title-format-backup nil)
(defvar org-state)
+(defvar org-link-bracket-re)
(defvar org-time-stamp-formats)
-
(defgroup org-clock nil
"Options concerning clocking working time in Org mode."
:tag "Org Clock"
@@ -303,6 +307,7 @@ string as argument."
:link nil
:narrow '40!
:indent t
+ :hidefiles nil
:formula nil
:timestamp nil
:level nil
@@ -524,8 +529,7 @@ cannot be translated."
(cond ((functionp org-clock-heading-function)
(funcall org-clock-heading-function))
((org-before-first-heading-p) "???")
- (t (replace-regexp-in-string
- org-bracket-link-analytic-regexp "\\5"
+ (t (org-link-display-format
(org-no-properties (org-get-heading t t t t))))))
(defun org-clock-menu ()
@@ -1352,6 +1356,7 @@ the default behavior."
;; add to frame title
(when (or (eq org-clock-clocked-in-display 'frame-title)
(eq org-clock-clocked-in-display 'both))
+ (setq org-frame-title-format-backup frame-title-format)
(setq frame-title-format org-clock-frame-title-format))
(org-clock-update-mode-line)
(when org-clock-mode-line-timer
@@ -1542,6 +1547,14 @@ line and position cursor in that line."
(org-log-states-order-reversed (goto-char (car (last positions))))
(t (goto-char (car positions))))))))
+(defun org-clock-restore-frame-title-format ()
+ "Restore `frame-title-format' from `org-frame-title-format-backup'.
+`frame-title-format' is restored if `org-frame-title-format-backup' is not nil
+and current `frame-title-format' is equal to `org-clock-frame-title-format'."
+ (when (and org-frame-title-format-backup
+ (equal frame-title-format org-clock-frame-title-format))
+ (setq frame-title-format org-frame-title-format-backup)))
+
;;;###autoload
(defun org-clock-out (&optional switch-to-state fail-quietly at-time)
"Stop the currently running clock.
@@ -1553,7 +1566,7 @@ to, overriding the existing value of `org-clock-out-switch-to-state'."
(when (not (org-clocking-p))
(setq global-mode-string
(delq 'org-mode-line-string global-mode-string))
- (setq frame-title-format org-frame-title-format-backup)
+ (org-clock-restore-frame-title-format)
(force-mode-line-update)
(if fail-quietly (throw 'exit t) (user-error "No active clock")))
(let ((org-clock-out-switch-to-state
@@ -1609,7 +1622,7 @@ to, overriding the existing value of `org-clock-out-switch-to-state'."
(setq org-clock-idle-timer nil))
(setq global-mode-string
(delq 'org-mode-line-string global-mode-string))
- (setq frame-title-format org-frame-title-format-backup)
+ (org-clock-restore-frame-title-format)
(when org-clock-out-switch-to-state
(save-excursion
(org-back-to-heading t)
@@ -1709,7 +1722,7 @@ Optional argument N tells to change by that many units."
(when (not (org-clocking-p))
(setq global-mode-string
(delq 'org-mode-line-string global-mode-string))
- (setq frame-title-format org-frame-title-format-backup)
+ (org-clock-restore-frame-title-format)
(force-mode-line-update)
(error "No active clock"))
(save-excursion ; Do not replace this with `with-current-buffer'.
@@ -1723,9 +1736,10 @@ Optional argument N tells to change by that many units."
(sit-for 2)))
(move-marker org-clock-marker nil)
(move-marker org-clock-hd-marker nil)
+ (setq org-clock-current-task nil)
(setq global-mode-string
(delq 'org-mode-line-string global-mode-string))
- (setq frame-title-format org-frame-title-format-backup)
+ (org-clock-restore-frame-title-format)
(force-mode-line-update)
(message "Clock canceled")
(run-hooks 'org-clock-cancel-hook))
@@ -2053,8 +2067,10 @@ in the buffer and update it."
(start (goto-char start)))
(org-update-dblock))
+(org-dynamic-block-define "clocktable" #'org-clock-report)
+
(defun org-day-of-week (day month year)
- "Returns the day of the week as an integer."
+ "Return the day of the week as an integer."
(nth 6
(decode-time
(date-to-time
@@ -2391,6 +2407,7 @@ the currently selected interval size."
(ws (plist-get params :wstart))
(ms (plist-get params :mstart))
(step (plist-get params :step))
+ (hide-files (plist-get params :hidefiles))
(formatter (or (plist-get params :formatter)
org-clock-clocktable-formatter
'org-clocktable-write-default))
@@ -2445,7 +2462,9 @@ the currently selected interval size."
;; Even though `file-with-archives' can consist of
;; multiple files, we consider this is one extended file
;; instead.
- (and (consp files) (not (eq scope 'file-with-archives)))))
+ (and (not hide-files)
+ (consp files)
+ (not (eq scope 'file-with-archives)))))
(funcall formatter
origin
@@ -2616,12 +2635,12 @@ from the dynamic block definition."
(when narrow-cut-p
(setq headline
(if (and (string-match
- (format "\\`%s\\'" org-bracket-link-regexp)
+ (format "\\`%s\\'" org-link-bracket-re)
headline)
- (match-end 3))
+ (match-end 2))
(format "[[%s][%s]]"
(match-string 1 headline)
- (org-shorten-string (match-string 3 headline)
+ (org-shorten-string (match-string 2 headline)
narrow))
(org-shorten-string headline narrow))))
(cl-flet ((format-field (f) (format (cond ((not emph) "%s |")
@@ -2689,80 +2708,88 @@ LEVEL is an integer. Indent by two spaces per level above 1."
(if (= level 1) ""
(concat "\\_" (make-string (* 2 (1- level)) ?\s))))
-(defun org-clocktable-increment-day (ts &optional n)
- "Increment day in TS by N (defaulting to 1).
-The TS argument has the same type as the return values of
-`float-time' or `current-time'."
- (let ((tsd (org-decode-time ts)))
- (cl-incf (nth 3 tsd) (or n 1))
- (setf (nth 8 tsd) nil) ; no time zone: increasing day skips one whole day
- (apply 'encode-time tsd)))
-
(defun org-clocktable-steps (params)
- "Step through the range to make a number of clock tables."
- (let* ((ts (plist-get params :tstart))
- (te (plist-get params :tend))
- (ws (plist-get params :wstart))
- (ms (plist-get params :mstart))
- (step0 (plist-get params :step))
- (stepskip0 (plist-get params :stepskip0))
- (block (plist-get params :block))
- cc tsb)
- (when block
- (setq cc (org-clock-special-range block nil t ws ms)
- ts (or (car cc)
- ;; The year Org was born.
- "<2003-01-01 Thu 00:00>")
- te (nth 1 cc)))
- (cond
- ((numberp ts)
- ;; If ts is a number, it's an absolute day number from
- ;; org-agenda.
- (pcase-let ((`(,month ,day ,year) (calendar-gregorian-from-absolute ts)))
- (setq ts (float-time (encode-time 0 0 0 day month year)))))
- (ts (setq ts (org-matcher-time ts))))
- (cond
- ((numberp te)
- ;; Likewise for te.
- (pcase-let ((`(,month ,day ,year) (calendar-gregorian-from-absolute te)))
- (setq te (float-time (encode-time 0 0 0 day month year)))))
- (te (setq te (org-matcher-time te))))
- (setq tsb
- (if (eq step0 'week)
- (let ((dow (nth 6 (org-decode-time ts))))
- (if (<= dow ws) ts
- (float-time (org-clocktable-increment-day ts ; decrement
- (- ws dow)))))
- ts))
- (while (< tsb te)
+ "Create one or more clock tables, according to PARAMS.
+Step through the range specifications in plist PARAMS to make
+a number of clock tables."
+ (let* ((ignore-empty-tables (plist-get params :stepskip0))
+ (step (plist-get params :step))
+ (step-header
+ (pcase step
+ (`day "Daily report: ")
+ (`week "Weekly report starting on: ")
+ (`month "Monthly report starting on: ")
+ (`year "Annual report starting on: ")
+ (_ (user-error "Unknown `:step' specification: %S" step))))
+ (week-start (or (plist-get params :wstart) 1))
+ (month-start (or (plist-get params :mstart) 1))
+ (range
+ (pcase (plist-get params :block)
+ (`nil nil)
+ (range
+ (org-clock-special-range range nil t week-start month-start))))
+ ;; For both START and END, any number is an absolute day
+ ;; number from Agenda. Otherwise, consider value to be an Org
+ ;; timestamp string. The `:block' property has precedence
+ ;; over `:tstart' and `:tend'.
+ (start
+ (pcase (if range (car range) (plist-get params :tstart))
+ ((and (pred numberp) n)
+ (pcase-let ((`(,m ,d ,y) (calendar-gregorian-from-absolute n)))
+ (apply #'encode-time (list 0 0 org-extend-today-until d m y))))
+ (timestamp
+ (seconds-to-time
+ (org-matcher-time (or timestamp
+ ;; The year Org was born.
+ "<2003-01-01 Thu 00:00>"))))))
+ (end
+ (pcase (if range (nth 1 range) (plist-get params :tend))
+ ((and (pred numberp) n)
+ (pcase-let ((`(,m ,d ,y) (calendar-gregorian-from-absolute n)))
+ (apply #'encode-time (list 0 0 org-extend-today-until d m y))))
+ (timestamp (seconds-to-time (org-matcher-time timestamp))))))
+ (while (time-less-p start end)
(unless (bolp) (insert "\n"))
- (let* ((start-time (max tsb ts))
- (dow (nth 6 (org-decode-time tsb)))
- (days-to-skip (cond ((eq step0 'day) 1)
- ;; else 'week:
- ((= dow ws) 7)
- (t (- ws dow)))))
- (setq tsb (float-time (org-clocktable-increment-day tsb days-to-skip)))
- (insert "\n"
- (if (eq step0 'day) "Daily report: "
- "Weekly report starting on: ")
- (org-format-time-string (org-time-stamp-format nil t) start-time)
- "\n")
- (let ((table-begin (line-beginning-position 0))
- (step-time
- (org-dblock-write:clocktable
- (org-combine-plists
- params
- (list
- :header "" :step nil :block nil
- :tstart (org-format-time-string (org-time-stamp-format t t)
- start-time)
- :tend (org-format-time-string (org-time-stamp-format t t)
- (min te tsb)))))))
- (re-search-forward "^[ \t]*#\\+END:")
- (when (and stepskip0 (equal step-time 0))
- ;; Remove the empty table
- (delete-region (line-beginning-position) table-begin))))
+ ;; Insert header before each clock table.
+ (insert "\n"
+ step-header
+ (format-time-string (org-time-stamp-format nil t) start)
+ "\n")
+ ;; Compute NEXT, which is the end of the current clock table,
+ ;; according to step.
+ (let* ((next
+ (apply #'encode-time
+ (pcase-let
+ ((`(,_ ,_ ,_ ,d ,m ,y ,dow . ,_) (decode-time start)))
+ (pcase step
+ (`day (list 0 0 org-extend-today-until (1+ d) m y))
+ (`week
+ (let ((offset (if (= dow week-start) 7
+ (mod (- week-start dow) 7))))
+ (list 0 0 org-extend-today-until (+ d offset) m y)))
+ (`month (list 0 0 0 month-start (1+ m) y))
+ (`year (list 0 0 org-extend-today-until 1 1 (1+ y)))))))
+ (table-begin (line-beginning-position 0))
+ (step-time
+ ;; Write clock table between START and NEXT.
+ (org-dblock-write:clocktable
+ (org-combine-plists
+ params (list :header ""
+ :step nil
+ :block nil
+ :tstart (format-time-string
+ (org-time-stamp-format t t)
+ start)
+ :tend (format-time-string
+ (org-time-stamp-format t t)
+ ;; Never include clocks past END.
+ (if (time-less-p end next) end next)))))))
+ (let ((case-fold-search t)) (re-search-forward "^[ \t]*#\\+END:"))
+ ;; Remove the table if it is empty and `:stepskip0' is
+ ;; non-nil.
+ (when (and ignore-empty-tables (equal step-time 0))
+ (delete-region (line-beginning-position) table-begin))
+ (setq start next))
(end-of-line 0))))
(defun org-clock-get-table-data (file params)
@@ -2846,8 +2873,8 @@ PROPERTIES: The list properties specified in the `:properties' parameter
(hdl
(if (not link) headline
(let ((search
- (org-make-org-heading-search-string headline)))
- (org-make-link-string
+ (org-link-heading-search-string headline)))
+ (org-link-make-string
(if (not (buffer-file-name)) search
(format "file:%s::%s" (buffer-file-name) search))
;; Prune statistics cookies. Replace
diff --git a/lisp/org-colview.el b/lisp/org-colview.el
index 27120dd..caef425 100644
--- a/lisp/org-colview.el
+++ b/lisp/org-colview.el
@@ -41,6 +41,9 @@
(declare-function org-element-property "org-element" (property element))
(declare-function org-element-restriction "org-element" (element))
(declare-function org-element-type "org-element" (element))
+(declare-function org-dynamic-block-define "org" (type func))
+(declare-function org-link-display-format "ol" (s))
+(declare-function org-link-open-from-string "ol" (s &optional arg))
(defvar org-agenda-columns-add-appointments-to-effort-sum)
(defvar org-agenda-columns-compute-summary-properties)
@@ -253,7 +256,7 @@ value for ITEM property."
(concat (make-string (1- (org-current-level))
(if org-hide-leading-stars ?\s ?*))
"* "))))
- (concat stars (org-columns-compact-links value))))
+ (concat stars (org-link-display-format value))))
(`(,_ ,_ ,_ ,_ nil) value)
;; If PRINTF is set, assume we are displaying a number and
;; obey to the format string.
@@ -517,14 +520,6 @@ for the duration of the command.")
(when (local-variable-p 'org-colview-initial-truncate-line-value)
(setq truncate-lines org-colview-initial-truncate-line-value))))
-(defun org-columns-compact-links (s)
- "Replace [[link][desc]] with [desc] or [link]."
- (while (string-match org-bracket-link-regexp s)
- (setq s (replace-match
- (concat "[" (match-string (if (match-end 3) 3 1) s) "]")
- t t s)))
- s)
-
(defun org-columns-show-value ()
"Show the full value of the property."
(interactive)
@@ -570,7 +565,9 @@ for the duration of the command.")
(defvar org-overriding-columns-format nil
"When set, overrides any other format definition for the agenda.
Don't set this, this is meant for dynamic scoping. Set
-`org-local-columns-format' instead.")
+`org-columns-default-format' and `org-columns-default-format-for-agenda'
+instead. You should use this variable only in the local settings
+section for a custom agenda view.")
(defvar-local org-local-columns-format nil
"When set, overrides any other format definition for the agenda.
@@ -772,7 +769,7 @@ around it."
(defun org-columns-open-link (&optional arg)
(interactive "P")
(let ((value (get-char-property (point) 'org-columns-value)))
- (org-open-link-from-string value arg)))
+ (org-link-open-from-string value arg)))
;;;###autoload
(defun org-columns-get-format-and-top-level ()
@@ -1132,16 +1129,7 @@ as a canonical duration, i.e., using units defined in
"Apply FUN to time values TIMES.
Return the result as a duration."
(org-duration-from-minutes
- (apply fun
- (mapcar (lambda (time)
- ;; Unlike to `org-duration-to-minutes' standard
- ;; behavior, we want to consider plain numbers as
- ;; hours. As a consequence, we treat them
- ;; differently.
- (if (string-match-p "\\`[0-9]+\\(?:\\.[0-9]*\\)?\\'" time)
- (* 60 (string-to-number time))
- (org-duration-to-minutes time)))
- times))
+ (apply fun (mapcar #'org-duration-to-minutes times))
(org-duration-h:mm-only-p times)))
(defun org-columns--compute-spec (spec &optional update)
@@ -1262,7 +1250,7 @@ When PRINTF is non-nil, use it to format the result."
"Summarize CHECK-BOXES with a check-box cookie."
(format "[%d/%d]"
(cl-count-if (lambda (b) (or (equal b "[X]")
- (string-match-p "\\[\\([1-9]\\)/\\1\\]" b)))
+ (string-match-p "\\[\\([1-9]\\)/\\1\\]" b)))
check-boxes)
(length check-boxes)))
@@ -1348,14 +1336,15 @@ and variances (respectively) of the individual estimates."
;;; Dynamic block for Column view
-(defun org-columns--capture-view (maxlevel match skip-empty format local)
+(defun org-columns--capture-view (maxlevel match skip-empty exclude-tags format local)
"Get the column view of the current buffer.
MAXLEVEL sets the level limit. SKIP-EMPTY tells whether to skip
empty rows, an empty row being one where all the column view
-specifiers but ITEM are empty. FORMAT is a format string for
-columns, or nil. When LOCAL is non-nil, only capture headings in
-current subtree.
+specifiers but ITEM are empty. EXCLUDE-TAGS is a list of tags
+that will be excluded from the resulting view. FORMAT is a
+format string for columns, or nil. When LOCAL is non-nil, only
+capture headings in current subtree.
This function returns a list containing the title row and all
other rows. Each row is a list of fields, as strings, or
@@ -1378,9 +1367,13 @@ other rows. Each row is a list of fields, as strings, or
'org-columns-value
'org-columns-value-modified)))
row)))
- (unless (and skip-empty
- (let ((r (delete-dups (remove "" row))))
- (or (null r) (and has-item (= (length r) 1)))))
+ (unless (or
+ (and skip-empty
+ (let ((r (delete-dups (remove "" row))))
+ (or (null r) (and has-item (= (length r) 1)))))
+ (and exclude-tags
+ (cl-some (lambda (tag) (member tag exclude-tags))
+ (org-get-tags))))
(push (cons (org-reduced-level (org-current-level)) (nreverse row))
table)))))
(or (and maxlevel (format "LEVEL<=%d" maxlevel))
@@ -1480,6 +1473,7 @@ PARAMS is a property list of parameters:
(org-columns--capture-view (plist-get params :maxlevel)
(plist-get params :match)
(plist-get params :skip-empty-rows)
+ (plist-get params :exclude-tags)
(plist-get params :format)
view-pos))))))
(when table
@@ -1556,6 +1550,7 @@ PARAMS is a property list of parameters:
(id)))))
(org-update-dblock))
+(org-dynamic-block-define "columnview" #'org-columns-insert-dblock)
;;; Column view in the agenda
@@ -1573,6 +1568,7 @@ PARAMS is a property list of parameters:
(cond
((bound-and-true-p org-overriding-columns-format))
((bound-and-true-p org-local-columns-format))
+ ((bound-and-true-p org-columns-default-format-for-agenda))
((let ((m (org-get-at-bol 'org-hd-marker)))
(and m
(or (org-entry-get m "COLUMNS" t)
diff --git a/lisp/org-compat.el b/lisp/org-compat.el
index 7603f96..4446a16 100644
--- a/lisp/org-compat.el
+++ b/lisp/org-compat.el
@@ -46,8 +46,8 @@
(declare-function org-end-of-subtree "org" (&optional invisible-ok to-heading))
(declare-function org-get-heading "org" (&optional no-tags no-todo no-priority no-comment))
(declare-function org-get-tags "org" (&optional pos local))
-(declare-function org-link-display-format "org" (s))
-(declare-function org-link-set-parameters "org" (type &rest rest))
+(declare-function org-link-display-format "ol" (s))
+(declare-function org-link-set-parameters "ol" (type &rest rest))
(declare-function org-log-into-drawer "org" ())
(declare-function org-make-tag-string "org" (tags))
(declare-function org-reduced-level "org" (l))
@@ -108,6 +108,10 @@ is nil)."
(defalias 'org-line-number-display-width 'line-number-display-width)
(defun org-line-number-display-width (&rest _) 0))
+(if (fboundp 'buffer-hash)
+ (defalias 'org-buffer-hash 'buffer-hash)
+ (defun org-buffer-hash () (md5 (current-buffer))))
+
(unless (fboundp 'file-attribute-modification-time)
(defsubst file-attribute-modification-time (attributes)
"The modification time in ATTRIBUTES returned by `file-attributes'.
@@ -302,6 +306,15 @@ Counting starts at 1."
(define-obsolete-variable-alias 'org-effort-durations 'org-duration-units
"Org 9.2")
+(define-obsolete-function-alias 'org-toggle-latex-fragment 'org-latex-preview
+ "Org 9.3")
+
+(define-obsolete-function-alias 'org-remove-latex-fragment-image-overlays
+ 'org-clear-latex-preview "Org 9.3")
+
+(define-obsolete-variable-alias 'org-attach-directory
+ 'org-attach-id-dir "Org 9.3")
+
(defun org-in-fixed-width-region-p ()
"Non-nil if point in a fixed-width region."
(save-match-data
@@ -355,7 +368,7 @@ See `org-link-parameters' for documentation on the other parameters."
;;;; Functions unused in Org core.
(defun org-table-recognize-table.el ()
"If there is a table.el table nearby, recognize it and move into it."
- (when (and org-table-tab-recognizes-table.el (org-at-table.el-p))
+ (when (org-at-table.el-p)
(beginning-of-line)
(unless (or (looking-at org-table-dataline-regexp)
(not (looking-at org-table1-hline-regexp)))
@@ -486,6 +499,84 @@ use of this function is for the stuck project list."
(define-obsolete-variable-alias 'org-agenda-overriding-columns-format
'org-overriding-columns-format "Org 9.2.2")
+(define-obsolete-variable-alias 'org-doi-server-url
+ 'org-link-doi-server-url "Org 9.3")
+
+(define-obsolete-variable-alias 'org-email-link-description-format
+ 'org-link-email-description-format "Org 9.3")
+
+(define-obsolete-variable-alias 'org-make-link-description-function
+ 'org-link-make-description-function "Org 9.3")
+
+(define-obsolete-variable-alias 'org-from-is-user-regexp
+ 'org-link-from-user-regexp "Org 9.3")
+
+(define-obsolete-variable-alias 'org-descriptive-links
+ 'org-link-descriptive "Org 9.3")
+
+(define-obsolete-variable-alias 'org-context-in-file-links
+ 'org-link-context-for-files "Org 9.3")
+
+(define-obsolete-variable-alias 'org-keep-stored-link-after-insertion
+ 'org-link-keep-stored-after-insertion "Org 9.3")
+
+(define-obsolete-variable-alias 'org-display-internal-link-with-indirect-buffer
+ 'org-link-use-indirect-buffer-for-internals "Org 9.3")
+
+(define-obsolete-variable-alias 'org-confirm-shell-link-function
+ 'org-link-shell-confirm-function "Org 9.3")
+
+(define-obsolete-variable-alias 'org-confirm-shell-link-not-regexp
+ 'org-link-shell-skip-confirm-regexp "Org 9.3")
+
+(define-obsolete-variable-alias 'org-confirm-elisp-link-function
+ 'org-link-elisp-confirm-function "Org 9.3")
+
+(define-obsolete-variable-alias 'org-confirm-elisp-link-not-regexp
+ 'org-link-elisp-skip-confirm-regexp "Org 9.3")
+
+(define-obsolete-function-alias 'org-file-complete-link
+ 'org-link-complete-file "Org 9.3")
+
+(define-obsolete-function-alias 'org-email-link-description
+ 'org-link-email-description "Org 9.3")
+
+(define-obsolete-function-alias 'org-make-link-string
+ 'org-link-make-string "Org 9.3")
+
+(define-obsolete-function-alias 'org-store-link-props
+ 'org-link-store-props "Org 9.3")
+
+(define-obsolete-function-alias 'org-add-link-props
+ 'org-link-add-props "Org 9.3")
+
+(define-obsolete-function-alias 'org-make-org-heading-search-string
+ 'org-link-heading-search-string "Org 9.3")
+
+(define-obsolete-function-alias 'org-make-link-regexps
+ 'org-link-make-regexps "Org 9.3")
+
+(define-obsolete-variable-alias 'org-angle-link-re
+ 'org-link-angle-re "Org 9.3")
+
+(define-obsolete-variable-alias 'org-plain-link-re
+ 'org-link-plain-re "Org 9.3")
+
+(define-obsolete-variable-alias 'org-bracket-link-regexp
+ 'org-link-bracket-re "Org 9.3")
+
+(define-obsolete-variable-alias 'org-bracket-link-analytic-regexp
+ 'org-link-bracket-re "Org 9.3")
+
+(define-obsolete-variable-alias 'org-any-link-re
+ 'org-link-any-re "Org 9.3")
+
+(define-obsolete-function-alias 'org-open-link-from-string
+ 'org-link-open-from-string "Org 9.3")
+
+(define-obsolete-function-alias 'org-add-angle-brackets
+ 'org-link-add-angle-brackets "Org 9.3")
+
;; The function was made obsolete by commit 65399674d5 of 2013-02-22.
;; This make-obsolete call was added 2016-09-01.
(make-obsolete 'org-capture-import-remember-templates
@@ -535,7 +626,7 @@ use of this function is for the stuck project list."
;;;; Obsolete link types
-(eval-after-load 'org
+(eval-after-load 'ol
'(progn
(org-link-set-parameters "file+emacs") ;since Org 9.0
(org-link-set-parameters "file+sys"))) ;since Org 9.0
diff --git a/lisp/org-crypt.el b/lisp/org-crypt.el
index 9cd76c9..1bdf623 100644
--- a/lisp/org-crypt.el
+++ b/lisp/org-crypt.el
@@ -190,7 +190,7 @@ See `org-crypt-disable-auto-save'."
(error (insert contents) (error (nth 1 err)))))
(when folded
(goto-char start-heading)
- (outline-hide-subtree))
+ (org-flag-subtree t))
nil)))))
(defun org-decrypt-entry ()
diff --git a/lisp/org-element.el b/lisp/org-element.el
index 77b8f95..56b3cc4 100644
--- a/lisp/org-element.el
+++ b/lisp/org-element.el
@@ -58,10 +58,55 @@
;;; Code:
-(require 'org)
(require 'avl-tree)
(require 'cl-lib)
-
+(require 'ol)
+(require 'org)
+(require 'org-compat)
+(require 'org-entities)
+(require 'org-footnote)
+(require 'org-list)
+(require 'org-macs)
+(require 'org-table)
+
+(declare-function org-at-heading-p "org" (&optional _))
+(declare-function org-end-of-subtree "org" (&optional invisible-ok to-heading))
+(declare-function org-escape-code-in-string "org-src" (s))
+(declare-function org-find-visible "org" ())
+(declare-function org-macro-escape-arguments "org-macro" (&rest args))
+(declare-function org-macro-extract-arguments "org-macro" (s))
+(declare-function org-reduced-level "org" (l))
+(declare-function org-unescape-code-in-string "org-src" (s))
+(declare-function outline-next-heading "outline" ())
+(declare-function outline-previous-heading "outline" ())
+
+(defvar org-archive-tag)
+(defvar org-clock-line-re)
+(defvar org-closed-string)
+(defvar org-comment-string)
+(defvar org-complex-heading-regexp)
+(defvar org-dblock-start-re)
+(defvar org-deadline-string)
+(defvar org-done-keywords)
+(defvar org-drawer-regexp)
+(defvar org-edit-src-content-indentation)
+(defvar org-emph-re)
+(defvar org-emphasis-regexp-components)
+(defvar org-keyword-time-not-clock-regexp)
+(defvar org-match-substring-regexp)
+(defvar org-odd-levels-only)
+(defvar org-outline-regexp-bol)
+(defvar org-planning-line-re)
+(defvar org-property-drawer-re)
+(defvar org-property-format)
+(defvar org-property-re)
+(defvar org-scheduled-string)
+(defvar org-src-preserve-indentation)
+(defvar org-tags-column)
+(defvar org-time-stamp-formats)
+(defvar org-todo-regexp)
+(defvar org-ts-regexp-both)
+(defvar org-verbatim-re)
;;; Definitions And Rules
@@ -91,7 +136,7 @@ specially in `org-element--object-lex'.")
(setq org-element-paragraph-separate
(concat "^\\(?:"
;; Headlines, inlinetasks.
- org-outline-regexp "\\|"
+ "\\*+ " "\\|"
;; Footnote definitions.
"\\[fn:[-_[:word:]]+\\]" "\\|"
;; Diary sexps.
@@ -117,7 +162,7 @@ specially in `org-element--object-lex'.")
;; LaTeX environments.
"\\\\begin{\\([A-Za-z0-9*]+\\)}" "\\|"
;; Clock lines.
- (regexp-quote org-clock-string) "\\|"
+ "CLOCK:" "\\|"
;; Lists.
(let ((term (pcase org-plain-list-ordered-item-terminator
(?\) ")") (?. "\\.") (_ "[.)]")))
@@ -928,7 +973,7 @@ Return value is a plist."
Return a list whose CAR is `headline' and CDR is a plist
containing `:raw-value', `:title', `:begin', `:end',
`:pre-blank', `:contents-begin' and `:contents-end', `:level',
-`:priority', `:tags', `:todo-keyword',`:todo-type', `:scheduled',
+`:priority', `:tags', `:todo-keyword', `:todo-type', `:scheduled',
`:deadline', `:closed', `:archivedp', `:commentedp'
`:footnote-section-p', `:post-blank' and `:post-affiliated'
keywords.
@@ -1723,7 +1768,7 @@ Return a list whose CAR is `clock' and CDR is a plist containing
(save-excursion
(let* ((case-fold-search nil)
(begin (point))
- (value (progn (search-forward org-clock-string (line-end-position) t)
+ (value (progn (search-forward "CLOCK:" (line-end-position) t)
(skip-chars-forward " \t")
(org-element-timestamp-parser)))
(duration (and (search-forward " => " (line-end-position) t)
@@ -1748,7 +1793,7 @@ Return a list whose CAR is `clock' and CDR is a plist containing
(defun org-element-clock-interpreter (clock _)
"Interpret CLOCK element as Org syntax."
- (concat org-clock-string " "
+ (concat "CLOCK: "
(org-element-timestamp-interpreter
(org-element-property :value clock) nil)
(let ((duration (org-element-property :duration clock)))
@@ -2834,7 +2879,7 @@ Assume point is at the beginning of the snippet."
When at a footnote reference, return a list whose car is
`footnote-reference' and cdr a plist with `:label', `:type',
-`:begin', `:end', `:content-begin', `:contents-end' and
+`:begin', `:end', `:contents-begin', `:contents-end' and
`:post-blank' as keywords. Otherwise, return nil."
(when (looking-at org-footnote-re)
(let ((closing (with-syntax-table org-element--pair-square-table
@@ -3097,10 +3142,10 @@ Assume point is at the beginning of the link."
(setq contents-begin (match-beginning 1))
(setq contents-end (match-end 1)))
;; Type 2: Standard link, i.e. [[https://orgmode.org][homepage]]
- ((looking-at org-bracket-link-regexp)
+ ((looking-at org-link-bracket-re)
(setq format 'bracket)
- (setq contents-begin (match-beginning 3))
- (setq contents-end (match-end 3))
+ (setq contents-begin (match-beginning 2))
+ (setq contents-end (match-end 2))
(setq link-end (match-end 0))
;; RAW-LINK is the original link. Decode any encoding.
;; Expand any abbreviation in it.
@@ -3147,7 +3192,7 @@ Assume point is at the beginning of the link."
(setq type "fuzzy")
(setq path raw-link))))
;; Type 3: Plain link, e.g., https://orgmode.org
- ((looking-at org-plain-link-re)
+ ((looking-at org-link-plain-re)
(setq format 'plain)
(setq raw-link (match-string-no-properties 0))
(setq type (match-string-no-properties 1))
@@ -3156,7 +3201,7 @@ Assume point is at the beginning of the link."
;; Type 4: Angular link, e.g., <https://orgmode.org>. Unlike to
;; bracket links, follow RFC 3986 and remove any extra
;; whitespace in URI.
- ((looking-at org-angle-link-re)
+ ((looking-at org-link-angle-re)
(setq format 'angle)
(setq type (match-string-no-properties 1))
(setq link-end (match-end 0))
@@ -3854,7 +3899,8 @@ element it has to parse."
((org-at-heading-p)
(org-element-inlinetask-parser limit raw-secondary-p))
;; From there, elements can have affiliated keywords.
- (t (let ((affiliated (org-element--collect-affiliated-keywords limit)))
+ (t (let ((affiliated (org-element--collect-affiliated-keywords
+ limit (memq granularity '(nil object)))))
(cond
;; Jumping over affiliated keywords put point off-limits.
;; Parse them as regular keywords.
@@ -3940,7 +3986,7 @@ element it has to parse."
;; that element, and, in the meantime, collect information they give
;; into appropriate properties. Hence the following function.
-(defun org-element--collect-affiliated-keywords (limit)
+(defun org-element--collect-affiliated-keywords (limit parse)
"Collect affiliated keywords from point down to LIMIT.
Return a list whose CAR is the position at the first of them and
@@ -3949,13 +3995,16 @@ beginning of the first line after them.
As a special case, if element doesn't start at the beginning of
the line (e.g., a paragraph starting an item), CAR is current
-position of point and CDR is nil."
+position of point and CDR is nil.
+
+When PARSE is non-nil, values from keywords belonging to
+`org-element-parsed-keywords' are parsed as secondary strings."
(if (not (bolp)) (list (point))
(let ((case-fold-search t)
(origin (point))
;; RESTRICT is the list of objects allowed in parsed
- ;; keywords value.
- (restrict (org-element-restriction 'keyword))
+ ;; keywords value. If PARSE is nil, no object is allowed.
+ (restrict (and parse (org-element-restriction 'keyword)))
output)
(while (and (< (point) limit) (looking-at org-element--affiliated-re))
(let* ((raw-kwd (upcase (match-string 1)))
@@ -3964,35 +4013,35 @@ position of point and CDR is nil."
(kwd (or (cdr (assoc raw-kwd
org-element-keyword-translation-alist))
raw-kwd))
+ ;; PARSED? is non-nil when keyword should have its
+ ;; value parsed.
+ (parsed? (member kwd org-element-parsed-keywords))
;; Find main value for any keyword.
(value
- (save-match-data
- (org-trim
- (buffer-substring-no-properties
- (match-end 0) (line-end-position)))))
- ;; PARSEDP is non-nil when keyword should have its
- ;; value parsed.
- (parsedp (member kwd org-element-parsed-keywords))
- ;; If KWD is a dual keyword, find its secondary
- ;; value. Maybe parse it.
- (dualp (member kwd org-element-dual-keywords))
+ (let ((beg (match-end 0))
+ (end (save-excursion
+ (end-of-line)
+ (skip-chars-backward " \t")
+ (point))))
+ (if parsed?
+ (org-element--parse-objects beg end nil restrict)
+ (org-trim (buffer-substring-no-properties beg end)))))
+ ;; If KWD is a dual keyword, find its secondary value.
+ ;; Maybe parse it.
+ (dual? (member kwd org-element-dual-keywords))
(dual-value
- (and dualp
+ (and dual?
(let ((sec (match-string-no-properties 2)))
- (if (or (not sec) (not parsedp)) sec
+ (cond
+ ((and sec parsed?)
(save-match-data
(org-element--parse-objects
- (match-beginning 2) (match-end 2) nil restrict))))))
+ (match-beginning 2) (match-end 2) nil restrict)))
+ (sec sec)))))
;; Attribute a property name to KWD.
(kwd-sym (and kwd (intern (concat ":" (downcase kwd))))))
;; Now set final shape for VALUE.
- (when parsedp
- (setq value
- (org-element--parse-objects
- (match-end 0)
- (progn (end-of-line) (skip-chars-backward " \t") (point))
- nil restrict)))
- (when dualp
+ (when dual?
(setq value (and (or value dual-value) (cons value dual-value))))
(when (or (member kwd org-element-multiple-keywords)
;; Attributes can always appear on multiple lines.
@@ -5513,7 +5562,7 @@ the process stopped before finding the expected result."
(defconst org-element--cache-sensitive-re
(concat
- org-outline-regexp-bol "\\|"
+ "^\\*+ " "\\|"
"\\\\end{[A-Za-z0-9*]+}[ \t]*$" "\\|"
"^[ \t]*\\(?:"
"#\\+\\(?:BEGIN[:_]\\|END\\(?:_\\|:?[ \t]*$\\)\\)" "\\|"
diff --git a/lisp/org-faces.el b/lisp/org-faces.el
index 8e9726c..a97d4dc 100644
--- a/lisp/org-faces.el
+++ b/lisp/org-faces.el
@@ -408,7 +408,7 @@ For source-blocks `org-src-block-faces' takes precedence."
:group 'org-faces)
(defface org-verbatim '((t (:inherit shadow)))
- "Face for fixed-with text like code snippets"
+ "Face for fixed-with text like code snippets."
:group 'org-faces
:version "22.1")
@@ -559,10 +559,6 @@ month and 365.24 days for a year)."
"Face for tag(s) in the mode-line when filtering the agenda."
:group 'org-faces)
-(defface org-agenda-filter-regexp '((t :inherit mode-line))
- "Face for regexp(s) in the mode-line when filtering the agenda."
- :group 'org-faces)
-
(defface org-agenda-filter-category '((t :inherit mode-line))
"Face for categories in the mode-line when filtering the agenda."
:group 'org-faces)
@@ -571,6 +567,10 @@ month and 365.24 days for a year)."
"Face for effort in the mode-line when filtering the agenda."
:group 'org-faces)
+(defface org-agenda-filter-regexp '((t :inherit mode-line))
+ "Face for regexp(s) in the mode-line when filtering the agenda."
+ :group 'org-faces)
+
(defface org-time-grid ;Copied from `font-lock-variable-name-face'
'((((class color) (min-colors 16) (background light)) (:foreground "DarkGoldenrod"))
(((class color) (min-colors 16) (background dark)) (:foreground "LightGoldenrod"))
@@ -608,8 +608,8 @@ If it is less than 8, the level-1 face gets re-used for level N+1 etc."
(defcustom org-cycle-level-faces t
"Non-nil means level styles cycle after level `org-n-level-faces'.
Then so level org-n-level-faces+1 is styled like level 1.
-If nil, then all levels >=org-n-level-faces are styled like
-level org-n-level-faces"
+If nil, then all levels >= org-n-level-faces are styled like
+level org-n-level-faces."
:group 'org-appearance
:group 'org-faces
:version "24.1"
diff --git a/lisp/org-feed.el b/lisp/org-feed.el
index 0f18673..f9f5fb0 100644
--- a/lisp/org-feed.el
+++ b/lisp/org-feed.el
@@ -407,12 +407,12 @@ it can be a list structured like an entry in `org-feed-alist'."
;; Write the new status
;; We do this only now, in case something goes wrong above, so
;; that would would end up with a status that does not reflect
- ;; which items truely have been handled
+ ;; which items truly have been handled
(org-feed-write-status inbox-pos drawer status)
;; Normalize the visibility of the inbox tree
(goto-char inbox-pos)
- (outline-hide-subtree)
+ (org-flag-subtree t)
(org-show-children)
;; Hooks and messages
diff --git a/lisp/org-footnote.el b/lisp/org-footnote.el
index 4a296b1..0fe3828 100644
--- a/lisp/org-footnote.el
+++ b/lisp/org-footnote.el
@@ -56,7 +56,7 @@
(defvar electric-indent-mode)
(defvar org-blank-before-new-entry) ; defined in org.el
-(defvar org-bracket-link-regexp) ; defined in org.el
+(defvar org-link-bracket-re) ; defined in org.el
(defvar org-complex-heading-regexp) ; defined in org.el
(defvar org-odd-levels-only) ; defined in org.el
(defvar org-outline-regexp) ; defined in org.el
@@ -489,7 +489,7 @@ This function is meant to be used for fontification only."
(goto-char beg)
(let ((linkp
(save-match-data
- (org-in-regexp org-bracket-link-regexp))))
+ (org-in-regexp org-link-bracket-re))))
(and linkp (< (point) (cdr linkp))))))
;; Verify point doesn't belong to a LaTeX macro.
(not (org-inside-latex-macro-p))
diff --git a/lisp/org-goto.el b/lisp/org-goto.el
index a399899..5ce9b8c 100644
--- a/lisp/org-goto.el
+++ b/lisp/org-goto.el
@@ -172,7 +172,6 @@ When nil, you can use these keybindings to navigate the buffer:
(defun org-goto-local-auto-isearch ()
"Start isearch."
(interactive)
- (goto-char (point-min))
(let ((keys (this-command-keys)))
(when (eq (lookup-key isearch-mode-map keys) 'isearch-printing-char)
(isearch-mode t)
@@ -228,7 +227,6 @@ position or nil."
(isearch-hide-immediately nil)
(isearch-search-fun-function
(lambda () #'org-goto--local-search-headings))
- (org-goto-selected-point org-goto-exit-command)
(help (or help org-goto-help)))
(save-excursion
(save-window-excursion
diff --git a/lisp/org-habit.el b/lisp/org-habit.el
index d19ab1b..77efad1 100644
--- a/lisp/org-habit.el
+++ b/lisp/org-habit.el
@@ -89,6 +89,21 @@ It will be green even if it was done after the deadline."
:group 'org-habit
:type 'boolean)
+(defcustom org-habit-scheduled-past-days nil
+"Value to use instead of `org-scheduled-past-days', for habits only.
+
+If nil, `org-scheduled-past-days' is used.
+
+Setting this to say 10000 is a way to make habits always show up
+as a reminder, even if you set `org-scheduled-past-days' to a
+small value because you regard scheduled items as a way of
+\"turning on\" TODO items on a particular date, rather than as a
+means of creating calendar-based reminders."
+ :group 'org-habit
+ :type '(choice integer (const nil))
+ :package-version '(Org . "9.3")
+ :safe (lambda (v) (or (integerp v) (null v))))
+
(defface org-habit-clear-face
'((((background light)) (:background "#8270f9"))
(((background dark)) (:background "blue")))
@@ -373,31 +388,30 @@ current time."
(throw :exit s))))))))))
donep)))
markedp face)
- (if donep
- (let ((done-time (time-add
- starting
- (days-to-time
- (- start (time-to-days starting))))))
-
- (aset graph index org-habit-completed-glyph)
- (setq markedp t)
- (put-text-property
- index (1+ index) 'help-echo
- (format-time-string (org-time-stamp-format) done-time) graph)
- (while (and done-dates
- (= start (car done-dates)))
- (setq last-done-date (car done-dates)
- done-dates (cdr done-dates))))
- (if todayp
- (aset graph index org-habit-today-glyph)))
+ (cond
+ (donep
+ (aset graph index org-habit-completed-glyph)
+ (setq markedp t)
+ (while (and done-dates (= start (car done-dates)))
+ (setq last-done-date (car done-dates))
+ (setq done-dates (cdr done-dates))))
+ (todayp
+ (aset graph index org-habit-today-glyph)))
(setq face (if (or in-the-past-p todayp)
(car faces)
(cdr faces)))
- (if (and in-the-past-p
- (not (eq face 'org-habit-overdue-face))
- (not markedp))
- (setq face (cdr faces)))
- (put-text-property index (1+ index) 'face face graph))
+ (when (and in-the-past-p
+ (not (eq face 'org-habit-overdue-face))
+ (not markedp))
+ (setq face (cdr faces)))
+ (put-text-property index (1+ index) 'face face graph)
+ (put-text-property index (1+ index)
+ 'help-echo
+ (concat (format-time-string
+ (org-time-stamp-format)
+ (time-add starting (days-to-time (- start (time-to-days starting)))))
+ (if donep " DONE" ""))
+ graph))
(setq start (1+ start)
index (1+ index)))
graph))
@@ -435,7 +449,18 @@ current time."
(message "Habits turned %s"
(if org-habit-show-habits "on" "off")))
-(org-defkey org-agenda-mode-map "K" 'org-habit-toggle-habits)
+(defun org-habit-toggle-display-in-agenda (arg)
+ "Toggle display of habits in agenda.
+With ARG toggle display of all vs. undone scheduled habits.
+See `org-habit-show-all-today'."
+ (interactive "P")
+ (if (not arg)
+ (org-habit-toggle-habits)
+ (org-agenda-check-type t 'agenda)
+ (setq org-habit-show-all-today (not org-habit-show-all-today))
+ (when org-habit-show-habits (org-agenda-redo))))
+
+(org-defkey org-agenda-mode-map "K" 'org-habit-toggle-display-in-agenda)
(provide 'org-habit)
diff --git a/lisp/org-id.el b/lisp/org-id.el
index 52fce54..653baf9 100644
--- a/lisp/org-id.el
+++ b/lisp/org-id.el
@@ -71,9 +71,11 @@
;;; Code:
(require 'org)
+(require 'ol)
(declare-function message-make-fqdn "message" ())
(declare-function org-goto-location "org-goto" (&optional _buf help))
+(declare-function org-link-set-parameters "ol" (type &rest rest))
;;; Customization
@@ -140,11 +142,15 @@ org Org's own internal method, using an encoding of the current time to
uuid Create random (version 4) UUIDs. If the program defined in
`org-id-uuid-program' is available it is used to create the ID.
- Otherwise an internal functions is used."
+ Otherwise an internal functions is used.
+
+ts Create ID's based on ISO8601 timestamps (without separators
+ and without timezone, local time). Precision down to seconds."
:group 'org-id
:type '(choice
(const :tag "Org's internal method" org)
- (const :tag "external: uuidgen" uuid)))
+ (const :tag "external: uuidgen" uuid)
+ (const :tag "ISO8601 timestamp" ts)))
(defcustom org-id-prefix nil
"The prefix for IDs.
@@ -161,7 +167,7 @@ to have no space characters in them."
"Non-nil means add the domain name to new IDs.
This ensures global uniqueness of IDs, and is also suggested by
the relevant RFCs. This is relevant only if `org-id-method' is
-`org'. When uuidgen is used, the domain will never be added.
+`org' or `ts'. When uuidgen is used, the domain will never be added.
The default is to not use this because we have no really good way to get
the true domain, and Org entries will normally not be shared with enough
@@ -189,6 +195,22 @@ This variable is only relevant when `org-id-track-globally' is set."
:group 'org-id
:type 'file)
+(defcustom org-id-locations-file-relative nil
+ "Determines if org-id-locations should be stored as relative links.
+Non-nil means that links to locations are stored as links
+relative to the location of where `org-id-locations-file' is
+stored.
+
+Nil means to store absolute paths to files.
+
+This customization is useful when folders are shared across
+systems but mounted at different roots. Relative path to
+`org-id-locations-file' still has to be maintained across
+systems."
+ :group 'org-id
+ :type 'boolean
+ :package-version '(Org . "9.3"))
+
(defvar org-id-locations nil
"List of files with IDs in those files.")
@@ -242,7 +264,7 @@ Create an ID if necessary."
"Get the ID property of the entry at point-or-marker POM.
If POM is nil, refer to the entry at point.
If the entry does not have an ID, the function returns nil.
-However, when CREATE is non nil, create an ID if none is present already.
+However, when CREATE is non-nil, create an ID if none is present already.
PREFIX will be passed through to `org-id-new'.
In any case, the ID of the entry is returned."
(org-with-point-at pom
@@ -350,6 +372,13 @@ So a typical ID could look like \"Org:4nd91V40HI\"."
(require 'message)
(concat "@" (message-make-fqdn))))))
(setq unique (concat etime postfix))))
+ ((eq org-id-method 'ts)
+ (let ((ts (format-time-string "%Y%m%dT%H%M%S.%6N"))
+ (postfix (if org-id-include-domain
+ (progn
+ (require 'message)
+ (concat "@" (message-make-fqdn))))))
+ (setq unique (concat ts postfix))))
(t (error "Invalid `org-id-method'")))
(concat prefix unique)))
@@ -447,81 +476,56 @@ and TIME is a Lisp time value (HI LO USEC)."
Store the relation between files and corresponding IDs.
This will scan all agenda files, all associated archives, and all
files currently mentioned in `org-id-locations'.
-When FILES is given, scan these files instead."
+When FILES is given, scan also these files."
(interactive)
(if (not org-id-track-globally)
(error "Please turn on `org-id-track-globally' if you want to track IDs")
- (let* ((org-id-search-archives
- (or org-id-search-archives
- (and (symbolp org-id-extra-files)
- (symbol-value org-id-extra-files)
- (member 'agenda-archives org-id-extra-files))))
- (files
- (or files
- (append
- ;; Agenda files and all associated archives
- (org-agenda-files t org-id-search-archives)
- ;; Explicit extra files
- (if (symbolp org-id-extra-files)
- (symbol-value org-id-extra-files)
- org-id-extra-files)
- ;; Files associated with live Org buffers
- (delq nil
- (mapcar (lambda (b)
- (with-current-buffer b
- (and (derived-mode-p 'org-mode) (buffer-file-name))))
- (buffer-list)))
- ;; All files known to have IDs
- org-id-files)))
- org-agenda-new-buffers
- file nfiles tfile ids reg found id seen (ndup 0))
- (when (member 'agenda-archives files)
- (setq files (delq 'agenda-archives (copy-sequence files))))
- (setq nfiles (length files))
- (while (setq file (pop files))
- (unless silent
- (message "Finding ID locations (%d/%d files): %s"
- (- nfiles (length files)) nfiles file))
- (setq tfile (file-truename file))
- (when (and (file-exists-p file) (not (member tfile seen)))
- (push tfile seen)
- (setq ids nil)
- (with-current-buffer (org-get-agenda-file-buffer file)
- (save-excursion
- (save-restriction
- (widen)
- (goto-char (point-min))
- (while (re-search-forward "^[ \t]*:ID:[ \t]+\\(\\S-+\\)[ \t]*$"
- nil t)
- (setq id (match-string-no-properties 1))
- (if (member id found)
- (progn
- (message "Duplicate ID \"%s\", also in file %s"
- id (or (car (delq
- nil
- (mapcar
- (lambda (x)
- (if (member id (cdr x))
- (car x)))
- reg)))
- (buffer-file-name)))
- (when (= ndup 0)
- (ding)
- (sit-for 2))
- (setq ndup (1+ ndup)))
- (push id found)
- (push id ids)))
- (push (cons (abbreviate-file-name file) ids) reg))))))
- (org-release-buffers org-agenda-new-buffers)
- (setq org-agenda-new-buffers nil)
- (setq org-id-locations reg)
+ (let* ((files (delete-dups
+ (mapcar #'file-truename
+ (append
+ ;; Agenda files and all associated archives
+ (org-agenda-files t org-id-search-archives)
+ ;; Explicit extra files
+ (unless (symbolp org-id-extra-files)
+ org-id-extra-files)
+ ;; All files known to have IDs
+ org-id-files
+ ;; function input
+ files))))
+ (nfiles (length files))
+ ids seen-ids (ndup 0) (i 0) file-id-alist)
+ (with-temp-buffer
+ (delay-mode-hooks
+ (org-mode)
+ (dolist (file files)
+ (unless silent
+ (setq i (1+ i))
+ (message "Finding ID locations (%d/%d files): %s"
+ i nfiles file))
+ (when (file-exists-p file)
+ (insert-file-contents file nil nil nil 'replace)
+ (setq ids (org-map-entries
+ (lambda ()
+ (org-entry-get (point) "ID"))
+ "ID<>\"\""))
+ (dolist (id ids)
+ (if (member id seen-ids)
+ (progn
+ (message "Duplicate ID \"%s\"" id)
+ (setq ndup (1+ ndup)))
+ (push id seen-ids)))
+ (when ids
+ (setq file-id-alist (cons (cons (abbreviate-file-name file) ids)
+ file-id-alist)))))))
+ (setq org-id-locations file-id-alist)
(setq org-id-files (mapcar 'car org-id-locations))
- (org-id-locations-save) ;; this function can also handle the alist form
+ (org-id-locations-save)
;; now convert to a hash
(setq org-id-locations (org-id-alist-to-hash org-id-locations))
- (if (> ndup 0)
- (message "WARNING: %d duplicate IDs found, check *Messages* buffer" ndup)
- (message "%d unique files scanned for IDs" (length org-id-files)))
+ (when (> ndup 0)
+ (warn "WARNING: %d duplicate IDs found, check *Messages* buffer" ndup))
+ (message "%d files scanned, %d files contains IDs and in total %d IDs found."
+ nfiles (length org-id-files) (hash-table-count org-id-locations))
org-id-locations)))
(defun org-id-locations-save ()
@@ -530,6 +534,16 @@ When FILES is given, scan these files instead."
(let ((out (if (hash-table-p org-id-locations)
(org-id-hash-to-alist org-id-locations)
org-id-locations)))
+ (when (and org-id-locations-file-relative out)
+ (setq out (mapcar
+ (lambda (item)
+ (if (file-name-absolute-p (car item))
+ (cons (file-relative-name
+ (car item) (file-name-directory
+ org-id-locations-file))
+ (cdr item))
+ item))
+ out)))
(with-temp-file org-id-locations-file
(let ((print-level nil)
(print-length nil))
@@ -543,7 +557,12 @@ When FILES is given, scan these files instead."
(condition-case nil
(progn
(insert-file-contents org-id-locations-file)
- (setq org-id-locations (read (current-buffer))))
+ (setq org-id-locations (read (current-buffer)))
+ (let ((loc (file-name-directory org-id-locations-file)))
+ (mapc (lambda (item)
+ (unless (file-name-absolute-p (car item))
+ (setf (car item) (expand-file-name (car item) loc))))
+ org-id-locations)))
(error
(message "Could not read org-id-values from %s. Setting it to nil."
org-id-locations-file))))
@@ -553,10 +572,12 @@ When FILES is given, scan these files instead."
(defun org-id-add-location (id file)
"Add the ID with location FILE to the database of ID locations."
;; Only if global tracking is on, and when the buffer has a file
- (when (and org-id-track-globally id file)
- (unless org-id-locations (org-id-locations-load))
- (puthash id (abbreviate-file-name file) org-id-locations)
- (add-to-list 'org-id-files (abbreviate-file-name file))))
+ (let ((afile (abbreviate-file-name file)))
+ (when (and org-id-track-globally id file)
+ (unless org-id-locations (org-id-locations-load))
+ (puthash id afile org-id-locations)
+ (unless (member afile org-id-files)
+ (add-to-list 'org-id-files afile)))))
(unless noninteractive
(add-hook 'kill-emacs-hook 'org-id-locations-save))
@@ -566,7 +587,7 @@ When FILES is given, scan these files instead."
(let (res x)
(maphash
(lambda (k v)
- (if (setq x (member v res))
+ (if (setq x (assoc v res))
(setcdr x (cons k (cdr x)))
(push (list v k) res)))
hash)
@@ -650,7 +671,7 @@ optional argument MARKERP, return the position as a new marker."
(match-string 4)
(match-string 0)))
link))))
- (org-store-link-props :link link :description desc :type "id")
+ (org-link-store-props :link link :description desc :type "id")
link)))
(defun org-id-open (id)
diff --git a/lisp/org-indent.el b/lisp/org-indent.el
index 15814e0..a69293a 100644
--- a/lisp/org-indent.el
+++ b/lisp/org-indent.el
@@ -299,7 +299,7 @@ LEVEL is the current level of heading. INDENTATION is the
expected indentation when wrapping line.
When optional argument HEADING is non-nil, assume line is at
-a heading. Moreover, if is is `inlinetask', the first star will
+a heading. Moreover, if it is `inlinetask', the first star will
have `org-warning' face."
(let* ((line (aref (pcase heading
(`nil org-indent--text-line-prefixes)
diff --git a/lisp/org-inlinetask.el b/lisp/org-inlinetask.el
index 775facd..c76d7d2 100644
--- a/lisp/org-inlinetask.el
+++ b/lisp/org-inlinetask.el
@@ -268,17 +268,6 @@ If the task has an end part, also demote it."
(goto-char beg)
(org-fixup-indentation diff)))))))
-(defun org-inlinetask-get-current-indentation ()
- "Get the indentation of the last non-while line above this one."
- (save-excursion
- (beginning-of-line 1)
- (skip-chars-backward " \t\n")
- (beginning-of-line 1)
- (or (org-at-item-p)
- (looking-at "[ \t]*"))
- (goto-char (match-end 0))
- (current-column)))
-
(defvar org-indent-indentation-per-level) ; defined in org-indent.el
(defface org-inlinetask '((t :inherit shadow))
diff --git a/lisp/org-keys.el b/lisp/org-keys.el
new file mode 100644
index 0000000..ae4f60d
--- /dev/null
+++ b/lisp/org-keys.el
@@ -0,0 +1,924 @@
+;;; org-keys.el --- Key bindings for Org mode -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2018 Free Software Foundation, Inc.
+
+;; Author: Nicolas Goaziou <mail@nicolasgoaziou.fr>
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This library adds bindings for Org mode buffers. It also
+;; implements both Speed keys and Babel speed keys. See manual for
+;; details.
+
+;;; Code:
+
+(defvar org-outline-regexp)
+
+(declare-function org-add-note "org" ())
+(declare-function org-agenda "org" (&optional arg org-keys restriction))
+(declare-function org-agenda-file-to-front "org" (&optional to-end))
+(declare-function org-agenda-remove-restriction-lock "org" (&optional noupdate))
+(declare-function org-agenda-set-restriction-lock "org" (&optional type))
+(declare-function org-archive-subtree "org" (&optional find-done))
+(declare-function org-archive-subtree-default "org" ())
+(declare-function org-archive-subtree-default-with-confirmation "org" ())
+(declare-function org-archive-to-archive-sibling "org" ())
+(declare-function org-at-heading-p "org" (&optional ignored))
+(declare-function org-attach "org" ())
+(declare-function org-backward-element "org" ())
+(declare-function org-backward-heading-same-level "org" (arg &optional invisible-ok))
+(declare-function org-backward-paragraph "org" ())
+(declare-function org-backward-sentence "org" (&optional arg))
+(declare-function org-beginning-of-line "org" (&optional n))
+(declare-function org-clock-cancel "org" ())
+(declare-function org-clock-display "org" (&optional arg))
+(declare-function org-clock-goto "org" (&optional select))
+(declare-function org-clock-in "org" (&optional select start-time))
+(declare-function org-clock-in-last "org" (&optional arg))
+(declare-function org-clock-out "org" (&optional switch-to-state fail-quietly at-time))
+(declare-function org-clone-subtree-with-time-shift "org" (n &optional shift))
+(declare-function org-columns "org" (&optional global columns-fmt-string))
+(declare-function org-comment-dwim "org" (arg))
+(declare-function org-copy "org" ())
+(declare-function org-copy-special "org" ())
+(declare-function org-copy-visible "org" (beg end))
+(declare-function org-ctrl-c-ctrl-c "org" (&optional arg))
+(declare-function org-ctrl-c-minus "org" ())
+(declare-function org-ctrl-c-ret "org" ())
+(declare-function org-ctrl-c-star "org" ())
+(declare-function org-ctrl-c-tab "org" (&optional arg))
+(declare-function org-cut-special "org" ())
+(declare-function org-cut-subtree "org" (&optional n))
+(declare-function org-cycle "org" (&optional arg))
+(declare-function org-cycle-agenda-files "org" ())
+(declare-function org-date-from-calendar "org" ())
+(declare-function org-dynamic-block-insert-dblock "org" (&optional arg))
+(declare-function org-dblock-update "org" (&optional arg))
+(declare-function org-deadline "org" (arg1 &optional time))
+(declare-function org-decrease-number-at-point "org" (&optional inc))
+(declare-function org-delete-backward-char "org" (n))
+(declare-function org-delete-char "org" (n))
+(declare-function org-delete-indentation "org" (&optional arg))
+(declare-function org-demote-subtree "org" ())
+(declare-function org-display-outline-path "org" (&optional file current separator just-return-string))
+(declare-function org-down-element "org" ())
+(declare-function org-edit-special "org" (&optional arg))
+(declare-function org-element-at-point "org-element" ())
+(declare-function org-element-type "org-element" (element))
+(declare-function org-emphasize "org" (&optional char))
+(declare-function org-end-of-line "org" (&optional n))
+(declare-function org-entry-put "org" (pom property value))
+(declare-function org-eval-in-calendar "org" (form &optional keepdate))
+(declare-function org-evaluate-time-range "org" (&optional to-buffer))
+(declare-function org-export-dispatch "org" (&optional arg))
+(declare-function org-feed-goto-inbox "org" (feed))
+(declare-function org-feed-update-all "org" ())
+(declare-function org-fill-paragraph "org" (&optional justify region))
+(declare-function org-find-file-at-mouse "org" (ev))
+(declare-function org-footnote-action "org" (&optional special))
+(declare-function org-force-cycle-archived "org" ())
+(declare-function org-force-self-insert "org" (n))
+(declare-function org-forward-element "org" ())
+(declare-function org-forward-heading-same-level "org" (arg &optional invisible-ok))
+(declare-function org-forward-paragraph "org" ())
+(declare-function org-forward-sentence "org" (&optional arg))
+(declare-function org-goto "org" (&optional alternative-interface))
+(declare-function org-goto-calendar "org" (&optional arg))
+(declare-function org-inc-effort "org" ())
+(declare-function org-increase-number-at-point "org" (&optional inc))
+(declare-function org-info-find-node "org" (&optional nodename))
+(declare-function org-insert-all-links "org" (arg &optional pre post))
+(declare-function org-insert-drawer "org" (&optional arg drawer))
+(declare-function org-insert-heading-respect-content "org" (&optional invisible-ok))
+(declare-function org-insert-last-stored-link "org" (arg))
+(declare-function org-insert-link "org" (&optional complete-file link-location default-description))
+(declare-function org-insert-structure-template "org" (type))
+(declare-function org-insert-todo-heading "org" (arg &optional force-heading))
+(declare-function org-insert-todo-heading-respect-content "org" (&optional force-state))
+(declare-function org-kill-line "org" (&optional arg))
+(declare-function org-kill-note-or-show-branches "org" ())
+(declare-function org-list-make-subtree "org" ())
+(declare-function org-mark-element "org" ())
+(declare-function org-mark-ring-goto "org" (&optional n))
+(declare-function org-mark-ring-push "org" (&optional pos buffer))
+(declare-function org-mark-subtree "org" (&optional up))
+(declare-function org-match-sparse-tree "org" (&optional todo-only match))
+(declare-function org-meta-return "org" (&optional arg))
+(declare-function org-metadown "org" (&optional _arg))
+(declare-function org-metaleft "org" (&optional _))
+(declare-function org-metaright "org" (&optional _arg))
+(declare-function org-metaup "org" (&optional _arg))
+(declare-function org-narrow-to-block "org" ())
+(declare-function org-narrow-to-element "org" ())
+(declare-function org-narrow-to-subtree "org" ())
+(declare-function org-next-block "org" (arg &optional backward block-regexp))
+(declare-function org-next-link "org" (&optional search-backward))
+(declare-function org-next-visible-heading "org" (arg))
+(declare-function org-open-at-mouse "org" (ev))
+(declare-function org-open-at-point "org" (&optional arg reference-buffer))
+(declare-function org-open-line "org" (n))
+(declare-function org-paste-special "org" (arg))
+(declare-function org-plot/gnuplot "org-plot" (&optional params))
+(declare-function org-previous-block "org" (arg &optional block-regexp))
+(declare-function org-previous-link "org" ())
+(declare-function org-previous-visible-heading "org" (arg))
+(declare-function org-priority "org" (&optional action show))
+(declare-function org-promote-subtree "org" ())
+(declare-function org-redisplay-inline-images "org" ())
+(declare-function org-refile "org" (&optional arg1 default-buffer rfloc msg))
+(declare-function org-reftex-citation "org" ())
+(declare-function org-reload "org" (&optional arg1))
+(declare-function org-remove-file "org" (&optional file))
+(declare-function org-resolve-clocks "org" (&optional only-dangling-p prompt-fn last-valid))
+(declare-function org-return "org" (&optional indent))
+(declare-function org-return-indent "org" ())
+(declare-function org-reveal "org" (&optional siblings))
+(declare-function org-schedule "org" (arg &optional time))
+(declare-function org-self-insert-command "org" (N))
+(declare-function org-set-effort "org" (&optional increment value))
+(declare-function org-set-property "org" (property value))
+(declare-function org-set-property-and-value "org" (use-last))
+(declare-function org-set-tags-command "org" (&optional arg))
+(declare-function org-shiftcontroldown "org" (&optional n))
+(declare-function org-shiftcontrolleft "org" ())
+(declare-function org-shiftcontrolright "org" ())
+(declare-function org-shiftcontrolup "org" (&optional n))
+(declare-function org-shiftdown "org" (&optional arg))
+(declare-function org-shiftleft "org" (&optional arg))
+(declare-function org-shiftmetadown "org" (&optional _arg))
+(declare-function org-shiftmetaleft "org" ())
+(declare-function org-shiftmetaright "org" ())
+(declare-function org-shiftmetaup "org" (&optional arg))
+(declare-function org-shiftright "org" (&optional arg))
+(declare-function org-shifttab "org" (&optional arg))
+(declare-function org-shiftup "org" (&optional arg))
+(declare-function org-show-all "org" (&optional types))
+(declare-function org-show-children "org" (&optional level))
+(declare-function org-show-subtree "org" ())
+(declare-function org-sort "org" (&optional with-case))
+(declare-function org-sparse-tree "org" (&optional arg type))
+(declare-function org-table-blank-field "org" ())
+(declare-function org-table-copy-down "org" (n))
+(declare-function org-table-create-or-convert-from-region "org" (arg))
+(declare-function org-table-create-with-table\.el "org-table" ())
+(declare-function org-table-edit-field "org" (arg))
+(declare-function org-table-eval-formula "org" (&optional arg equation suppress-align suppress-const suppress-store suppress-analysis))
+(declare-function org-table-field-info "org" (arg))
+(declare-function org-table-rotate-recalc-marks "org" (&optional newchar))
+(declare-function org-table-sum "org" (&optional beg end nlast))
+(declare-function org-table-toggle-coordinate-overlays "org" ())
+(declare-function org-table-toggle-formula-debugger "org" ())
+(declare-function org-time-stamp "org" (arg &optional inactive))
+(declare-function org-time-stamp-inactive "org" (&optional arg))
+(declare-function org-timer "org" (&optional restart no-insert))
+(declare-function org-timer-item "org" (&optional arg))
+(declare-function org-timer-pause-or-continue "org" (&optional stop))
+(declare-function org-timer-set-timer "org" (&optional opt))
+(declare-function org-timer-start "org" (&optional offset))
+(declare-function org-timer-stop "org" ())
+(declare-function org-todo "org" (&optional arg1))
+(declare-function org-toggle-archive-tag "org" (&optional find-done))
+(declare-function org-toggle-checkbox "org" (&optional toggle-presence))
+(declare-function org-toggle-comment "org" ())
+(declare-function org-toggle-fixed-width "org" ())
+(declare-function org-toggle-inline-images "org" (&optional include-linked))
+(declare-function org-latex-preview "org" (&optional arg))
+(declare-function org-toggle-narrow-to-subtree "org" ())
+(declare-function org-toggle-ordered-property "org" ())
+(declare-function org-toggle-pretty-entities "org" ())
+(declare-function org-toggle-tags-groups "org" ())
+(declare-function org-toggle-time-stamp-overlays "org" ())
+(declare-function org-transpose-element "org" ())
+(declare-function org-transpose-words "org" ())
+(declare-function org-tree-to-indirect-buffer "org" (&optional arg))
+(declare-function org-up-element "org" ())
+(declare-function org-update-statistics-cookies "org" (all))
+(declare-function org-yank "org" (&optional arg))
+(declare-function orgtbl-ascii-plot "org-table" (&optional ask))
+
+
+
+;;; Variables
+
+(defvar org-mode-map (make-sparse-keymap)
+ "Keymap fo Org mode.")
+
+(defcustom org-replace-disputed-keys nil
+ "Non-nil means use alternative key bindings for some keys.
+
+Org mode uses S-<cursor> keys for changing timestamps and priorities.
+These keys are also used by other packages like Shift Select mode,
+CUA mode or Windmove. If you want to use Org mode together with
+one of these other modes, or more generally if you would like to
+move some Org mode commands to other keys, set this variable and
+configure the keys with the variable `org-disputed-keys'.
+
+This option is only relevant at load-time of Org mode, and must be set
+*before* org.el is loaded. Changing it requires a restart of Emacs to
+become effective."
+ :group 'org-startup
+ :type 'boolean
+ :safe #'booleanp)
+
+(defcustom org-use-extra-keys nil
+ "Non-nil means use extra key sequence definitions for certain commands.
+This happens automatically if `window-system' is nil. This
+variable lets you do the same manually. You must set it before
+loading Org."
+ :group 'org-startup
+ :type 'boolean
+ :safe #'booleanp)
+
+(defvaralias 'org-CUA-compatible 'org-replace-disputed-keys)
+
+(defcustom org-disputed-keys
+ '(([(shift up)] . [(meta p)])
+ ([(shift down)] . [(meta n)])
+ ([(shift left)] . [(meta -)])
+ ([(shift right)] . [(meta +)])
+ ([(control shift right)] . [(meta shift +)])
+ ([(control shift left)] . [(meta shift -)]))
+ "Keys for which Org mode and other modes compete.
+This is an alist, cars are the default keys, second element specifies
+the alternative to use when `org-replace-disputed-keys' is t.
+
+Keys can be specified in any syntax supported by `define-key'.
+The value of this option takes effect only at Org mode startup,
+therefore you'll have to restart Emacs to apply it after changing."
+ :group 'org-startup
+ :type 'alist)
+
+(defcustom org-mouse-1-follows-link
+ (if (boundp 'mouse-1-click-follows-link) mouse-1-click-follows-link t)
+ "Non-nil means mouse-1 on a link will follow the link.
+A longer mouse click will still set point. Needs to be set
+before org.el is loaded."
+ :group 'org-link-follow
+ :version "26.1"
+ :package-version '(Org . "8.3")
+ :type '(choice
+ (const :tag "A double click follows the link" double)
+ (const :tag "Unconditionally follow the link with mouse-1" t)
+ (integer :tag "mouse-1 click does not follow the link if longer than N ms" 450))
+ :safe t)
+
+(defcustom org-tab-follows-link nil
+ "Non-nil means on links TAB will follow the link.
+Needs to be set before Org is loaded.
+This really should not be used, it does not make sense, and the
+implementation is bad."
+ :group 'org-link-follow
+ :type 'boolean)
+
+(defcustom org-follow-link-hook nil
+ "Hook that is run after a link has been followed."
+ :group 'org-link-follow
+ :type 'hook)
+
+(defcustom org-return-follows-link nil
+ "Non-nil means on links RET will follow the link.
+In tables, the special behavior of RET has precedence."
+ :group 'org-link-follow
+ :type 'boolean
+ :safe t)
+
+
+;;; Functions
+
+;;;; Base functions
+(defun org-key (key)
+ "Select key according to `org-replace-disputed-keys' and `org-disputed-keys'.
+Or return the original if not disputed."
+ (when org-replace-disputed-keys
+ (let* ((nkey (key-description key))
+ (x (cl-find-if (lambda (x) (equal (key-description (car x)) nkey))
+ org-disputed-keys)))
+ (setq key (if x (cdr x) key))))
+ key)
+
+(defun org-defkey (keymap key def)
+ "Define a key, possibly translated, as returned by `org-key'."
+ (define-key keymap (org-key key) def))
+
+(defun org-remap (map &rest commands)
+ "In MAP, remap the functions given in COMMANDS.
+COMMANDS is a list of alternating OLDDEF NEWDEF command names."
+ (let (new old)
+ (while commands
+ (setq old (pop commands) new (pop commands))
+ (org-defkey map (vector 'remap old) new))))
+
+
+;;; Mouse map
+
+(defvar org-mouse-map (make-sparse-keymap))
+(org-defkey org-mouse-map [mouse-2] 'org-open-at-mouse)
+(org-defkey org-mouse-map [mouse-3] 'org-find-file-at-mouse)
+
+(when org-mouse-1-follows-link
+ (org-defkey org-mouse-map [follow-link] 'mouse-face))
+
+(when org-tab-follows-link
+ (org-defkey org-mouse-map (kbd "<tab>") #'org-open-at-point)
+ (org-defkey org-mouse-map (kbd "TAB") #'org-open-at-point))
+
+
+;;; Read date map
+
+(defvar org-read-date-minibuffer-local-map
+ (let* ((map (make-sparse-keymap)))
+ (set-keymap-parent map minibuffer-local-map)
+ (org-defkey map (kbd ".")
+ (lambda () (interactive)
+ ;; Are we at the beginning of the prompt?
+ (if (looking-back "^[^:]+: "
+ (let ((inhibit-field-text-motion t))
+ (line-beginning-position)))
+ (org-eval-in-calendar '(calendar-goto-today))
+ (insert "."))))
+ (org-defkey map (kbd "C-.")
+ (lambda () (interactive)
+ (org-eval-in-calendar '(calendar-goto-today))))
+ (org-defkey map (kbd "M-S-<left>")
+ (lambda () (interactive)
+ (org-eval-in-calendar '(calendar-backward-month 1))))
+ (org-defkey map (kbd "ESC S-<left>")
+ (lambda () (interactive)
+ (org-eval-in-calendar '(calendar-backward-month 1))))
+ (org-defkey map (kbd "M-S-<right>")
+ (lambda () (interactive)
+ (org-eval-in-calendar '(calendar-forward-month 1))))
+ (org-defkey map (kbd "ESC S-<right>")
+ (lambda () (interactive)
+ (org-eval-in-calendar '(calendar-forward-month 1))))
+ (org-defkey map (kbd "M-S-<up>")
+ (lambda () (interactive)
+ (org-eval-in-calendar '(calendar-backward-year 1))))
+ (org-defkey map (kbd "ESC S-<up>")
+ (lambda () (interactive)
+ (org-eval-in-calendar '(calendar-backward-year 1))))
+ (org-defkey map (kbd "M-S-<down>")
+ (lambda () (interactive)
+ (org-eval-in-calendar '(calendar-forward-year 1))))
+ (org-defkey map (kbd "ESC S-<down>")
+ (lambda () (interactive)
+ (org-eval-in-calendar '(calendar-forward-year 1))))
+ (org-defkey map (kbd "S-<up>")
+ (lambda () (interactive)
+ (org-eval-in-calendar '(calendar-backward-week 1))))
+ (org-defkey map (kbd "S-<down>")
+ (lambda () (interactive)
+ (org-eval-in-calendar '(calendar-forward-week 1))))
+ (org-defkey map (kbd "S-<left>")
+ (lambda () (interactive)
+ (org-eval-in-calendar '(calendar-backward-day 1))))
+ (org-defkey map (kbd "S-<right>")
+ (lambda () (interactive)
+ (org-eval-in-calendar '(calendar-forward-day 1))))
+ (org-defkey map (kbd "!")
+ (lambda () (interactive)
+ (org-eval-in-calendar '(diary-view-entries))
+ (message "")))
+ (org-defkey map (kbd ">")
+ (lambda () (interactive)
+ (org-eval-in-calendar '(calendar-scroll-left 1))))
+ (org-defkey map (kbd "<")
+ (lambda () (interactive)
+ (org-eval-in-calendar '(calendar-scroll-right 1))))
+ (org-defkey map (kbd "C-v")
+ (lambda () (interactive)
+ (org-eval-in-calendar
+ '(calendar-scroll-left-three-months 1))))
+ (org-defkey map (kbd "M-v")
+ (lambda () (interactive)
+ (org-eval-in-calendar
+ '(calendar-scroll-right-three-months 1))))
+ map)
+ "Keymap for minibuffer commands when using `org-read-date'.")
+
+
+;;; Global bindings
+
+;;;; Outline functions
+(define-key org-mode-map [menu-bar headings] 'undefined)
+(define-key org-mode-map [menu-bar hide] 'undefined)
+(define-key org-mode-map [menu-bar show] 'undefined)
+
+(define-key org-mode-map [remap outline-mark-subtree] #'org-mark-subtree)
+(define-key org-mode-map [remap outline-show-subtree] #'org-show-subtree)
+(define-key org-mode-map [remap outline-forward-same-level]
+ #'org-forward-heading-same-level)
+(define-key org-mode-map [remap outline-backward-same-level]
+ #'org-backward-heading-same-level)
+(define-key org-mode-map [remap outline-show-branches]
+ #'org-kill-note-or-show-branches)
+(define-key org-mode-map [remap outline-promote] #'org-promote-subtree)
+(define-key org-mode-map [remap outline-demote] #'org-demote-subtree)
+(define-key org-mode-map [remap outline-insert-heading] #'org-ctrl-c-ret)
+(define-key org-mode-map [remap outline-next-visible-heading]
+ #'org-next-visible-heading)
+(define-key org-mode-map [remap outline-previous-visible-heading]
+ #'org-previous-visible-heading)
+(define-key org-mode-map [remap show-children] #'org-show-children)
+
+;;;; Make `C-c C-x' a prefix key
+(org-defkey org-mode-map (kbd "C-c C-x") (make-sparse-keymap))
+
+;;;; TAB key with modifiers
+(org-defkey org-mode-map (kbd "C-i") #'org-cycle)
+(org-defkey org-mode-map (kbd "<tab>") #'org-cycle)
+(org-defkey org-mode-map (kbd "C-<tab>") #'org-force-cycle-archived)
+;; Override text-mode binding to expose `complete-symbol' for
+;; pcomplete functionality.
+(org-defkey org-mode-map (kbd "M-<tab>") nil)
+(org-defkey org-mode-map (kbd "M-TAB") nil)
+(org-defkey org-mode-map (kbd "ESC <tab>") nil)
+(org-defkey org-mode-map (kbd "ESC TAB") nil)
+
+(org-defkey org-mode-map (kbd "<S-iso-leftab>") #'org-shifttab)
+(org-defkey org-mode-map (kbd "S-<tab>") #'org-shifttab)
+(org-defkey org-mode-map (kbd "S-TAB") #'org-shifttab)
+(define-key org-mode-map (kbd "<backtab>") #'org-shifttab)
+
+;;;; RET/<return> key with modifiers
+(org-defkey org-mode-map (kbd "S-<return>") #'org-table-copy-down)
+(org-defkey org-mode-map (kbd "S-RET") #'org-table-copy-down)
+(org-defkey org-mode-map (kbd "M-S-<return>") #'org-insert-todo-heading)
+(org-defkey org-mode-map (kbd "M-S-RET") #'org-insert-todo-heading)
+(org-defkey org-mode-map (kbd "ESC S-<return>") #'org-insert-todo-heading)
+(org-defkey org-mode-map (kbd "ESC S-RET") #'org-insert-todo-heading)
+(org-defkey org-mode-map (kbd "M-<return>") #'org-meta-return)
+(org-defkey org-mode-map (kbd "M-RET") #'org-meta-return)
+(org-defkey org-mode-map (kbd "ESC <return>") #'org-meta-return)
+(org-defkey org-mode-map (kbd "ESC RET") #'org-meta-return)
+
+;;;; Cursor keys with modifiers
+(org-defkey org-mode-map (kbd "M-<left>") #'org-metaleft)
+(org-defkey org-mode-map (kbd "M-<right>") #'org-metaright)
+(org-defkey org-mode-map (kbd "ESC <right>") #'org-metaright)
+(org-defkey org-mode-map (kbd "M-<up>") #'org-metaup)
+(org-defkey org-mode-map (kbd "ESC <up>") #'org-metaup)
+(org-defkey org-mode-map (kbd "M-<down>") #'org-metadown)
+(org-defkey org-mode-map (kbd "ESC <down>") #'org-metadown)
+
+(org-defkey org-mode-map (kbd "C-M-S-<right>") #'org-increase-number-at-point)
+(org-defkey org-mode-map (kbd "C-M-S-<left>") #'org-decrease-number-at-point)
+(org-defkey org-mode-map (kbd "M-S-<left>") #'org-shiftmetaleft)
+(org-defkey org-mode-map (kbd "ESC S-<left>") #'org-shiftmetaleft)
+(org-defkey org-mode-map (kbd "M-S-<right>") #'org-shiftmetaright)
+(org-defkey org-mode-map (kbd "ESC S-<right>") #'org-shiftmetaright)
+(org-defkey org-mode-map (kbd "M-S-<up>") #'org-shiftmetaup)
+(org-defkey org-mode-map (kbd "ESC S-<up>") #'org-shiftmetaup)
+(org-defkey org-mode-map (kbd "M-S-<down>") #'org-shiftmetadown)
+(org-defkey org-mode-map (kbd "ESC S-<down>") #'org-shiftmetadown)
+
+(org-defkey org-mode-map (kbd "S-<up>") #'org-shiftup)
+(org-defkey org-mode-map (kbd "S-<down>") #'org-shiftdown)
+(org-defkey org-mode-map (kbd "S-<left>") #'org-shiftleft)
+(org-defkey org-mode-map (kbd "S-<right>") #'org-shiftright)
+
+(org-defkey org-mode-map (kbd "C-S-<right>") #'org-shiftcontrolright)
+(org-defkey org-mode-map (kbd "C-S-<left>") #'org-shiftcontrolleft)
+(org-defkey org-mode-map (kbd "C-S-<up>") #'org-shiftcontrolup)
+(org-defkey org-mode-map (kbd "C-S-<down>") #'org-shiftcontroldown)
+
+;;;; Extra keys for TTY access.
+
+;; We only set them when really needed because otherwise the
+;; menus don't show the simple keys
+
+(when (or org-use-extra-keys (not window-system))
+ (org-defkey org-mode-map (kbd "C-c C-x c") #'org-table-copy-down)
+ (org-defkey org-mode-map (kbd "C-c C-x m") #'org-meta-return)
+ (org-defkey org-mode-map (kbd "C-c C-x M") #'org-insert-todo-heading)
+ (org-defkey org-mode-map (kbd "C-c C-x RET") #'org-meta-return)
+ (org-defkey org-mode-map (kbd "ESC RET") #'org-meta-return)
+ (org-defkey org-mode-map (kbd "ESC <left>") #'org-metaleft)
+ (org-defkey org-mode-map (kbd "C-c C-x l") #'org-metaleft)
+ (org-defkey org-mode-map (kbd "ESC <right>") #'org-metaright)
+ (org-defkey org-mode-map (kbd "C-c C-x r") #'org-metaright)
+ (org-defkey org-mode-map (kbd "C-c C-x u") #'org-metaup)
+ (org-defkey org-mode-map (kbd "C-c C-x d") #'org-metadown)
+ (org-defkey org-mode-map (kbd "C-c C-x L") #'org-shiftmetaleft)
+ (org-defkey org-mode-map (kbd "C-c C-x R") #'org-shiftmetaright)
+ (org-defkey org-mode-map (kbd "C-c C-x U") #'org-shiftmetaup)
+ (org-defkey org-mode-map (kbd "C-c C-x D") #'org-shiftmetadown)
+ (org-defkey org-mode-map (kbd "C-c <up>") #'org-shiftup)
+ (org-defkey org-mode-map (kbd "C-c <down>") #'org-shiftdown)
+ (org-defkey org-mode-map (kbd "C-c <left>") #'org-shiftleft)
+ (org-defkey org-mode-map (kbd "C-c <right>") #'org-shiftright)
+ (org-defkey org-mode-map (kbd "C-c C-x <right>") #'org-shiftcontrolright)
+ (org-defkey org-mode-map (kbd "C-c C-x <left>") #'org-shiftcontrolleft))
+
+;;;; Narrowing bindings
+(org-defkey org-mode-map (kbd "C-x n s") #'org-narrow-to-subtree)
+(org-defkey org-mode-map (kbd "C-x n b") #'org-narrow-to-block)
+(org-defkey org-mode-map (kbd "C-x n e") #'org-narrow-to-element)
+
+;;;; Remap usual Emacs bindings
+(org-remap org-mode-map
+ 'self-insert-command 'org-self-insert-command
+ 'delete-char 'org-delete-char
+ 'delete-backward-char 'org-delete-backward-char
+ 'kill-line 'org-kill-line
+ 'open-line 'org-open-line
+ 'yank 'org-yank
+ 'comment-dwim 'org-comment-dwim
+ 'move-beginning-of-line 'org-beginning-of-line
+ 'move-end-of-line 'org-end-of-line
+ 'forward-paragraph 'org-forward-paragraph
+ 'backward-paragraph 'org-backward-paragraph
+ 'backward-sentence 'org-backward-sentence
+ 'forward-sentence 'org-forward-sentence
+ 'fill-paragraph 'org-fill-paragraph
+ 'delete-indentation 'org-delete-indentation
+ 'transpose-words 'org-transpose-words)
+
+;;;; All the other keys
+(org-defkey org-mode-map (kbd "|") #'org-force-self-insert)
+(org-defkey org-mode-map (kbd "C-c C-r") #'org-reveal)
+(org-defkey org-mode-map (kbd "C-M-t") #'org-transpose-element)
+(org-defkey org-mode-map (kbd "M-}") #'org-forward-element)
+(org-defkey org-mode-map (kbd "ESC }") #'org-forward-element)
+(org-defkey org-mode-map (kbd "M-{") #'org-backward-element)
+(org-defkey org-mode-map (kbd "ESC {") #'org-backward-element)
+(org-defkey org-mode-map (kbd "C-c C-^") #'org-up-element)
+(org-defkey org-mode-map (kbd "C-c C-_") #'org-down-element)
+(org-defkey org-mode-map (kbd "C-c C-f") #'org-forward-heading-same-level)
+(org-defkey org-mode-map (kbd "C-c C-b") #'org-backward-heading-same-level)
+(org-defkey org-mode-map (kbd "C-c M-f") #'org-next-block)
+(org-defkey org-mode-map (kbd "C-c M-b") #'org-previous-block)
+(org-defkey org-mode-map (kbd "C-c $") #'org-archive-subtree)
+(org-defkey org-mode-map (kbd "C-c C-x C-s") #'org-archive-subtree)
+(org-defkey org-mode-map (kbd "C-c C-x C-a") #'org-archive-subtree-default)
+(org-defkey org-mode-map (kbd "C-c C-x d") #'org-insert-drawer)
+(org-defkey org-mode-map (kbd "C-c C-x a") #'org-toggle-archive-tag)
+(org-defkey org-mode-map (kbd "C-c C-x A") #'org-archive-to-archive-sibling)
+(org-defkey org-mode-map (kbd "C-c C-x b") #'org-tree-to-indirect-buffer)
+(org-defkey org-mode-map (kbd "C-c C-x q") #'org-toggle-tags-groups)
+(org-defkey org-mode-map (kbd "C-c C-j") #'org-goto)
+(org-defkey org-mode-map (kbd "C-c C-t") #'org-todo)
+(org-defkey org-mode-map (kbd "C-c C-q") #'org-set-tags-command)
+(org-defkey org-mode-map (kbd "C-c C-s") #'org-schedule)
+(org-defkey org-mode-map (kbd "C-c C-d") #'org-deadline)
+(org-defkey org-mode-map (kbd "C-c ;") #'org-toggle-comment)
+(org-defkey org-mode-map (kbd "C-c C-w") #'org-refile)
+(org-defkey org-mode-map (kbd "C-c M-w") #'org-copy)
+(org-defkey org-mode-map (kbd "C-c /") #'org-sparse-tree) ;minor-mode reserved
+(org-defkey org-mode-map (kbd "C-c \\") #'org-match-sparse-tree) ;minor-mode r.
+(org-defkey org-mode-map (kbd "C-c RET") #'org-ctrl-c-ret)
+(org-defkey org-mode-map (kbd "C-c C-x c") #'org-clone-subtree-with-time-shift)
+(org-defkey org-mode-map (kbd "C-c C-x v") #'org-copy-visible)
+(org-defkey org-mode-map (kbd "C-<return>") #'org-insert-heading-respect-content)
+(org-defkey org-mode-map (kbd "C-S-<return>") #'org-insert-todo-heading-respect-content)
+(org-defkey org-mode-map (kbd "C-c C-x C-n") #'org-next-link)
+(org-defkey org-mode-map (kbd "C-c C-x C-p") #'org-previous-link)
+(org-defkey org-mode-map (kbd "C-c C-l") #'org-insert-link)
+(org-defkey org-mode-map (kbd "C-c M-l") #'org-insert-last-stored-link)
+(org-defkey org-mode-map (kbd "C-c C-M-l") #'org-insert-all-links)
+(org-defkey org-mode-map (kbd "C-c C-o") #'org-open-at-point)
+(org-defkey org-mode-map (kbd "C-c %") #'org-mark-ring-push)
+(org-defkey org-mode-map (kbd "C-c &") #'org-mark-ring-goto)
+(org-defkey org-mode-map (kbd "C-c C-z") #'org-add-note) ;alternative binding
+(org-defkey org-mode-map (kbd "C-c .") #'org-time-stamp) ;minor-mode reserved
+(org-defkey org-mode-map (kbd "C-c !") #'org-time-stamp-inactive) ;minor-mode r.
+(org-defkey org-mode-map (kbd "C-c ,") #'org-priority) ;minor-mode reserved
+(org-defkey org-mode-map (kbd "C-c C-y") #'org-evaluate-time-range)
+(org-defkey org-mode-map (kbd "C-c >") #'org-goto-calendar)
+(org-defkey org-mode-map (kbd "C-c <") #'org-date-from-calendar)
+(org-defkey org-mode-map (kbd "C-,") #'org-cycle-agenda-files)
+(org-defkey org-mode-map (kbd "C-'") #'org-cycle-agenda-files)
+(org-defkey org-mode-map (kbd "C-c [") #'org-agenda-file-to-front)
+(org-defkey org-mode-map (kbd "C-c ]") #'org-remove-file)
+(org-defkey org-mode-map (kbd "C-c C-x <") #'org-agenda-set-restriction-lock)
+(org-defkey org-mode-map (kbd "C-c C-x >") #'org-agenda-remove-restriction-lock)
+(org-defkey org-mode-map (kbd "C-c -") #'org-ctrl-c-minus)
+(org-defkey org-mode-map (kbd "C-c *") #'org-ctrl-c-star)
+(org-defkey org-mode-map (kbd "C-c TAB") #'org-ctrl-c-tab)
+(org-defkey org-mode-map (kbd "C-c ^") #'org-sort)
+(org-defkey org-mode-map (kbd "C-c C-c") #'org-ctrl-c-ctrl-c)
+(org-defkey org-mode-map (kbd "C-c C-k") #'org-kill-note-or-show-branches)
+(org-defkey org-mode-map (kbd "C-c #") #'org-update-statistics-cookies)
+(org-defkey org-mode-map (kbd "RET") #'org-return)
+(org-defkey org-mode-map (kbd "C-j") #'org-return-indent)
+(org-defkey org-mode-map (kbd "C-c ?") #'org-table-field-info)
+(org-defkey org-mode-map (kbd "C-c SPC") #'org-table-blank-field)
+(org-defkey org-mode-map (kbd "C-c +") #'org-table-sum)
+(org-defkey org-mode-map (kbd "C-c =") #'org-table-eval-formula)
+(org-defkey org-mode-map (kbd "C-c '") #'org-edit-special)
+(org-defkey org-mode-map (kbd "C-c `") #'org-table-edit-field)
+(org-defkey org-mode-map (kbd "C-c \" a") #'orgtbl-ascii-plot)
+(org-defkey org-mode-map (kbd "C-c \" g") #'org-plot/gnuplot)
+(org-defkey org-mode-map (kbd "C-c |") #'org-table-create-or-convert-from-region)
+(org-defkey org-mode-map (kbd "C-#") #'org-table-rotate-recalc-marks)
+(org-defkey org-mode-map (kbd "C-c ~") #'org-table-create-with-table.el)
+(org-defkey org-mode-map (kbd "C-c C-a") #'org-attach)
+(org-defkey org-mode-map (kbd "C-c }") #'org-table-toggle-coordinate-overlays)
+(org-defkey org-mode-map (kbd "C-c {") #'org-table-toggle-formula-debugger)
+(org-defkey org-mode-map (kbd "C-c C-e") #'org-export-dispatch)
+(org-defkey org-mode-map (kbd "C-c :") #'org-toggle-fixed-width)
+(org-defkey org-mode-map (kbd "C-c C-x C-f") #'org-emphasize)
+(org-defkey org-mode-map (kbd "C-c C-x f") #'org-footnote-action)
+(org-defkey org-mode-map (kbd "C-c @") #'org-mark-subtree)
+(org-defkey org-mode-map (kbd "M-h") #'org-mark-element)
+(org-defkey org-mode-map (kbd "ESC h") #'org-mark-element)
+(org-defkey org-mode-map (kbd "C-c C-*") #'org-list-make-subtree)
+(org-defkey org-mode-map (kbd "C-c C-x C-w") #'org-cut-special)
+(org-defkey org-mode-map (kbd "C-c C-x M-w") #'org-copy-special)
+(org-defkey org-mode-map (kbd "C-c C-x C-y") #'org-paste-special)
+(org-defkey org-mode-map (kbd "C-c C-x C-t") #'org-toggle-time-stamp-overlays)
+(org-defkey org-mode-map (kbd "C-c C-x C-i") #'org-clock-in)
+(org-defkey org-mode-map (kbd "C-c C-x C-x") #'org-clock-in-last)
+(org-defkey org-mode-map (kbd "C-c C-x C-z") #'org-resolve-clocks)
+(org-defkey org-mode-map (kbd "C-c C-x C-o") #'org-clock-out)
+(org-defkey org-mode-map (kbd "C-c C-x C-j") #'org-clock-goto)
+(org-defkey org-mode-map (kbd "C-c C-x C-q") #'org-clock-cancel)
+(org-defkey org-mode-map (kbd "C-c C-x C-d") #'org-clock-display)
+(org-defkey org-mode-map (kbd "C-c C-x x") #'org-dynamic-block-insert-dblock)
+(org-defkey org-mode-map (kbd "C-c C-x C-u") #'org-dblock-update)
+(org-defkey org-mode-map (kbd "C-c C-x C-l") #'org-latex-preview)
+(org-defkey org-mode-map (kbd "C-c C-x C-v") #'org-toggle-inline-images)
+(org-defkey org-mode-map (kbd "C-c C-x C-M-v") #'org-redisplay-inline-images)
+(org-defkey org-mode-map (kbd "C-c C-x \\") #'org-toggle-pretty-entities)
+(org-defkey org-mode-map (kbd "C-c C-x C-b") #'org-toggle-checkbox)
+(org-defkey org-mode-map (kbd "C-c C-x p") #'org-set-property)
+(org-defkey org-mode-map (kbd "C-c C-x P") #'org-set-property-and-value)
+(org-defkey org-mode-map (kbd "C-c C-x e") #'org-set-effort)
+(org-defkey org-mode-map (kbd "C-c C-x E") #'org-inc-effort)
+(org-defkey org-mode-map (kbd "C-c C-x o") #'org-toggle-ordered-property)
+(org-defkey org-mode-map (kbd "C-c C-,") #'org-insert-structure-template)
+(org-defkey org-mode-map (kbd "C-c C-x .") #'org-timer)
+(org-defkey org-mode-map (kbd "C-c C-x -") #'org-timer-item)
+(org-defkey org-mode-map (kbd "C-c C-x 0") #'org-timer-start)
+(org-defkey org-mode-map (kbd "C-c C-x _") #'org-timer-stop)
+(org-defkey org-mode-map (kbd "C-c C-x ;") #'org-timer-set-timer)
+(org-defkey org-mode-map (kbd "C-c C-x ,") #'org-timer-pause-or-continue)
+(org-defkey org-mode-map (kbd "C-c C-x C-c") #'org-columns)
+(org-defkey org-mode-map (kbd "C-c C-x !") #'org-reload)
+(org-defkey org-mode-map (kbd "C-c C-x g") #'org-feed-update-all)
+(org-defkey org-mode-map (kbd "C-c C-x G") #'org-feed-goto-inbox)
+(org-defkey org-mode-map (kbd "C-c C-x [") #'org-reftex-citation)
+(org-defkey org-mode-map (kbd "C-c C-x I") #'org-info-find-node)
+
+
+;;; Speed keys
+
+(defcustom org-use-speed-commands nil
+ "Non-nil means activate single letter commands at beginning of a headline.
+This may also be a function to test for appropriate locations where speed
+commands should be active.
+
+For example, to activate speed commands when the point is on any
+star at the beginning of the headline, you can do this:
+
+ (setq org-use-speed-commands
+ (lambda () (and (looking-at org-outline-regexp) (looking-back \"^\\**\"))))"
+ :group 'org-structure
+ :type '(choice
+ (const :tag "Never" nil)
+ (const :tag "At beginning of headline stars" t)
+ (function)))
+
+(defcustom org-speed-commands-user nil
+ "Alist of additional speed commands.
+This list will be checked before `org-speed-commands-default'
+when the variable `org-use-speed-commands' is non-nil
+and when the cursor is at the beginning of a headline.
+The car of each entry is a string with a single letter, which must
+be assigned to `self-insert-command' in the global map.
+The cdr is either a command to be called interactively, a function
+to be called, or a form to be evaluated.
+An entry that is just a list with a single string will be interpreted
+as a descriptive headline that will be added when listing the speed
+commands in the Help buffer using the `?' speed command."
+ :group 'org-structure
+ :type '(repeat :value ("k" . ignore)
+ (choice :value ("k" . ignore)
+ (list :tag "Descriptive Headline" (string :tag "Headline"))
+ (cons :tag "Letter and Command"
+ (string :tag "Command letter")
+ (choice
+ (function)
+ (sexp))))))
+
+(defcustom org-speed-command-hook
+ '(org-speed-command-activate org-babel-speed-command-activate)
+ "Hook for activating speed commands at strategic locations.
+Hook functions are called in sequence until a valid handler is
+found.
+
+Each hook takes a single argument, a user-pressed command key
+which is also a `self-insert-command' from the global map.
+
+Within the hook, examine the cursor position and the command key
+and return nil or a valid handler as appropriate. Handler could
+be one of an interactive command, a function, or a form.
+
+Set `org-use-speed-commands' to non-nil value to enable this
+hook. The default setting is `org-speed-command-activate'."
+ :group 'org-structure
+ :version "24.1"
+ :type 'hook)
+
+(defconst org-speed-commands-default
+ '(("Outline Navigation")
+ ("n" . (org-speed-move-safe 'org-next-visible-heading))
+ ("p" . (org-speed-move-safe 'org-previous-visible-heading))
+ ("f" . (org-speed-move-safe 'org-forward-heading-same-level))
+ ("b" . (org-speed-move-safe 'org-backward-heading-same-level))
+ ("F" . org-next-block)
+ ("B" . org-previous-block)
+ ("u" . (org-speed-move-safe 'outline-up-heading))
+ ("j" . org-goto)
+ ("g" . (org-refile t))
+ ("Outline Visibility")
+ ("c" . org-cycle)
+ ("C" . org-shifttab)
+ (" " . org-display-outline-path)
+ ("s" . org-toggle-narrow-to-subtree)
+ ("k" . org-cut-subtree)
+ ("=" . org-columns)
+ ("Outline Structure Editing")
+ ("U" . org-metaup)
+ ("D" . org-metadown)
+ ("r" . org-metaright)
+ ("l" . org-metaleft)
+ ("R" . org-shiftmetaright)
+ ("L" . org-shiftmetaleft)
+ ("i" . (progn (forward-char 1) (call-interactively
+ 'org-insert-heading-respect-content)))
+ ("^" . org-sort)
+ ("w" . org-refile)
+ ("a" . org-archive-subtree-default-with-confirmation)
+ ("@" . org-mark-subtree)
+ ("#" . org-toggle-comment)
+ ("Clock Commands")
+ ("I" . org-clock-in)
+ ("O" . org-clock-out)
+ ("Meta Data Editing")
+ ("t" . org-todo)
+ ("," . (org-priority))
+ ("0" . (org-priority ?\ ))
+ ("1" . (org-priority ?A))
+ ("2" . (org-priority ?B))
+ ("3" . (org-priority ?C))
+ (":" . org-set-tags-command)
+ ("e" . org-set-effort)
+ ("E" . org-inc-effort)
+ ("W" . (lambda(m) (interactive "sMinutes before warning: ")
+ (org-entry-put (point) "APPT_WARNTIME" m)))
+ ("Agenda Views etc")
+ ("v" . org-agenda)
+ ("/" . org-sparse-tree)
+ ("Misc")
+ ("o" . org-open-at-point)
+ ("?" . org-speed-command-help)
+ ("<" . (org-agenda-set-restriction-lock 'subtree))
+ (">" . (org-agenda-remove-restriction-lock)))
+ "The default speed commands.")
+
+(defun org-print-speed-command (e)
+ (if (> (length (car e)) 1)
+ (progn
+ (princ "\n")
+ (princ (car e))
+ (princ "\n")
+ (princ (make-string (length (car e)) ?-))
+ (princ "\n"))
+ (princ (car e))
+ (princ " ")
+ (if (symbolp (cdr e))
+ (princ (symbol-name (cdr e)))
+ (prin1 (cdr e)))
+ (princ "\n")))
+
+(defun org-speed-command-help ()
+ "Show the available speed commands."
+ (interactive)
+ (unless org-use-speed-commands
+ (user-error "Speed commands are not activated, customize `org-use-speed-commands'"))
+ (with-output-to-temp-buffer "*Help*"
+ (princ "User-defined Speed commands\n===========================\n")
+ (mapc #'org-print-speed-command org-speed-commands-user)
+ (princ "\n")
+ (princ "Built-in Speed commands\n=======================\n")
+ (mapc #'org-print-speed-command org-speed-commands-default))
+ (with-current-buffer "*Help*"
+ (setq truncate-lines t)))
+
+(defun org-speed-move-safe (cmd)
+ "Execute CMD, but make sure that the cursor always ends up in a headline.
+If not, return to the original position and throw an error."
+ (interactive)
+ (let ((pos (point)))
+ (call-interactively cmd)
+ (unless (and (bolp) (org-at-heading-p))
+ (goto-char pos)
+ (error "Boundary reached while executing %s" cmd))))
+
+(defun org-speed-command-activate (keys)
+ "Hook for activating single-letter speed commands.
+`org-speed-commands-default' specifies a minimal command set.
+Use `org-speed-commands-user' for further customization."
+ (when (or (and (bolp) (looking-at org-outline-regexp))
+ (and (functionp org-use-speed-commands)
+ (funcall org-use-speed-commands)))
+ (cdr (assoc keys (append org-speed-commands-user
+ org-speed-commands-default)))))
+
+
+;;; Babel speed keys
+
+(defvar org-babel-key-prefix "\C-c\C-v"
+ "The key prefix for Babel interactive key-bindings.
+See `org-babel-key-bindings' for the list of interactive Babel
+functions which are assigned key bindings, and see
+`org-babel-map' for the actual babel keymap.")
+
+(defvar org-babel-map (make-sparse-keymap)
+ "The keymap for interactive Babel functions.")
+
+(defvar org-babel-key-bindings
+ '(("p" . org-babel-previous-src-block)
+ ("\C-p" . org-babel-previous-src-block)
+ ("n" . org-babel-next-src-block)
+ ("\C-n" . org-babel-next-src-block)
+ ("e" . org-babel-execute-maybe)
+ ("\C-e" . org-babel-execute-maybe)
+ ("o" . org-babel-open-src-block-result)
+ ("\C-o" . org-babel-open-src-block-result)
+ ("\C-v" . org-babel-expand-src-block)
+ ("v" . org-babel-expand-src-block)
+ ("u" . org-babel-goto-src-block-head)
+ ("\C-u" . org-babel-goto-src-block-head)
+ ("g" . org-babel-goto-named-src-block)
+ ("r" . org-babel-goto-named-result)
+ ("\C-r" . org-babel-goto-named-result)
+ ("\C-b" . org-babel-execute-buffer)
+ ("b" . org-babel-execute-buffer)
+ ("\C-s" . org-babel-execute-subtree)
+ ("s" . org-babel-execute-subtree)
+ ("\C-d" . org-babel-demarcate-block)
+ ("d" . org-babel-demarcate-block)
+ ("\C-t" . org-babel-tangle)
+ ("t" . org-babel-tangle)
+ ("\C-f" . org-babel-tangle-file)
+ ("f" . org-babel-tangle-file)
+ ("\C-c" . org-babel-check-src-block)
+ ("c" . org-babel-check-src-block)
+ ("\C-j" . org-babel-insert-header-arg)
+ ("j" . org-babel-insert-header-arg)
+ ("\C-l" . org-babel-load-in-session)
+ ("l" . org-babel-load-in-session)
+ ("\C-i" . org-babel-lob-ingest)
+ ("i" . org-babel-lob-ingest)
+ ("\C-I" . org-babel-view-src-block-info)
+ ("I" . org-babel-view-src-block-info)
+ ("\C-z" . org-babel-switch-to-session)
+ ("z" . org-babel-switch-to-session-with-code)
+ ("\C-a" . org-babel-sha1-hash)
+ ("a" . org-babel-sha1-hash)
+ ("h" . org-babel-describe-bindings)
+ ("\C-x" . org-babel-do-key-sequence-in-edit-buffer)
+ ("x" . org-babel-do-key-sequence-in-edit-buffer)
+ ("k" . org-babel-remove-result-one-or-many)
+ ("\C-\M-h" . org-babel-mark-block))
+ "Alist of key bindings and interactive Babel functions.
+This list associates interactive Babel functions
+with keys. Each element of this list will add an entry to the
+`org-babel-map' using the letter key which is the `car' of the
+a-list placed behind the generic `org-babel-key-prefix'.")
+
+(define-key org-mode-map org-babel-key-prefix org-babel-map)
+(pcase-dolist (`(,key . ,def) org-babel-key-bindings)
+ (define-key org-babel-map key def))
+
+(defun org-babel-speed-command-activate (keys)
+ "Hook for activating single-letter code block commands."
+ (when (and (bolp)
+ (let ((case-fold-search t)) (looking-at "[ \t]*#\\+begin_src"))
+ (eq 'src-block (org-element-type (org-element-at-point))))
+ (cdr (assoc keys org-babel-key-bindings))))
+
+;;;###autoload
+(defun org-babel-describe-bindings ()
+ "Describe all keybindings behind `org-babel-key-prefix'."
+ (interactive)
+ (describe-bindings org-babel-key-prefix))
+
+
+(provide 'org-keys)
+;;; org-keys.el ends here
diff --git a/lisp/org-lint.el b/lisp/org-lint.el
index 95cbb8d..5b959db 100644
--- a/lisp/org-lint.el
+++ b/lisp/org-lint.el
@@ -106,10 +106,10 @@
;;; Code:
(require 'cl-lib)
-(require 'org-element)
+(require 'ob)
+(require 'ol)
(require 'org-macro)
(require 'ox)
-(require 'ob)
;;; Checkers
@@ -288,8 +288,14 @@
:description "Report obsolete \"file+application\" link"
:categories '(link obsolete))
(make-org-lint-checker
+ :name 'percent-encoding-link-escape
+ :description "Report obsolete escape syntax in links"
+ :categories '(link obsolete)
+ :trust 'low)
+ (make-org-lint-checker
:name 'spurious-colons
- :description "Report spurious colons in tags"))
+ :description "Report spurious colons in tags"
+ :categories '(tags)))
"List of all available checkers.")
(defun org-lint--collect-duplicates
@@ -607,14 +613,13 @@ Use :header-args: instead"
"Non-existent file argument in INCLUDE keyword")
(let* ((visiting (if file (find-buffer-visiting file)
(current-buffer)))
- (buffer (or visiting (find-file-noselect file))))
+ (buffer (or visiting (find-file-noselect file)))
+ (org-link-search-must-match-exact-headline t))
(unwind-protect
(with-current-buffer buffer
(when (and search
- (not
- (ignore-errors
- (let ((org-link-search-inhibit-query t))
- (org-link-search search nil t)))))
+ (not (ignore-errors
+ (org-link-search search nil t))))
(list (org-element-property :post-affiliated k)
(format
"Invalid search part \"%s\" in INCLUDE keyword"
@@ -885,6 +890,23 @@ Use \"export %s\" instead"
(list (org-element-property :begin l)
(format "Deprecated \"file+%s\" link type" app)))))))
+(defun org-lint-percent-encoding-link-escape (ast)
+ (org-element-map ast 'link
+ (lambda (l)
+ (when (eq 'bracket (org-element-property :format l))
+ (let* ((uri (org-element-property :path l))
+ (start 0)
+ (obsolete-flag
+ (catch :obsolete
+ (while (string-match "%\\(..\\)?" uri start)
+ (setq start (match-end 0))
+ (unless (member (match-string 1 uri) '("25" "5B" "5D" "20"))
+ (throw :obsolete nil)))
+ (string-match-p "%" uri))))
+ (when obsolete-flag
+ (list (org-element-property :begin l)
+ "Link escaped with obsolete percent-encoding syntax")))))))
+
(defun org-lint-wrong-header-argument (ast)
(let* ((reports)
(verify
diff --git a/lisp/org-list.el b/lisp/org-list.el
index 2a95947..c4aef32 100644
--- a/lisp/org-list.el
+++ b/lisp/org-list.el
@@ -328,14 +328,6 @@ with the word \"recursive\" in the value."
:group 'org-plain-lists
:type 'boolean)
-(defcustom org-list-description-max-indent 20
- "Maximum indentation for the second line of a description list.
-When the indentation would be larger than this, it will become
-5 characters instead."
- :group 'org-plain-lists
- :type 'integer
- :safe #'wholenump)
-
(defcustom org-list-indent-offset 0
"Additional indentation for sub-items in a list.
By setting this to a small number, usually 1 or 2, one can more
@@ -348,14 +340,6 @@ clearly distinguish sub-items in a list."
"Names of blocks where lists are not allowed.
Names must be in lower case.")
-(defvar org-list-export-context '(block inlinetask)
- "Context types where lists will be interpreted during export.
-
-Valid types are `drawer', `inlinetask' and `block'. More
-specifically, type `block' is determined by the variable
-`org-list-forbidden-blocks'.")
-
-
;;; Predicates and regexps
@@ -2074,25 +2058,13 @@ Possible values are: `folded', `children' or `subtree'. See
"Return column at which body of ITEM should start."
(save-excursion
(goto-char item)
- (if (save-excursion
- (end-of-line)
- (re-search-backward
- "[ \t]::\\([ \t]\\|$\\)" (line-beginning-position) t))
- ;; Descriptive list item. Body starts after item's tag, if
- ;; possible.
- (let ((start (1+ (- (match-beginning 1) (line-beginning-position))))
- (ind (current-indentation)))
- (if (> start (+ ind org-list-description-max-indent))
- (+ ind 5)
- start))
- ;; Regular item. Body starts after bullet.
- (looking-at "[ \t]*\\(\\S-+\\)")
- (+ (progn (goto-char (match-end 1)) (current-column))
- (if (and org-list-two-spaces-after-bullet-regexp
- (string-match-p org-list-two-spaces-after-bullet-regexp
- (match-string 1)))
- 2
- 1)))))
+ (looking-at "[ \t]*\\(\\S-+\\)")
+ (+ (progn (goto-char (match-end 1)) (current-column))
+ (if (and org-list-two-spaces-after-bullet-regexp
+ (string-match-p org-list-two-spaces-after-bullet-regexp
+ (match-string 1)))
+ 2
+ 1))))
@@ -3179,10 +3151,14 @@ Point is left at list's end."
(defun org-list-make-subtree ()
"Convert the plain list at point into a subtree."
(interactive)
- (if (not (ignore-errors (goto-char (org-in-item-p))))
- (error "Not in a list")
- (let ((list (save-excursion (org-list-to-lisp t))))
- (insert (org-list-to-subtree list) "\n"))))
+ (let ((item (org-in-item-p)))
+ (unless item (error "Not in a list"))
+ (goto-char item)
+ (let ((level (pcase (org-current-level)
+ (`nil 1)
+ (l (1+ (org-reduced-level l)))))
+ (list (save-excursion (org-list-to-lisp t))))
+ (insert (org-list-to-subtree list level) "\n"))))
(defun org-list-to-generic (list params)
"Convert a LIST parsed through `org-list-to-lisp' to a custom format.
@@ -3491,21 +3467,22 @@ with overruling parameters for `org-list-to-generic'."
:cbtrans "[-] ")))
(org-list-to-generic list (org-combine-plists defaults params))))
-(defun org-list-to-subtree (list &optional params)
+(defun org-list-to-subtree (list &optional start-level params)
"Convert LIST into an Org subtree.
-LIST is as returned by `org-list-to-lisp'. PARAMS is a property
-list with overruling parameters for `org-list-to-generic'."
+LIST is as returned by `org-list-to-lisp'. Subtree starts at
+START-LEVEL or level 1 if nil. PARAMS is a property list with
+overruling parameters for `org-list-to-generic'."
(let* ((blank (pcase (cdr (assq 'heading org-blank-before-new-entry))
(`t t)
(`auto (save-excursion
(org-with-limited-levels (outline-previous-heading))
(org-previous-line-empty-p)))))
- (level (org-reduced-level (or (org-current-level) 0)))
+ (level (or start-level 1))
(make-stars
(lambda (_type depth &optional _count)
;; Return the string for the heading, depending on DEPTH
;; of current sub-list.
- (let ((oddeven-level (+ level depth)))
+ (let ((oddeven-level (+ level (1- depth))))
(concat (make-string (if org-odd-levels-only
(1- (* 2 oddeven-level))
oddeven-level)
diff --git a/lisp/org-macro.el b/lisp/org-macro.el
index e1241c3..c928ea7 100644
--- a/lisp/org-macro.el
+++ b/lisp/org-macro.el
@@ -62,7 +62,7 @@
(declare-function org-file-contents "org" (file &optional noerror nocache))
(declare-function org-file-url-p "org" (file))
(declare-function org-in-commented-heading-p "org" (&optional no-inheritance))
-(declare-function org-link-search "org" (s &optional avoid-pos stealth))
+(declare-function org-link-search "ol" (s &optional avoid-pos stealth))
(declare-function org-mode "org" ())
(declare-function vc-backend "vc-hooks" (f))
(declare-function vc-call "vc-hooks" (fun file &rest args) t)
@@ -149,6 +149,7 @@ In addition to buffer-defined macros, the function installs the
following ones: \"n\", \"author\", \"email\", \"keyword\",
\"time\", \"property\", and, if the buffer is associated to
a file, \"input-file\" and \"modification-time\"."
+ (require 'org-element)
(org-macro--counter-initialize) ;for "n" macro
(setq org-macro-templates
(nconc
diff --git a/lisp/org-macs.el b/lisp/org-macs.el
index 43d34b7..3cc6810 100644
--- a/lisp/org-macs.el
+++ b/lisp/org-macs.el
@@ -209,17 +209,6 @@ because otherwise all these markers will point to nowhere."
`(let (pop-up-frames display-buffer-alist)
,@body))
-(defmacro org-table-with-shrunk-field (&rest body)
- "Save field shrunk state, execute BODY and restore state."
- (declare (debug (body)))
- (org-with-gensyms (end shrunk size)
- `(let* ((,shrunk (save-match-data (org-table--shrunk-field)))
- (,end (and ,shrunk (copy-marker (overlay-end ,shrunk) t)))
- (,size (and ,shrunk (- ,end (overlay-start ,shrunk)))))
- (when ,shrunk (delete-overlay ,shrunk))
- (unwind-protect (progn ,@body)
- (when ,shrunk (move-overlay ,shrunk (- ,end ,size) ,end))))))
-
;;; Buffer and windows
@@ -346,7 +335,7 @@ if it fails."
(let ((min-ind (point-max)))
(save-excursion
(while (re-search-forward "^[ \t]*\\S-" nil t)
- (let ((ind (1- (current-column))))
+ (let ((ind (current-indentation)))
(if (zerop ind) (throw :exit nil)
(setq min-ind (min min-ind ind))))))
min-ind))))
@@ -643,7 +632,7 @@ program is needed for, so that the error message can be more informative."
(defvar org-inlinetask-min-level) ; defined in org-inlinetask.el
(defun org-get-limited-outline-regexp ()
"Return outline-regexp with limited number of levels.
-The number of levels is controlled by `org-inlinetask-min-level'"
+The number of levels is controlled by `org-inlinetask-min-level'."
(cond ((not (derived-mode-p 'org-mode))
outline-regexp)
((not (featurep 'org-inlinetask))
@@ -991,6 +980,43 @@ as-is if removal failed."
(insert code)
(if (org-do-remove-indentation n) (buffer-string) code)))
+(defun org-fill-template (template alist)
+ "Find each %key of ALIST in TEMPLATE and replace it."
+ (let ((case-fold-search nil))
+ (dolist (entry (sort (copy-sequence alist)
+ (lambda (a b) (< (length (car a)) (length (car b))))))
+ (setq template
+ (replace-regexp-in-string
+ (concat "%" (regexp-quote (car entry)))
+ (or (cdr entry) "") template t t)))
+ template))
+
+(defun org-replace-escapes (string table)
+ "Replace %-escapes in STRING with values in TABLE.
+TABLE is an association list with keys like \"%a\" and string values.
+The sequences in STRING may contain normal field width and padding information,
+for example \"%-5s\". Replacements happen in the sequence given by TABLE,
+so values can contain further %-escapes if they are define later in TABLE."
+ (let ((tbl (copy-alist table))
+ (case-fold-search nil)
+ (pchg 0)
+ re rpl)
+ (dolist (e tbl)
+ (setq re (concat "%-?[0-9.]*" (substring (car e) 1)))
+ (when (and (cdr e) (string-match re (cdr e)))
+ (let ((sref (substring (cdr e) (match-beginning 0) (match-end 0)))
+ (safe "SREF"))
+ (add-text-properties 0 3 (list 'sref sref) safe)
+ (setcdr e (replace-match safe t t (cdr e)))))
+ (while (string-match re string)
+ (setq rpl (format (concat (substring (match-string 0 string) 0 -1) "s")
+ (cdr e)))
+ (setq string (replace-match rpl t t string))))
+ (while (setq pchg (next-property-change pchg string))
+ (let ((sref (get-text-property pchg 'sref string)))
+ (when (and sref (string-match "SREF" string pchg))
+ (setq string (replace-match sref t t string)))))
+ string))
;;; Text properties
@@ -1072,7 +1098,7 @@ nil, just return 0."
((numberp s) s)
((stringp s)
(condition-case nil
- (float-time (org-time-string-to-time s))
+ (float-time (apply #'encode-time (org-parse-time-string s)))
(error 0)))
(t 0)))
diff --git a/lisp/org-mobile.el b/lisp/org-mobile.el
index 8fdf84a..26a3f57 100644
--- a/lisp/org-mobile.el
+++ b/lisp/org-mobile.el
@@ -31,11 +31,10 @@
;; iPhone and Android - any external viewer/flagging/editing
;; application that uses the same conventions could be used.
+(require 'cl-lib)
(require 'org)
(require 'org-agenda)
-(require 'cl-lib)
-
-(defvar org-agenda-keep-restricted-file-list)
+(require 'ol)
;;; Code:
@@ -57,7 +56,7 @@ In addition to this, the list may also contain the following symbols:
`org-agenda-text-search-extra-files'
Include the files given in the variable
- `org-agenda-text-search-extra-files'"
+ `org-agenda-text-search-extra-files'."
:group 'org-mobile
:type '(list :greedy t
(option (const :tag "org-agenda-files" org-agenda-files))
@@ -670,8 +669,7 @@ The table of checksums is written to the file mobile-checksums."
(org-mobile-escape-olp (nth 4 (org-heading-components))))))
(defun org-mobile-escape-olp (s)
- (let ((table '(?: ?/)))
- (org-link-escape s table)))
+ (org-link-encode s '(?: ?/)))
(defun org-mobile-create-sumo-agenda ()
"Create a file that contains all custom agenda views."
@@ -965,7 +963,7 @@ is currently a noop.")
(if (not (string-match "\\`olp:\\(.*?\\)$" link))
nil
(let ((file (match-string 1 link)))
- (setq file (org-link-unescape file))
+ (setq file (org-link-decode file))
(setq file (expand-file-name file org-directory))
(save-excursion
(find-file file)
@@ -975,9 +973,9 @@ is currently a noop.")
(point-marker))))
(let ((file (match-string 1 link))
(path (match-string 2 link)))
- (setq file (org-link-unescape file))
+ (setq file (org-link-decode file))
(setq file (expand-file-name file org-directory))
- (setq path (mapcar 'org-link-unescape
+ (setq path (mapcar #'org-link-decode
(org-split-string path "/")))
(org-find-olp (cons file path))))))
diff --git a/lisp/org-num.el b/lisp/org-num.el
new file mode 100644
index 0000000..5604819
--- /dev/null
+++ b/lisp/org-num.el
@@ -0,0 +1,469 @@
+;;; org-num.el --- Dynamic Headlines Numbering -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2018-2019 Free Software Foundation, Inc.
+
+;; Author: Nicolas Goaziou <mail@nicolasgoaziou.fr>
+;; Keywords: outlines, hypermedia, calendar, wp
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This library provides dynamic numbering for Org headlines. Use
+;;
+;; <M-x org-num-mode>
+;;
+;; to toggle it.
+;;
+;; You can select what is numbered according to level, tags, COMMENT
+;; keyword, or UNNUMBERED property. You can also skip footnotes
+;; sections. See `org-num-max-level', `org-num-skip-tags',
+;; `org-num-skip-commented', `org-num-skip-unnumbered', and
+;; `org-num-skip-footnotes' for details.
+;;
+;; You can also control how the numbering is displayed by setting
+;;`org-num-face' and `org-num-format-function'.
+;;
+;; Internally, the library handles an ordered list, per buffer
+;; position, of overlays in `org-num--overlays'. These overlays are
+;; marked with the `org-num' property set to a non-nil value.
+;;
+;; Overlays store the level of the headline in the `level' property,
+;; and the face used for the numbering in `numbering-face'.
+;;
+;; The `skip' property is set to t when the corresponding headline has
+;; some characteristic -- e.g., a node property, or a tag -- that
+;; prevents it from being numbered.
+;;
+;; An overlay with `org-num' property set to `invalid' is called an
+;; invalid overlay. Modified overlays automatically become invalid
+;; and set `org-num--invalid-flag' to a non-nil value. After
+;; a change, `org-num--invalid-flag' indicates numbering needs to be
+;; updated and invalid overlays indicate where the buffer needs to be
+;; parsed. So does `org-num--missing-overlay' variable. See
+;; `org-num--verify' function for details.
+;;
+;; Numbering display is done through the `after-string' property.
+
+
+;;; Code:
+
+(require 'cl-lib)
+(require 'org-macs)
+
+(defvar org-comment-string)
+(defvar org-complex-heading-regexp)
+(defvar org-cycle-level-faces)
+(defvar org-footnote-section)
+(defvar org-level-faces)
+(defvar org-n-level-faces)
+(defvar org-odd-levels-only)
+
+(declare-function org-back-to-heading "org" (&optional invisible-ok))
+(declare-function org-entry-get "org" (pom property &optional inherit literal-nil))
+(declare-function org-reduced-level "org" (l))
+
+
+;;; Customization
+
+(defcustom org-num-face nil
+ "Face to use for numbering.
+When nil, use the same face as the headline. This value is
+ignored if `org-num-format-function' specifies a face for its
+output."
+ :group 'org-appearance
+ :package-version '(Org . "9.3")
+ :type '(choice (const :tag "Like the headline" nil)
+ (face :tag "Use face"))
+ :safe (lambda (val) (or (null val) (facep val))))
+
+(defcustom org-num-format-function 'org-num-default-format
+ "Function used to display numbering.
+It is called with one argument, a list of numbers, and should
+return a string, or nil. When nil, no numbering is displayed.
+Any `face' text property on the returned string overrides
+`org-num-face'."
+ :group 'org-appearance
+ :package-version '(Org . "9.3")
+ :type 'function
+ :safe nil)
+
+(defcustom org-num-max-level nil
+ "Level below which headlines are not numbered.
+When set to nil, all headlines are numbered."
+ :group 'org-appearance
+ :package-version '(Org . "9.3")
+ :type '(choice (const :tag "Number everything" nil)
+ (integer :tag "Stop numbering at level"))
+ :safe (lambda (val) (or (null val) (wholenump val))))
+
+(defcustom org-num-skip-commented nil
+ "Non-nil means commented sub-trees are not numbered."
+ :group 'org-appearance
+ :package-version '(Org . "9.3")
+ :type 'boolean
+ :safe #'booleanp)
+
+(defcustom org-num-skip-footnotes nil
+ "Non-nil means footnotes sections are not numbered."
+ :group 'org-appearance
+ :package-version '(Org . "9.3")
+ :type 'boolean
+ :safe #'booleanp)
+
+(defcustom org-num-skip-tags nil
+ "List of tags preventing the numbering of sub-trees.
+
+For example, add \"ARCHIVE\" to this list to avoid numbering
+archived sub-trees.
+
+Tag in this list prevent numbering the whole sub-tree,
+irrespective to `org-use-tags-inheritance', or other means to
+control tag inheritance."
+ :group 'org-appearance
+ :package-version '(Org . "9.3")
+ :type '(repeat (string :tag "Tag"))
+ :safe (lambda (val) (and (listp val) (cl-every #'stringp val))))
+
+(defcustom org-num-skip-unnumbered nil
+ "Non-nil means numbering obeys to UNNUMBERED property."
+ :group 'org-appearance
+ :package-version '(Org . "9.3")
+ :type 'boolean
+ :safe #'booleanp)
+
+
+;;; Internal Variables
+
+(defconst org-num--comment-re (format "\\`%s\\(?: \\|$\\)" org-comment-string)
+ "Regexp matching a COMMENT keyword at headline beginning.")
+
+(defvar-local org-num--overlays nil
+ "Ordered list of overlays used for numbering outlines.")
+
+(defvar-local org-num--skip-level nil
+ "Level below which headlines from current tree are not numbered.
+When nil, all headlines are numbered. It is used to handle
+inheritance of no-numbering attributes.")
+
+(defvar-local org-num--numbering nil
+ "Current headline numbering.
+A numbering is a list of integers, in reverse order. So numbering
+for headline \"1.2.3\" is (3 2 1).")
+
+(defvar-local org-num--missing-overlay nil
+ "Buffer position signaling a headline without an overlay.")
+
+(defvar-local org-num--invalid-flag nil
+ "Non-nil means an overlay became invalid since last update.")
+
+
+;;; Internal Functions
+
+(defsubst org-num--headline-regexp ()
+ "Return regexp matching a numbered headline."
+ (if (null org-num-max-level) (org-with-limited-levels org-outline-regexp-bol)
+ (format "^\\*\\{1,%d\\} "
+ (if org-odd-levels-only (1- (* 2 org-num-max-level))
+ org-num-max-level))))
+
+(defsubst org-num--overlay-p (o)
+ "Non-nil if overlay O is a numbering overlay."
+ (overlay-get o 'org-num))
+
+(defsubst org-num--valid-overlay-p (o)
+ "Non-nil if overlay O is still active in the buffer."
+ (not (eq 'invalid (overlay-get o 'org-num))))
+
+(defsubst org-num--invalidate-overlay (o)
+ "Mark overlay O as invalid.
+Update `org-num--invalid-flag' accordingly."
+ (overlay-put o 'org-num 'invalid)
+ (setq org-num--invalid-flag t))
+
+(defun org-num--clear ()
+ "Remove all numbering overlays in current buffer."
+ (mapc #'delete-overlay org-num--overlays)
+ (setq org-num--overlays nil))
+
+(defun org-num--make-overlay (numbering level skip)
+ "Return overlay for numbering headline at point.
+
+NUMBERING is the numbering to use, as a list of integers, or nil
+if nothing should be displayed. LEVEL is the level of the
+headline. SKIP is its skip value.
+
+Assume point is at a headline."
+ (let ((after-edit-functions
+ (list (lambda (o &rest _) (org-num--invalidate-overlay o))))
+ (o (save-excursion
+ (beginning-of-line)
+ (skip-chars-forward "*")
+ (make-overlay (line-beginning-position) (1+ (point))))))
+ (overlay-put o 'org-num t)
+ (overlay-put o 'skip skip)
+ (overlay-put o 'level level)
+ (overlay-put o 'numbering-face
+ (or org-num-face
+ ;; Compute face that would be used at the
+ ;; headline. We cannot extract it from the
+ ;; buffer: at the time the overlay is created,
+ ;; Font Lock has not proceeded yet.
+ (nth (if org-cycle-level-faces
+ (% (1- level) org-n-level-faces)
+ (1- (min level org-n-level-faces)))
+ org-level-faces)))
+ (overlay-put o 'modification-hooks after-edit-functions)
+ (overlay-put o 'insert-in-front-hooks after-edit-functions)
+ (org-num--refresh-display o numbering)
+ o))
+
+(defun org-num--refresh-display (overlay numbering)
+ "Refresh OVERLAY's display.
+NUMBERING specifies the new numbering, as a list of integers, or
+nil if nothing should be displayed. Assume OVERLAY is valid."
+ (let ((display (and numbering
+ (funcall org-num-format-function (reverse numbering)))))
+ (when (and display (not (get-text-property 0 'face display)))
+ (org-add-props display `(face ,(overlay-get overlay 'numbering-face))))
+ (overlay-put overlay 'after-string display)))
+
+(defun org-num--skip-value ()
+ "Return skip value for headline at point.
+Value is t when headline should not be numbered, and nil
+otherwise."
+ (org-match-line org-complex-heading-regexp)
+ (let ((title (match-string 4))
+ (tags (and org-num-skip-tags
+ (match-end 5)
+ (org-split-string (match-string 5) ":"))))
+ (or (and org-num-skip-footnotes
+ org-footnote-section
+ (equal title org-footnote-section))
+ (and org-num-skip-commented
+ (let ((case-fold-search nil))
+ (string-match org-num--comment-re title))
+ t)
+ (and org-num-skip-tags
+ (cl-some (lambda (tag) (member tag org-num-skip-tags))
+ tags)
+ t)
+ (and org-num-skip-unnumbered
+ (org-entry-get (point) "UNNUMBERED")
+ t))))
+
+(defun org-num--current-numbering (level skip)
+ "Return numbering for current headline.
+LEVEL is headline's level, and SKIP its skip value. Return nil
+if headline should be skipped."
+ (cond
+ ;; Skipped by inheritance.
+ ((and org-num--skip-level (> level org-num--skip-level)) nil)
+ ;; Skipped by a non-nil skip value; set `org-num--skip-level'
+ ;; to skip the whole sub-tree later on.
+ (skip (setq org-num--skip-level level) nil)
+ (t
+ (setq org-num--skip-level nil)
+ ;; Compute next numbering, and update `org-num--numbering'.
+ (let ((last-level (length org-num--numbering)))
+ (setq org-num--numbering
+ (cond
+ ;; First headline : nil => (1), or (1 0)...
+ ((null org-num--numbering) (cons 1 (make-list (1- level) 0)))
+ ;; Sibling: (1 1) => (2 1).
+ ((= level last-level)
+ (cons (1+ (car org-num--numbering)) (cdr org-num--numbering)))
+ ;; Parent: (1 1 1) => (2 1), or (2).
+ ((< level last-level)
+ (let ((suffix (nthcdr (- last-level level) org-num--numbering)))
+ (cons (1+ (car suffix)) (cdr suffix))))
+ ;; Child: (1 1) => (1 1 1), or (1 0 1 1)...
+ (t
+ (append (cons 1 (make-list (- level last-level 1) 0))
+ org-num--numbering))))))))
+
+(defun org-num--number-region (start end)
+ "Add numbering overlays between START and END positions.
+When START or END are nil, use buffer boundaries. Narrowing, if
+any, is ignored. Return the list of created overlays, newest
+first."
+ (org-with-point-at (or start 1)
+ ;; Do not match headline starting at START.
+ (when start (end-of-line))
+ (let ((regexp (org-num--headline-regexp))
+ (new nil))
+ (while (re-search-forward regexp end t)
+ (let* ((level (org-reduced-level
+ (- (match-end 0) (match-beginning 0) 1)))
+ (skip (org-num--skip-value))
+ (numbering (org-num--current-numbering level skip)))
+ ;; Apply numbering to current headline. Store overlay for
+ ;; the return value.
+ (push (org-num--make-overlay numbering level skip)
+ new)))
+ new)))
+
+(defun org-num--update ()
+ "Update buffer's numbering.
+This function removes invalid overlays and refreshes numbering
+for the valid ones in the numbering overlays list. It also adds
+missing overlays to that list."
+ (setq org-num--skip-level nil)
+ (setq org-num--numbering nil)
+ (let ((new-overlays nil)
+ (overlay nil))
+ (while (setq overlay (pop org-num--overlays))
+ (cond
+ ;; Valid overlay.
+ ;;
+ ;; First handle possible missing overlays OVERLAY. If missing
+ ;; overlay marker is pointing before next overlay and after the
+ ;; last known overlay, make sure to parse the buffer between
+ ;; these two overlays.
+ ((org-num--valid-overlay-p overlay)
+ (let ((next (overlay-start overlay))
+ (last (and new-overlays (overlay-start (car new-overlays)))))
+ (cond
+ ((null org-num--missing-overlay))
+ ((> org-num--missing-overlay next))
+ ((or (null last) (> org-num--missing-overlay last))
+ (setq org-num--missing-overlay nil)
+ (setq new-overlays (nconc (org-num--number-region last next)
+ new-overlays)))
+ ;; If it is already after the last known overlay, reset it:
+ ;; some previous invalid overlay already triggered the
+ ;; necessary parsing.
+ (t
+ (setq org-num--missing-overlay nil))))
+ ;; Update OVERLAY's numbering.
+ (let* ((level (overlay-get overlay 'level))
+ (skip (overlay-get overlay 'skip))
+ (numbering (org-num--current-numbering level skip)))
+ (org-num--refresh-display overlay numbering)
+ (push overlay new-overlays)))
+ ;; Invalid overlay. It indicates that the buffer needs to be
+ ;; parsed again between the two surrounding valid overlays or
+ ;; buffer boundaries.
+ (t
+ ;; Delete all consecutive invalid overlays: we re-create all
+ ;; overlays between last valid overlay and the next one.
+ (delete-overlay overlay)
+ (while (and org-num--overlays
+ (not (org-num--valid-overlay-p (car org-num--overlays))))
+ (delete-overlay (pop org-num--overlays)))
+ ;; Create and register new overlays.
+ (let ((last (and new-overlays (overlay-start (car new-overlays))))
+ (next (and org-num--overlays
+ (overlay-start (car org-num--overlays)))))
+ (setq new-overlays (nconc (org-num--number-region last next)
+ new-overlays))))))
+ ;; If invalid position hasn't been handled yet, it must be located
+ ;; between last valid overlay and end of the buffer. Parse that
+ ;; area before returning.
+ (when org-num--missing-overlay
+ (let ((last (and new-overlays (overlay-start (car new-overlays)))))
+ (setq new-overlays (nconc (org-num--number-region last nil)
+ new-overlays))))
+ ;; Numbering is now up-to-date. Reset invalid flag. Also return
+ ;; `org-num--overlays' in a sorted fashion.
+ (setq org-num--invalid-flag nil)
+ (setq org-num--overlays (nreverse new-overlays))))
+
+(defun org-num--verify (beg end _)
+ "Check numbering integrity; update it if necessary.
+This function is meant to be used in `after-change-functions'.
+See this variable for the meaning of BEG and END."
+ (setq org-num--missing-overlay nil)
+ (save-match-data
+ (org-with-point-at beg
+ (let ((regexp (org-num--headline-regexp)))
+ ;; At this point, directly altered overlays between BEG and
+ ;; END are marked as invalid and will trigger a full update.
+ ;; However, there are still two cases to handle.
+ ;;
+ ;; First, some valid overlays may need to be invalidated, due
+ ;; to an indirect change. That happens when the skip value --
+ ;; see `org-num--skip-value' -- of the heading BEG belongs to
+ ;; is altered, or when deleting the newline character right
+ ;; before the next headline.
+ (save-excursion
+ ;; Bail out if we're before first headline or within
+ ;; a headline too deep to be numbered.
+ (when (and (org-with-limited-levels
+ (ignore-errors (org-back-to-heading t)))
+ (looking-at regexp))
+ (pcase (get-char-property-and-overlay (point) 'org-num)
+ (`(nil)
+ ;; At a headline, without a numbering overlay: change
+ ;; just created one. Mark it for parsing.
+ (setq org-num--missing-overlay (point)))
+ (`(t . ,o)
+ ;; Check if skip value changed. Invalidate overlay
+ ;; accordingly.
+ (unless (eq (org-num--skip-value) (overlay-get o 'skip))
+ (org-num--invalidate-overlay o)))
+ (_ nil))))
+ ;; Deleting the newline character before a numbering overlay
+ ;; doesn't invalidate it, even though it could land in the
+ ;; middle of a line. Be sure to catch this case.
+ (when (and (= beg end) (not (bolp)))
+ (pcase (get-char-property-and-overlay (point) 'org-num)
+ (`(t . ,o) (org-num--invalidate-overlay o))
+ (_ nil)))
+ ;; Second, if nothing is marked as invalid, and therefore if
+ ;; no full update is due so far, changes may still have
+ ;; created new headlines, at BEG -- which is actually handled
+ ;; by the previous phase --, or, in case of a multi-line
+ ;; insertion, at END, or in-between.
+ (unless (or org-num--invalid-flag
+ org-num--missing-overlay
+ (<= end (line-end-position))) ;single line change
+ (forward-line)
+ (when (or (re-search-forward regexp end 'move)
+ ;; Check if change created a headline after END.
+ (progn (skip-chars-backward "*") (looking-at regexp)))
+ (setq org-num--missing-overlay (line-beginning-position))))))
+ ;; Update numbering only if a headline was altered or created.
+ (when (or org-num--missing-overlay org-num--invalid-flag)
+ (org-num--update))))
+
+
+;;; Public Functions
+
+;;;###autoload
+(defun org-num-default-format (numbering)
+ "Default numbering display function.
+NUMBERING is a list of numbers."
+ (concat (mapconcat #'number-to-string numbering ".") " "))
+
+;;;###autoload
+(define-minor-mode org-num-mode
+ "Dynamic numbering of headlines in an Org buffer."
+ :lighter " o#"
+ (cond
+ (org-num-mode
+ (unless (derived-mode-p 'org-mode)
+ (user-error "Cannot activate headline numbering outside Org mode"))
+ (setq org-num--numbering nil)
+ (setq org-num--overlays (nreverse (org-num--number-region nil nil)))
+ (add-hook 'after-change-functions #'org-num--verify nil t)
+ (add-hook 'change-major-mode-hook #'org-num--clear nil t))
+ (t
+ (org-num--clear)
+ (remove-hook 'after-change-functions #'org-num--verify t)
+ (remove-hook 'change-major-mode-hook #'org-num--clear t))))
+
+
+(provide 'org-num)
+;;; org-num.el ends here
diff --git a/lisp/org-pcomplete.el b/lisp/org-pcomplete.el
index 38fd27f..e557b1a 100644
--- a/lisp/org-pcomplete.el
+++ b/lisp/org-pcomplete.el
@@ -44,7 +44,7 @@
(declare-function org-get-export-keywords "org" ())
(declare-function org-get-heading "org" (&optional no-tags no-todo no-priority no-comment))
(declare-function org-get-tags "org" (&optional pos local))
-(declare-function org-make-org-heading-search-string "org" (&optional string))
+(declare-function org-link-heading-search-string "ol" (&optional string))
(declare-function org-tag-alist-to-string "org" (alist &optional skip-key))
(defvar org-current-tag-alist)
@@ -352,8 +352,7 @@ This needs more work, to handle headings with lots of spaces in them."
(goto-char (point-min))
(let (tbl)
(while (re-search-forward org-outline-regexp nil t)
- (push (org-make-org-heading-search-string
- (org-get-heading t t t t))
+ (push (org-link-heading-search-string (org-get-heading t t t t))
tbl))
(pcomplete-uniquify-list tbl)))
;; When completing a bracketed link, i.e., "[[*", argument
@@ -430,8 +429,9 @@ switches."
":tstart" ":tend" ":block" ":step"
":stepskip0" ":fileskip0"
":emphasize" ":link" ":narrow" ":indent"
- ":tcolumns" ":level" ":compact" ":timestamp"
- ":formula" ":formatter" ":wstart" ":mstart"))))
+ ":hidefiles" ":tcolumns" ":level" ":compact"
+ ":timestamp" ":formula" ":formatter"
+ ":wstart" ":mstart"))))
;;; Finish up
diff --git a/lisp/org-plot.el b/lisp/org-plot.el
index a5635e3..4e84dbe 100644
--- a/lisp/org-plot.el
+++ b/lisp/org-plot.el
@@ -131,7 +131,7 @@ Pass PARAMS through to `orgtbl-to-generic' when exporting TABLE."
"Export the data in TABLE to DATA-FILE for gnuplot.
This means in a format appropriate for grid plotting by gnuplot.
PARAMS specifies which columns of TABLE should be plotted as independent
-and dependant variables."
+and dependent variables."
(interactive)
(let* ((ind (- (plist-get params :ind) 1))
(deps (if (plist-member params :deps)
diff --git a/lisp/org-protocol.el b/lisp/org-protocol.el
index 0577c31..44c6abb 100644
--- a/lisp/org-protocol.el
+++ b/lisp/org-protocol.el
@@ -116,6 +116,7 @@
;;; Code:
(require 'org)
+(require 'ol)
(declare-function org-publish-get-project-from-filename "ox-publish"
(filename &optional up))
@@ -300,7 +301,7 @@ results of that splitting are returned as a list."
(split-parts (split-string data sep)))
(cond ((not unhexify) split-parts)
((fboundp unhexify) (mapcar unhexify split-parts))
- (t (mapcar #'org-link-unescape split-parts)))))
+ (t (mapcar #'org-link-decode split-parts)))))
(defun org-protocol-flatten-greedy (param-list &optional strip-path replacement)
"Transform PARAM-LIST into a flat list for greedy handlers.
@@ -381,7 +382,7 @@ If INFO is already a property list, return it unchanged."
(while data
(setq result
(append result
- (list (pop data) (org-link-unescape (pop data))))))
+ (list (pop data) (org-link-decode (pop data))))))
result)
(let ((data (org-protocol-split-data info t org-protocol-data-separator)))
(if default-order
@@ -489,12 +490,12 @@ Now template ?b will be used."
(region (or (plist-get parts :body) ""))
(orglink
(if (null url) title
- (org-make-link-string url (or (org-string-nw-p title) url))))
+ (org-link-make-string url (or (org-string-nw-p title) url))))
;; Avoid call to `org-store-link'.
(org-capture-link-is-already-stored t))
;; Only store link if there's a URL to insert later on.
(when url (push (list url title) org-stored-links))
- (org-store-link-props :type type
+ (org-link-store-props :type type
:link url
:description title
:annotation orglink
diff --git a/lisp/org-src.el b/lisp/org-src.el
index de6d0d7..5e50a1b 100644
--- a/lisp/org-src.el
+++ b/lisp/org-src.el
@@ -32,10 +32,10 @@
;;; Code:
(require 'cl-lib)
+(require 'ob-comint)
(require 'org-macs)
(require 'org-compat)
-(require 'ob-keys)
-(require 'ob-comint)
+(require 'org-keys)
(declare-function org-element-at-point "org-element" ())
(declare-function org-element-class "org-element" (datum &optional parent))
@@ -152,6 +152,8 @@ current-window Show edit buffer in the current window, keeping all other
windows.
split-window-below Show edit buffer below the current window, keeping all
other windows.
+split-window-right Show edit buffer to the right of the current window,
+ keeping all other windows.
other-window Use `switch-to-buffer-other-window' to display edit buffer.
reorganize-frame Show only two windows on the current frame, the current
window and the edit buffer. When exiting the edit buffer,
@@ -162,6 +164,7 @@ other-frame Use `switch-to-buffer-other-frame' to display edit buffer.
:type '(choice
(const current-window)
(const split-window-below)
+ (const split-window-right)
(const other-frame)
(const other-window)
(const reorganize-frame)))
@@ -255,6 +258,9 @@ issued in the language major mode buffer."
(defvar-local org-src--block-indentation nil)
(put 'org-src--block-indentation 'permanent-local t)
+(defvar-local org-src--content-indentation nil)
+(put 'org-src--content-indentation 'permanent-local t)
+
(defvar-local org-src--end-marker nil)
(put 'org-src--end-marker 'permanent-local t)
@@ -270,9 +276,6 @@ issued in the language major mode buffer."
(defvar-local org-src--remote nil)
(put 'org-src--remote 'permanent-local t)
-(defvar-local org-src--saved-temp-window-config nil)
-(put 'org-src--saved-temp-window-config 'permanent-local t)
-
(defvar-local org-src--source-type nil
"Type of element being edited, as a symbol.")
(put 'org-src--source-type 'permanent-local t)
@@ -304,15 +307,6 @@ Return nil if there is no such buffer."
(eq (marker-buffer end) (marker-buffer org-src--end-marker))
(throw 'exit b))))))
-(defun org-src--get-lang-mode (lang)
- "Return major mode that should be used for LANG.
-LANG is a string, and the returned major mode is a symbol."
- (intern
- (concat
- (let ((l (or (cdr (assoc lang org-src-lang-modes)) lang)))
- (if (symbolp l) (symbol-name l) l))
- "-mode")))
-
(defun org-src--coordinates (pos beg end)
"Return coordinates of POS relatively to BEG and END.
POS, BEG and END are buffer positions. Return value is either
@@ -431,7 +425,7 @@ Assume point is in the corresponding edit buffer."
(if org-src--preserve-indentation 0
(+ (or org-src--block-indentation 0)
(if (memq org-src--source-type '(example-block src-block))
- org-edit-src-content-indentation
+ org-src--content-indentation
0))))
(use-tabs? (and (> org-src--tab-width 0) t))
(source-tab-width org-src--tab-width)
@@ -475,7 +469,6 @@ When REMOTE is non-nil, do not try to preserve point or mark when
moving from the edit area to the source.
Leave point in edit buffer."
- (setq org-src--saved-temp-window-config (current-window-configuration))
(let* ((area (org-src--contents-area datum))
(beg (copy-marker (nth 0 area)))
(end (copy-marker (nth 1 area) t))
@@ -494,9 +487,9 @@ Leave point in edit buffer."
(source-file-name (buffer-file-name (buffer-base-buffer)))
(source-tab-width (if indent-tabs-mode tab-width 0))
(type (org-element-type datum))
- (ind (org-with-wide-buffer
- (goto-char (org-element-property :begin datum))
- (current-indentation)))
+ (block-ind (org-with-point-at (org-element-property :begin datum)
+ (current-indentation)))
+ (content-ind org-edit-src-content-indentation)
(preserve-ind
(and (memq type '(example-block src-block))
(or (org-element-property :preserve-indent datum)
@@ -539,7 +532,8 @@ Leave point in edit buffer."
(setq org-src--end-marker end)
(setq org-src--remote remote)
(setq org-src--source-type type)
- (setq org-src--block-indentation ind)
+ (setq org-src--block-indentation block-ind)
+ (setq org-src--content-indentation content-ind)
(setq org-src--preserve-indentation preserve-ind)
(setq org-src--overlay overlay)
(setq org-src--allow-write-back write-back)
@@ -572,7 +566,7 @@ Leave point in edit buffer."
"Fontify code block.
This function is called by emacs automatic fontification, as long
as `org-src-fontify-natively' is non-nil."
- (let ((lang-mode (org-src--get-lang-mode lang)))
+ (let ((lang-mode (org-src-get-lang-mode lang)))
(when (fboundp lang-mode)
(let ((string (buffer-substring-no-properties start end))
(modified (buffer-modified-p))
@@ -766,6 +760,15 @@ Org-babel commands."
(org-src-do-at-code-block
(call-interactively (lookup-key org-babel-map key)))))
+(defun org-src-get-lang-mode (lang)
+ "Return major mode that should be used for LANG.
+LANG is a string, and the returned major mode is a symbol."
+ (intern
+ (concat
+ (let ((l (or (cdr (assoc lang org-src-lang-modes)) lang)))
+ (if (symbolp l) (symbol-name l) l))
+ "-mode")))
+
(defun org-src-edit-buffer-p (&optional buffer)
"Non-nil when current buffer is a source editing buffer.
If BUFFER is non-nil, test it instead."
@@ -793,7 +796,14 @@ Raise an error when current buffer is not a source editing buffer."
(`other-window
(switch-to-buffer-other-window buffer))
(`split-window-below
- (select-window (split-window-vertically))
+ (if (eq context 'exit)
+ (delete-window)
+ (select-window (split-window-vertically)))
+ (pop-to-buffer-same-window buffer))
+ (`split-window-right
+ (if (eq context 'exit)
+ (delete-window)
+ (select-window (split-window-horizontally)))
(pop-to-buffer-same-window buffer))
(`other-frame
(pcase context
@@ -950,7 +960,7 @@ the LaTeX environment in the Org mode buffer."
(org-src--edit-element
element
(org-src--construct-edit-buffer-name (buffer-name) "LaTeX environment")
- (org-src--get-lang-mode "latex")
+ (org-src-get-lang-mode "latex")
t)
t))
@@ -975,7 +985,7 @@ Throw an error when not at an export block."
;; Missing export-block type. Fallback
;; to default mode.
"fundamental")))
- (mode (org-src--get-lang-mode type)))
+ (mode (org-src-get-lang-mode type)))
(unless (functionp mode) (error "No such language mode: %s" mode))
(org-src--edit-element
element
@@ -1008,7 +1018,7 @@ name of the sub-editing buffer."
(let* ((lang
(if (eq type 'src-block) (org-element-property :language element)
"example"))
- (lang-f (and (eq type 'src-block) (org-src--get-lang-mode lang)))
+ (lang-f (and (eq type 'src-block) (org-src-get-lang-mode lang)))
(babel-info (and (eq type 'src-block)
(org-babel-get-src-block-info 'light)))
deactivate-mark)
@@ -1041,7 +1051,7 @@ name of the sub-editing buffer."
(org-src--on-datum-p context))
(user-error "Not on inline source code"))
(let* ((lang (org-element-property :language context))
- (lang-f (org-src--get-lang-mode lang))
+ (lang-f (org-src-get-lang-mode lang))
(babel-info (org-babel-get-src-block-info 'light))
deactivate-mark)
(unless (functionp lang-f) (error "No such language mode: %s" lang-f))
@@ -1172,10 +1182,7 @@ Throw an error if there is no such buffer."
(write-back (org-src--goto-coordinates coordinates beg end))))
;; Clean up left-over markers and restore window configuration.
(set-marker beg nil)
- (set-marker end nil)
- (when org-src--saved-temp-window-config
- (set-window-configuration org-src--saved-temp-window-config)
- (setq org-src--saved-temp-window-config nil))))
+ (set-marker end nil)))
(provide 'org-src)
diff --git a/lisp/org-table.el b/lisp/org-table.el
index f6eb425..a21587a 100644
--- a/lisp/org-table.el
+++ b/lisp/org-table.el
@@ -35,51 +35,66 @@
;;; Code:
(require 'cl-lib)
-(require 'org)
+(require 'org-macs)
+(require 'org-compat)
+(require 'org-keys)
+(declare-function calc-eval "calc" (str &optional separator &rest args))
+(declare-function org-at-timestamp-p "org" (&optional extended))
+(declare-function org-delete-backward-char "org" (N))
(declare-function org-element-at-point "org-element" ())
(declare-function org-element-contents "org-element" (element))
(declare-function org-element-extract-element "org-element" (element))
(declare-function org-element-interpret-data "org-element" (data))
-(declare-function org-element-lineage "org-element"
- (blob &optional types with-self))
-(declare-function org-element-map "org-element"
- (data types fun
- &optional info first-match no-recursion with-affiliated))
-(declare-function org-element-parse-buffer "org-element"
- (&optional granularity visible-only))
+(declare-function org-element-lineage "org-element" (blob &optional types with-self))
+(declare-function org-element-map "org-element" (data types fun &optional info first-match no-recursion with-affiliated))
+(declare-function org-element-parse-buffer "org-element" (&optional granularity visible-only))
(declare-function org-element-property "org-element" (property element))
(declare-function org-element-type "org-element" (element))
-
+(declare-function org-entry-get "org" (pom property &optional inherit literal-nil))
(declare-function org-export-create-backend "ox" (&rest rest) t)
(declare-function org-export-data-with-backend "ox" (data backend info))
-(declare-function org-export-filter-apply-functions "ox"
- (filters value info))
+(declare-function org-export-filter-apply-functions "ox" (filters value info))
(declare-function org-export-first-sibling-p "ox" (blob info))
(declare-function org-export-get-backend "ox" (name))
-(declare-function org-export-get-environment "ox"
- (&optional backend subtreep ext-plist))
+(declare-function org-export-get-environment "ox" (&optional backend subtreep ext-plist))
(declare-function org-export-install-filters "ox" (info))
(declare-function org-export-table-has-special-column-p "ox" (table))
(declare-function org-export-table-row-is-special-p "ox" (table-row info))
-
-(declare-function calc-eval "calc" (str &optional separator &rest args))
+(declare-function org-id-find "org-id" (id &optional markerp))
+(declare-function org-indent-line "org" ())
+(declare-function org-load-modules-maybe "org" (&optional force))
+(declare-function org-restart-font-lock "org" ())
+(declare-function org-sort-remove-invisible "org" (s))
+(declare-function org-time-stamp-format "org" (&optional long inactive))
+(declare-function org-time-string-to-absolute "org" (s &optional daynr prefer buffer pos))
+(declare-function org-time-string-to-time "org" (s))
+(declare-function org-timestamp-up-day "org" (&optional arg))
(defvar constants-unit-system)
+(defvar org-M-RET-may-split-line)
(defvar org-element-use-cache)
(defvar org-export-filters-alist)
-(defvar org-table-follow-field-mode)
-(defvar orgtbl-mode) ; defined below
-(defvar orgtbl-mode-menu) ; defined when orgtbl mode get initialized
+(defvar org-finish-function)
+(defvar org-inhibit-highlight-removal)
+(defvar org-inhibit-startup)
+(defvar org-selected-window)
+(defvar org-self-insert-cluster-for-undo)
+(defvar org-self-insert-command-undo-counter)
+(defvar org-ts-regexp)
+(defvar org-ts-regexp-both)
+(defvar org-ts-regexp-inactive)
+(defvar org-ts-regexp3)
+(defvar org-window-configuration)
(defvar sort-fold-case)
-(defvar orgtbl-after-send-table-hook nil
- "Hook for functions attaching to `C-c C-c', if the table is sent.
-This can be used to add additional functionality after the table is sent
-to the receiver position, otherwise, if table is not sent, the functions
-are not run.")
+
+;;; Customizables
-(defvar org-table-TBLFM-begin-regexp "^[ \t]*|.*\n[ \t]*#\\+TBLFM: ")
+(defgroup org-table nil
+ "Options concerning tables in Org mode."
+ :tag "Org Table"
+ :group 'org)
(defcustom orgtbl-optimized t
"Non-nil means use the optimized table editor version for `orgtbl-mode'.
@@ -193,6 +208,15 @@ alignment to the right border applies."
:group 'org-table-settings
:type 'number)
+(defcustom org-table-formula-field-format "%s"
+ "Format for fields which contain the result of a formula.
+For example, using \"~%s~\" will display the result within tilde
+characters. Beware that modifying the display can prevent the
+field from being used in another formula."
+ :group 'org-table-settings
+ :version "24.1"
+ :type 'string)
+
(defgroup org-table-editing nil
"Behavior of tables during editing in Org mode."
:tag "Org Table Editing"
@@ -241,6 +265,13 @@ this line."
:group 'org-table-editing
:type 'boolean)
+(defcustom org-table-shrunk-column-indicator "…"
+ "String to be displayed in a shrunk column."
+ :group 'org-table-editing
+ :type 'string
+ :package-version '(Org . "9.2")
+ :safe (lambda (v) (and (stringp v) (not (equal v "")))))
+
(defgroup org-table-calculation nil
"Options concerning tables in Org mode."
:tag "Org Table Calculation"
@@ -276,8 +307,7 @@ t accept as input and present for editing"
calc-prefer-frac nil
calc-symbolic-mode nil
calc-date-format (YYYY "-" MM "-" DD " " Www (" " hh ":" mm))
- calc-display-working-message t
- )
+ calc-display-working-message t)
"List with Calc mode settings for use in `calc-eval' for table formulas.
The list must contain alternating symbols (Calc modes variables and values).
Don't remove any of the default settings, just change the values. Org mode
@@ -310,15 +340,6 @@ So this is about 08:32:34 versus 8:33:34."
:type 'boolean
:safe #'booleanp)
-(defcustom org-table-formula-field-format "%s"
- "Format for fields which contain the result of a formula.
-For example, using \"~%s~\" will display the result within tilde
-characters. Beware that modifying the display can prevent the
-field from being used in another formula."
- :group 'org-table-settings
- :version "24.1"
- :type 'string)
-
(defcustom org-table-formula-evaluate-inline t
"Non-nil means TAB and RET evaluate a formula in current table field.
If the current field starts with an equal sign, it is assumed to be a formula
@@ -390,7 +411,6 @@ many columns as needed. When set to `warn', issue a warning when
doing so. When set to `prompt', ask user before creating a new
column. Otherwise, throw an error."
:group 'org-table-calculation
- :version "26.1"
:package-version '(Org . "8.3")
:type '(choice
(const :tag "Out-of-bounds field generates an error (default)" nil)
@@ -416,19 +436,37 @@ available parameters."
"Max lines that `org-table-convert-region' will attempt to process.
The function can be slow on larger regions; this safety feature
-prevents it from hanging emacs."
+prevents it from hanging Emacs."
:group 'org-table-import-export
:type 'integer
- :version "26.1"
:package-version '(Org . "8.3"))
-(defcustom org-table-shrunk-column-indicator "…"
- "String to be displayed in a shrunk column."
- :group 'org-table-editing
- :type 'string
- :version "27.1"
- :package-version '(Org . "9.2")
- :safe (lambda (v) (and (stringp v) (not (equal v "")))))
+
+;;; Regexps Constants
+
+(defconst org-table-any-line-regexp "^[ \t]*\\(|\\|\\+-[-+]\\)"
+ "Detect an org-type or table-type table.")
+
+(defconst org-table-line-regexp "^[ \t]*|"
+ "Detect an org-type table line.")
+
+(defconst org-table-dataline-regexp "^[ \t]*|[^-]"
+ "Detect an org-type table line.")
+
+(defconst org-table-hline-regexp "^[ \t]*|-"
+ "Detect an org-type table hline.")
+
+(defconst org-table1-hline-regexp "^[ \t]*\\+-[-+]"
+ "Detect a table-type table hline.")
+
+(defconst org-table-any-border-regexp "^[ \t]*[^|+ \t]"
+ "Detect the first line outside a table when searching from within it.
+This works for both table types.")
+
+(defconst org-TBLFM-regexp "^[ \t]*#\\+TBLFM: "
+ "Detect a #+TBLFM line.")
+
+(defvar org-table-TBLFM-begin-regexp "^[ \t]*|.*\n[ \t]*#\\+TBLFM: ")
(defconst org-table-auto-recalculate-regexp "^[ \t]*| *# *\\(|\\|$\\)"
"Regexp matching a line marked for automatic recalculation.")
@@ -442,10 +480,52 @@ prevents it from hanging emacs."
(defconst org-table-border-regexp "^[ \t]*[^| \t]"
"Regexp matching any line outside an Org table.")
+(defconst org-table-range-regexp
+ "@\\([-+]?I*[-+]?[0-9]*\\)\\(\\$[-+]?[0-9]+\\)?\\(\\.\\.@?\\([-+]?I*[-+]?[0-9]*\\)\\(\\$[-+]?[0-9]+\\)?\\)?"
+ ;; 1 2 3 4 5
+ "Regular expression for matching ranges in formulas.")
+
+(defconst org-table-range-regexp2
+ (concat
+ "\\(" "@[-0-9I$&]+" "\\|" "[a-zA-Z]\\{1,2\\}\\([0-9]+\\|&\\)" "\\|" "\\$[a-zA-Z0-9]+" "\\)"
+ "\\.\\."
+ "\\(" "@?[-0-9I$&]+" "\\|" "[a-zA-Z]\\{1,2\\}\\([0-9]+\\|&\\)" "\\|" "\\$[a-zA-Z0-9]+" "\\)")
+ "Match a range for reference display.")
+
+(defconst org-table-translate-regexp
+ (concat "\\(" "@[-0-9I$]+" "\\|" "[a-zA-Z]\\{1,2\\}\\([0-9]+\\|&\\)" "\\)")
+ "Match a reference that needs translation, for reference display.")
+
+(defconst org-table-separator-space
+ (propertize " " 'display '(space :relative-width 1))
+ "Space used around fields when aligning the table.
+This space serves as a segment separator for the purposes of the
+bidirectional reordering.")
+
+
+;;; Internal Variables
+
(defvar org-table-last-highlighted-reference nil)
(defvar org-table-formula-history nil)
+(defvar org-field-marker nil)
+(defvar org-table-buffer-is-an nil)
+
+(defvar-local org-table-formula-constants-local nil
+ "Local version of `org-table-formula-constants'.")
+
+(defvar org-table-may-need-update t
+ "Indicates that a table might need an update.
+This variable is set by `org-before-change-function'.
+`org-table-align' sets it back to nil.")
+
+(defvar orgtbl-after-send-table-hook nil
+ "Hook for functions attaching to `C-c C-c', if the table is sent.
+This can be used to add additional functionality after the table is sent
+to the receiver position, otherwise, if table is not sent, the functions
+are not run.")
+
(defvar org-table-column-names nil
"Alist with column names, derived from the `!' line.
This variable is initialized with `org-table-analyze'.")
@@ -488,43 +568,59 @@ variable is initialized with `org-table-analyze'.")
Line numbers are counted from the beginning of the table. This
variable is initialized with `org-table-analyze'.")
-(defconst org-table-range-regexp
- "@\\([-+]?I*[-+]?[0-9]*\\)\\(\\$[-+]?[0-9]+\\)?\\(\\.\\.@?\\([-+]?I*[-+]?[0-9]*\\)\\(\\$[-+]?[0-9]+\\)?\\)?"
- ;; 1 2 3 4 5
- "Regular expression for matching ranges in formulas.")
+(defvar org-table-aligned-begin-marker (make-marker)
+ "Marker at the beginning of the table last aligned.
+Used to check if cursor still is in that table, to minimize realignment.")
-(defconst org-table-range-regexp2
- (concat
- "\\(" "@[-0-9I$&]+" "\\|" "[a-zA-Z]\\{1,2\\}\\([0-9]+\\|&\\)" "\\|" "\\$[a-zA-Z0-9]+" "\\)"
- "\\.\\."
- "\\(" "@?[-0-9I$&]+" "\\|" "[a-zA-Z]\\{1,2\\}\\([0-9]+\\|&\\)" "\\|" "\\$[a-zA-Z0-9]+" "\\)")
- "Match a range for reference display.")
+(defvar org-table-aligned-end-marker (make-marker)
+ "Marker at the end of the table last aligned.
+Used to check if cursor still is in that table, to minimize realignment.")
-(defconst org-table-translate-regexp
- (concat "\\(" "@[-0-9I$]+" "\\|" "[a-zA-Z]\\{1,2\\}\\([0-9]+\\|&\\)" "\\)")
- "Match a reference that needs translation, for reference display.")
+(defvar org-table-last-alignment nil
+ "List of flags for flushright alignment, from the last re-alignment.
+This is being used to correctly align a single field after TAB or RET.")
-(defconst org-table-separator-space
- (propertize " " 'display '(space :relative-width 1))
- "Space used around fields when aligning the table.
-This space serves as a segment separator for the purposes of the
-bidirectional reordering.")
+(defvar org-table-last-column-widths nil
+ "List of max width of fields in each column.
+This is being used to correctly align a single field after TAB or RET.")
-(defmacro org-table-save-field (&rest body)
- "Save current field; execute BODY; restore field.
-Field is restored even in case of abnormal exit."
- (declare (debug (body)))
- (org-with-gensyms (line column)
- `(let ((,line (copy-marker (line-beginning-position)))
- (,column (org-table-current-column)))
- (unwind-protect
- (progn ,@body)
- (goto-char ,line)
- (org-table-goto-column ,column)
- (set-marker ,line nil)))))
+(defvar-local org-table-formula-debug nil
+ "Non-nil means debug table formulas.
+When nil, simply write \"#ERROR\" in corrupted fields.")
+
+(defvar-local org-table-overlay-coordinates nil
+ "Overlay coordinates after each align of a table.")
+
+(defvar org-last-recalc-line nil)
+
+(defvar org-show-positions nil)
+
+(defvar org-table-rectangle-overlays nil)
+
+(defvar org-table-clip nil
+ "Clipboard for table regions.")
-;;; See org-macs.el for the definition of org-table-with-shrunk-field,
-;;; including the reason why it is defined there and not here.
+(defvar org-timecnt nil)
+
+(defvar org-recalc-commands nil
+ "List of commands triggering the recalculation of a line.
+Will be filled automatically during use.")
+
+(defvar org-recalc-marks
+ '((" " . "Unmarked: no special line, no automatic recalculation")
+ ("#" . "Automatically recalculate this line upon TAB, RET, and C-c C-c in the line")
+ ("*" . "Recalculate only when entire table is recalculated with `C-u C-c *'")
+ ("!" . "Column name definition line. Reference in formula as $name.")
+ ("$" . "Parameter definition line name=value. Reference in formula as $name.")
+ ("_" . "Names for values in row below this one.")
+ ("^" . "Names for values in row above this one.")))
+
+(defvar org-tbl-calc-modes nil)
+
+(defvar org-pos nil)
+
+
+;;; Macros and Inlined Functions
(defmacro org-table-with-shrunk-columns (&rest body)
"Expand all columns before executing BODY, then shrink them again."
@@ -540,6 +636,90 @@ Field is restored even in case of abnormal exit."
(set-marker ,begin nil)
(set-marker ,end nil)))))
+(defmacro org-table-with-shrunk-field (&rest body)
+ "Save field shrunk state, execute BODY and restore state."
+ (declare (debug (body)))
+ (org-with-gensyms (end shrunk size)
+ `(let* ((,shrunk (save-match-data (org-table--shrunk-field)))
+ (,end (and ,shrunk (copy-marker (overlay-end ,shrunk) t)))
+ (,size (and ,shrunk (- ,end (overlay-start ,shrunk)))))
+ (when ,shrunk (delete-overlay ,shrunk))
+ (unwind-protect (progn ,@body)
+ (when ,shrunk (move-overlay ,shrunk (- ,end ,size) ,end))))))
+
+(defmacro org-table-save-field (&rest body)
+ "Save current field; execute BODY; restore field.
+Field is restored even in case of abnormal exit."
+ (declare (debug (body)))
+ (org-with-gensyms (line column)
+ `(let ((,line (copy-marker (line-beginning-position)))
+ (,column (org-table-current-column)))
+ (unwind-protect
+ (progn ,@body)
+ (goto-char ,line)
+ (org-table-goto-column ,column)
+ (set-marker ,line nil)))))
+
+(defsubst org-table--set-calc-mode (var &optional value)
+ (if (stringp var)
+ (setq var (assoc var '(("D" calc-angle-mode deg)
+ ("R" calc-angle-mode rad)
+ ("F" calc-prefer-frac t)
+ ("S" calc-symbolic-mode t)))
+ value (nth 2 var) var (nth 1 var)))
+ (if (memq var org-tbl-calc-modes)
+ (setcar (cdr (memq var org-tbl-calc-modes)) value)
+ (cons var (cons value org-tbl-calc-modes)))
+ org-tbl-calc-modes)
+
+
+;;; Predicates
+
+(defun org-at-TBLFM-p (&optional pos)
+ "Non-nil when point (or POS) is in #+TBLFM line."
+ (save-excursion
+ (goto-char (or pos (point)))
+ (beginning-of-line)
+ (and (let ((case-fold-search t)) (looking-at org-TBLFM-regexp))
+ (eq (org-element-type (org-element-at-point)) 'table))))
+
+(defun org-at-table-p (&optional table-type)
+ "Non-nil if the cursor is inside an Org table.
+If TABLE-TYPE is non-nil, also check for table.el-type tables."
+ (and (org-match-line (if table-type "[ \t]*[|+]" "[ \t]*|"))
+ (or (not (derived-mode-p 'org-mode))
+ (let ((e (org-element-lineage (org-element-at-point) '(table) t)))
+ (and e (or table-type
+ (eq 'org (org-element-property :type e))))))))
+
+(defun org-at-table.el-p ()
+ "Non-nil when point is at a table.el table."
+ (and (org-match-line "[ \t]*[|+]")
+ (let ((element (org-element-at-point)))
+ (and (eq (org-element-type element) 'table)
+ (eq (org-element-property :type element) 'table.el)))))
+
+(defun org-at-table-hline-p ()
+ "Non-nil when point is inside a hline in a table.
+Assume point is already in a table."
+ (org-match-line org-table-hline-regexp))
+
+(defun org-table-check-inside-data-field (&optional noerror assume-table)
+ "Non-nil when point is inside a table data field.
+Raise an error otherwise, unless NOERROR is non-nil. In that
+case, return nil if point is not inside a data field. When
+optional argument ASSUME-TABLE is non-nil, assume point is within
+a table."
+ (cond ((and (or assume-table (org-at-table-p))
+ (not (save-excursion (skip-chars-backward " \t") (bolp)))
+ (not (org-at-table-hline-p))
+ (not (looking-at-p "[ \t]*$"))))
+ (noerror nil)
+ (t (user-error "Not in table data field"))))
+
+
+;;; Create, Import, and Convert Tables
+
;;;###autoload
(defun org-table-create-with-table.el ()
"Use the table.el package to insert a new table.
@@ -699,205 +879,53 @@ regexp When a regular expression, use it to match the separator."
(insert-file-contents file)
(org-table-convert-region beg (+ (point) (- (point-max) pm)) separator)))
-
-;;;###autoload
-(defun org-table-export (&optional file format)
- "Export table to a file, with configurable format.
-Such a file can be imported into usual spreadsheet programs.
-
-FILE can be the output file name. If not given, it will be taken
-from a TABLE_EXPORT_FILE property in the current entry or higher
-up in the hierarchy, or the user will be prompted for a file
-name. FORMAT can be an export format, of the same kind as it
-used when `orgtbl-mode' sends a table in a different format.
-
-The command suggests a format depending on TABLE_EXPORT_FORMAT,
-whether it is set locally or up in the hierarchy, then on the
-extension of the given file name, and finally on the variable
-`org-table-export-default-format'."
+(defun org-table-convert ()
+ "Convert from Org table to table.el and back.
+Obviously, this only works within limits. When an Org table is converted
+to table.el, all horizontal separator lines get lost, because table.el uses
+these as cell boundaries and has no notion of horizontal lines. A table.el
+table can be converted to an Org table only if it does not do row or column
+spanning. Multiline cells will become multiple cells. Beware, Org mode
+does not test if the table can be successfully converted - it blindly
+applies a recipe that works for simple tables."
(interactive)
- (unless (org-at-table-p) (user-error "No table at point"))
- (org-table-align) ; Make sure we have everything we need.
- (let ((file (or file (org-entry-get (point) "TABLE_EXPORT_FILE" t))))
- (unless file
- (setq file (read-file-name "Export table to: "))
- (unless (or (not (file-exists-p file))
- (y-or-n-p (format "Overwrite file %s? " file)))
- (user-error "File not written")))
- (when (file-directory-p file)
- (user-error "This is a directory path, not a file"))
- (when (and (buffer-file-name (buffer-base-buffer))
- (file-equal-p
- (file-truename file)
- (file-truename (buffer-file-name (buffer-base-buffer)))))
- (user-error "Please specify a file name that is different from current"))
- (let ((fileext (concat (file-name-extension file) "$"))
- (format (or format (org-entry-get (point) "TABLE_EXPORT_FORMAT" t))))
- (unless format
- (let* ((formats '("orgtbl-to-tsv" "orgtbl-to-csv" "orgtbl-to-latex"
- "orgtbl-to-html" "orgtbl-to-generic"
- "orgtbl-to-texinfo" "orgtbl-to-orgtbl"
- "orgtbl-to-unicode"))
- (deffmt-readable
- (replace-regexp-in-string
- "\t" "\\t"
- (replace-regexp-in-string
- "\n" "\\n"
- (or (car (delq nil
- (mapcar
- (lambda (f)
- (and (string-match-p fileext f) f))
- formats)))
- org-table-export-default-format)
- t t) t t)))
- (setq format
- (org-completing-read
- "Format: " formats nil nil deffmt-readable))))
- (if (string-match "\\([^ \t\r\n]+\\)\\( +.*\\)?" format)
- (let ((transform (intern (match-string 1 format)))
- (params (and (match-end 2)
- (read (concat "(" (match-string 2 format) ")"))))
- (table (org-table-to-lisp
- (buffer-substring-no-properties
- (org-table-begin) (org-table-end)))))
- (unless (fboundp transform)
- (user-error "No such transformation function %s" transform))
- (let (buf)
- (with-current-buffer (find-file-noselect file)
- (setq buf (current-buffer))
- (erase-buffer)
- (fundamental-mode)
- (insert (funcall transform table params) "\n")
- (save-buffer))
- (kill-buffer buf))
- (message "Export done."))
- (user-error "TABLE_EXPORT_FORMAT invalid")))))
-
-(defvar org-table-aligned-begin-marker (make-marker)
- "Marker at the beginning of the table last aligned.
-Used to check if cursor still is in that table, to minimize realignment.")
-(defvar org-table-aligned-end-marker (make-marker)
- "Marker at the end of the table last aligned.
-Used to check if cursor still is in that table, to minimize realignment.")
-(defvar org-table-last-alignment nil
- "List of flags for flushright alignment, from the last re-alignment.
-This is being used to correctly align a single field after TAB or RET.")
-(defvar org-table-last-column-widths nil
- "List of max width of fields in each column.
-This is being used to correctly align a single field after TAB or RET.")
-(defvar-local org-table-formula-debug nil
- "Non-nil means debug table formulas.
-When nil, simply write \"#ERROR\" in corrupted fields.")
-(defvar-local org-table-overlay-coordinates nil
- "Overlay coordinates after each align of a table.")
-
-(defvar org-last-recalc-line nil)
-
-(defun org-table--align-field (field width align)
- "Format FIELD according to column WIDTH and alignement ALIGN.
-FIELD is a string. WIDTH is a number. ALIGN is either \"c\",
-\"l\" or\"r\"."
- (let* ((spaces (- width (org-string-width field)))
- (prefix (pcase align
- ("l" "")
- ("r" (make-string spaces ?\s))
- ("c" (make-string (/ spaces 2) ?\s))))
- (suffix (make-string (- spaces (length prefix)) ?\s)))
- (concat org-table-separator-space
- prefix
- field
- suffix
- org-table-separator-space)))
+ (require 'table)
+ (if (org-at-table.el-p)
+ ;; convert to Org table
+ (let ((beg (copy-marker (org-table-begin t)))
+ (end (copy-marker (org-table-end t))))
+ (table-unrecognize-region beg end)
+ (goto-char beg)
+ (while (re-search-forward "^\\([ \t]*\\)\\+-.*\n" end t)
+ (replace-match ""))
+ (goto-char beg))
+ (if (org-at-table-p)
+ ;; convert to table.el table
+ (let ((beg (copy-marker (org-table-begin)))
+ (end (copy-marker (org-table-end))))
+ ;; first, get rid of all horizontal lines
+ (goto-char beg)
+ (while (re-search-forward "^\\([ \t]*\\)|-.*\n" end t)
+ (replace-match ""))
+ ;; insert a hline before first
+ (goto-char beg)
+ (org-table-insert-hline 'above)
+ (beginning-of-line -1)
+ ;; insert a hline after each line
+ (while (progn (beginning-of-line 3) (< (point) end))
+ (org-table-insert-hline))
+ (goto-char beg)
+ (setq end (move-marker end (org-table-end)))
+ ;; replace "+" at beginning and ending of hlines
+ (while (re-search-forward "^\\([ \t]*\\)|-" end t)
+ (replace-match "\\1+-"))
+ (goto-char beg)
+ (while (re-search-forward "-|[ \t]*$" end t)
+ (replace-match "-+"))
+ (goto-char beg)))))
-;;;###autoload
-(defun org-table-align ()
- "Align the table at point by aligning all vertical bars."
- (interactive)
- (let ((beg (org-table-begin))
- (end (copy-marker (org-table-end))))
- (org-table-save-field
- ;; Make sure invisible characters in the table are at the right
- ;; place since column widths take them into account.
- (org-font-lock-ensure beg end)
- (move-marker org-table-aligned-begin-marker beg)
- (move-marker org-table-aligned-end-marker end)
- (goto-char beg)
- (org-table-with-shrunk-columns
- (let* ((indent (progn (looking-at "[ \t]*") (match-string 0)))
- ;; Table's rows as lists of fields. Rules are replaced
- ;; by nil. Trailing spaces are removed.
- (fields (mapcar
- (lambda (l)
- (and (not (string-match-p org-table-hline-regexp l))
- (org-split-string l "[ \t]*|[ \t]*")))
- (split-string (buffer-substring beg end) "\n" t)))
- ;; Compute number of columns. If the table contains no
- ;; field, create a default table and bail out.
- (columns-number
- (if fields (apply #'max (mapcar #'length fields))
- (kill-region beg end)
- (org-table-create org-table-default-size)
- (user-error "Empty table - created default table")))
- (widths nil)
- (alignments nil))
- ;; Compute alignment and width for each column.
- (dotimes (i columns-number)
- (let* ((max-width 1)
- (fixed-align? nil)
- (numbers 0)
- (non-empty 0))
- (dolist (row fields)
- (let ((cell (or (nth i row) "")))
- (setq max-width (max max-width (org-string-width cell)))
- (cond (fixed-align? nil)
- ((equal cell "") nil)
- ((string-match "\\`<\\([lrc]\\)[0-9]*>\\'" cell)
- (setq fixed-align? (match-string 1 cell)))
- (t
- (cl-incf non-empty)
- (when (string-match-p org-table-number-regexp cell)
- (cl-incf numbers))))))
- (push max-width widths)
- (push (cond
- (fixed-align?)
- ((>= numbers (* org-table-number-fraction non-empty)) "r")
- (t "l"))
- alignments)))
- (setq widths (nreverse widths))
- (setq alignments (nreverse alignments))
- ;; Store alignment of this table, for later editing of single
- ;; fields.
- (setq org-table-last-alignment alignments)
- (setq org-table-last-column-widths widths)
- ;; Build new table rows. Only replace rows that actually
- ;; changed.
- (dolist (row fields)
- (let ((previous (buffer-substring (point) (line-end-position)))
- (new
- (format "%s|%s|"
- indent
- (if (null row) ;horizontal rule
- (mapconcat (lambda (w) (make-string (+ 2 w) ?-))
- widths
- "+")
- (let ((cells ;add missing fields
- (append row
- (make-list (- columns-number
- (length row))
- ""))))
- (mapconcat #'identity
- (cl-mapcar #'org-table--align-field
- cells
- widths
- alignments)
- "|"))))))
- (if (equal new previous)
- (forward-line)
- (insert new "\n")
- (delete-region (point) (line-beginning-position 2)))))
- (set-marker end nil)
- (when org-table-overlay-coordinates (org-table-overlay-coordinates))
- (setq org-table-may-need-update nil))))))
+
+;;; Navigation and Structure Editing
;;;###autoload
(defun org-table-begin (&optional table-type)
@@ -935,54 +963,6 @@ a table."
(if (bolp) (point) (line-end-position))))))
;;;###autoload
-(defun org-table-justify-field-maybe (&optional new)
- "Justify the current field, text to left, number to right.
-Optional argument NEW may specify text to replace the current field content."
- (cond
- ((and (not new) org-table-may-need-update)) ; Realignment will happen anyway
- ((org-at-table-hline-p))
- ((and (not new)
- (or (not (eq (marker-buffer org-table-aligned-begin-marker)
- (current-buffer)))
- (< (point) org-table-aligned-begin-marker)
- (>= (point) org-table-aligned-end-marker)))
- ;; This is not the same table, force a full re-align.
- (setq org-table-may-need-update t))
- (t
- ;; Realign the current field, based on previous full realign.
- (let ((pos (point))
- (col (org-table-current-column)))
- (when (> col 0)
- (skip-chars-backward "^|")
- (if (not (looking-at " *\\([^|\n]*?\\) *\\(|\\|$\\)"))
- (setq org-table-may-need-update t)
- (let* ((align (nth (1- col) org-table-last-alignment))
- (width (nth (1- col) org-table-last-column-widths))
- (cell (match-string 0))
- (field (match-string 1))
- (properly-closed? (/= (match-beginning 2) (match-end 2)))
- (new-cell
- (save-match-data
- (cond (org-table-may-need-update
- (format " %s |" (or new field)))
- ((not properly-closed?)
- (setq org-table-may-need-update t)
- (format " %s |" (or new field)))
- ((not new)
- (concat (org-table--align-field field width align)
- "|"))
- ((<= (org-string-width new) width)
- (concat (org-table--align-field new width align)
- "|"))
- (t
- (setq org-table-may-need-update t)
- (format " %s |" new))))))
- (unless (equal new-cell cell)
- (let (org-table-may-need-update)
- (replace-match new-cell t t)))
- (goto-char pos))))))))
-
-;;;###autoload
(defun org-table-next-field ()
"Go to the next field in the current table, creating new lines as needed.
Before doing so, re-align the table if necessary."
@@ -1090,109 +1070,6 @@ Before doing so, re-align the table if necessary."
(skip-chars-backward "^|\n\r")
(when (looking-at " ") (forward-char))))
-;;;###autoload
-(defun org-table-copy-down (n)
- "Copy the value of the current field one row below.
-
-If the field at the cursor is empty, copy the content of the
-nearest non-empty field above. With argument N, use the Nth
-non-empty field.
-
-If the current field is not empty, it is copied down to the next
-row, and the cursor is moved with it. Therefore, repeating this
-command causes the column to be filled row-by-row.
-
-If the variable `org-table-copy-increment' is non-nil and the
-field is an integer or a timestamp, it will be incremented while
-copying. By default, increment by the difference between the
-value in the current field and the one in the field above. To
-increment using a fixed integer, set `org-table-copy-increment'
-to a number. In the case of a timestamp, increment by days."
- (interactive "p")
- (let* ((colpos (org-table-current-column))
- (col (current-column))
- (field (save-excursion (org-table-get-field)))
- (field-up (or (save-excursion
- (org-table-get (1- (org-table-current-line))
- (org-table-current-column))) ""))
- (non-empty (string-match "[^ \t]" field))
- (non-empty-up (string-match "[^ \t]" field-up))
- (beg (org-table-begin))
- (orig-n n)
- txt txt-up inc)
- (org-table-check-inside-data-field)
- (if (not non-empty)
- (save-excursion
- (setq txt
- (catch 'exit
- (while (progn (beginning-of-line 1)
- (re-search-backward org-table-dataline-regexp
- beg t))
- (org-table-goto-column colpos t)
- (if (and (looking-at
- "|[ \t]*\\([^| \t][^|]*?\\)[ \t]*|")
- (<= (setq n (1- n)) 0))
- (throw 'exit (match-string 1))))))
- (setq field-up
- (catch 'exit
- (while (progn (beginning-of-line 1)
- (re-search-backward org-table-dataline-regexp
- beg t))
- (org-table-goto-column colpos t)
- (if (and (looking-at
- "|[ \t]*\\([^| \t][^|]*?\\)[ \t]*|")
- (<= (setq n (1- n)) 0))
- (throw 'exit (match-string 1))))))
- (setq non-empty-up (and field-up (string-match "[^ \t]" field-up))))
- ;; Above field was not empty, go down to the next row. Skip
- ;; alignment since we do it at the end of the process anyway.
- (setq txt (org-trim field))
- (let ((org-table-may-need-update nil)) (org-table-next-row))
- (org-table-blank-field))
- (if non-empty-up (setq txt-up (org-trim field-up)))
- (setq inc (cond
- ((numberp org-table-copy-increment) org-table-copy-increment)
- (txt-up (cond ((and (string-match org-ts-regexp3 txt-up)
- (string-match org-ts-regexp3 txt))
- (- (org-time-string-to-absolute txt)
- (org-time-string-to-absolute txt-up)))
- ((string-match org-ts-regexp3 txt) 1)
- ((string-match "\\([-+]\\)?[0-9]*\\(?:\\.[0-9]+\\)?" txt-up)
- (- (string-to-number txt)
- (string-to-number (match-string 0 txt-up))))
- (t 1)))
- (t 1)))
- (if (not txt)
- (user-error "No non-empty field found")
- (if (and org-table-copy-increment
- (not (equal orig-n 0))
- (string-match-p "^[-+^/*0-9eE.]+$" txt)
- (< (string-to-number txt) 100000000))
- (setq txt (calc-eval (concat txt "+" (number-to-string inc)))))
- (insert txt)
- (org-move-to-column col)
- (if (and org-table-copy-increment (org-at-timestamp-p 'lax))
- (org-timestamp-up-day inc)
- (org-table-maybe-recalculate-line))
- (org-table-align)
- (org-move-to-column col))))
-
-(defun org-table-check-inside-data-field (&optional noerror assume-table)
- "Non-nil when point is inside a table data field.
-Raise an error otherwise, unless NOERROR is non-nil. In that
-case, return nil if point is not inside a data field. When
-optional argument ASSUME-TABLE is non-nil, assume point is within
-a table."
- (cond ((and (or assume-table (org-at-table-p))
- (not (save-excursion (skip-chars-backward " \t") (bolp)))
- (not (org-at-table-hline-p))
- (not (looking-at-p "[ \t]*$"))))
- (noerror nil)
- (t (user-error "Not in table data field"))))
-
-(defvar org-table-clip nil
- "Clipboard for table regions.")
-
(defun org-table-get (line column)
"Get the field in table line LINE, column COLUMN.
If LINE is larger than the number of data lines in the table, the function
@@ -1225,6 +1102,30 @@ When ALIGN is set, also realign the table."
(< (point-at-eol) pos))))
cnt))
+(defun org-table-current-column ()
+ "Return current column number."
+ (interactive)
+ (save-excursion
+ (let ((pos (point)))
+ (beginning-of-line)
+ (if (not (search-forward "|" pos t)) 0
+ (let ((column 1)
+ (separator (if (org-at-table-hline-p) "[+|]" "|")))
+ (while (re-search-forward separator pos t) (cl-incf column))
+ column)))))
+
+(defun org-table-current-dline ()
+ "Find out what table data line we are in.
+Only data lines count for this."
+ (save-excursion
+ (let ((c 0)
+ (pos (line-beginning-position)))
+ (goto-char (org-table-begin))
+ (while (<= (point) pos)
+ (when (looking-at org-table-dataline-regexp) (cl-incf c))
+ (forward-line))
+ c)))
+
(defun org-table-goto-line (N)
"Go to the Nth data line in the current table.
Return t when the line exists, nil if it does not exist."
@@ -1319,29 +1220,36 @@ value."
(car eqn) "=" (cdr eqn))))
"")))))
-(defun org-table-current-column ()
- "Return current column number."
- (interactive)
- (save-excursion
- (let ((pos (point)))
- (beginning-of-line)
- (if (not (search-forward "|" pos t)) 0
- (let ((column 1)
- (separator (if (org-at-table-hline-p) "[+|]" "|")))
- (while (re-search-forward separator pos t) (cl-incf column))
- column)))))
+(defun org-table-goto-field (ref &optional create-column-p)
+ "Move point to a specific field in the current table.
-(defun org-table-current-dline ()
- "Find out what table data line we are in.
-Only data lines count for this."
- (save-excursion
- (let ((c 0)
- (pos (line-beginning-position)))
- (goto-char (org-table-begin))
- (while (<= (point) pos)
- (when (looking-at org-table-dataline-regexp) (cl-incf c))
- (forward-line))
- c)))
+REF is either the name of a field its absolute reference, as
+a string. No column is created unless CREATE-COLUMN-P is
+non-nil. If it is a function, it is called with the column
+number as its argument as is used as a predicate to know if the
+column can be created.
+
+This function assumes the table is already analyzed (i.e., using
+`org-table-analyze')."
+ (let* ((coordinates
+ (cond
+ ((cdr (assoc ref org-table-named-field-locations)))
+ ((string-match "\\`@\\([1-9][0-9]*\\)\\$\\([1-9][0-9]*\\)\\'" ref)
+ (list (condition-case nil
+ (aref org-table-dlines
+ (string-to-number (match-string 1 ref)))
+ (error (user-error "Invalid row number in %s" ref)))
+ (string-to-number (match-string 2 ref))))
+ (t (user-error "Unknown field: %s" ref))))
+ (line (car coordinates))
+ (column (nth 1 coordinates))
+ (create-new-column (if (functionp create-column-p)
+ (funcall create-column-p column)
+ create-column-p)))
+ (when coordinates
+ (goto-char org-table-current-begin-pos)
+ (forward-line line)
+ (org-table-goto-column column nil create-new-column))))
;;;###autoload
(defun org-table-goto-column (n &optional on-delim force)
@@ -1443,6 +1351,80 @@ non-nil, the one above is used."
(above min)
(t max)))))))
+(defun org-table--swap-cells (row1 col1 row2 col2)
+ "Swap two cells indicated by the coordinates provided.
+ROW1, COL1, ROW2, COL2 are integers indicating the row/column
+position of the two cells that will be swapped in the table."
+ (let ((content1 (org-table-get row1 col1))
+ (content2 (org-table-get row2 col2)))
+ (org-table-put row1 col1 content2)
+ (org-table-put row2 col2 content1)))
+
+(defun org-table--move-cell (direction)
+ "Move the current cell in a cardinal direction.
+DIRECTION is a symbol among `up', `down', `left', and `right'.
+The contents the current cell are swapped with cell in the
+indicated direction. Raise an error if the move cannot be done."
+ (let ((row-shift (pcase direction (`up -1) (`down 1) (_ 0)))
+ (column-shift (pcase direction (`left -1) (`right 1) (_ 0))))
+ (when (and (= 0 row-shift) (= 0 column-shift))
+ (error "Invalid direction: %S" direction))
+ ;; Initialize `org-table-current-ncol' and `org-table-dlines'.
+ (org-table-analyze)
+ (let* ((row (org-table-current-line))
+ (column (org-table-current-column))
+ (target-row (+ row row-shift))
+ (target-column (+ column column-shift))
+ (org-table-current-nrow (1- (length org-table-dlines))))
+ (when (or (< target-column 1)
+ (< target-row 1)
+ (> target-column org-table-current-ncol)
+ (> target-row org-table-current-nrow))
+ (user-error "Cannot move cell further"))
+ (org-table--swap-cells row column target-row target-column)
+ (org-table-goto-line target-row)
+ (org-table-goto-column target-column))))
+
+;;;###autoload
+(defun org-table-move-cell-up ()
+ "Move a single cell up in a table.
+Swap with anything in target cell."
+ (interactive)
+ (unless (org-table-check-inside-data-field)
+ (error "No table at point"))
+ (org-table--move-cell 'up)
+ (org-table-align))
+
+;;;###autoload
+(defun org-table-move-cell-down ()
+ "Move a single cell down in a table.
+Swap with anything in target cell."
+ (interactive)
+ (unless (org-table-check-inside-data-field)
+ (error "No table at point"))
+ (org-table--move-cell 'down)
+ (org-table-align))
+
+;;;###autoload
+(defun org-table-move-cell-left ()
+ "Move a single cell left in a table.
+Swap with anything in target cell."
+ (interactive)
+ (unless (org-table-check-inside-data-field)
+ (error "No table at point"))
+ (org-table--move-cell 'left)
+ (org-table-align))
+
+;;;###autoload
+(defun org-table-move-cell-right ()
+ "Move a single cell right in a table.
+Swap with anything in target cell."
+ (interactive)
+ (unless (org-table-check-inside-data-field)
+ (error "No table at point"))
+ (org-table--move-cell 'right)
+ (org-table-align))
+
;;;###autoload
(defun org-table-delete-column ()
"Delete a column from the table."
@@ -1690,133 +1672,6 @@ In particular, this does handle wide and invisible characters."
"@" (list (cons (number-to-string dline) "INVALID")) dline -1 dline)))))
;;;###autoload
-(defun org-table-sort-lines
- (&optional with-case sorting-type getkey-func compare-func interactive?)
- "Sort table lines according to the column at point.
-
-The position of point indicates the column to be used for
-sorting, and the range of lines is the range between the nearest
-horizontal separator lines, or the entire table of no such lines
-exist. If point is before the first column, you will be prompted
-for the sorting column. If there is an active region, the mark
-specifies the first line and the sorting column, while point
-should be in the last line to be included into the sorting.
-
-The command then prompts for the sorting type which can be
-alphabetically, numerically, or by time (as given in a time stamp
-in the field, or as a HH:MM value). Sorting in reverse order is
-also possible.
-
-With prefix argument WITH-CASE, alphabetic sorting will be case-sensitive
-if the locale allows for it.
-
-If SORTING-TYPE is specified when this function is called from a Lisp
-program, no prompting will take place. SORTING-TYPE must be a character,
-any of (?a ?A ?n ?N ?t ?T ?f ?F) where the capital letters indicate that
-sorting should be done in reverse order.
-
-If the SORTING-TYPE is ?f or ?F, then GETKEY-FUNC specifies
-a function to be called to extract the key. It must return a value
-that is compatible with COMPARE-FUNC, the function used to compare
-entries.
-
-A non-nil value for INTERACTIVE? is used to signal that this
-function is being called interactively."
- (interactive (list current-prefix-arg nil nil nil t))
- (when (org-region-active-p) (goto-char (region-beginning)))
- ;; Point must be either within a field or before a data line.
- (save-excursion
- (skip-chars-backward " \t")
- (when (bolp) (search-forward "|" (line-end-position) t))
- (org-table-check-inside-data-field))
- ;; Set appropriate case sensitivity and column used for sorting.
- (let ((column (let ((c (org-table-current-column)))
- (cond ((> c 0) c)
- (interactive?
- (read-number "Use column N for sorting: "))
- (t 1))))
- (sorting-type
- (or sorting-type
- (read-char-exclusive "Sort Table: [a]lphabetic, [n]umeric, \
-\[t]ime, [f]unc. A/N/T/F means reversed: ")))
- (start (org-table-begin))
- (end (org-table-end)))
- (save-restriction
- ;; Narrow buffer to appropriate sorting area.
- (if (org-region-active-p)
- (progn (goto-char (region-beginning))
- (narrow-to-region
- (point)
- (save-excursion (goto-char (region-end))
- (line-beginning-position 2))))
- (narrow-to-region
- (save-excursion
- (if (re-search-backward org-table-hline-regexp start t)
- (line-beginning-position 2)
- start))
- (if (save-excursion (re-search-forward org-table-hline-regexp end t))
- (match-beginning 0)
- end)))
- ;; Determine arguments for `sort-subr'. Also record original
- ;; position. `org-table-save-field' cannot help here since
- ;; sorting is too much destructive.
- (let* ((coordinates
- (cons (count-lines (point-min) (line-beginning-position))
- (current-column)))
- (extract-key-from-field
- ;; Function to be called on the contents of the field
- ;; used for sorting in the current row.
- (cl-case sorting-type
- ((?n ?N) #'string-to-number)
- ((?a ?A) #'org-sort-remove-invisible)
- ((?t ?T)
- (lambda (f)
- (cond ((string-match org-ts-regexp-both f)
- (float-time
- (org-time-string-to-time (match-string 0 f))))
- ((org-duration-p f) (org-duration-to-minutes f))
- ((string-match "\\<[0-9]+:[0-9]\\{2\\}\\>" f)
- (org-duration-to-minutes (match-string 0 f)))
- (t 0))))
- ((?f ?F)
- (or getkey-func
- (and interactive?
- (org-read-function "Function for extracting keys: "))
- (error "Missing key extractor to sort rows")))
- (t (user-error "Invalid sorting type `%c'" sorting-type))))
- (predicate
- (cl-case sorting-type
- ((?n ?N ?t ?T) #'<)
- ((?a ?A) (if with-case #'org-string-collate-lessp
- (lambda (s1 s2) (org-string-collate-lessp s1 s2 nil t))))
- ((?f ?F)
- (or compare-func
- (and interactive?
- (org-read-function
- "Function for comparing keys (empty for default \
-`sort-subr' predicate): "
- 'allow-empty))))))
- (shrunk-columns (remq column (org-table--list-shrunk-columns))))
- (goto-char (point-min))
- (sort-subr (memq sorting-type '(?A ?N ?T ?F))
- (lambda ()
- (forward-line)
- (while (and (not (eobp))
- (not (looking-at org-table-dataline-regexp)))
- (forward-line)))
- #'end-of-line
- (lambda ()
- (funcall extract-key-from-field
- (org-trim (org-table-get-field column))))
- nil
- predicate)
- ;; Hide all columns but the one being sorted.
- (org-table--shrink-columns shrunk-columns start end)
- ;; Move back to initial field.
- (forward-line (car coordinates))
- (move-to-column (cdr coordinates))))))
-
-;;;###autoload
(defun org-table-cut-region (beg end)
"Copy region in table to the clipboard and blank all relevant fields.
If there is no active region, use just the field at point."
@@ -1825,6 +1680,171 @@ If there is no active region, use just the field at point."
(if (org-region-active-p) (region-end) (point))))
(org-table-copy-region beg end 'cut))
+(defun org-table--increment-field (field previous)
+ "Increment string FIELD according to PREVIOUS field.
+
+Increment FIELD only if it is a string representing a number, per
+Emacs Lisp syntax, a timestamp, or is either prefixed or suffixed
+with a number. In any other case, return FIELD as-is.
+
+If PREVIOUS has the same structure as FIELD, e.g.,
+a number-prefixed string with the same pattern, the increment
+step is the difference between numbers (or timestamps, measured
+in days) in PREVIOUS and FIELD. Otherwise, it uses
+`org-table-copy-increment', if the variable contains a number, or
+default to 1.
+
+The function assumes `org-table-copy-increment' is non-nil."
+ (let* ((default-step (if (numberp org-table-copy-increment)
+ org-table-copy-increment
+ 1))
+ (number-regexp ;Lisp read syntax for numbers
+ (rx (and string-start
+ (opt (any "+-"))
+ (or (and (one-or-more digit) (opt "."))
+ (and (zero-or-more digit) "." (one-or-more digit)))
+ (opt (any "eE") (opt (opt (any "+-")) (one-or-more digit)))
+ string-end)))
+ (number-prefix-regexp (rx (and string-start (one-or-more digit))))
+ (number-suffix-regexp (rx (and (one-or-more digit) string-end)))
+ (analyze
+ (lambda (field)
+ ;; Analyse string FIELD and return information related to
+ ;; increment or nil. When non-nil, return value has the
+ ;; following scheme: (TYPE VALUE PATTERN) where
+ ;; - TYPE is a symbol among `number', `prefix', `suffix'
+ ;; and `timestamp',
+ ;; - VALUE is a timestamp if TYPE is `timestamp', or
+ ;; a number otherwise,
+ ;; - PATTERN is the field without its prefix, or suffix if
+ ;; TYPE is either `prefix' or `suffix' , or nil
+ ;; otherwise.
+ (cond ((not (org-string-nw-p field)) nil)
+ ((string-match-p number-regexp field)
+ (list 'number
+ (string-to-number field)
+ nil))
+ ((string-match number-prefix-regexp field)
+ (list 'prefix
+ (string-to-number (match-string 0 field))
+ (substring field (match-end 0))))
+ ((string-match number-suffix-regexp field)
+ (list 'suffix
+ (string-to-number (match-string 0 field))
+ (substring field 0 (match-beginning 0))))
+ ((string-match-p org-ts-regexp3 field)
+ (list 'timestamp field nil))
+ (t nil))))
+ (next-number-string
+ (lambda (n1 &optional n2)
+ ;; Increment number N1 and return it as a string. If N2
+ ;; is also a number, deduce increment step from the
+ ;; difference between N1 and N2. Otherwise, increment
+ ;; step is `default-step'.
+ (number-to-string (if n2 (+ n1 (- n1 n2)) (+ n1 default-step)))))
+ (shift-timestamp
+ (lambda (t1 &optional t2)
+ ;; Increment timestamp T1 and return it. If T2 is also
+ ;; a timestamp, deduce increment step from the difference,
+ ;; in days, between T1 and T2. Otherwise, increment by
+ ;; `default-step' days.
+ (with-temp-buffer
+ (insert t1)
+ (org-timestamp-up-day (if (not t2) default-step
+ (- (org-time-string-to-absolute t1)
+ (org-time-string-to-absolute t2))))
+ (buffer-string)))))
+ ;; Check if both PREVIOUS and FIELD have the same type. Also, if
+ ;; the case of prefixed or suffixed numbers, make sure their
+ ;; pattern, i.e., the part of the string without the prefix or the
+ ;; suffix, is the same.
+ (pcase (cons (funcall analyze field) (funcall analyze previous))
+ (`((number ,n1 ,_) . (number ,n2 ,_))
+ (funcall next-number-string n1 n2))
+ (`((number ,n ,_) . ,_)
+ (funcall next-number-string n))
+ (`((prefix ,n1 ,p1) . (prefix ,n2 ,p2))
+ (concat (funcall next-number-string n1 (and (equal p1 p2) n2)) p1))
+ (`((prefix ,n ,p) . ,_)
+ (concat (funcall next-number-string n) p))
+ (`((suffix ,n1 ,p1) . (suffix ,n2 ,p2))
+ (concat p1 (funcall next-number-string n1 (and (equal p1 p2) n2))))
+ (`((suffix ,n ,p) . ,_)
+ (concat p (funcall next-number-string n)))
+ (`((timestamp ,t1 ,_) . (timestamp ,t2 ,_))
+ (funcall shift-timestamp t1 t2))
+ (`((timestamp ,t1 ,_) . ,_)
+ (funcall shift-timestamp t1))
+ (_ field))))
+
+;;;###autoload
+(defun org-table-copy-down (n)
+ "Copy the value of the current field one row below.
+
+If the field at the cursor is empty, copy the content of the
+nearest non-empty field above. With argument N, use the Nth
+non-empty field.
+
+If the current field is not empty, it is copied down to the next
+row, and the cursor is moved with it. Therefore, repeating this
+command causes the column to be filled row-by-row.
+
+If the variable `org-table-copy-increment' is non-nil and the
+field is a number, a timestamp, or is either prefixed or suffixed
+with a number, it will be incremented while copying. By default,
+increment by the difference between the value in the current
+field and the one in the field above, if any. To increment using
+a fixed integer, set `org-table-copy-increment' to a number. In
+the case of a timestamp, increment by days.
+
+However, when N is 0, do not increment the field at all."
+ (interactive "p")
+ (org-table-check-inside-data-field)
+ (let* ((beg (org-table-begin))
+ (column (org-table-current-column))
+ (initial-field (save-excursion
+ (let ((f (org-string-nw-p (org-table-get-field))))
+ (and f (org-trim f)))))
+ field field-above next-field)
+ (save-excursion
+ ;; Get reference field.
+ (if initial-field (setq field initial-field)
+ (beginning-of-line)
+ (setq field
+ (catch :exit
+ (while (re-search-backward org-table-dataline-regexp beg t)
+ (let ((f (org-string-nw-p (org-table-get-field column))))
+ (cond ((and (> n 1) f) (cl-decf n))
+ (f (throw :exit (org-trim f)))
+ (t nil))
+ (beginning-of-line)))
+ (user-error "No non-empty field found"))))
+ ;; Check if increment is appropriate, and how it should be done.
+ (when (and org-table-copy-increment (/= n 0))
+ ;; If increment step is not explicit, get non-empty field just
+ ;; above the field being incremented to guess it.
+ (unless (numberp org-table-copy-increment)
+ (setq field-above
+ (let ((f (unless (= beg (line-beginning-position))
+ (forward-line -1)
+ (not (org-at-table-hline-p))
+ (org-table-get-field column))))
+ (and (org-string-nw-p f)
+ (org-trim f)))))
+ ;; Compute next field.
+ (setq next-field (org-table--increment-field field field-above))))
+ ;; Since initial field in not empty, we modify row below instead.
+ ;; Skip alignment since we do it at the end of the process anyway.
+ (when initial-field
+ (let ((org-table-may-need-update nil)) (org-table-next-row))
+ (org-table-blank-field))
+ ;; Insert the new field. NEW-FIELD may be nil if
+ ;; `org-table-increment' is nil, or N = 0. In that case, copy
+ ;; FIELD.
+ (insert (or next-field field))
+ (org-table-maybe-recalculate-line)
+ (org-table-align)))
+
;;;###autoload
(defun org-table-copy-region (beg end &optional cut)
"Copy rectangular region in table to clipboard.
@@ -1891,160 +1911,26 @@ lines."
(forward-line)))
(org-table-align)))
-;;;###autoload
-(defun org-table-convert ()
- "Convert from `org-mode' table to table.el and back.
-Obviously, this only works within limits. When an Org table is converted
-to table.el, all horizontal separator lines get lost, because table.el uses
-these as cell boundaries and has no notion of horizontal lines. A table.el
-table can be converted to an Org table only if it does not do row or column
-spanning. Multiline cells will become multiple cells. Beware, Org mode
-does not test if the table can be successfully converted - it blindly
-applies a recipe that works for simple tables."
- (interactive)
- (require 'table)
- (if (org-at-table.el-p)
- ;; convert to Org table
- (let ((beg (copy-marker (org-table-begin t)))
- (end (copy-marker (org-table-end t))))
- (table-unrecognize-region beg end)
- (goto-char beg)
- (while (re-search-forward "^\\([ \t]*\\)\\+-.*\n" end t)
- (replace-match ""))
- (goto-char beg))
- (if (org-at-table-p)
- ;; convert to table.el table
- (let ((beg (copy-marker (org-table-begin)))
- (end (copy-marker (org-table-end))))
- ;; first, get rid of all horizontal lines
- (goto-char beg)
- (while (re-search-forward "^\\([ \t]*\\)|-.*\n" end t)
- (replace-match ""))
- ;; insert a hline before first
- (goto-char beg)
- (org-table-insert-hline 'above)
- (beginning-of-line -1)
- ;; insert a hline after each line
- (while (progn (beginning-of-line 3) (< (point) end))
- (org-table-insert-hline))
- (goto-char beg)
- (setq end (move-marker end (org-table-end)))
- ;; replace "+" at beginning and ending of hlines
- (while (re-search-forward "^\\([ \t]*\\)|-" end t)
- (replace-match "\\1+-"))
- (goto-char beg)
- (while (re-search-forward "-|[ \t]*$" end t)
- (replace-match "-+"))
- (goto-char beg)))))
-
-(defun org-table-transpose-table-at-point ()
- "Transpose Org table at point and eliminate hlines.
-So a table like
-
-| 1 | 2 | 4 | 5 |
-|---+---+---+---|
-| a | b | c | d |
-| e | f | g | h |
-
-will be transposed as
-
-| 1 | a | e |
-| 2 | b | f |
-| 4 | c | g |
-| 5 | d | h |
-
-Note that horizontal lines disappear."
- (interactive)
- (let* ((table (delete 'hline (org-table-to-lisp)))
- (dline_old (org-table-current-line))
- (col_old (org-table-current-column))
- (contents (mapcar (lambda (_)
- (let ((tp table))
- (mapcar
- (lambda (_)
- (prog1
- (pop (car tp))
- (setq tp (cdr tp))))
- table)))
- (car table))))
- (goto-char (org-table-begin))
- (re-search-forward "|")
- (backward-char)
- (delete-region (point) (org-table-end))
- (insert (mapconcat
- (lambda(x)
- (concat "| " (mapconcat 'identity x " | " ) " |\n" ))
- contents ""))
- (org-table-goto-line col_old)
- (org-table-goto-column dline_old))
- (org-table-align))
-
-;;;###autoload
-(defun org-table-wrap-region (arg)
- "Wrap several fields in a column like a paragraph.
-This is useful if you'd like to spread the contents of a field over several
-lines, in order to keep the table compact.
-
-If there is an active region, and both point and mark are in the same column,
-the text in the column is wrapped to minimum width for the given number of
-lines. Generally, this makes the table more compact. A prefix ARG may be
-used to change the number of desired lines. For example, \
-`C-2 \\[org-table-wrap-region]'
-formats the selected text to two lines. If the region was longer than two
-lines, the remaining lines remain empty. A negative prefix argument reduces
-the current number of lines by that amount. The wrapped text is pasted back
-into the table. If you formatted it to more lines than it was before, fields
-further down in the table get overwritten - so you might need to make space in
-the table first.
-
-If there is no region, the current field is split at the cursor position and
-the text fragment to the right of the cursor is prepended to the field one
-line down.
-
-If there is no region, but you specify a prefix ARG, the current field gets
-blank, and the content is appended to the field above."
- (interactive "P")
- (org-table-check-inside-data-field)
- (if (org-region-active-p)
- ;; There is a region: fill as a paragraph.
- (let ((start (region-beginning)))
- (org-table-cut-region (region-beginning) (region-end))
- (when (> (length (car org-table-clip)) 1)
- (user-error "Region must be limited to single column"))
- (let ((nlines (cond ((not arg) (length org-table-clip))
- ((< arg 1) (+ (length org-table-clip) arg))
- (t arg))))
- (setq org-table-clip
- (mapcar #'list
- (org-wrap (mapconcat #'car org-table-clip " ")
- nil
- nlines))))
- (goto-char start)
- (org-table-paste-rectangle))
- ;; No region, split the current field at point.
- (unless (org-get-alist-option org-M-RET-may-split-line 'table)
- (skip-chars-forward "^\r\n|"))
- (cond
- (arg ; Combine with field above.
- (let ((s (org-table-blank-field))
- (col (org-table-current-column)))
- (forward-line -1)
- (while (org-at-table-hline-p) (forward-line -1))
- (org-table-goto-column col)
- (skip-chars-forward "^|")
- (skip-chars-backward " ")
- (insert " " (org-trim s))
- (org-table-align)))
- ((looking-at "\\([^|]+\\)+|") ; Split field.
- (let ((s (match-string 1)))
- (replace-match " |")
- (goto-char (match-beginning 0))
- (org-table-next-row)
- (insert (org-trim s) " ")
- (org-table-align)))
- (t (org-table-next-row)))))
+
+;;; Follow Field minor mode
-(defvar org-field-marker nil)
+(define-minor-mode org-table-follow-field-mode
+ "Minor mode to make the table field editor window follow the cursor.
+When this mode is active, the field editor window will always show the
+current field. The mode exits automatically when the cursor leaves the
+table (but see `org-table-exit-follow-field-mode-when-leaving-table')."
+ nil " TblFollow" nil
+ (if org-table-follow-field-mode
+ (add-hook 'post-command-hook 'org-table-follow-fields-with-editor
+ 'append 'local)
+ (remove-hook 'post-command-hook 'org-table-follow-fields-with-editor 'local)
+ (let* ((buf (get-buffer "*Org Table Edit Field*"))
+ (win (and buf (get-buffer-window buf))))
+ (when win (delete-window win))
+ (when buf
+ (with-current-buffer buf
+ (move-marker org-field-marker nil))
+ (kill-buffer buf)))))
;;;###autoload
(defun org-table-edit-field (arg)
@@ -2098,6 +1984,17 @@ toggle `org-table-follow-field-mode'."
(setq-local org-field-marker pos)
(message "Edit and finish with C-c C-c")))))
+(defun org-table-follow-fields-with-editor ()
+ (if (and org-table-exit-follow-field-mode-when-leaving-table
+ (not (org-at-table-p)))
+ ;; We have left the table, exit the follow mode
+ (org-table-follow-field-mode -1)
+ (when (org-table-check-inside-data-field 'noerror)
+ (let ((win (selected-window)))
+ (org-table-edit-field nil)
+ (org-fit-window-to-buffer)
+ (select-window win)))))
+
(defun org-table-finish-edit-field ()
"Finish editing a table data field.
Remove all newline characters, insert the result into the table, realign
@@ -2121,114 +2018,8 @@ the table and kill the editing buffer."
(org-table-align)
(message "New field value inserted")))
-(define-minor-mode org-table-follow-field-mode
- "Minor mode to make the table field editor window follow the cursor.
-When this mode is active, the field editor window will always show the
-current field. The mode exits automatically when the cursor leaves the
-table (but see `org-table-exit-follow-field-mode-when-leaving-table')."
- nil " TblFollow" nil
- (if org-table-follow-field-mode
- (add-hook 'post-command-hook 'org-table-follow-fields-with-editor
- 'append 'local)
- (remove-hook 'post-command-hook 'org-table-follow-fields-with-editor 'local)
- (let* ((buf (get-buffer "*Org Table Edit Field*"))
- (win (and buf (get-buffer-window buf))))
- (when win (delete-window win))
- (when buf
- (with-current-buffer buf
- (move-marker org-field-marker nil))
- (kill-buffer buf)))))
-
-(defun org-table-follow-fields-with-editor ()
- (if (and org-table-exit-follow-field-mode-when-leaving-table
- (not (org-at-table-p)))
- ;; We have left the table, exit the follow mode
- (org-table-follow-field-mode -1)
- (when (org-table-check-inside-data-field 'noerror)
- (let ((win (selected-window)))
- (org-table-edit-field nil)
- (org-fit-window-to-buffer)
- (select-window win)))))
-
-(defvar org-timecnt) ; dynamically scoped parameter
-
-;;;###autoload
-(defun org-table-sum (&optional beg end nlast)
- "Sum numbers in region of current table column.
-The result will be displayed in the echo area, and will be available
-as kill to be inserted with \\[yank].
-
-If there is an active region, it is interpreted as a rectangle and all
-numbers in that rectangle will be summed. If there is no active
-region and point is located in a table column, sum all numbers in that
-column.
-
-If at least one number looks like a time HH:MM or HH:MM:SS, all other
-numbers are assumed to be times as well (in decimal hours) and the
-numbers are added as such.
-
-If NLAST is a number, only the NLAST fields will actually be summed."
- (interactive)
- (save-excursion
- (let (col (org-timecnt 0) diff h m s org-table-clip)
- (cond
- ((and beg end)) ; beg and end given explicitly
- ((org-region-active-p)
- (setq beg (region-beginning) end (region-end)))
- (t
- (setq col (org-table-current-column))
- (goto-char (org-table-begin))
- (unless (re-search-forward "^[ \t]*|[^-]" nil t)
- (user-error "No table data"))
- (org-table-goto-column col)
- (setq beg (point))
- (goto-char (org-table-end))
- (unless (re-search-backward "^[ \t]*|[^-]" nil t)
- (user-error "No table data"))
- (org-table-goto-column col)
- (setq end (point))))
- (let* ((items (apply 'append (org-table-copy-region beg end)))
- (items1 (cond ((not nlast) items)
- ((>= nlast (length items)) items)
- (t (setq items (reverse items))
- (setcdr (nthcdr (1- nlast) items) nil)
- (nreverse items))))
- (numbers (delq nil (mapcar 'org-table-get-number-for-summing
- items1)))
- (res (apply '+ numbers))
- (sres (if (= org-timecnt 0)
- (number-to-string res)
- (setq diff (* 3600 res)
- h (floor diff 3600) diff (mod diff 3600)
- m (floor diff 60) diff (mod diff 60)
- s diff)
- (format "%.0f:%02.0f:%02.0f" h m s))))
- (kill-new sres)
- (when (called-interactively-p 'interactive)
- (message "%s" (substitute-command-keys
- (format "Sum of %d items: %-20s \
-\(\\[yank] will insert result into buffer)" (length numbers) sres))))
- sres))))
-
-(defun org-table-get-number-for-summing (s)
- (let (n)
- (if (string-match "^ *|? *" s)
- (setq s (replace-match "" nil nil s)))
- (if (string-match " *|? *$" s)
- (setq s (replace-match "" nil nil s)))
- (setq n (string-to-number s))
- (cond
- ((and (string-match "0" s)
- (string-match "\\`[-+ \t0.edED]+\\'" s)) 0)
- ((string-match "\\`[ \t]+\\'" s) nil)
- ((string-match "\\`\\([0-9]+\\):\\([0-9]+\\)\\(:\\([0-9]+\\)\\)?\\'" s)
- (let ((h (string-to-number (or (match-string 1 s) "0")))
- (m (string-to-number (or (match-string 2 s) "0")))
- (s (string-to-number (or (match-string 4 s) "0"))))
- (if (boundp 'org-timecnt) (setq org-timecnt (1+ org-timecnt)))
- (* 1.0 (+ h (/ m 60.0) (/ s 3600.0)))))
- ((equal n 0) nil)
- (t n))))
+
+;;; Formulas
(defun org-table-current-field-formula (&optional key noerror)
"Return the formula active for the current field.
@@ -2446,19 +2237,6 @@ If yes, store the formula and apply it."
(org-table-eval-formula (and named '(4))
(org-table-formula-from-user eq))))))
-(defvar org-recalc-commands nil
- "List of commands triggering the recalculation of a line.
-Will be filled automatically during use.")
-
-(defvar org-recalc-marks
- '((" " . "Unmarked: no special line, no automatic recalculation")
- ("#" . "Automatically recalculate this line upon TAB, RET, and C-c C-c in the line")
- ("*" . "Recalculate only when entire table is recalculated with `C-u C-c *'")
- ("!" . "Column name definition line. Reference in formula as $name.")
- ("$" . "Parameter definition line name=value. Reference in formula as $name.")
- ("_" . "Names for values in row below this one.")
- ("^" . "Names for values in row above this one.")))
-
;;;###autoload
(defun org-table-rotate-recalc-marks (&optional newchar)
"Rotate the recalculation mark in the first column.
@@ -2530,141 +2308,6 @@ of the new mark."
(message "%s" (cdr (assoc newchar org-recalc-marks))))))
;;;###autoload
-(defun org-table-analyze ()
- "Analyze table at point and store results.
-
-This function sets up the following dynamically scoped variables:
-
- `org-table-column-name-regexp',
- `org-table-column-names',
- `org-table-current-begin-pos',
- `org-table-current-line-types',
- `org-table-current-ncol',
- `org-table-dlines',
- `org-table-hlines',
- `org-table-local-parameters',
- `org-table-named-field-locations'."
- (let ((beg (org-table-begin))
- (end (org-table-end)))
- (save-excursion
- (goto-char beg)
- ;; Extract column names.
- (setq org-table-column-names nil)
- (when (save-excursion
- (re-search-forward "^[ \t]*| *! *\\(|.*\\)" end t))
- (let ((c 1))
- (dolist (name (org-split-string (match-string 1) " *| *"))
- (cl-incf c)
- (when (string-match "\\`[a-zA-Z][_a-zA-Z0-9]*\\'" name)
- (push (cons name (int-to-string c)) org-table-column-names)))))
- (setq org-table-column-names (nreverse org-table-column-names))
- (setq org-table-column-name-regexp
- (format "\\$\\(%s\\)\\>"
- (regexp-opt (mapcar #'car org-table-column-names) t)))
- ;; Extract local parameters.
- (setq org-table-local-parameters nil)
- (save-excursion
- (while (re-search-forward "^[ \t]*| *\\$ *\\(|.*\\)" end t)
- (dolist (field (org-split-string (match-string 1) " *| *"))
- (when (string-match
- "\\`\\([a-zA-Z][_a-zA-Z0-9]*\\|%\\) *= *\\(.*\\)" field)
- (push (cons (match-string 1 field) (match-string 2 field))
- org-table-local-parameters)))))
- ;; Update named fields locations. We minimize `count-lines'
- ;; processing by storing last known number of lines in LAST.
- (setq org-table-named-field-locations nil)
- (save-excursion
- (let ((last (cons (point) 0)))
- (while (re-search-forward "^[ \t]*| *\\([_^]\\) *\\(|.*\\)" end t)
- (let ((c (match-string 1))
- (fields (org-split-string (match-string 2) " *| *")))
- (save-excursion
- (forward-line (if (equal c "_") 1 -1))
- (let ((fields1
- (and (looking-at "^[ \t]*|[^|]*\\(|.*\\)")
- (org-split-string (match-string 1) " *| *")))
- (line (cl-incf (cdr last) (count-lines (car last) (point))))
- (col 1))
- (setcar last (point)) ; Update last known position.
- (while (and fields fields1)
- (let ((field (pop fields))
- (v (pop fields1)))
- (cl-incf col)
- (when (and (stringp field)
- (stringp v)
- (string-match "\\`[a-zA-Z][_a-zA-Z0-9]*\\'"
- field))
- (push (cons field v) org-table-local-parameters)
- (push (list field line col)
- org-table-named-field-locations))))))))))
- ;; Re-use existing markers when possible.
- (if (markerp org-table-current-begin-pos)
- (move-marker org-table-current-begin-pos (point))
- (setq org-table-current-begin-pos (point-marker)))
- ;; Analyze the line types.
- (let ((l 0) hlines dlines types)
- (while (looking-at "[ \t]*|\\(-\\)?")
- (push (if (match-end 1) 'hline 'dline) types)
- (if (match-end 1) (push l hlines) (push l dlines))
- (forward-line)
- (cl-incf l))
- (push 'hline types) ; Add an imaginary extra hline to the end.
- (setq org-table-current-line-types (apply #'vector (nreverse types)))
- (setq org-table-dlines (apply #'vector (cons nil (nreverse dlines))))
- (setq org-table-hlines (apply #'vector (cons nil (nreverse hlines)))))
- ;; Get the number of columns from the first data line in table.
- (goto-char beg)
- (forward-line (aref org-table-dlines 1))
- (let* ((fields
- (org-split-string
- (buffer-substring (line-beginning-position) (line-end-position))
- "[ \t]*|[ \t]*"))
- (nfields (length fields))
- al al2)
- (setq org-table-current-ncol nfields)
- (let ((last-dline
- (aref org-table-dlines (1- (length org-table-dlines)))))
- (dotimes (i nfields)
- (let ((column (1+ i)))
- (push (list (format "LR%d" column) last-dline column) al)
- (push (cons (format "LR%d" column) (nth i fields)) al2))))
- (setq org-table-named-field-locations
- (append org-table-named-field-locations al))
- (setq org-table-local-parameters
- (append org-table-local-parameters al2))))))
-
-(defun org-table-goto-field (ref &optional create-column-p)
- "Move point to a specific field in the current table.
-
-REF is either the name of a field its absolute reference, as
-a string. No column is created unless CREATE-COLUMN-P is
-non-nil. If it is a function, it is called with the column
-number as its argument as is used as a predicate to know if the
-column can be created.
-
-This function assumes the table is already analyzed (i.e., using
-`org-table-analyze')."
- (let* ((coordinates
- (cond
- ((cdr (assoc ref org-table-named-field-locations)))
- ((string-match "\\`@\\([1-9][0-9]*\\)\\$\\([1-9][0-9]*\\)\\'" ref)
- (list (condition-case nil
- (aref org-table-dlines
- (string-to-number (match-string 1 ref)))
- (error (user-error "Invalid row number in %s" ref)))
- (string-to-number (match-string 2 ref))))
- (t (user-error "Unknown field: %s" ref))))
- (line (car coordinates))
- (column (nth 1 coordinates))
- (create-new-column (if (functionp create-column-p)
- (funcall create-column-p column)
- create-column-p)))
- (when coordinates
- (goto-char org-table-current-begin-pos)
- (forward-line line)
- (org-table-goto-column column nil create-new-column))))
-
-;;;###autoload
(defun org-table-maybe-recalculate-line ()
"Recompute the current line if marked for it, and if we haven't just done it."
(interactive)
@@ -2675,19 +2318,6 @@ This function assumes the table is already analyzed (i.e., using
(looking-at org-table-auto-recalculate-regexp))
(org-table-recalculate) t))
-(defvar org-tbl-calc-modes) ;; Dynamically bound in `org-table-eval-formula'
-(defsubst org-set-calc-mode (var &optional value)
- (if (stringp var)
- (setq var (assoc var '(("D" calc-angle-mode deg)
- ("R" calc-angle-mode rad)
- ("F" calc-prefer-frac t)
- ("S" calc-symbolic-mode t)))
- value (nth 2 var) var (nth 1 var)))
- (if (memq var org-tbl-calc-modes)
- (setcar (cdr (memq var org-tbl-calc-modes)) value)
- (cons var (cons value org-tbl-calc-modes)))
- org-tbl-calc-modes)
-
;;;###autoload
(defun org-table-eval-formula (&optional arg equation
suppress-align suppress-const
@@ -2767,9 +2397,10 @@ location of point."
(setq c (string-to-char (match-string 1 fmt))
n (string-to-number (match-string 2 fmt)))
(if (= c ?p)
- (setq org-tbl-calc-modes (org-set-calc-mode 'calc-internal-prec n))
+ (setq org-tbl-calc-modes
+ (org-table--set-calc-mode 'calc-internal-prec n))
(setq org-tbl-calc-modes
- (org-set-calc-mode
+ (org-table--set-calc-mode
'calc-float-format
(list (cdr (assoc c '((?n . float) (?f . fix)
(?s . sci) (?e . eng))))
@@ -2793,7 +2424,8 @@ location of point."
(setq keep-empty t
fmt (replace-match "" t t fmt)))
(while (string-match "[DRFS]" fmt)
- (setq org-tbl-calc-modes (org-set-calc-mode (match-string 0 fmt)))
+ (setq org-tbl-calc-modes
+ (org-table--set-calc-mode (match-string 0 fmt)))
(setq fmt (replace-match "" t t fmt)))
(unless (string-match "\\S-" fmt)
(setq fmt nil))))
@@ -3618,7 +3250,6 @@ Parameters get priority."
["Standard Refs (B3 instead of @3$2)" org-table-fedit-toggle-ref-type
:style toggle :selected org-table-buffer-is-an]))
-(defvar org-pos)
(defvar org-table--fedit-source nil
"Position of the TBLFM line being edited.")
@@ -3826,9 +3457,336 @@ minutes or seconds."
secs0)))))
(if (< secs 0) (concat "-" res) res)))
+(defun org-table-fedit-convert-buffer (function)
+ "Convert all references in this buffer, using FUNCTION."
+ (let ((origin (copy-marker (line-beginning-position))))
+ (goto-char (point-min))
+ (while (not (eobp))
+ (insert (funcall function (buffer-substring (point) (line-end-position))))
+ (delete-region (point) (line-end-position))
+ (forward-line))
+ (goto-char origin)
+ (set-marker origin nil)))
+
+(defun org-table-fedit-toggle-ref-type ()
+ "Convert all references in the buffer from B3 to @3$2 and back."
+ (interactive)
+ (setq-local org-table-buffer-is-an (not org-table-buffer-is-an))
+ (org-table-fedit-convert-buffer
+ (if org-table-buffer-is-an
+ 'org-table-convert-refs-to-an 'org-table-convert-refs-to-rc))
+ (message "Reference type switched to %s"
+ (if org-table-buffer-is-an "A1 etc" "@row$column")))
+
+(defun org-table-fedit-ref-up ()
+ "Shift the reference at point one row/hline up."
+ (interactive)
+ (org-table-fedit-shift-reference 'up))
+
+(defun org-table-fedit-ref-down ()
+ "Shift the reference at point one row/hline down."
+ (interactive)
+ (org-table-fedit-shift-reference 'down))
+
+(defun org-table-fedit-ref-left ()
+ "Shift the reference at point one field to the left."
+ (interactive)
+ (org-table-fedit-shift-reference 'left))
+
+(defun org-table-fedit-ref-right ()
+ "Shift the reference at point one field to the right."
+ (interactive)
+ (org-table-fedit-shift-reference 'right))
+
+(defun org-table--rematch-and-replace (n &optional decr hline)
+ "Re-match the group N, and replace it with the shifted reference."
+ (or (match-end n) (user-error "Cannot shift reference in this direction"))
+ (goto-char (match-beginning n))
+ (and (looking-at (regexp-quote (match-string n)))
+ (replace-match (org-table-shift-refpart (match-string 0) decr hline)
+ t t)))
+
+(defun org-table-fedit-shift-reference (dir)
+ (cond
+ ((org-in-regexp "\\(\\<[a-zA-Z]\\)&")
+ (if (memq dir '(left right))
+ (org-table--rematch-and-replace 1 (eq dir 'left))
+ (user-error "Cannot shift reference in this direction")))
+ ((org-in-regexp "\\(\\<[a-zA-Z]\\{1,2\\}\\)\\([0-9]+\\)")
+ ;; A B3-like reference
+ (if (memq dir '(up down))
+ (org-table--rematch-and-replace 2 (eq dir 'up))
+ (org-table--rematch-and-replace 1 (eq dir 'left))))
+ ((org-in-regexp
+ "\\(@\\|\\.\\.\\)\\([-+]?\\(I+\\>\\|[0-9]+\\)\\)\\(\\$\\([-+]?[0-9]+\\)\\)?")
+ ;; An internal reference
+ (if (memq dir '(up down))
+ (org-table--rematch-and-replace 2 (eq dir 'up) (match-end 3))
+ (org-table--rematch-and-replace 5 (eq dir 'left))))))
+
+(defun org-table-shift-refpart (ref &optional decr hline)
+ "Shift a reference part REF.
+If DECR is set, decrease the references row/column, else increase.
+If HLINE is set, this may be a hline reference, it certainly is not
+a translation reference."
+ (save-match-data
+ (let* ((sign (string-match "^[-+]" ref)) n)
+
+ (if sign (setq sign (substring ref 0 1) ref (substring ref 1)))
+ (cond
+ ((and hline (string-match "^I+" ref))
+ (setq n (string-to-number (concat sign (number-to-string (length ref)))))
+ (setq n (+ n (if decr -1 1)))
+ (if (= n 0) (setq n (+ n (if decr -1 1))))
+ (if sign
+ (setq sign (if (< n 0) "-" "+") n (abs n))
+ (setq n (max 1 n)))
+ (concat sign (make-string n ?I)))
+
+ ((string-match "^[0-9]+" ref)
+ (setq n (string-to-number (concat sign ref)))
+ (setq n (+ n (if decr -1 1)))
+ (if sign
+ (concat (if (< n 0) "-" "+") (number-to-string (abs n)))
+ (number-to-string (max 1 n))))
+
+ ((string-match "^[a-zA-Z]+" ref)
+ (org-number-to-letters
+ (max 1 (+ (org-letters-to-number ref) (if decr -1 1)))))
+
+ (t (user-error "Cannot shift reference"))))))
+
+(defun org-table-fedit-toggle-coordinates ()
+ "Toggle the display of coordinates in the referenced table."
+ (interactive)
+ (let ((pos (marker-position org-pos)))
+ (with-current-buffer (marker-buffer org-pos)
+ (save-excursion
+ (goto-char pos)
+ (org-table-toggle-coordinate-overlays)))))
+
+(defun org-table-fedit-finish (&optional arg)
+ "Parse the buffer for formula definitions and install them.
+With prefix ARG, apply the new formulas to the table."
+ (interactive "P")
+ (org-table-remove-rectangle-highlight)
+ (when org-table-use-standard-references
+ (org-table-fedit-convert-buffer 'org-table-convert-refs-to-rc)
+ (setq org-table-buffer-is-an nil))
+ (let ((pos org-pos)
+ (sel-win org-selected-window)
+ (source org-table--fedit-source)
+ eql)
+ (goto-char (point-min))
+ (while (re-search-forward
+ "^\\(@[-+I<>0-9.$@]+\\|@?[0-9]+\\|\\$\\([a-zA-Z0-9]+\\|[<>]+\\)\\) *= *\\(.*\\(\n[ \t]+.*$\\)*\\)"
+ nil t)
+ (let ((var (match-string 1))
+ (form (org-trim (match-string 3))))
+ (unless (equal form "")
+ (while (string-match "[ \t]*\n[ \t]*" form)
+ (setq form (replace-match " " t t form)))
+ (when (assoc var eql)
+ (user-error "Double formulas for %s" var))
+ (push (cons var form) eql))))
+ (set-window-configuration org-window-configuration)
+ (select-window sel-win)
+ (goto-char source)
+ (org-table-store-formulas eql)
+ (set-marker pos nil)
+ (set-marker source nil)
+ (kill-buffer "*Edit Formulas*")
+ (if arg
+ (org-table-recalculate 'all)
+ (message "New formulas installed - press C-u C-c C-c to apply."))))
+
+(defun org-table-fedit-abort ()
+ "Abort editing formulas, without installing the changes."
+ (interactive)
+ (org-table-remove-rectangle-highlight)
+ (let ((pos org-pos) (sel-win org-selected-window))
+ (set-window-configuration org-window-configuration)
+ (select-window sel-win)
+ (goto-char pos)
+ (move-marker pos nil)
+ (message "Formula editing aborted without installing changes")))
+
+(defun org-table-fedit-lisp-indent ()
+ "Pretty-print and re-indent Lisp expressions in the Formula Editor."
+ (interactive)
+ (let ((pos (point)) beg end ind)
+ (beginning-of-line 1)
+ (cond
+ ((looking-at "[ \t]")
+ (goto-char pos)
+ (call-interactively 'lisp-indent-line))
+ ((looking-at "[$&@0-9a-zA-Z]+ *= *[^ \t\n']") (goto-char pos))
+ ((not (fboundp 'pp-buffer))
+ (user-error "Cannot pretty-print. Command `pp-buffer' is not available"))
+ ((looking-at "[$&@0-9a-zA-Z]+ *= *'(")
+ (goto-char (- (match-end 0) 2))
+ (setq beg (point))
+ (setq ind (make-string (current-column) ?\ ))
+ (condition-case nil (forward-sexp 1)
+ (error
+ (user-error "Cannot pretty-print Lisp expression: Unbalanced parenthesis")))
+ (setq end (point))
+ (save-restriction
+ (narrow-to-region beg end)
+ (if (eq last-command this-command)
+ (progn
+ (goto-char (point-min))
+ (setq this-command nil)
+ (while (re-search-forward "[ \t]*\n[ \t]*" nil t)
+ (replace-match " ")))
+ (pp-buffer)
+ (untabify (point-min) (point-max))
+ (goto-char (1+ (point-min)))
+ (while (re-search-forward "^." nil t)
+ (beginning-of-line 1)
+ (insert ind))
+ (goto-char (point-max))
+ (org-delete-backward-char 1)))
+ (goto-char beg))
+ (t nil))))
+
+(defun org-table-fedit-line-up ()
+ "Move cursor one line up in the window showing the table."
+ (interactive)
+ (org-table-fedit-move 'previous-line))
+
+(defun org-table-fedit-line-down ()
+ "Move cursor one line down in the window showing the table."
+ (interactive)
+ (org-table-fedit-move 'next-line))
+
+(defun org-table-fedit-move (command)
+ "Move the cursor in the window showing the table.
+Use COMMAND to do the motion, repeat if necessary to end up in a data line."
+ (let ((org-table-allow-automatic-line-recalculation nil)
+ (pos org-pos) (win (selected-window)) p)
+ (select-window (get-buffer-window (marker-buffer org-pos)))
+ (setq p (point))
+ (call-interactively command)
+ (while (and (org-at-table-p)
+ (org-at-table-hline-p))
+ (call-interactively command))
+ (or (org-at-table-p) (goto-char p))
+ (move-marker pos (point))
+ (select-window win)))
+
+(defun org-table-fedit-scroll (N)
+ (interactive "p")
+ (let ((other-window-scroll-buffer (marker-buffer org-pos)))
+ (scroll-other-window N)))
+
+(defun org-table-fedit-scroll-down (N)
+ (interactive "p")
+ (org-table-fedit-scroll (- N)))
+
+(defun org-table-add-rectangle-overlay (beg end &optional face)
+ "Add a new overlay."
+ (let ((ov (make-overlay beg end)))
+ (overlay-put ov 'face (or face 'secondary-selection))
+ (push ov org-table-rectangle-overlays)))
+
+(defun org-table-highlight-rectangle (&optional beg end face)
+ "Highlight rectangular region in a table.
+When buffer positions BEG and END are provided, use them to
+delimit the region to highlight. Otherwise, refer to point. Use
+FACE, when non-nil, for the highlight."
+ (let* ((beg (or beg (point)))
+ (end (or end (point)))
+ (b (min beg end))
+ (e (max beg end))
+ (start-coordinates
+ (save-excursion
+ (goto-char b)
+ (cons (line-beginning-position) (org-table-current-column))))
+ (end-coordinates
+ (save-excursion
+ (goto-char e)
+ (cons (line-beginning-position) (org-table-current-column)))))
+ (when (boundp 'org-show-positions)
+ (setq org-show-positions (cons b (cons e org-show-positions))))
+ (goto-char (car start-coordinates))
+ (let ((column-start (min (cdr start-coordinates) (cdr end-coordinates)))
+ (column-end (max (cdr start-coordinates) (cdr end-coordinates)))
+ (last-row (car end-coordinates)))
+ (while (<= (point) last-row)
+ (when (looking-at org-table-dataline-regexp)
+ (org-table-goto-column column-start)
+ (skip-chars-backward "^|\n")
+ (let ((p (point)))
+ (org-table-goto-column column-end)
+ (skip-chars-forward "^|\n")
+ (org-table-add-rectangle-overlay p (point) face)))
+ (forward-line)))
+ (goto-char (car start-coordinates)))
+ (add-hook 'before-change-functions #'org-table-remove-rectangle-highlight))
+
+(defun org-table-remove-rectangle-highlight (&rest _ignore)
+ "Remove the rectangle overlays."
+ (unless org-inhibit-highlight-removal
+ (remove-hook 'before-change-functions 'org-table-remove-rectangle-highlight)
+ (mapc 'delete-overlay org-table-rectangle-overlays)
+ (setq org-table-rectangle-overlays nil)))
+
+(defvar-local org-table-coordinate-overlays nil
+ "Collects the coordinate grid overlays, so that they can be removed.")
+
+(defun org-table-overlay-coordinates ()
+ "Add overlays to the table at point, to show row/column coordinates."
+ (interactive)
+ (mapc 'delete-overlay org-table-coordinate-overlays)
+ (setq org-table-coordinate-overlays nil)
+ (save-excursion
+ (let ((id 0) (ih 0) hline eol str ov)
+ (goto-char (org-table-begin))
+ (while (org-at-table-p)
+ (setq eol (point-at-eol))
+ (setq ov (make-overlay (point-at-bol) (1+ (point-at-bol))))
+ (push ov org-table-coordinate-overlays)
+ (setq hline (looking-at org-table-hline-regexp))
+ (setq str (if hline (format "I*%-2d" (setq ih (1+ ih)))
+ (format "%4d" (setq id (1+ id)))))
+ (org-overlay-before-string ov str 'org-special-keyword 'evaporate)
+ (when hline
+ (let ((ic 0))
+ (while (re-search-forward "[+|]\\(-+\\)" eol t)
+ (cl-incf ic)
+ (let* ((beg (1+ (match-beginning 0)))
+ (s1 (format "$%d" ic))
+ (s2 (org-number-to-letters ic))
+ (str (if (eq t org-table-use-standard-references) s2 s1))
+ (ov (make-overlay beg (+ beg (length str)))))
+ (push ov org-table-coordinate-overlays)
+ (org-overlay-display ov str 'org-special-keyword 'evaporate)))))
+ (forward-line)))))
+
+;;;###autoload
+(defun org-table-toggle-coordinate-overlays ()
+ "Toggle the display of Row/Column numbers in tables."
+ (interactive)
+ (setq org-table-overlay-coordinates (not org-table-overlay-coordinates))
+ (message "Tables Row/Column numbers display turned %s"
+ (if org-table-overlay-coordinates "on" "off"))
+ (when (and (org-at-table-p) org-table-overlay-coordinates)
+ (org-table-align))
+ (unless org-table-overlay-coordinates
+ (mapc 'delete-overlay org-table-coordinate-overlays)
+ (setq org-table-coordinate-overlays nil)))
+
+;;;###autoload
+(defun org-table-toggle-formula-debugger ()
+ "Toggle the formula debugger in tables."
+ (interactive)
+ (setq org-table-formula-debug (not org-table-formula-debug))
+ (message "Formula debugging has been turned %s"
+ (if org-table-formula-debug "on" "off")))
-;;; Columns shrinking
+;;; Columns Shrinking
(defun org-table--shrunk-field ()
"Non-nil if current field is narrowed.
@@ -4212,201 +4170,687 @@ beginning and end position of the current table."
(end (or end (org-table-end))))
(remove-overlays begin end 'org-overlay-type 'table-column-hide))))
-
-;;; Formula editing
+;;; Generic Tools
-(defun org-table-fedit-convert-buffer (function)
- "Convert all references in this buffer, using FUNCTION."
- (let ((origin (copy-marker (line-beginning-position))))
- (goto-char (point-min))
- (while (not (eobp))
- (insert (funcall function (buffer-substring (point) (line-end-position))))
- (delete-region (point) (line-end-position))
- (forward-line))
- (goto-char origin)
- (set-marker origin nil)))
+;;;###autoload
+(defun org-table-map-tables (f &optional quietly)
+ "Apply function F to the start of all tables in the buffer."
+ (org-with-point-at 1
+ (while (re-search-forward org-table-line-regexp nil t)
+ (let ((table (org-element-lineage (org-element-at-point) '(table) t)))
+ (when table
+ (unless quietly
+ (message "Mapping tables: %d%%"
+ (floor (* 100.0 (point)) (buffer-size))))
+ (goto-char (org-element-property :post-affiliated table))
+ (let ((end (copy-marker (org-element-property :end table))))
+ (unwind-protect
+ (progn (funcall f) (goto-char end))
+ (set-marker end nil)))))))
+ (unless quietly (message "Mapping tables: done")))
-(defun org-table-fedit-toggle-ref-type ()
- "Convert all references in the buffer from B3 to @3$2 and back."
- (interactive)
- (setq-local org-table-buffer-is-an (not org-table-buffer-is-an))
- (org-table-fedit-convert-buffer
- (if org-table-buffer-is-an
- 'org-table-convert-refs-to-an 'org-table-convert-refs-to-rc))
- (message "Reference type switched to %s"
- (if org-table-buffer-is-an "A1 etc" "@row$column")))
+;;;###autoload
+(defun org-table-export (&optional file format)
+ "Export table to a file, with configurable format.
+Such a file can be imported into usual spreadsheet programs.
-(defun org-table-fedit-ref-up ()
- "Shift the reference at point one row/hline up."
- (interactive)
- (org-table-fedit-shift-reference 'up))
-(defun org-table-fedit-ref-down ()
- "Shift the reference at point one row/hline down."
- (interactive)
- (org-table-fedit-shift-reference 'down))
-(defun org-table-fedit-ref-left ()
- "Shift the reference at point one field to the left."
+FILE can be the output file name. If not given, it will be taken
+from a TABLE_EXPORT_FILE property in the current entry or higher
+up in the hierarchy, or the user will be prompted for a file
+name. FORMAT can be an export format, of the same kind as it
+used when `-mode' sends a table in a different format.
+
+The command suggests a format depending on TABLE_EXPORT_FORMAT,
+whether it is set locally or up in the hierarchy, then on the
+extension of the given file name, and finally on the variable
+`org-table-export-default-format'."
(interactive)
- (org-table-fedit-shift-reference 'left))
-(defun org-table-fedit-ref-right ()
- "Shift the reference at point one field to the right."
+ (unless (org-at-table-p) (user-error "No table at point"))
+ (org-table-align) ; Make sure we have everything we need.
+ (let ((file (or file (org-entry-get (point) "TABLE_EXPORT_FILE" t))))
+ (unless file
+ (setq file (read-file-name "Export table to: "))
+ (unless (or (not (file-exists-p file))
+ (y-or-n-p (format "Overwrite file %s? " file)))
+ (user-error "File not written")))
+ (when (file-directory-p file)
+ (user-error "This is a directory path, not a file"))
+ (when (and (buffer-file-name (buffer-base-buffer))
+ (file-equal-p
+ (file-truename file)
+ (file-truename (buffer-file-name (buffer-base-buffer)))))
+ (user-error "Please specify a file name that is different from current"))
+ (let ((fileext (concat (file-name-extension file) "$"))
+ (format (or format (org-entry-get (point) "TABLE_EXPORT_FORMAT" t))))
+ (unless format
+ (let* ((formats '("orgtbl-to-tsv" "orgtbl-to-csv" "orgtbl-to-latex"
+ "orgtbl-to-html" "orgtbl-to-generic"
+ "orgtbl-to-texinfo" "orgtbl-to-orgtbl"
+ "orgtbl-to-unicode"))
+ (deffmt-readable
+ (replace-regexp-in-string
+ "\t" "\\t"
+ (replace-regexp-in-string
+ "\n" "\\n"
+ (or (car (delq nil
+ (mapcar
+ (lambda (f)
+ (and (string-match-p fileext f) f))
+ formats)))
+ org-table-export-default-format)
+ t t) t t)))
+ (setq format
+ (org-completing-read
+ "Format: " formats nil nil deffmt-readable))))
+ (if (string-match "\\([^ \t\r\n]+\\)\\( +.*\\)?" format)
+ (let ((transform (intern (match-string 1 format)))
+ (params (and (match-end 2)
+ (read (concat "(" (match-string 2 format) ")"))))
+ (table (org-table-to-lisp
+ (buffer-substring-no-properties
+ (org-table-begin) (org-table-end)))))
+ (unless (fboundp transform)
+ (user-error "No such transformation function %s" transform))
+ (let (buf)
+ (with-current-buffer (find-file-noselect file)
+ (setq buf (current-buffer))
+ (erase-buffer)
+ (fundamental-mode)
+ (insert (funcall transform table params) "\n")
+ (save-buffer))
+ (kill-buffer buf))
+ (message "Export done."))
+ (user-error "TABLE_EXPORT_FORMAT invalid")))))
+
+;;;###autoload
+(defun org-table--align-field (field width align)
+ "Format FIELD according to column WIDTH and alignment ALIGN.
+FIELD is a string. WIDTH is a number. ALIGN is either \"c\",
+\"l\" or\"r\"."
+ (let* ((spaces (- width (org-string-width field)))
+ (prefix (pcase align
+ ("l" "")
+ ("r" (make-string spaces ?\s))
+ ("c" (make-string (/ spaces 2) ?\s))))
+ (suffix (make-string (- spaces (length prefix)) ?\s)))
+ (concat org-table-separator-space
+ prefix
+ field
+ suffix
+ org-table-separator-space)))
+
+(defun org-table-align ()
+ "Align the table at point by aligning all vertical bars."
(interactive)
- (org-table-fedit-shift-reference 'right))
+ (let ((beg (org-table-begin))
+ (end (copy-marker (org-table-end))))
+ (org-table-save-field
+ ;; Make sure invisible characters in the table are at the right
+ ;; place since column widths take them into account.
+ (org-font-lock-ensure beg end)
+ (move-marker org-table-aligned-begin-marker beg)
+ (move-marker org-table-aligned-end-marker end)
+ (goto-char beg)
+ (org-table-with-shrunk-columns
+ (let* ((indent (progn (looking-at "[ \t]*") (match-string 0)))
+ ;; Table's rows as lists of fields. Rules are replaced
+ ;; by nil. Trailing spaces are removed.
+ (fields (mapcar
+ (lambda (l)
+ (and (not (string-match-p org-table-hline-regexp l))
+ (org-split-string l "[ \t]*|[ \t]*")))
+ (split-string (buffer-substring beg end) "\n" t)))
+ ;; Compute number of columns. If the table contains no
+ ;; field, create a default table and bail out.
+ (columns-number
+ (if fields (apply #'max (mapcar #'length fields))
+ (kill-region beg end)
+ (org-table-create org-table-default-size)
+ (user-error "Empty table - created default table")))
+ (widths nil)
+ (alignments nil))
+ ;; Compute alignment and width for each column.
+ (dotimes (i columns-number)
+ (let* ((max-width 1)
+ (fixed-align? nil)
+ (numbers 0)
+ (non-empty 0))
+ (dolist (row fields)
+ (let ((cell (or (nth i row) "")))
+ (setq max-width (max max-width (org-string-width cell)))
+ (cond (fixed-align? nil)
+ ((equal cell "") nil)
+ ((string-match "\\`<\\([lrc]\\)[0-9]*>\\'" cell)
+ (setq fixed-align? (match-string 1 cell)))
+ (t
+ (cl-incf non-empty)
+ (when (string-match-p org-table-number-regexp cell)
+ (cl-incf numbers))))))
+ (push max-width widths)
+ (push (cond
+ (fixed-align?)
+ ((>= numbers (* org-table-number-fraction non-empty)) "r")
+ (t "l"))
+ alignments)))
+ (setq widths (nreverse widths))
+ (setq alignments (nreverse alignments))
+ ;; Store alignment of this table, for later editing of single
+ ;; fields.
+ (setq org-table-last-alignment alignments)
+ (setq org-table-last-column-widths widths)
+ ;; Build new table rows. Only replace rows that actually
+ ;; changed.
+ (dolist (row fields)
+ (let ((previous (buffer-substring (point) (line-end-position)))
+ (new
+ (format "%s|%s|"
+ indent
+ (if (null row) ;horizontal rule
+ (mapconcat (lambda (w) (make-string (+ 2 w) ?-))
+ widths
+ "+")
+ (let ((cells ;add missing fields
+ (append row
+ (make-list (- columns-number
+ (length row))
+ ""))))
+ (mapconcat #'identity
+ (cl-mapcar #'org-table--align-field
+ cells
+ widths
+ alignments)
+ "|"))))))
+ (if (equal new previous)
+ (forward-line)
+ (insert new "\n")
+ (delete-region (point) (line-beginning-position 2)))))
+ (set-marker end nil)
+ (when org-table-overlay-coordinates (org-table-overlay-coordinates))
+ (setq org-table-may-need-update nil))))))
-(defun org-table-fedit-shift-reference (dir)
+;;;###autoload
+(defun org-table-justify-field-maybe (&optional new)
+ "Justify the current field, text to left, number to right.
+Optional argument NEW may specify text to replace the current field content."
(cond
- ((org-in-regexp "\\(\\<[a-zA-Z]\\)&")
- (if (memq dir '(left right))
- (org-rematch-and-replace 1 (eq dir 'left))
- (user-error "Cannot shift reference in this direction")))
- ((org-in-regexp "\\(\\<[a-zA-Z]\\{1,2\\}\\)\\([0-9]+\\)")
- ;; A B3-like reference
- (if (memq dir '(up down))
- (org-rematch-and-replace 2 (eq dir 'up))
- (org-rematch-and-replace 1 (eq dir 'left))))
- ((org-in-regexp
- "\\(@\\|\\.\\.\\)\\([-+]?\\(I+\\>\\|[0-9]+\\)\\)\\(\\$\\([-+]?[0-9]+\\)\\)?")
- ;; An internal reference
- (if (memq dir '(up down))
- (org-rematch-and-replace 2 (eq dir 'up) (match-end 3))
- (org-rematch-and-replace 5 (eq dir 'left))))))
+ ((and (not new) org-table-may-need-update)) ; Realignment will happen anyway
+ ((org-at-table-hline-p))
+ ((and (not new)
+ (or (not (eq (marker-buffer org-table-aligned-begin-marker)
+ (current-buffer)))
+ (< (point) org-table-aligned-begin-marker)
+ (>= (point) org-table-aligned-end-marker)))
+ ;; This is not the same table, force a full re-align.
+ (setq org-table-may-need-update t))
+ (t
+ ;; Realign the current field, based on previous full realign.
+ (let ((pos (point))
+ (col (org-table-current-column)))
+ (when (> col 0)
+ (skip-chars-backward "^|")
+ (if (not (looking-at " *\\([^|\n]*?\\) *\\(|\\|$\\)"))
+ (setq org-table-may-need-update t)
+ (let* ((align (nth (1- col) org-table-last-alignment))
+ (width (nth (1- col) org-table-last-column-widths))
+ (cell (match-string 0))
+ (field (match-string 1))
+ (properly-closed? (/= (match-beginning 2) (match-end 2)))
+ (new-cell
+ (save-match-data
+ (cond (org-table-may-need-update
+ (format " %s |" (or new field)))
+ ((not properly-closed?)
+ (setq org-table-may-need-update t)
+ (format " %s |" (or new field)))
+ ((not new)
+ (concat (org-table--align-field field width align)
+ "|"))
+ ((<= (org-string-width new) width)
+ (concat (org-table--align-field new width align)
+ "|"))
+ (t
+ (setq org-table-may-need-update t)
+ (format " %s |" new))))))
+ (unless (equal new-cell cell)
+ (let (org-table-may-need-update)
+ (replace-match new-cell t t)))
+ (goto-char pos))))))))
-(defun org-rematch-and-replace (n &optional decr hline)
- "Re-match the group N, and replace it with the shifted reference."
- (or (match-end n) (user-error "Cannot shift reference in this direction"))
- (goto-char (match-beginning n))
- (and (looking-at (regexp-quote (match-string n)))
- (replace-match (org-table-shift-refpart (match-string 0) decr hline)
- t t)))
+;;;###autoload
+(defun org-table-sort-lines
+ (&optional with-case sorting-type getkey-func compare-func interactive?)
+ "Sort table lines according to the column at point.
-(defun org-table-shift-refpart (ref &optional decr hline)
- "Shift a reference part REF.
-If DECR is set, decrease the references row/column, else increase.
-If HLINE is set, this may be a hline reference, it certainly is not
-a translation reference."
- (save-match-data
- (let* ((sign (string-match "^[-+]" ref)) n)
+The position of point indicates the column to be used for
+sorting, and the range of lines is the range between the nearest
+horizontal separator lines, or the entire table of no such lines
+exist. If point is before the first column, you will be prompted
+for the sorting column. If there is an active region, the mark
+specifies the first line and the sorting column, while point
+should be in the last line to be included into the sorting.
- (if sign (setq sign (substring ref 0 1) ref (substring ref 1)))
- (cond
- ((and hline (string-match "^I+" ref))
- (setq n (string-to-number (concat sign (number-to-string (length ref)))))
- (setq n (+ n (if decr -1 1)))
- (if (= n 0) (setq n (+ n (if decr -1 1))))
- (if sign
- (setq sign (if (< n 0) "-" "+") n (abs n))
- (setq n (max 1 n)))
- (concat sign (make-string n ?I)))
+The command then prompts for the sorting type which can be
+alphabetically, numerically, or by time (as given in a time stamp
+in the field, or as a HH:MM value). Sorting in reverse order is
+also possible.
- ((string-match "^[0-9]+" ref)
- (setq n (string-to-number (concat sign ref)))
- (setq n (+ n (if decr -1 1)))
- (if sign
- (concat (if (< n 0) "-" "+") (number-to-string (abs n)))
- (number-to-string (max 1 n))))
+With prefix argument WITH-CASE, alphabetic sorting will be case-sensitive
+if the locale allows for it.
- ((string-match "^[a-zA-Z]+" ref)
- (org-number-to-letters
- (max 1 (+ (org-letters-to-number ref) (if decr -1 1)))))
+If SORTING-TYPE is specified when this function is called from a Lisp
+program, no prompting will take place. SORTING-TYPE must be a character,
+any of (?a ?A ?n ?N ?t ?T ?f ?F) where the capital letters indicate that
+sorting should be done in reverse order.
- (t (user-error "Cannot shift reference"))))))
+If the SORTING-TYPE is ?f or ?F, then GETKEY-FUNC specifies
+a function to be called to extract the key. It must return a value
+that is compatible with COMPARE-FUNC, the function used to compare
+entries.
-(defun org-table-fedit-toggle-coordinates ()
- "Toggle the display of coordinates in the referenced table."
+A non-nil value for INTERACTIVE? is used to signal that this
+function is being called interactively."
+ (interactive (list current-prefix-arg nil nil nil t))
+ (when (org-region-active-p) (goto-char (region-beginning)))
+ ;; Point must be either within a field or before a data line.
+ (save-excursion
+ (skip-chars-backward " \t")
+ (when (bolp) (search-forward "|" (line-end-position) t))
+ (org-table-check-inside-data-field))
+ ;; Set appropriate case sensitivity and column used for sorting.
+ (let ((column (let ((c (org-table-current-column)))
+ (cond ((> c 0) c)
+ (interactive?
+ (read-number "Use column N for sorting: "))
+ (t 1))))
+ (sorting-type
+ (or sorting-type
+ (read-char-exclusive "Sort Table: [a]lphabetic, [n]umeric, \
+\[t]ime, [f]unc. A/N/T/F means reversed: ")))
+ (start (org-table-begin))
+ (end (org-table-end)))
+ (save-restriction
+ ;; Narrow buffer to appropriate sorting area.
+ (if (org-region-active-p)
+ (progn (goto-char (region-beginning))
+ (narrow-to-region
+ (point)
+ (save-excursion (goto-char (region-end))
+ (line-beginning-position 2))))
+ (narrow-to-region
+ (save-excursion
+ (if (re-search-backward org-table-hline-regexp start t)
+ (line-beginning-position 2)
+ start))
+ (if (save-excursion (re-search-forward org-table-hline-regexp end t))
+ (match-beginning 0)
+ end)))
+ ;; Determine arguments for `sort-subr'. Also record original
+ ;; position. `org-table-save-field' cannot help here since
+ ;; sorting is too much destructive.
+ (let* ((coordinates
+ (cons (count-lines (point-min) (line-beginning-position))
+ (current-column)))
+ (extract-key-from-field
+ ;; Function to be called on the contents of the field
+ ;; used for sorting in the current row.
+ (cl-case sorting-type
+ ((?n ?N) #'string-to-number)
+ ((?a ?A) #'org-sort-remove-invisible)
+ ((?t ?T)
+ (lambda (f)
+ (cond ((string-match org-ts-regexp-both f)
+ (float-time
+ (org-time-string-to-time (match-string 0 f))))
+ ((org-duration-p f) (org-duration-to-minutes f))
+ ((string-match "\\<[0-9]+:[0-9]\\{2\\}\\>" f)
+ (org-duration-to-minutes (match-string 0 f)))
+ (t 0))))
+ ((?f ?F)
+ (or getkey-func
+ (and interactive?
+ (org-read-function "Function for extracting keys: "))
+ (error "Missing key extractor to sort rows")))
+ (t (user-error "Invalid sorting type `%c'" sorting-type))))
+ (predicate
+ (cl-case sorting-type
+ ((?n ?N ?t ?T) #'<)
+ ((?a ?A) (if with-case #'org-string-collate-lessp
+ (lambda (s1 s2) (org-string-collate-lessp s1 s2 nil t))))
+ ((?f ?F)
+ (or compare-func
+ (and interactive?
+ (org-read-function
+ "Function for comparing keys (empty for default \
+`sort-subr' predicate): "
+ 'allow-empty))))))
+ (shrunk-columns (remq column (org-table--list-shrunk-columns))))
+ (goto-char (point-min))
+ (sort-subr (memq sorting-type '(?A ?N ?T ?F))
+ (lambda ()
+ (forward-line)
+ (while (and (not (eobp))
+ (not (looking-at org-table-dataline-regexp)))
+ (forward-line)))
+ #'end-of-line
+ (lambda ()
+ (funcall extract-key-from-field
+ (org-trim (org-table-get-field column))))
+ nil
+ predicate)
+ ;; Hide all columns but the one being sorted.
+ (org-table--shrink-columns shrunk-columns start end)
+ ;; Move back to initial field.
+ (forward-line (car coordinates))
+ (move-to-column (cdr coordinates))))))
+
+(defun org-table-transpose-table-at-point ()
+ "Transpose Org table at point and eliminate hlines.
+So a table like
+
+| 1 | 2 | 4 | 5 |
+|---+---+---+---|
+| a | b | c | d |
+| e | f | g | h |
+
+will be transposed as
+
+| 1 | a | e |
+| 2 | b | f |
+| 4 | c | g |
+| 5 | d | h |
+
+Note that horizontal lines disappear."
(interactive)
- (let ((pos (marker-position org-pos)))
- (with-current-buffer (marker-buffer org-pos)
- (save-excursion
- (goto-char pos)
- (org-table-toggle-coordinate-overlays)))))
+ (let* ((table (delete 'hline (org-table-to-lisp)))
+ (dline_old (org-table-current-line))
+ (col_old (org-table-current-column))
+ (contents (mapcar (lambda (_)
+ (let ((tp table))
+ (mapcar
+ (lambda (_)
+ (prog1
+ (pop (car tp))
+ (setq tp (cdr tp))))
+ table)))
+ (car table))))
+ (goto-char (org-table-begin))
+ (re-search-forward "|")
+ (backward-char)
+ (delete-region (point) (org-table-end))
+ (insert (mapconcat
+ (lambda(x)
+ (concat "| " (mapconcat 'identity x " | " ) " |\n" ))
+ contents ""))
+ (org-table-goto-line col_old)
+ (org-table-goto-column dline_old))
+ (org-table-align))
-(defun org-table-fedit-finish (&optional arg)
- "Parse the buffer for formula definitions and install them.
-With prefix ARG, apply the new formulas to the table."
+;;;###autoload
+(defun org-table-wrap-region (arg)
+ "Wrap several fields in a column like a paragraph.
+This is useful if you'd like to spread the contents of a field over several
+lines, in order to keep the table compact.
+
+If there is an active region, and both point and mark are in the same column,
+the text in the column is wrapped to minimum width for the given number of
+lines. Generally, this makes the table more compact. A prefix ARG may be
+used to change the number of desired lines. For example, \
+`C-2 \\[org-table-wrap-region]'
+formats the selected text to two lines. If the region was longer than two
+lines, the remaining lines remain empty. A negative prefix argument reduces
+the current number of lines by that amount. The wrapped text is pasted back
+into the table. If you formatted it to more lines than it was before, fields
+further down in the table get overwritten - so you might need to make space in
+the table first.
+
+If there is no region, the current field is split at the cursor position and
+the text fragment to the right of the cursor is prepended to the field one
+line down.
+
+If there is no region, but you specify a prefix ARG, the current field gets
+blank, and the content is appended to the field above."
(interactive "P")
- (org-table-remove-rectangle-highlight)
- (when org-table-use-standard-references
- (org-table-fedit-convert-buffer 'org-table-convert-refs-to-rc)
- (setq org-table-buffer-is-an nil))
- (let ((pos org-pos)
- (sel-win org-selected-window)
- (source org-table--fedit-source)
- eql)
- (goto-char (point-min))
- (while (re-search-forward
- "^\\(@[-+I<>0-9.$@]+\\|@?[0-9]+\\|\\$\\([a-zA-Z0-9]+\\|[<>]+\\)\\) *= *\\(.*\\(\n[ \t]+.*$\\)*\\)"
- nil t)
- (let ((var (match-string 1))
- (form (org-trim (match-string 3))))
- (unless (equal form "")
- (while (string-match "[ \t]*\n[ \t]*" form)
- (setq form (replace-match " " t t form)))
- (when (assoc var eql)
- (user-error "Double formulas for %s" var))
- (push (cons var form) eql))))
- (set-window-configuration org-window-configuration)
- (select-window sel-win)
- (goto-char source)
- (org-table-store-formulas eql)
- (set-marker pos nil)
- (set-marker source nil)
- (kill-buffer "*Edit Formulas*")
- (if arg
- (org-table-recalculate 'all)
- (message "New formulas installed - press C-u C-c C-c to apply."))))
+ (org-table-check-inside-data-field)
+ (if (org-region-active-p)
+ ;; There is a region: fill as a paragraph.
+ (let ((start (region-beginning)))
+ (org-table-cut-region (region-beginning) (region-end))
+ (when (> (length (car org-table-clip)) 1)
+ (user-error "Region must be limited to single column"))
+ (let ((nlines (cond ((not arg) (length org-table-clip))
+ ((< arg 1) (+ (length org-table-clip) arg))
+ (t arg))))
+ (setq org-table-clip
+ (mapcar #'list
+ (org-wrap (mapconcat #'car org-table-clip " ")
+ nil
+ nlines))))
+ (goto-char start)
+ (org-table-paste-rectangle))
+ ;; No region, split the current field at point.
+ (unless (org-get-alist-option org-M-RET-may-split-line 'table)
+ (skip-chars-forward "^\r\n|"))
+ (cond
+ (arg ; Combine with field above.
+ (let ((s (org-table-blank-field))
+ (col (org-table-current-column)))
+ (forward-line -1)
+ (while (org-at-table-hline-p) (forward-line -1))
+ (org-table-goto-column col)
+ (skip-chars-forward "^|")
+ (skip-chars-backward " ")
+ (insert " " (org-trim s))
+ (org-table-align)))
+ ((looking-at "\\([^|]+\\)+|") ; Split field.
+ (let ((s (match-string 1)))
+ (replace-match " |")
+ (goto-char (match-beginning 0))
+ (org-table-next-row)
+ (insert (org-trim s) " ")
+ (org-table-align)))
+ (t (org-table-next-row)))))
-(defun org-table-fedit-abort ()
- "Abort editing formulas, without installing the changes."
- (interactive)
- (org-table-remove-rectangle-highlight)
- (let ((pos org-pos) (sel-win org-selected-window))
- (set-window-configuration org-window-configuration)
- (select-window sel-win)
- (goto-char pos)
- (move-marker pos nil)
- (message "Formula editing aborted without installing changes")))
+(defun org-table--number-for-summing (s)
+ (let (n)
+ (if (string-match "^ *|? *" s)
+ (setq s (replace-match "" nil nil s)))
+ (if (string-match " *|? *$" s)
+ (setq s (replace-match "" nil nil s)))
+ (setq n (string-to-number s))
+ (cond
+ ((and (string-match "0" s)
+ (string-match "\\`[-+ \t0.edED]+\\'" s)) 0)
+ ((string-match "\\`[ \t]+\\'" s) nil)
+ ((string-match "\\`\\([0-9]+\\):\\([0-9]+\\)\\(:\\([0-9]+\\)\\)?\\'" s)
+ (let ((h (string-to-number (or (match-string 1 s) "0")))
+ (m (string-to-number (or (match-string 2 s) "0")))
+ (s (string-to-number (or (match-string 4 s) "0"))))
+ (if (boundp 'org-timecnt) (setq org-timecnt (1+ org-timecnt)))
+ (* 1.0 (+ h (/ m 60.0) (/ s 3600.0)))))
+ ((equal n 0) nil)
+ (t n))))
-(defun org-table-fedit-lisp-indent ()
- "Pretty-print and re-indent Lisp expressions in the Formula Editor."
+;;;###autoload
+(defun org-table-sum (&optional beg end nlast)
+ "Sum numbers in region of current table column.
+The result will be displayed in the echo area, and will be available
+as kill to be inserted with \\[yank].
+
+If there is an active region, it is interpreted as a rectangle and all
+numbers in that rectangle will be summed. If there is no active
+region and point is located in a table column, sum all numbers in that
+column.
+
+If at least one number looks like a time HH:MM or HH:MM:SS, all other
+numbers are assumed to be times as well (in decimal hours) and the
+numbers are added as such.
+
+If NLAST is a number, only the NLAST fields will actually be summed."
(interactive)
- (let ((pos (point)) beg end ind)
- (beginning-of-line 1)
- (cond
- ((looking-at "[ \t]")
- (goto-char pos)
- (call-interactively 'lisp-indent-line))
- ((looking-at "[$&@0-9a-zA-Z]+ *= *[^ \t\n']") (goto-char pos))
- ((not (fboundp 'pp-buffer))
- (user-error "Cannot pretty-print. Command `pp-buffer' is not available"))
- ((looking-at "[$&@0-9a-zA-Z]+ *= *'(")
- (goto-char (- (match-end 0) 2))
- (setq beg (point))
- (setq ind (make-string (current-column) ?\ ))
- (condition-case nil (forward-sexp 1)
- (error
- (user-error "Cannot pretty-print Lisp expression: Unbalanced parenthesis")))
- (setq end (point))
- (save-restriction
- (narrow-to-region beg end)
- (if (eq last-command this-command)
- (progn
- (goto-char (point-min))
- (setq this-command nil)
- (while (re-search-forward "[ \t]*\n[ \t]*" nil t)
- (replace-match " ")))
- (pp-buffer)
- (untabify (point-min) (point-max))
- (goto-char (1+ (point-min)))
- (while (re-search-forward "^." nil t)
- (beginning-of-line 1)
- (insert ind))
- (goto-char (point-max))
- (org-delete-backward-char 1)))
- (goto-char beg))
- (t nil))))
+ (save-excursion
+ (let (col (org-timecnt 0) diff h m s org-table-clip)
+ (cond
+ ((and beg end)) ; beg and end given explicitly
+ ((org-region-active-p)
+ (setq beg (region-beginning) end (region-end)))
+ (t
+ (setq col (org-table-current-column))
+ (goto-char (org-table-begin))
+ (unless (re-search-forward "^[ \t]*|[^-]" nil t)
+ (user-error "No table data"))
+ (org-table-goto-column col)
+ (setq beg (point))
+ (goto-char (org-table-end))
+ (unless (re-search-backward "^[ \t]*|[^-]" nil t)
+ (user-error "No table data"))
+ (org-table-goto-column col)
+ (setq end (point))))
+ (let* ((items (apply 'append (org-table-copy-region beg end)))
+ (items1 (cond ((not nlast) items)
+ ((>= nlast (length items)) items)
+ (t (setq items (reverse items))
+ (setcdr (nthcdr (1- nlast) items) nil)
+ (nreverse items))))
+ (numbers (delq nil (mapcar #'org-table--number-for-summing
+ items1)))
+ (res (apply '+ numbers))
+ (sres (if (= org-timecnt 0)
+ (number-to-string res)
+ (setq diff (* 3600 res)
+ h (floor diff 3600) diff (mod diff 3600)
+ m (floor diff 60) diff (mod diff 60)
+ s diff)
+ (format "%.0f:%02.0f:%02.0f" h m s))))
+ (kill-new sres)
+ (when (called-interactively-p 'interactive)
+ (message (substitute-command-keys
+ (format "Sum of %d items: %-20s \
+\(\\[yank] will insert result into buffer)"
+ (length numbers)
+ sres))))
+ sres))))
-(defvar org-show-positions nil)
+;;;###autoload
+(defun org-table-analyze ()
+ "Analyze table at point and store results.
+
+This function sets up the following dynamically scoped variables:
+
+ `org-table-column-name-regexp',
+ `org-table-column-names',
+ `org-table-current-begin-pos',
+ `org-table-current-line-types',
+ `org-table-current-ncol',
+ `org-table-dlines',
+ `org-table-hlines',
+ `org-table-local-parameters',
+ `org-table-named-field-locations'."
+ (let ((beg (org-table-begin))
+ (end (org-table-end)))
+ (save-excursion
+ (goto-char beg)
+ ;; Extract column names.
+ (setq org-table-column-names nil)
+ (when (save-excursion
+ (re-search-forward "^[ \t]*| *! *\\(|.*\\)" end t))
+ (let ((c 1))
+ (dolist (name (org-split-string (match-string 1) " *| *"))
+ (cl-incf c)
+ (when (string-match "\\`[a-zA-Z][_a-zA-Z0-9]*\\'" name)
+ (push (cons name (int-to-string c)) org-table-column-names)))))
+ (setq org-table-column-names (nreverse org-table-column-names))
+ (setq org-table-column-name-regexp
+ (format "\\$\\(%s\\)\\>"
+ (regexp-opt (mapcar #'car org-table-column-names) t)))
+ ;; Extract local parameters.
+ (setq org-table-local-parameters nil)
+ (save-excursion
+ (while (re-search-forward "^[ \t]*| *\\$ *\\(|.*\\)" end t)
+ (dolist (field (org-split-string (match-string 1) " *| *"))
+ (when (string-match
+ "\\`\\([a-zA-Z][_a-zA-Z0-9]*\\|%\\) *= *\\(.*\\)" field)
+ (push (cons (match-string 1 field) (match-string 2 field))
+ org-table-local-parameters)))))
+ ;; Update named fields locations. We minimize `count-lines'
+ ;; processing by storing last known number of lines in LAST.
+ (setq org-table-named-field-locations nil)
+ (save-excursion
+ (let ((last (cons (point) 0)))
+ (while (re-search-forward "^[ \t]*| *\\([_^]\\) *\\(|.*\\)" end t)
+ (let ((c (match-string 1))
+ (fields (org-split-string (match-string 2) " *| *")))
+ (save-excursion
+ (forward-line (if (equal c "_") 1 -1))
+ (let ((fields1
+ (and (looking-at "^[ \t]*|[^|]*\\(|.*\\)")
+ (org-split-string (match-string 1) " *| *")))
+ (line (cl-incf (cdr last) (count-lines (car last) (point))))
+ (col 1))
+ (setcar last (point)) ; Update last known position.
+ (while (and fields fields1)
+ (let ((field (pop fields))
+ (v (pop fields1)))
+ (cl-incf col)
+ (when (and (stringp field)
+ (stringp v)
+ (string-match "\\`[a-zA-Z][_a-zA-Z0-9]*\\'"
+ field))
+ (push (cons field v) org-table-local-parameters)
+ (push (list field line col)
+ org-table-named-field-locations))))))))))
+ ;; Re-use existing markers when possible.
+ (if (markerp org-table-current-begin-pos)
+ (move-marker org-table-current-begin-pos (point))
+ (setq org-table-current-begin-pos (point-marker)))
+ ;; Analyze the line types.
+ (let ((l 0) hlines dlines types)
+ (while (looking-at "[ \t]*|\\(-\\)?")
+ (push (if (match-end 1) 'hline 'dline) types)
+ (if (match-end 1) (push l hlines) (push l dlines))
+ (forward-line)
+ (cl-incf l))
+ (push 'hline types) ; Add an imaginary extra hline to the end.
+ (setq org-table-current-line-types (apply #'vector (nreverse types)))
+ (setq org-table-dlines (apply #'vector (cons nil (nreverse dlines))))
+ (setq org-table-hlines (apply #'vector (cons nil (nreverse hlines)))))
+ ;; Get the number of columns from the first data line in table.
+ (goto-char beg)
+ (forward-line (aref org-table-dlines 1))
+ (let* ((fields
+ (org-split-string
+ (buffer-substring (line-beginning-position) (line-end-position))
+ "[ \t]*|[ \t]*"))
+ (nfields (length fields))
+ al al2)
+ (setq org-table-current-ncol nfields)
+ (let ((last-dline
+ (aref org-table-dlines (1- (length org-table-dlines)))))
+ (dotimes (i nfields)
+ (let ((column (1+ i)))
+ (push (list (format "LR%d" column) last-dline column) al)
+ (push (cons (format "LR%d" column) (nth i fields)) al2))))
+ (setq org-table-named-field-locations
+ (append org-table-named-field-locations al))
+ (setq org-table-local-parameters
+ (append org-table-local-parameters al2))))))
+
+(defun org-table--force-dataline ()
+ "Move point to the closest data line in a table.
+Raise an error if the table contains no data line. Preserve
+column when moving point."
+ (unless (org-match-line org-table-dataline-regexp)
+ (let* ((re org-table-dataline-regexp)
+ (column (current-column))
+ (p1 (save-excursion (re-search-forward re (org-table-end) t)))
+ (p2 (save-excursion (re-search-backward re (org-table-begin) t))))
+ (cond ((and p1 p2)
+ (goto-char (if (< (abs (- p1 (point))) (abs (- p2 (point))))
+ p1
+ p2)))
+ ((or p1 p2) (goto-char (or p1 p2)))
+ (t (user-error "No table data line around here")))
+ (org-move-to-column column))))
(defun org-table-show-reference (&optional local)
"Show the location/value of the $ expression at point.
@@ -4467,7 +4911,7 @@ When LOCAL is non-nil, show references for the table at point."
(org-switch-to-buffer-other-window (get-buffer-window
(marker-buffer pos)))))
(goto-char pos)
- (org-table-force-dataline)
+ (org-table--force-dataline)
(let ((table-start
(if local org-table-current-begin-pos (org-table-begin))))
(when dest
@@ -4539,161 +4983,8 @@ When LOCAL is non-nil, show references for the table at point."
(set-window-start (selected-window) max)))))
(select-window win))))
-(defun org-table-force-dataline ()
- "Move point to the closest data line in a table.
-Raise an error if the table contains no data line. Preserve
-column when moving point."
- (unless (org-match-line org-table-dataline-regexp)
- (let* ((re org-table-dataline-regexp)
- (column (current-column))
- (p1 (save-excursion (re-search-forward re (org-table-end) t)))
- (p2 (save-excursion (re-search-backward re (org-table-begin) t))))
- (cond ((and p1 p2)
- (goto-char (if (< (abs (- p1 (point))) (abs (- p2 (point))))
- p1
- p2)))
- ((or p1 p2) (goto-char (or p1 p2)))
- (t (user-error "No table data line around here")))
- (org-move-to-column column))))
-
-(defun org-table-fedit-line-up ()
- "Move cursor one line up in the window showing the table."
- (interactive)
- (org-table-fedit-move 'previous-line))
-
-(defun org-table-fedit-line-down ()
- "Move cursor one line down in the window showing the table."
- (interactive)
- (org-table-fedit-move 'next-line))
-
-(defun org-table-fedit-move (command)
- "Move the cursor in the window showing the table.
-Use COMMAND to do the motion, repeat if necessary to end up in a data line."
- (let ((org-table-allow-automatic-line-recalculation nil)
- (pos org-pos) (win (selected-window)) p)
- (select-window (get-buffer-window (marker-buffer org-pos)))
- (setq p (point))
- (call-interactively command)
- (while (and (org-at-table-p)
- (org-at-table-hline-p))
- (call-interactively command))
- (or (org-at-table-p) (goto-char p))
- (move-marker pos (point))
- (select-window win)))
-
-(defun org-table-fedit-scroll (N)
- (interactive "p")
- (let ((other-window-scroll-buffer (marker-buffer org-pos)))
- (scroll-other-window N)))
-
-(defun org-table-fedit-scroll-down (N)
- (interactive "p")
- (org-table-fedit-scroll (- N)))
-
-(defvar org-table-rectangle-overlays nil)
-
-(defun org-table-add-rectangle-overlay (beg end &optional face)
- "Add a new overlay."
- (let ((ov (make-overlay beg end)))
- (overlay-put ov 'face (or face 'secondary-selection))
- (push ov org-table-rectangle-overlays)))
-
-(defun org-table-highlight-rectangle (&optional beg end face)
- "Highlight rectangular region in a table.
-When buffer positions BEG and END are provided, use them to
-delimit the region to highlight. Otherwise, refer to point. Use
-FACE, when non-nil, for the highlight."
- (let* ((beg (or beg (point)))
- (end (or end (point)))
- (b (min beg end))
- (e (max beg end))
- (start-coordinates
- (save-excursion
- (goto-char b)
- (cons (line-beginning-position) (org-table-current-column))))
- (end-coordinates
- (save-excursion
- (goto-char e)
- (cons (line-beginning-position) (org-table-current-column)))))
- (when (boundp 'org-show-positions)
- (setq org-show-positions (cons b (cons e org-show-positions))))
- (goto-char (car start-coordinates))
- (let ((column-start (min (cdr start-coordinates) (cdr end-coordinates)))
- (column-end (max (cdr start-coordinates) (cdr end-coordinates)))
- (last-row (car end-coordinates)))
- (while (<= (point) last-row)
- (when (looking-at org-table-dataline-regexp)
- (org-table-goto-column column-start)
- (skip-chars-backward "^|\n")
- (let ((p (point)))
- (org-table-goto-column column-end)
- (skip-chars-forward "^|\n")
- (org-table-add-rectangle-overlay p (point) face)))
- (forward-line)))
- (goto-char (car start-coordinates)))
- (add-hook 'before-change-functions #'org-table-remove-rectangle-highlight))
-
-(defun org-table-remove-rectangle-highlight (&rest _ignore)
- "Remove the rectangle overlays."
- (unless org-inhibit-highlight-removal
- (remove-hook 'before-change-functions 'org-table-remove-rectangle-highlight)
- (mapc 'delete-overlay org-table-rectangle-overlays)
- (setq org-table-rectangle-overlays nil)))
-
-(defvar-local org-table-coordinate-overlays nil
- "Collects the coordinate grid overlays, so that they can be removed.")
-
-(defun org-table-overlay-coordinates ()
- "Add overlays to the table at point, to show row/column coordinates."
- (interactive)
- (mapc 'delete-overlay org-table-coordinate-overlays)
- (setq org-table-coordinate-overlays nil)
- (save-excursion
- (let ((id 0) (ih 0) hline eol str ov)
- (goto-char (org-table-begin))
- (while (org-at-table-p)
- (setq eol (point-at-eol))
- (setq ov (make-overlay (point-at-bol) (1+ (point-at-bol))))
- (push ov org-table-coordinate-overlays)
- (setq hline (looking-at org-table-hline-regexp))
- (setq str (if hline (format "I*%-2d" (setq ih (1+ ih)))
- (format "%4d" (setq id (1+ id)))))
- (org-overlay-before-string ov str 'org-special-keyword 'evaporate)
- (when hline
- (let ((ic 0))
- (while (re-search-forward "[+|]\\(-+\\)" eol t)
- (cl-incf ic)
- (let* ((beg (1+ (match-beginning 0)))
- (s1 (format "$%d" ic))
- (s2 (org-number-to-letters ic))
- (str (if (eq t org-table-use-standard-references) s2 s1))
- (ov (make-overlay beg (+ beg (length str)))))
- (push ov org-table-coordinate-overlays)
- (org-overlay-display ov str 'org-special-keyword 'evaporate)))))
- (forward-line)))))
-
-;;;###autoload
-(defun org-table-toggle-coordinate-overlays ()
- "Toggle the display of Row/Column numbers in tables."
- (interactive)
- (setq org-table-overlay-coordinates (not org-table-overlay-coordinates))
- (message "Tables Row/Column numbers display turned %s"
- (if org-table-overlay-coordinates "on" "off"))
- (when (and (org-at-table-p) org-table-overlay-coordinates)
- (org-table-align))
- (unless org-table-overlay-coordinates
- (mapc 'delete-overlay org-table-coordinate-overlays)
- (setq org-table-coordinate-overlays nil)))
-
-;;;###autoload
-(defun org-table-toggle-formula-debugger ()
- "Toggle the formula debugger in tables."
- (interactive)
- (setq org-table-formula-debug (not org-table-formula-debug))
- (message "Formula debugging has been turned %s"
- (if org-table-formula-debug "on" "off")))
-
-;;; The orgtbl minor mode
+
+;;; The Orgtbl minor mode
;; Define a minor mode which can be used in other modes in order to
;; integrate the Org table editor.
@@ -4722,7 +5013,6 @@ FACE, when non-nil, for the highlight."
;; active, this binding is ignored inside tables and replaced with a
;; modified self-insert.
-
(defvar orgtbl-mode-map (make-keymap)
"Keymap for `orgtbl-mode'.")
@@ -4738,10 +5028,78 @@ FACE, when non-nil, for the highlight."
0 (quote 'org-table) 'prepend))
"Extra `font-lock-keywords' to be added when `orgtbl-mode' is active.")
+;;;###autoload
+(defun turn-on-orgtbl ()
+ "Unconditionally turn on `orgtbl-mode'."
+ (require 'org-table)
+ (orgtbl-mode 1))
+
;; Install it as a minor mode.
(put 'orgtbl-mode :included t)
(put 'orgtbl-mode :menu-tag "Org Table Mode")
+(easy-menu-define orgtbl-mode-menu orgtbl-mode-map "OrgTbl menu"
+ '("OrgTbl"
+ ["Create or convert" org-table-create-or-convert-from-region
+ :active (not (org-at-table-p)) :keys "C-c |" ]
+ "--"
+ ["Align" org-ctrl-c-ctrl-c :active (org-at-table-p) :keys "C-c C-c"]
+ ["Next Field" org-cycle :active (org-at-table-p) :keys "TAB"]
+ ["Previous Field" org-shifttab :active (org-at-table-p) :keys "S-TAB"]
+ ["Next Row" org-return :active (org-at-table-p) :keys "RET"]
+ "--"
+ ["Blank Field" org-table-blank-field :active (org-at-table-p) :keys "C-c SPC"]
+ ["Edit Field" org-table-edit-field :active (org-at-table-p) :keys "C-c ` "]
+ ["Copy Field from Above"
+ org-table-copy-down :active (org-at-table-p) :keys "S-RET"]
+ "--"
+ ("Column"
+ ["Move Column Left" org-metaleft :active (org-at-table-p) :keys "M-<left>"]
+ ["Move Column Right" org-metaright :active (org-at-table-p) :keys "M-<right>"]
+ ["Delete Column" org-shiftmetaleft :active (org-at-table-p) :keys "M-S-<left>"]
+ ["Insert Column" org-shiftmetaright :active (org-at-table-p) :keys "M-S-<right>"])
+ ("Row"
+ ["Move Row Up" org-metaup :active (org-at-table-p) :keys "M-<up>"]
+ ["Move Row Down" org-metadown :active (org-at-table-p) :keys "M-<down>"]
+ ["Delete Row" org-shiftmetaup :active (org-at-table-p) :keys "M-S-<up>"]
+ ["Insert Row" org-shiftmetadown :active (org-at-table-p) :keys "M-S-<down>"]
+ ["Sort lines in region" org-table-sort-lines :active (org-at-table-p) :keys "C-c ^"]
+ "--"
+ ["Insert Hline" org-table-insert-hline :active (org-at-table-p) :keys "C-c -"])
+ ("Rectangle"
+ ["Copy Rectangle" org-copy-special :active (org-at-table-p)]
+ ["Cut Rectangle" org-cut-special :active (org-at-table-p)]
+ ["Paste Rectangle" org-paste-special :active (org-at-table-p)]
+ ["Fill Rectangle" org-table-wrap-region :active (org-at-table-p)])
+ "--"
+ ("Radio tables"
+ ["Insert table template" orgtbl-insert-radio-table
+ (cl-assoc-if #'derived-mode-p orgtbl-radio-table-templates)]
+ ["Comment/uncomment table" orgtbl-toggle-comment t])
+ "--"
+ ["Set Column Formula" org-table-eval-formula :active (org-at-table-p) :keys "C-c ="]
+ ["Set Field Formula" (org-table-eval-formula '(4)) :active (org-at-table-p) :keys "C-u C-c ="]
+ ["Edit Formulas" org-table-edit-formulas :active (org-at-table-p) :keys "C-c '"]
+ ["Recalculate line" org-table-recalculate :active (org-at-table-p) :keys "C-c *"]
+ ["Recalculate all" (org-table-recalculate '(4)) :active (org-at-table-p) :keys "C-u C-c *"]
+ ["Iterate all" (org-table-recalculate '(16)) :active (org-at-table-p) :keys "C-u C-u C-c *"]
+ ["Toggle Recalculate Mark" org-table-rotate-recalc-marks :active (org-at-table-p) :keys "C-c #"]
+ ["Sum Column/Rectangle" org-table-sum
+ :active (or (org-at-table-p) (org-region-active-p)) :keys "C-c +"]
+ ["Which Column?" org-table-current-column :active (org-at-table-p) :keys "C-c ?"]
+ ["Debug Formulas"
+ org-table-toggle-formula-debugger :active (org-at-table-p)
+ :keys "C-c {"
+ :style toggle :selected org-table-formula-debug]
+ ["Show Col/Row Numbers"
+ org-table-toggle-coordinate-overlays :active (org-at-table-p)
+ :keys "C-c }"
+ :style toggle :selected org-table-overlay-coordinates]
+ "--"
+ ("Plot"
+ ["Ascii plot" orgtbl-ascii-plot :active (org-at-table-p) :keys "C-c \" a"]
+ ["Gnuplot" org-plot/gnuplot :active (org-at-table-p) :keys "C-c \" g"])))
+
;;;###autoload
(define-minor-mode orgtbl-mode
"The Org mode table editor as a minor mode for use in other modes."
@@ -4896,67 +5254,6 @@ to execute outside of tables."
'delete-char 'org-delete-char
'delete-backward-char 'org-delete-backward-char)
(org-defkey orgtbl-mode-map "|" 'org-force-self-insert))
- (easy-menu-define orgtbl-mode-menu orgtbl-mode-map "OrgTbl menu"
- '("OrgTbl"
- ["Create or convert" org-table-create-or-convert-from-region
- :active (not (org-at-table-p)) :keys "C-c |" ]
- "--"
- ["Align" org-ctrl-c-ctrl-c :active (org-at-table-p) :keys "C-c C-c"]
- ["Next Field" org-cycle :active (org-at-table-p) :keys "TAB"]
- ["Previous Field" org-shifttab :active (org-at-table-p) :keys "S-TAB"]
- ["Next Row" org-return :active (org-at-table-p) :keys "RET"]
- "--"
- ["Blank Field" org-table-blank-field :active (org-at-table-p) :keys "C-c SPC"]
- ["Edit Field" org-table-edit-field :active (org-at-table-p) :keys "C-c ` "]
- ["Copy Field from Above"
- org-table-copy-down :active (org-at-table-p) :keys "S-RET"]
- "--"
- ("Column"
- ["Move Column Left" org-metaleft :active (org-at-table-p) :keys "M-<left>"]
- ["Move Column Right" org-metaright :active (org-at-table-p) :keys "M-<right>"]
- ["Delete Column" org-shiftmetaleft :active (org-at-table-p) :keys "M-S-<left>"]
- ["Insert Column" org-shiftmetaright :active (org-at-table-p) :keys "M-S-<right>"])
- ("Row"
- ["Move Row Up" org-metaup :active (org-at-table-p) :keys "M-<up>"]
- ["Move Row Down" org-metadown :active (org-at-table-p) :keys "M-<down>"]
- ["Delete Row" org-shiftmetaup :active (org-at-table-p) :keys "M-S-<up>"]
- ["Insert Row" org-shiftmetadown :active (org-at-table-p) :keys "M-S-<down>"]
- ["Sort lines in region" org-table-sort-lines :active (org-at-table-p) :keys "C-c ^"]
- "--"
- ["Insert Hline" org-table-insert-hline :active (org-at-table-p) :keys "C-c -"])
- ("Rectangle"
- ["Copy Rectangle" org-copy-special :active (org-at-table-p)]
- ["Cut Rectangle" org-cut-special :active (org-at-table-p)]
- ["Paste Rectangle" org-paste-special :active (org-at-table-p)]
- ["Fill Rectangle" org-table-wrap-region :active (org-at-table-p)])
- "--"
- ("Radio tables"
- ["Insert table template" orgtbl-insert-radio-table
- (cl-assoc-if #'derived-mode-p orgtbl-radio-table-templates)]
- ["Comment/uncomment table" orgtbl-toggle-comment t])
- "--"
- ["Set Column Formula" org-table-eval-formula :active (org-at-table-p) :keys "C-c ="]
- ["Set Field Formula" (org-table-eval-formula '(4)) :active (org-at-table-p) :keys "C-u C-c ="]
- ["Edit Formulas" org-table-edit-formulas :active (org-at-table-p) :keys "C-c '"]
- ["Recalculate line" org-table-recalculate :active (org-at-table-p) :keys "C-c *"]
- ["Recalculate all" (org-table-recalculate '(4)) :active (org-at-table-p) :keys "C-u C-c *"]
- ["Iterate all" (org-table-recalculate '(16)) :active (org-at-table-p) :keys "C-u C-u C-c *"]
- ["Toggle Recalculate Mark" org-table-rotate-recalc-marks :active (org-at-table-p) :keys "C-c #"]
- ["Sum Column/Rectangle" org-table-sum
- :active (or (org-at-table-p) (org-region-active-p)) :keys "C-c +"]
- ["Which Column?" org-table-current-column :active (org-at-table-p) :keys "C-c ?"]
- ["Debug Formulas"
- org-table-toggle-formula-debugger :active (org-at-table-p)
- :keys "C-c {"
- :style toggle :selected org-table-formula-debug]
- ["Show Col/Row Numbers"
- org-table-toggle-coordinate-overlays :active (org-at-table-p)
- :keys "C-c }"
- :style toggle :selected org-table-overlay-coordinates]
- "--"
- ("Plot"
- ["Ascii plot" orgtbl-ascii-plot :active (org-at-table-p) :keys "C-c \" a"]
- ["Gnuplot" org-plot/gnuplot :active (org-at-table-p) :keys "C-c \" g"])))
t))
(defun orgtbl-ctrl-c-ctrl-c (arg)
diff --git a/lisp/org-timer.el b/lisp/org-timer.el
index d831936..68fe966 100644
--- a/lisp/org-timer.el
+++ b/lisp/org-timer.el
@@ -419,7 +419,9 @@ using three `C-u' prefix arguments."
(if (numberp org-timer-default-timer)
(number-to-string org-timer-default-timer)
org-timer-default-timer))
- (effort-minutes (ignore-errors (floor (org-get-at-eol 'effort-minutes 1))))
+ (effort-minutes (let ((effort (org-entry-get nil org-effort-property)))
+ (when (org-string-nw-p effort)
+ (floor (org-duration-to-minutes effort)))))
(minutes (or (and (numberp opt) (number-to-string opt))
(and (not (equal opt '(64)))
effort-minutes
@@ -464,7 +466,8 @@ time is up."
(run-hooks 'org-timer-done-hook)))))
(defun org-timer--get-timer-title ()
- "Construct timer title from heading or file name of Org buffer."
+ "Construct timer title.
+Try to use an Org header, otherwise use the buffer name."
(cond
((derived-mode-p 'org-agenda-mode)
(let* ((marker (or (get-text-property (point) 'org-marker)
@@ -480,7 +483,7 @@ time is up."
((derived-mode-p 'org-mode)
(or (ignore-errors (org-get-heading))
(buffer-name (buffer-base-buffer))))
- (t (error "Not in an Org buffer"))))
+ (t (buffer-name (buffer-base-buffer)))))
(provide 'org-timer)
diff --git a/lisp/org.el b/lisp/org.el
index aa83e5b..67c5d1b 100644
--- a/lisp/org.el
+++ b/lisp/org.el
@@ -6,7 +6,7 @@
;; Author: Carsten Dominik <carsten at orgmode dot org>
;; Keywords: outlines, hypermedia, calendar, wp
;; Homepage: https://orgmode.org
-;; Version: 9.2.6
+;; Version: 9.3
;;
;; This file is part of GNU Emacs.
;;
@@ -64,8 +64,6 @@
;;; Code:
(defvar org-inhibit-highlight-removal nil) ; dynamically scoped param
-(defvar-local org-table-formula-constants-local nil
- "Local version of `org-table-formula-constants'.")
(defvar org-inlinetask-min-level)
;;;; Require other packages
@@ -91,6 +89,9 @@
(eval-and-compile (require 'org-macs))
(require 'org-compat)
+(require 'org-keys)
+(require 'ol)
+(require 'org-table)
;; `org-outline-regexp' ought to be a defconst but is let-bound in
;; some places -- e.g. see the macro `org-with-limited-levels'.
@@ -159,71 +160,35 @@ Stars are put in group 1 and the trimmed body in group 2.")
(declare-function org-element-swap-A-B "org-element" (elem-a elem-b))
(declare-function org-element-timestamp-parser "org-element" ())
(declare-function org-element-type "org-element" (element))
-(declare-function org-element-update-syntax "org-element" ())
(declare-function org-export-dispatch "ox" (&optional arg))
(declare-function org-export-get-backend "ox" (name))
-(declare-function org-export-get-backend "ox" (name))
-(declare-function org-export-get-environment "ox" (&optional backend subtreep ext-plist))
(declare-function org-export-get-environment "ox" (&optional backend subtreep ext-plist))
(declare-function org-feed-goto-inbox "org-feed" (feed))
(declare-function org-feed-update-all "org-feed" ())
(declare-function org-goto "org-goto" (&optional alternative-interface))
-(declare-function org-goto "org-goto" (&optional alternative-interface))
(declare-function org-id-find-id-file "org-id" (id))
(declare-function org-id-get-create "org-id" (&optional force))
(declare-function org-inlinetask-at-task-p "org-inlinetask" ())
(declare-function org-inlinetask-outline-regexp "org-inlinetask" ())
(declare-function org-inlinetask-toggle-visibility "org-inlinetask" ())
(declare-function org-latex-make-preamble "ox-latex" (info &optional template snippet?))
-(declare-function org-latex-make-preamble "ox-latex" (info &optional template snippet?))
(declare-function org-plot/gnuplot "org-plot" (&optional params))
-(declare-function org-table--shrunk-field "org-table" ()) ;; For `org-table-with-shrunk-field'.
-(declare-function org-table-align "org-table" ())
-(declare-function org-table-begin "org-table" (&optional table-type))
-(declare-function org-table-beginning-of-field "org-table" (&optional n))
-(declare-function org-table-blank-field "org-table" ())
-(declare-function org-table-calc-current-TBLFM "org-table" (&optional arg))
-(declare-function org-table-copy-down "org-table" (N))
-(declare-function org-table-copy-region "org-table" (beg end &optional cut))
-(declare-function org-table-create-or-convert-from-region "org-table" (arg))
-(declare-function org-table-create-with-table.el "org-table" ())
-(declare-function org-table-cut-region "org-table" (beg end))
-(declare-function org-table-edit-field "org-table" (arg))
-(declare-function org-table-end "org-table" (&optional table-type))
-(declare-function org-table-end-of-field "org-table" (&optional n))
-(declare-function org-table-eval-formula "org-table" (&optional arg equation suppress-align suppress-const suppress-store suppress-analysis))
-(declare-function org-table-field-info "org-table" (arg))
-(declare-function org-table-insert-row "org-table" (&optional arg))
-(declare-function org-table-justify-field-maybe "org-table" (&optional new))
-(declare-function org-table-maybe-eval-formula "org-table" ())
-(declare-function org-table-maybe-recalculate-line "org-table" ())
-(declare-function org-table-next-row "org-table" ())
-(declare-function org-table-paste-rectangle "org-table" ())
-(declare-function org-table-recalculate "org-table" (&optional all noalign))
-(declare-function org-table-rotate-recalc-marks "org-table" (&optional newchar))
-(declare-function org-table-shrink "org-table" (&optional begin end))
-(declare-function org-table-sort-lines "org-table" (&optional with-case sorting-type getkey-func compare-func interactive?))
-(declare-function org-table-sum "org-table" (&optional beg end nlast))
-(declare-function org-table-toggle-column-width "org-table" (&optional arg))
-(declare-function org-table-toggle-coordinate-overlays "org-table" ())
-(declare-function org-table-toggle-formula-debugger "org-table" ())
-(declare-function org-table-wrap-region "org-table" (arg))
(declare-function org-tags-view "org-agenda" (&optional todo-only match))
(declare-function org-timer "org-timer" (&optional restart no-insert))
(declare-function org-timer-item "org-timer" (&optional arg))
(declare-function org-timer-pause-or-continue "org-timer" (&optional stop))
-(declare-function org-timer-pause-or-continue "org-timer" (&optional stop))
(declare-function org-timer-set-timer "org-timer" (&optional opt))
(declare-function org-timer-start "org-timer" (&optional offset))
(declare-function org-timer-stop "org-timer" ())
-(declare-function org-timer-stop "org-timer" ())
(declare-function org-toggle-archive-tag "org-archive" (&optional find-done))
-(declare-function orgtbl-ascii-plot "org-table" (&optional ask))
-(declare-function orgtbl-mode "org-table" (&optional arg))
+(declare-function org-update-radio-target-regexp "ol" ())
(defvar ffap-url-regexp)
(defvar org-element-paragraph-separate)
(defvar org-indent-indentation-per-level)
+(defvar org-radio-target-regexp)
+(defvar org-target-link-regexp)
+(defvar org-target-regexp)
;; load languages based on value of `org-babel-load-languages'
(defvar org-babel-load-languages)
@@ -241,36 +206,27 @@ Stars are put in group 1 and the trimmed body in group 2.")
(fmakunbound
(intern (concat "org-babel-expand-body:" lang)))))))
-(declare-function org-babel-tangle-file "ob-tangle" (file &optional target-file lang))
+
;;;###autoload
(defun org-babel-load-file (file &optional compile)
"Load Emacs Lisp source code blocks in the Org FILE.
This function exports the source code using `org-babel-tangle'
-and then loads the resulting file using `load-file'. With prefix
-arg (noninteractively: 2nd arg) COMPILE the tangled Emacs Lisp
-file to byte-code before it is loaded."
+and then loads the resulting file using `load-file'. With
+optional prefix argument COMPILE, the tangled Emacs Lisp file is
+byte-compiled before it is loaded."
(interactive "fFile to load: \nP")
- (let* ((age (lambda (file)
- (float-time
- (time-since
- (file-attribute-modification-time
- (or (file-attributes (file-truename file))
- (file-attributes file)))))))
- (base-name (file-name-sans-extension file))
- (exported-file (concat base-name ".el")))
- ;; tangle if the Org file is newer than the elisp file
- (unless (and (file-exists-p exported-file)
- (> (funcall age file) (funcall age exported-file)))
- ;; Tangle-file traversal returns reversed list of tangled files
- ;; and we want to evaluate the first target.
- (setq exported-file
- (car (last (org-babel-tangle-file file exported-file "emacs-lisp")))))
- (message "%s %s"
- (if compile
- (progn (byte-compile-file exported-file 'load)
- "Compiled and loaded")
- (progn (load-file exported-file) "Loaded"))
- exported-file)))
+ (let* ((tangled-file (concat (file-name-sans-extension file) ".el")))
+ ;; Tangle only if the Org file is newer than the Elisp file.
+ (unless (org-file-newer-than-p
+ tangled-file
+ (file-attribute-modification-time (file-attributes file)))
+ (org-babel-tangle-file file tangled-file "emacs-lisp"))
+ (if compile
+ (progn
+ (byte-compile-file tangled-file 'load)
+ (message "Compiled and loaded %s" tangled-file))
+ (load-file tangled-file)
+ (message "Loaded %s" tangled-file))))
(defcustom org-babel-load-languages '((emacs-lisp . t))
"Languages which can be evaluated in Org buffers.
@@ -606,30 +562,6 @@ An entry can be toggled between COMMENT and normal with
"The property that is being used to keep track of effort estimates.
Effort estimates given in this property need to have the format H:MM.")
-;;;; Table
-
-(defconst org-table-any-line-regexp "^[ \t]*\\(|\\|\\+-[-+]\\)"
- "Detect an org-type or table-type table.")
-
-(defconst org-table-line-regexp "^[ \t]*|"
- "Detect an org-type table line.")
-
-(defconst org-table-dataline-regexp "^[ \t]*|[^-]"
- "Detect an org-type table line.")
-
-(defconst org-table-hline-regexp "^[ \t]*|-"
- "Detect an org-type table hline.")
-
-(defconst org-table1-hline-regexp "^[ \t]*\\+-[-+]"
- "Detect a table-type table hline.")
-
-(defconst org-table-any-border-regexp "^[ \t]*[^|+ \t]"
- "Detect the first line outside a table when searching from within it.
-This works for both table types.")
-
-(defconst org-TBLFM-regexp "^[ \t]*#\\+TBLFM: "
- "Detect a #+TBLFM line.")
-
;;;; Timestamp
(defconst org-ts-regexp "<\\([0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\} ?[^\r\n>]*?\\)>"
@@ -727,7 +659,7 @@ After a match, group 1 contains the repeat expression.")
(org-load-modules-maybe 'force)
(org-element-cache-reset 'all)))
-(defcustom org-modules '(org-w3m org-bbdb org-bibtex org-docview org-gnus org-info org-irc org-mhe org-rmail org-eww)
+(defcustom org-modules '(ol-w3m ol-bbdb ol-bibtex ol-docview ol-gnus ol-info ol-irc ol-mhe ol-rmail ol-eww)
"Modules that should always be loaded together with org.el.
If a description starts with <C>, the file is not part of Emacs
@@ -748,60 +680,59 @@ For export specific modules, see also `org-export-backends'."
:package-version '(Org . "9.2")
:type
'(set :greedy t
- (const :tag " bbdb: Links to BBDB entries" org-bbdb)
- (const :tag " bibtex: Links to BibTeX entries" org-bibtex)
+ (const :tag " bbdb: Links to BBDB entries" ol-bbdb)
+ (const :tag " bibtex: Links to BibTeX entries" ol-bibtex)
(const :tag " crypt: Encryption of subtrees" org-crypt)
(const :tag " ctags: Access to Emacs tags with links" org-ctags)
- (const :tag " docview: Links to doc-view buffers" org-docview)
- (const :tag " eww: Store link to url of eww" org-eww)
- (const :tag " gnus: Links to GNUS folders/messages" org-gnus)
+ (const :tag " docview: Links to Docview buffers" ol-docview)
+ (const :tag " eww: Store link to URL of Eww" ol-eww)
+ (const :tag " gnus: Links to GNUS folders/messages" ol-gnus)
(const :tag " habit: Track your consistency with habits" org-habit)
(const :tag " id: Global IDs for identifying entries" org-id)
- (const :tag " info: Links to Info nodes" org-info)
+ (const :tag " info: Links to Info nodes" ol-info)
(const :tag " inlinetask: Tasks independent of outline hierarchy" org-inlinetask)
- (const :tag " irc: Links to IRC/ERC chat sessions" org-irc)
- (const :tag " mhe: Links to MHE folders/messages" org-mhe)
+ (const :tag " irc: Links to IRC/ERC chat sessions" ol-irc)
+ (const :tag " mhe: Links to MHE folders/messages" ol-mhe)
(const :tag " mouse: Additional mouse support" org-mouse)
(const :tag " protocol: Intercept calls from emacsclient" org-protocol)
- (const :tag " rmail: Links to RMAIL folders/messages" org-rmail)
+ (const :tag " rmail: Links to RMAIL folders/messages" ol-rmail)
(const :tag " tempo: Fast completion for structures" org-tempo)
- (const :tag " w3m: Special cut/paste from w3m to Org mode." org-w3m)
- (const :tag " eshell: Support for links to working directories in eshell" org-eshell)
+ (const :tag " w3m: Special cut/paste from w3m to Org mode." ol-w3m)
+ (const :tag " eshell: Links to working directories in Eshell" ol-eshell)
- (const :tag "C annotate-file: Annotate a file with org syntax" org-annotate-file)
- (const :tag "C bookmark: Org links to bookmarks" org-bookmark)
+ (const :tag "C annotate-file: Annotate a file with Org syntax" org-annotate-file)
+ (const :tag "C bookmark: Links to bookmarks" ol-bookmark)
(const :tag "C checklist: Extra functions for checklists in repeated tasks" org-checklist)
(const :tag "C choose: Use TODO keywords to mark decisions states" org-choose)
(const :tag "C collector: Collect properties into tables" org-collector)
(const :tag "C depend: TODO dependencies for Org mode\n\t\t\t(PARTIALLY OBSOLETE, see built-in dependency support))" org-depend)
- (const :tag "C drill: Flashcards and spaced repetition for Org mode" org-drill)
- (const :tag "C elisp-symbol: Org links to emacs-lisp symbols" org-elisp-symbol)
+ (const :tag "C elisp-symbol: Links to emacs-lisp symbols" ol-elisp-symbol)
(const :tag "C eval-light: Evaluate inbuffer-code on demand" org-eval-light)
(const :tag "C eval: Include command output as text" org-eval)
(const :tag "C expiry: Expiry mechanism for Org entries" org-expiry)
- (const :tag "C git-link: Provide org links to specific file version" org-git-link)
+ (const :tag "C git-link: Links to specific file version" ol-git-link)
(const :tag "C interactive-query: Interactive modification of tags query\n\t\t\t(PARTIALLY OBSOLETE, see secondary filtering)" org-interactive-query)
(const :tag "C invoice: Help manage client invoices in Org mode" org-invoice)
(const :tag "C learn: SuperMemo's incremental learning algorithm" org-learn)
(const :tag "C mac-iCal: Imports events from iCal.app to the Emacs diary" org-mac-iCal)
(const :tag "C mac-link: Grab links and url from various mac Applications" org-mac-link)
(const :tag "C mairix: Hook mairix search into Org for different MUAs" org-mairix)
- (const :tag "C man: Support for links to manpages in Org mode" org-man)
- (const :tag "C mew: Links to Mew folders/messages" org-mew)
- (const :tag "C notify: Notifications for Org-mode" org-notify)
- (const :tag "C notmuch: Provide org links to notmuch searches or messages" org-notmuch)
+ (const :tag "C man: Links to man pages in Org mode" ol-man)
+ (const :tag "C mew: Links to Mew folders/messages" ol-mew)
+ (const :tag "C notify: Notifications for Org mode" org-notify)
+ (const :tag "C notmuch: Provide Org links to notmuch searches or messages" ol-notmuch)
(const :tag "C panel: Simple routines for us with bad memory" org-panel)
(const :tag "C registry: A registry for Org links" org-registry)
- (const :tag "C screen: Visit screen sessions through Org links" org-screen)
- (const :tag "C screenshot: Take and manage screenshots in Org-mode files" org-screenshot)
+ (const :tag "C screen: Visit screen sessions through links" org-screen)
+ (const :tag "C screenshot: Take and manage screenshots in Org files" org-screenshot)
(const :tag "C secretary: Team management with Org" org-secretary)
(const :tag "C sqlinsert: Convert Org tables to SQL insertions" orgtbl-sqlinsert)
(const :tag "C toc: Table of contents for Org buffer" org-toc)
(const :tag "C track: Keep up with Org mode development" org-track)
(const :tag "C velocity Something like Notational Velocity for Org" org-velocity)
- (const :tag "C vm: Links to VM folders/messages" org-vm)
+ (const :tag "C vm: Links to VM folders/messages" ol-vm)
(const :tag "C wikinodes: CamelCase wiki-like links" org-wikinodes)
- (const :tag "C wl: Links to Wanderlust folders/messages" org-wl)
+ (const :tag "C wl: Links to Wanderlust folders/messages" ol-wl)
(repeat :tag "External packages" :inline t (symbol :tag "Package"))))
(defvar org-export-registered-backends) ; From ox.el.
@@ -1119,63 +1050,6 @@ has been set."
:group 'org-startup
:type 'boolean)
-(defvaralias 'org-CUA-compatible 'org-replace-disputed-keys)
-
-(defcustom org-replace-disputed-keys nil
- "Non-nil means use alternative key bindings for some keys.
-
-Org mode uses S-<cursor> keys for changing timestamps and priorities.
-These keys are also used by other packages like Shift Select mode,
-CUA mode or Windmove. If you want to use Org mode together with
-one of these other modes, or more generally if you would like to
-move some Org mode commands to other keys, set this variable and
-configure the keys with the variable `org-disputed-keys'.
-
-This option is only relevant at load-time of Org mode, and must be set
-*before* org.el is loaded. Changing it requires a restart of Emacs to
-become effective."
- :group 'org-startup
- :type 'boolean)
-
-(defcustom org-use-extra-keys nil
- "Non-nil means use extra key sequence definitions for certain commands.
-This happens automatically if `window-system' is nil. This
-variable lets you do the same manually. You must set it before
-loading Org."
- :group 'org-startup
- :type 'boolean)
-
-(defcustom org-disputed-keys
- '(([(shift up)] . [(meta p)])
- ([(shift down)] . [(meta n)])
- ([(shift left)] . [(meta -)])
- ([(shift right)] . [(meta +)])
- ([(control shift right)] . [(meta shift +)])
- ([(control shift left)] . [(meta shift -)]))
- "Keys for which Org mode and other modes compete.
-This is an alist, cars are the default keys, second element specifies
-the alternative to use when `org-replace-disputed-keys' is t.
-
-Keys can be specified in any syntax supported by `define-key'.
-The value of this option takes effect only at Org mode startup,
-therefore you'll have to restart Emacs to apply it after changing."
- :group 'org-startup
- :type 'alist)
-
-(defun org-key (key)
- "Select key according to `org-replace-disputed-keys' and `org-disputed-keys'.
-Or return the original if not disputed."
- (when org-replace-disputed-keys
- (let* ((nkey (key-description key))
- (x (cl-find-if (lambda (x) (equal (key-description (car x)) nkey))
- org-disputed-keys)))
- (setq key (if x (cdr x) key))))
- key)
-
-(defun org-defkey (keymap key def)
- "Define a key, possibly translated, as returned by `org-key'."
- (define-key keymap (org-key key) def))
-
(defcustom org-ellipsis nil
"The ellipsis to use in the Org mode outline.
@@ -1313,43 +1187,158 @@ new-frame Make a new frame each time. Note that in this case
(const :tag "Each time a new frame" new-frame)
(const :tag "One dedicated frame" dedicated-frame)))
-(defcustom org-use-speed-commands nil
- "Non-nil means activate single letter commands at beginning of a headline.
-This may also be a function to test for appropriate locations where speed
-commands should be active.
+(defconst org-file-apps-gnu
+ '((remote . emacs)
+ (system . mailcap)
+ (t . mailcap))
+ "Default file applications on a UNIX or GNU/Linux system.
+See `org-file-apps'.")
-For example, to activate speed commands when the point is on any
-star at the beginning of the headline, you can do this:
+(defconst org-file-apps-macos
+ '((remote . emacs)
+ (system . "open %s")
+ ("ps.gz" . "gv %s")
+ ("eps.gz" . "gv %s")
+ ("dvi" . "xdvi %s")
+ ("fig" . "xfig %s")
+ (t . "open %s"))
+ "Default file applications on a macOS system.
+The system \"open\" is known as a default, but we use X11 applications
+for some files for which the OS does not have a good default.
+See `org-file-apps'.")
- (setq org-use-speed-commands
- (lambda () (and (looking-at org-outline-regexp) (looking-back \"^\\**\"))))"
- :group 'org-structure
- :type '(choice
- (const :tag "Never" nil)
- (const :tag "At beginning of headline stars" t)
- (function)))
+(defconst org-file-apps-windowsnt
+ (list '(remote . emacs)
+ (cons 'system (lambda (file _path)
+ (with-no-warnings (w32-shell-execute "open" file))))
+ (cons t (lambda (file _path)
+ (with-no-warnings (w32-shell-execute "open" file)))))
+ "Default file applications on a Windows NT system.
+The system \"open\" is used for most files.
+See `org-file-apps'.")
-(defcustom org-speed-commands-user nil
- "Alist of additional speed commands.
-This list will be checked before `org-speed-commands-default'
-when the variable `org-use-speed-commands' is non-nil
-and when the cursor is at the beginning of a headline.
-The car of each entry is a string with a single letter, which must
-be assigned to `self-insert-command' in the global map.
-The cdr is either a command to be called interactively, a function
-to be called, or a form to be evaluated.
-An entry that is just a list with a single string will be interpreted
-as a descriptive headline that will be added when listing the speed
-commands in the Help buffer using the `?' speed command."
- :group 'org-structure
- :type '(repeat :value ("k" . ignore)
- (choice :value ("k" . ignore)
- (list :tag "Descriptive Headline" (string :tag "Headline"))
- (cons :tag "Letter and Command"
- (string :tag "Command letter")
- (choice
- (function)
- (sexp))))))
+(defcustom org-file-apps
+ '((auto-mode . emacs)
+ ("\\.mm\\'" . default)
+ ("\\.x?html?\\'" . default)
+ ("\\.pdf\\'" . default))
+ "External applications for opening `file:path' items in a document.
+
+\\<org-mode-map>
+Org mode uses system defaults for different file types, but
+you can use this variable to set the application for a given file
+extension. The entries in this list are cons cells where the car identifies
+files and the cdr the corresponding command.
+
+Possible values for the file identifier are:
+
+ \"string\" A string as a file identifier can be interpreted in different
+ ways, depending on its contents:
+
+ - Alphanumeric characters only:
+ Match links with this file extension.
+ Example: (\"pdf\" . \"evince %s\")
+ to open PDFs with evince.
+
+ - Regular expression: Match links where the
+ filename matches the regexp. If you want to
+ use groups here, use shy groups.
+
+ Example: (\"\\\\.x?html\\\\\\='\" . \"firefox %s\")
+ (\"\\\\(?:xhtml\\\\|html\\\\)\\\\\\='\" . \"firefox %s\")
+ to open *.html and *.xhtml with firefox.
+
+ - Regular expression which contains (non-shy) groups:
+ Match links where the whole link, including \"::\", and
+ anything after that, matches the regexp.
+ In a custom command string, %1, %2, etc. are replaced with
+ the parts of the link that were matched by the groups.
+ For backwards compatibility, if a command string is given
+ that does not use any of the group matches, this case is
+ handled identically to the second one (i.e. match against
+ file name only).
+ In a custom function, you can access the group matches with
+ (match-string n link).
+
+ Example: (\"\\\\.pdf::\\\\([0-9]+\\\\)\\\\\\='\" . \
+\"evince -p %1 %s\")
+ to open [[file:document.pdf::5]] with evince at page 5.
+
+ `directory' Matches a directory
+ `remote' Matches a remote file, accessible through tramp or efs.
+ Remote files most likely should be visited through Emacs
+ because external applications cannot handle such paths.
+`auto-mode' Matches files that are matched by any entry in `auto-mode-alist',
+ so all files Emacs knows how to handle. Using this with
+ command `emacs' will open most files in Emacs. Beware that this
+ will also open html files inside Emacs, unless you add
+ (\"html\" . default) to the list as well.
+ `system' The system command to open files, like `open' on Windows
+ and macOS, and mailcap under GNU/Linux. This is the command
+ that will be selected if you call `org-open-at-point' with a
+ double prefix argument (`\\[universal-argument] \
+\\[universal-argument] \\[org-open-at-point]').
+ t Default for files not matched by any of the other options.
+
+Possible values for the command are:
+
+ `emacs' The file will be visited by the current Emacs process.
+ `default' Use the default application for this file type, which is the
+ association for t in the list, most likely in the system-specific
+ part. This can be used to overrule an unwanted setting in the
+ system-specific variable.
+ `system' Use the system command for opening files, like \"open\".
+ This command is specified by the entry whose car is `system'.
+ Most likely, the system-specific version of this variable
+ does define this command, but you can overrule/replace it
+ here.
+`mailcap' Use command specified in the mailcaps.
+ string A command to be executed by a shell; %s will be replaced
+ by the path to the file.
+ function A Lisp function, which will be called with two arguments:
+ the file path and the original link string, without the
+ \"file:\" prefix.
+
+For more examples, see the system specific constants
+`org-file-apps-macos'
+`org-file-apps-windowsnt'
+`org-file-apps-gnu'."
+ :group 'org
+ :type '(repeat
+ (cons (choice :value ""
+ (string :tag "Extension")
+ (const :tag "System command to open files" system)
+ (const :tag "Default for unrecognized files" t)
+ (const :tag "Remote file" remote)
+ (const :tag "Links to a directory" directory)
+ (const :tag "Any files that have Emacs modes"
+ auto-mode))
+ (choice :value ""
+ (const :tag "Visit with Emacs" emacs)
+ (const :tag "Use default" default)
+ (const :tag "Use the system command" system)
+ (string :tag "Command")
+ (function :tag "Function")))))
+
+(defcustom org-open-non-existing-files nil
+ "Non-nil means `org-open-file' opens non-existing files.
+
+When nil, an error is thrown.
+
+This variable applies only to external applications because they
+might choke on non-existing files. If the link is to a file that
+will be opened in Emacs, the variable is ignored."
+ :group 'org
+ :type 'boolean
+ :safe #'booleanp)
+
+(defcustom org-open-directory-means-index-dot-org nil
+ "When non-nil a link to a directory really means to \"index.org\".
+When nil, following a directory link runs Dired or opens
+a finder/explorer window on that directory."
+ :group 'org
+ :type 'boolean
+ :safe #'booleanp)
(defcustom org-bookmark-names-plist
'(:last-capture "org-capture-last-stored"
@@ -1707,13 +1696,6 @@ make an intelligent decision whether to insert a blank line or not."
:group 'org-edit-structure
:type 'hook)
-(defcustom org-enable-fixed-width-editor t
- "Non-nil means lines starting with \":\" are treated as fixed-width.
-This currently only means they are never auto-wrapped.
-When nil, such lines will be treated like ordinary lines."
- :group 'org-edit-structure
- :type 'boolean)
-
(defgroup org-sparse-trees nil
"Options concerning sparse trees in Org mode."
:tag "Org Sparse Trees"
@@ -1732,8 +1714,8 @@ changed by an edit command."
Such highlights are created by `org-occur' and `org-clock-display'.
When nil, `\\[org-ctrl-c-ctrl-c]' needs to be used \
to get rid of the highlights.
-The highlights created by `org-toggle-latex-fragment' always need
-`\\[org-toggle-latex-fragment]' to be removed."
+The highlights created by `org-latex-preview' always need
+`\\[org-latex-preview]' to be removed."
:group 'org-sparse-trees
:group 'org-time
:type 'boolean)
@@ -1756,11 +1738,6 @@ as possible."
:group 'org-sparse-trees
:type 'hook)
-(defgroup org-table nil
- "Options concerning tables in Org mode."
- :tag "Org Table"
- :group 'org)
-
(defcustom org-self-insert-cluster-for-undo nil
"Non-nil means cluster self-insert commands for undo when possible.
If this is set, then, like in the Emacs command loop, 20 consecutive
@@ -1769,155 +1746,6 @@ This is configurable, because there is some impact on typing performance."
:group 'org-table
:type 'boolean)
-(defcustom org-table-tab-recognizes-table.el t
- "Non-nil means TAB will automatically notice a table.el table.
-When it sees such a table, it moves point into it and - if necessary -
-calls `table-recognize-table'."
- :group 'org-table-editing
- :type 'boolean)
-
-(defgroup org-link nil
- "Options concerning links in Org mode."
- :tag "Org Link"
- :group 'org)
-
-(defvar-local org-link-abbrev-alist-local nil
- "Buffer-local version of `org-link-abbrev-alist', which see.
-The value of this is taken from the #+LINK lines.")
-
-(defcustom org-link-parameters
- '(("doi" :follow org--open-doi-link)
- ("elisp" :follow org--open-elisp-link)
- ("file" :complete org-file-complete-link)
- ("ftp" :follow (lambda (path) (browse-url (concat "ftp:" path))))
- ("help" :follow org--open-help-link)
- ("http" :follow (lambda (path) (browse-url (concat "http:" path))))
- ("https" :follow (lambda (path) (browse-url (concat "https:" path))))
- ("mailto" :follow (lambda (path) (browse-url (concat "mailto:" path))))
- ("news" :follow (lambda (path) (browse-url (concat "news:" path))))
- ("shell" :follow org--open-shell-link))
- "An alist of properties that defines all the links in Org mode.
-The key in each association is a string of the link type.
-Subsequent optional elements make up a p-list of link properties.
-
-:follow - A function that takes the link path as an argument.
-
-:export - A function that takes the link path, description and
-export-backend as arguments.
-
-:store - A function responsible for storing the link. See the
-function `org-store-link-functions'.
-
-:complete - A function that inserts a link with completion. The
-function takes one optional prefix arg.
-
-:face - A face for the link, or a function that returns a face.
-The function takes one argument which is the link path. The
-default face is `org-link'.
-
-:mouse-face - The mouse-face. The default is `highlight'.
-
-:display - `full' will not fold the link in descriptive
-display. Default is `org-link'.
-
-:help-echo - A string or function that takes (window object position)
-as arguments and returns a string.
-
-:keymap - A keymap that is active on the link. The default is
-`org-mouse-map'.
-
-:htmlize-link - A function for the htmlize-link. Defaults
-to (list :uri \"type:path\")
-
-:activate-func - A function to run at the end of font-lock
-activation. The function must accept (link-start link-end path bracketp)
-as arguments."
- :group 'org-link
- :type '(alist :tag "Link display parameters"
- :value-type plist)
- :version "26.1"
- :package-version '(Org . "9.1"))
-
-(defun org-link-get-parameter (type key)
- "Get TYPE link property for KEY.
-TYPE is a string and KEY is a plist keyword."
- (plist-get
- (cdr (assoc type org-link-parameters))
- key))
-
-(defun org-link-set-parameters (type &rest parameters)
- "Set link TYPE properties to PARAMETERS.
- PARAMETERS should be :key val pairs."
- (let ((data (assoc type org-link-parameters)))
- (if data (setcdr data (org-combine-plists (cdr data) parameters))
- (push (cons type parameters) org-link-parameters)
- (org-make-link-regexps)
- (org-element-update-syntax))))
-
-(defun org-link-types ()
- "Return a list of known link types."
- (mapcar #'car org-link-parameters))
-
-(defcustom org-link-abbrev-alist nil
- "Alist of link abbreviations.
-The car of each element is a string, to be replaced at the start of a link.
-The cdrs are replacement values, like (\"linkkey\" . REPLACE). Abbreviated
-links in Org buffers can have an optional tag after a double colon, e.g.,
-
- [[linkkey:tag][description]]
-
-The `linkkey' must be a single word, starting with a letter, followed
-by letters, numbers, `-' or `_'.
-
-If REPLACE is a string, the tag will simply be appended to create the link.
-If the string contains \"%s\", the tag will be inserted there. If the string
-contains \"%h\", it will cause a url-encoded version of the tag to be inserted
-at that point (see the function `url-hexify-string'). If the string contains
-the specifier \"%(my-function)\", then the custom function `my-function' will
-be invoked: this function takes the tag as its only argument and must return
-a string.
-
-REPLACE may also be a function that will be called with the tag as the
-only argument to create the link, which should be returned as a string.
-
-See the manual for examples."
- :group 'org-link
- :type '(repeat
- (cons
- (string :tag "Protocol")
- (choice
- (string :tag "Format")
- (function)))))
-
-(defcustom org-descriptive-links t
- "Non-nil means Org will display descriptive links.
-E.g. [[https://orgmode.org][Org website]] will be displayed as
-\"Org Website\", hiding the link itself and just displaying its
-description. When set to nil, Org will display the full links
-literally.
-
-You can interactively set the value of this variable by calling
-`org-toggle-link-display' or from the menu Org>Hyperlinks menu."
- :group 'org-link
- :type 'boolean)
-
-(defcustom org-link-file-path-type 'adaptive
- "How the path name in file links should be stored.
-Valid values are:
-
-relative Relative to the current directory, i.e. the directory of the file
- into which the link is being inserted.
-absolute Absolute path, if possible with ~ for home directory.
-noabbrev Absolute path, no abbreviation of home directory.
-adaptive Use relative path for files in the current directory and sub-
- directories of it. For other files, use an absolute path."
- :group 'org-link
- :type '(choice
- (const relative)
- (const absolute)
- (const noabbrev)
- (const adaptive)))
-
(defvaralias 'org-activate-links 'org-highlight-links)
(defcustom org-highlight-links '(bracket angle plain radio tag date footnote)
"Types of links that should be highlighted in Org files.
@@ -1942,7 +1770,6 @@ footnote Footnote labels.
If you set this variable during an Emacs session, use `org-mode-restart'
in the Org buffer so that the change takes effect."
- :group 'org-link
:group 'org-appearance
:type '(set :greedy t
(const :tag "Double bracket links" bracket)
@@ -1953,437 +1780,12 @@ in the Org buffer so that the change takes effect."
(const :tag "Timestamps" date)
(const :tag "Footnotes" footnote)))
-(defcustom org-make-link-description-function nil
- "Function to use for generating link descriptions from links.
-This function must take two parameters: the first one is the
-link, the second one is the description generated by
-`org-insert-link'. The function should return the description to
-use."
- :group 'org-link
- :type '(choice (const nil) (function)))
-
-(defgroup org-link-store nil
- "Options concerning storing links in Org mode."
- :tag "Org Store Link"
- :group 'org-link)
-
-(defcustom org-url-hexify-p t
- "When non-nil, hexify URL when creating a link."
- :type 'boolean
- :version "24.3"
- :group 'org-link-store)
-
-(defcustom org-email-link-description-format "Email %c: %.30s"
- "Format of the description part of a link to an email or usenet message.
-The following %-escapes will be replaced by corresponding information:
-
-%F full \"From\" field
-%f name, taken from \"From\" field, address if no name
-%T full \"To\" field
-%t first name in \"To\" field, address if no name
-%c correspondent. Usually \"from NAME\", but if you sent it yourself, it
- will be \"to NAME\". See also the variable `org-from-is-user-regexp'.
-%s subject
-%d date
-%m message-id.
-
-You may use normal field width specification between the % and the letter.
-This is for example useful to limit the length of the subject.
-
-Examples: \"%f on: %.30s\", \"Email from %f\", \"Email %c\""
- :group 'org-link-store
- :type 'string)
-
-(defcustom org-from-is-user-regexp
- (let (r1 r2)
- (when (and user-mail-address (not (string= user-mail-address "")))
- (setq r1 (concat "\\<" (regexp-quote user-mail-address) "\\>")))
- (when (and user-full-name (not (string= user-full-name "")))
- (setq r2 (concat "\\<" (regexp-quote user-full-name) "\\>")))
- (if (and r1 r2) (concat r1 "\\|" r2) (or r1 r2)))
- "Regexp matched against the \"From:\" header of an email or usenet message.
-It should match if the message is from the user him/herself."
- :group 'org-link-store
- :type 'regexp)
-
-(defcustom org-context-in-file-links t
- "Non-nil means file links from `org-store-link' contain context.
-\\<org-mode-map>
-A search string will be added to the file name with :: as separator
-and used to find the context when the link is activated by the command
-`org-open-at-point'. When this option is t, the entire active region
-will be placed in the search string of the file link. If set to a
-positive integer, only the first n lines of context will be stored.
-
-Using a prefix arg to the command `org-store-link' (`\\[universal-argument] \
-\\[org-store-link]')
-negates this setting for the duration of the command."
- :group 'org-link-store
- :type '(choice boolean integer))
-
-(defcustom org-keep-stored-link-after-insertion nil
- "Non-nil means keep link in list for entire session.
-\\<org-mode-map>
-The command `org-store-link' adds a link pointing to the current
-location to an internal list. These links accumulate during a session.
-The command `org-insert-link' can be used to insert links into any
-Org file (offering completion for all stored links).
-
-When this option is nil, every link which has been inserted once using
-`\\[org-insert-link]' will be removed from the list, to make completing the \
-unused
-links more efficient."
- :group 'org-link-store
- :type 'boolean)
-
-(defgroup org-link-follow nil
- "Options concerning following links in Org mode."
- :tag "Org Follow Link"
- :group 'org-link)
-
-(defcustom org-link-translation-function nil
- "Function to translate links with different syntax to Org syntax.
-This can be used to translate links created for example by the Planner
-or emacs-wiki packages to Org syntax.
-The function must accept two parameters, a TYPE containing the link
-protocol name like \"rmail\" or \"gnus\" as a string, and the linked path,
-which is everything after the link protocol. It should return a cons
-with possibly modified values of type and path.
-Org contains a function for this, so if you set this variable to
-`org-translate-link-from-planner', you should be able follow many
-links created by planner."
- :group 'org-link-follow
- :type '(choice (const nil) (function)))
-
-(defcustom org-follow-link-hook nil
- "Hook that is run after a link has been followed."
- :group 'org-link-follow
- :type 'hook)
-
-(defcustom org-tab-follows-link nil
- "Non-nil means on links TAB will follow the link.
-Needs to be set before org.el is loaded.
-This really should not be used, it does not make sense, and the
-implementation is bad."
- :group 'org-link-follow
- :type 'boolean)
-
-(defcustom org-return-follows-link nil
- "Non-nil means on links RET will follow the link.
-In tables, the special behavior of RET has precedence."
- :group 'org-link-follow
- :type 'boolean)
-
-(defcustom org-mouse-1-follows-link
- (if (boundp 'mouse-1-click-follows-link) mouse-1-click-follows-link t)
- "Non-nil means mouse-1 on a link will follow the link.
-A longer mouse click will still set point. Needs to be set
-before org.el is loaded."
- :group 'org-link-follow
- :version "26.1"
- :package-version '(Org . "8.3")
- :type '(choice
- (const :tag "A double click follows the link" double)
- (const :tag "Unconditionally follow the link with mouse-1" t)
- (integer :tag "mouse-1 click does not follow the link if longer than N ms" 450)))
-
(defcustom org-mark-ring-length 4
"Number of different positions to be recorded in the ring.
Changing this requires a restart of Emacs to work correctly."
:group 'org-link-follow
:type 'integer)
-(defcustom org-link-search-must-match-exact-headline 'query-to-create
- "Non-nil means internal fuzzy links can only match headlines.
-
-When nil, the a fuzzy link may point to a target or a named
-construct in the document. When set to the special value
-`query-to-create', offer to create a new headline when none
-matched.
-
-Spaces and statistics cookies are ignored during heading searches."
- :group 'org-link-follow
- :version "24.1"
- :type '(choice
- (const :tag "Use fuzzy text search" nil)
- (const :tag "Match only exact headline" t)
- (const :tag "Match exact headline or query to create it"
- query-to-create))
- :safe #'symbolp)
-
-(defcustom org-link-frame-setup
- '((vm . vm-visit-folder-other-frame)
- (vm-imap . vm-visit-imap-folder-other-frame)
- (gnus . org-gnus-no-new-news)
- (file . find-file-other-window)
- (wl . wl-other-frame))
- "Setup the frame configuration for following links.
-When following a link with Emacs, it may often be useful to display
-this link in another window or frame. This variable can be used to
-set this up for the different types of links.
-For VM, use any of
- `vm-visit-folder'
- `vm-visit-folder-other-window'
- `vm-visit-folder-other-frame'
-For Gnus, use any of
- `gnus'
- `gnus-other-frame'
- `org-gnus-no-new-news'
-For FILE, use any of
- `find-file'
- `find-file-other-window'
- `find-file-other-frame'
-For Wanderlust use any of
- `wl'
- `wl-other-frame'
-For the calendar, use the variable `calendar-setup'.
-For BBDB, it is currently only possible to display the matches in
-another window."
- :group 'org-link-follow
- :type '(list
- (cons (const vm)
- (choice
- (const vm-visit-folder)
- (const vm-visit-folder-other-window)
- (const vm-visit-folder-other-frame)))
- (cons (const vm-imap)
- (choice
- (const vm-visit-imap-folder)
- (const vm-visit-imap-folder-other-window)
- (const vm-visit-imap-folder-other-frame)))
- (cons (const gnus)
- (choice
- (const gnus)
- (const gnus-other-frame)
- (const org-gnus-no-new-news)))
- (cons (const file)
- (choice
- (const find-file)
- (const find-file-other-window)
- (const find-file-other-frame)))
- (cons (const wl)
- (choice
- (const wl)
- (const wl-other-frame)))))
-
-(defcustom org-display-internal-link-with-indirect-buffer nil
- "Non-nil means use indirect buffer to display infile links.
-Activating internal links (from one location in a file to another location
-in the same file) normally just jumps to the location. When the link is
-activated with a `\\[universal-argument]' prefix (or with mouse-3), the link \
-is displayed in
-another window. When this option is set, the other window actually displays
-an indirect buffer clone of the current buffer, to avoid any visibility
-changes to the current buffer."
- :group 'org-link-follow
- :type 'boolean)
-
-(defcustom org-open-non-existing-files nil
- "Non-nil means `org-open-file' will open non-existing files.
-When nil, an error will be generated.
-This variable applies only to external applications because they
-might choke on non-existing files. If the link is to a file that
-will be opened in Emacs, the variable is ignored."
- :group 'org-link-follow
- :type 'boolean)
-
-(defcustom org-open-directory-means-index-dot-org nil
- "Non-nil means a link to a directory really means to index.org.
-When nil, following a directory link will run dired or open a finder/explorer
-window on that directory."
- :group 'org-link-follow
- :type 'boolean)
-
-(defcustom org-confirm-shell-link-function 'yes-or-no-p
- "Non-nil means ask for confirmation before executing shell links.
-Shell links can be dangerous: just think about a link
-
- [[shell:rm -rf ~/*][Google Search]]
-
-This link would show up in your Org document as \"Google Search\",
-but really it would remove your entire home directory.
-Therefore we advise against setting this variable to nil.
-Just change it to `y-or-n-p' if you want to confirm with a
-single keystroke rather than having to type \"yes\"."
- :group 'org-link-follow
- :type '(choice
- (const :tag "with yes-or-no (safer)" yes-or-no-p)
- (const :tag "with y-or-n (faster)" y-or-n-p)
- (const :tag "no confirmation (dangerous)" nil)))
-(put 'org-confirm-shell-link-function
- 'safe-local-variable
- (lambda (x) (member x '(yes-or-no-p y-or-n-p))))
-
-(defcustom org-confirm-shell-link-not-regexp ""
- "A regexp to skip confirmation for shell links."
- :group 'org-link-follow
- :version "24.1"
- :type 'regexp)
-
-(defcustom org-confirm-elisp-link-function 'yes-or-no-p
- "Non-nil means ask for confirmation before executing Emacs Lisp links.
-Elisp links can be dangerous: just think about a link
-
- [[elisp:(shell-command \"rm -rf ~/*\")][Google Search]]
-
-This link would show up in your Org document as \"Google Search\",
-but really it would remove your entire home directory.
-Therefore we advise against setting this variable to nil.
-Just change it to `y-or-n-p' if you want to confirm with a
-single keystroke rather than having to type \"yes\"."
- :group 'org-link-follow
- :type '(choice
- (const :tag "with yes-or-no (safer)" yes-or-no-p)
- (const :tag "with y-or-n (faster)" y-or-n-p)
- (const :tag "no confirmation (dangerous)" nil)))
-(put 'org-confirm-shell-link-function
- 'safe-local-variable
- (lambda (x) (member x '(yes-or-no-p y-or-n-p))))
-
-(defcustom org-confirm-elisp-link-not-regexp ""
- "A regexp to skip confirmation for Elisp links."
- :group 'org-link-follow
- :version "24.1"
- :type 'regexp)
-
-(defconst org-file-apps-defaults-gnu
- '((remote . emacs)
- (system . mailcap)
- (t . mailcap))
- "Default file applications on a UNIX or GNU/Linux system.
-See `org-file-apps'.")
-
-(defconst org-file-apps-defaults-macosx
- '((remote . emacs)
- (system . "open %s")
- ("ps.gz" . "gv %s")
- ("eps.gz" . "gv %s")
- ("dvi" . "xdvi %s")
- ("fig" . "xfig %s")
- (t . "open %s"))
- "Default file applications on a macOS system.
-The system \"open\" is known as a default, but we use X11 applications
-for some files for which the OS does not have a good default.
-See `org-file-apps'.")
-
-(defconst org-file-apps-defaults-windowsnt
- (list '(remote . emacs)
- (cons 'system (lambda (file _path)
- (with-no-warnings (w32-shell-execute "open" file))))
- (cons t (lambda (file _path)
- (with-no-warnings (w32-shell-execute "open" file)))))
- "Default file applications on a Windows NT system.
-The system \"open\" is used for most files.
-See `org-file-apps'.")
-
-(defcustom org-file-apps
- '((auto-mode . emacs)
- ("\\.mm\\'" . default)
- ("\\.x?html?\\'" . default)
- ("\\.pdf\\'" . default))
- "External applications for opening `file:path' items in a document.
-\\<org-mode-map>
-Org mode uses system defaults for different file types, but
-you can use this variable to set the application for a given file
-extension. The entries in this list are cons cells where the car identifies
-files and the cdr the corresponding command.
-
-Possible values for the file identifier are:
-
- \"string\" A string as a file identifier can be interpreted in different
- ways, depending on its contents:
-
- - Alphanumeric characters only:
- Match links with this file extension.
- Example: (\"pdf\" . \"evince %s\")
- to open PDFs with evince.
-
- - Regular expression: Match links where the
- filename matches the regexp. If you want to
- use groups here, use shy groups.
-
- Example: (\"\\\\.x?html\\\\\\='\" . \"firefox %s\")
- (\"\\\\(?:xhtml\\\\|html\\\\)\\\\\\='\" . \"firefox %s\")
- to open *.html and *.xhtml with firefox.
-
- - Regular expression which contains (non-shy) groups:
- Match links where the whole link, including \"::\", and
- anything after that, matches the regexp.
- In a custom command string, %1, %2, etc. are replaced with
- the parts of the link that were matched by the groups.
- For backwards compatibility, if a command string is given
- that does not use any of the group matches, this case is
- handled identically to the second one (i.e. match against
- file name only).
- In a custom function, you can access the group matches with
- (match-string n link).
-
- Example: (\"\\\\.pdf::\\\\([0-9]+\\\\)\\\\\\='\" . \
-\"evince -p %1 %s\")
- to open [[file:document.pdf::5]] with evince at page 5.
-
- `directory' Matches a directory
- `remote' Matches a remote file, accessible through tramp or efs.
- Remote files most likely should be visited through Emacs
- because external applications cannot handle such paths.
-`auto-mode' Matches files that are matched by any entry in `auto-mode-alist',
- so all files Emacs knows how to handle. Using this with
- command `emacs' will open most files in Emacs. Beware that this
- will also open html files inside Emacs, unless you add
- (\"html\" . default) to the list as well.
- `system' The system command to open files, like `open' on Windows
- and macOS, and mailcap under GNU/Linux. This is the command
- that will be selected if you call `org-open-at-point' with a
- double prefix argument (`\\[universal-argument] \
-\\[universal-argument] \\[org-open-at-point]').
- t Default for files not matched by any of the other options.
-
-Possible values for the command are:
-
- `emacs' The file will be visited by the current Emacs process.
- `default' Use the default application for this file type, which is the
- association for t in the list, most likely in the system-specific
- part. This can be used to overrule an unwanted setting in the
- system-specific variable.
- `system' Use the system command for opening files, like \"open\".
- This command is specified by the entry whose car is `system'.
- Most likely, the system-specific version of this variable
- does define this command, but you can overrule/replace it
- here.
-`mailcap' Use command specified in the mailcaps.
- string A command to be executed by a shell; %s will be replaced
- by the path to the file.
- function A Lisp function, which will be called with two arguments:
- the file path and the original link string, without the
- \"file:\" prefix.
-
-For more examples, see the system specific constants
-`org-file-apps-defaults-macosx'
-`org-file-apps-defaults-windowsnt'
-`org-file-apps-defaults-gnu'."
- :group 'org-link-follow
- :type '(repeat
- (cons (choice :value ""
- (string :tag "Extension")
- (const :tag "System command to open files" system)
- (const :tag "Default for unrecognized files" t)
- (const :tag "Remote file" remote)
- (const :tag "Links to a directory" directory)
- (const :tag "Any files that have Emacs modes"
- auto-mode))
- (choice :value ""
- (const :tag "Visit with Emacs" emacs)
- (const :tag "Use default" default)
- (const :tag "Use the system command" system)
- (string :tag "Command")
- (function :tag "Function")))))
-
-(defcustom org-doi-server-url "http://dx.doi.org/"
- "The URL of the DOI server."
- :type 'string
- :version "24.3"
- :group 'org-link-follow)
-
(defgroup org-refile nil
"Options concerning refiling entries in Org mode."
:tag "Org Refile"
@@ -2706,31 +2108,35 @@ more information."
:type '(choice (const sequence)
(const type)))
-(defcustom org-use-fast-todo-selection t
+(defcustom org-use-fast-todo-selection 'auto
"\\<org-mode-map>\
Non-nil means use the fast todo selection scheme with `\\[org-todo]'.
This variable describes if and under what circumstances the cycling
mechanism for TODO keywords will be replaced by a single-key, direct
-selection scheme.
+selection scheme, where the choices are displayed in a little window.
-When nil, fast selection is never used.
+When nil, fast selection is never used. This means that the command
+will always switch to the next state.
-When the symbol `prefix', it will be used when `org-todo' is called
-with a prefix argument, i.e. `\\[universal-argument] \\[org-todo]' \
-in an Org buffer, and
-`\\[universal-argument] t' in an agenda buffer.
+When it is the symbol `auto', fast selection is whenever selection
+keys have been defined.
-When t, fast selection is used by default. In this case, the prefix
-argument forces cycling instead.
+`expert' is like `auto', but no special window with the keyword
+will be shown, choices will only be listed in the prompt.
In all cases, the special interface is only used if access keys have
actually been assigned by the user, i.e. if keywords in the configuration
are followed by a letter in parenthesis, like TODO(t)."
:group 'org-todo
+ :set (lambda (var val)
+ (cond
+ ((eq var t) (set var 'auto))
+ ((eq var 'prefix) (set var nil))
+ (t (set var val))))
:type '(choice
(const :tag "Never" nil)
- (const :tag "By default" t)
- (const :tag "Only with C-u C-c C-t" prefix)))
+ (const :tag "Automatically, when key letter have been defined" auto)
+ (const :tag "Automatically, but don't show the selection window" expert)))
(defcustom org-provide-todo-statistics t
"Non-nil means update todo statistics after insert and toggle.
@@ -3379,7 +2785,7 @@ When nil, only the minibuffer will be available."
(defcustom org-extend-today-until 0
"The hour when your day really ends. Must be an integer.
This has influence for the following applications:
-- When switching the agenda to \"today\". It it is still earlier than
+- When switching the agenda to \"today\". If it is still earlier than
the time given here, the day recognized as TODAY is actually yesterday.
- When a date is read from the user and it is still before the time given
here, the current date and time will be assumed to be yesterday, 23:59.
@@ -3700,7 +3106,7 @@ and the properties ending in \"_ALL\" when they are used as descriptor
for valid values of a property.
Note for programmers:
-When querying an entry with `org-entry-get', you can control if inheritance
+When querying an entry with `org-entry-get', you can control if inheritance
should be used. By default, `org-entry-get' looks only at the local
properties. You can request inheritance by setting the inherit argument
to t (to force inheritance) or to `selective' (to respect the setting
@@ -3731,6 +3137,18 @@ This variable can be set on the per-file basis by inserting a line
:group 'org-properties
:type 'string)
+(defcustom org-columns-default-format-for-agenda nil
+ "The default column format in an agenda buffer.
+This will be used for column view in the agenda unless a format has
+been set by adding `org-overriding-columns-format' to the local
+settings list of a custom agenda view. When nil, the columns format
+for the first item in the agenda list will be used, or as a fall-back,
+`org-columns-default-format'."
+ :group 'org-properties
+ :type '(choice
+ (const :tag "No default" nil)
+ (string :tag "Format string")))
+
(defcustom org-columns-ellipses ".."
"The ellipses to be used when a field in column view is truncated.
When this is the empty string, as many characters as possible are shown,
@@ -3949,12 +3367,11 @@ All available processes and theirs documents can be found in
:image-output-type "png"
:image-size-adjust (1.0 . 1.0)
:latex-compiler ("latex -interaction nonstopmode -output-directory %o %f")
- :image-converter ("dvipng -fg %F -bg %B -D %D -T tight -o %O %f"))
+ :image-converter ("dvipng -D %D -T tight -o %O %f"))
(dvisvgm
:programs ("latex" "dvisvgm")
:description "dvi > svg"
:message "you need to install the programs: latex and dvisvgm."
- :use-xcolor t
:image-input-type "dvi"
:image-output-type "svg"
:image-size-adjust (1.7 . 1.5)
@@ -3964,7 +3381,6 @@ All available processes and theirs documents can be found in
:programs ("latex" "convert")
:description "pdf > png"
:message "you need to install the programs: latex and imagemagick."
- :use-xcolor t
:image-input-type "pdf"
:image-output-type "png"
:image-size-adjust (1.0 . 1.0)
@@ -3984,11 +3400,6 @@ PROPERTIES accepts the following attributes:
:message string, message it when required programs cannot be found.
:image-input-type string, input file type of image converter (e.g., \"dvi\").
:image-output-type string, output file type of image converter (e.g., \"png\").
- :use-xcolor boolean, when non-nil, LaTeX \"xcolor\" macro is used to
- deal with background and foreground color of image.
- Otherwise, dvipng style background and foreground color
- format are generated. You may then refer to them in
- command options with \"%F\" and \"%B\".
:image-size-adjust cons of numbers, the car element is used to adjust LaTeX
image size showed in buffer and the cdr element is for
HTML file. This option is only useful for process
@@ -4020,8 +3431,6 @@ Place-holders used by `:image-converter' and `:latex-compiler':
Place-holders only used by `:image-converter':
- %F foreground of image
- %B background of image
%D dpi, which is used to adjust image size by some processing commands.
%S the image size scale ratio, which is used to adjust image size by some
processing commands."
@@ -4279,10 +3688,18 @@ org-level-* faces."
:group 'org-appearance
:type 'boolean)
+(defcustom org-fontify-whole-block-delimiter-line t
+ "Non-nil means fontify the whole line for begin/end lines of blocks.
+This is useful when setting a background color for the
+org-block-begin-line and org-block-end-line faces."
+ :group 'org-appearance
+ :type 'boolean)
+
(defcustom org-highlight-latex-and-related nil
"Non-nil means highlight LaTeX related syntax in the buffer.
-When non nil, the value should be a list containing any of the
+When non-nil, the value should be a list containing any of the
following symbols:
+ `native' Highlight LaTeX snippets and environments natively.
`latex' Highlight LaTeX snippets and environments.
`script' Highlight subscript and superscript.
`entities' Highlight entities."
@@ -4292,6 +3709,7 @@ following symbols:
:type '(choice
(const :tag "No highlighting" nil)
(set :greedy t :tag "Highlight"
+ (const :tag "LaTeX snippets and environments (native)" native)
(const :tag "LaTeX snippets and environments" latex)
(const :tag "Subscript and superscript" script)
(const :tag "Entities" entities))))
@@ -4442,14 +3860,15 @@ This is needed for font-lock setup.")
(beg end))
(declare-function org-agenda-set-restriction-lock "org-agenda" (&optional type))
(declare-function org-agenda-skip "org-agenda" ())
-(declare-function org-attach-reveal "org-attach" (&optional if-exists))
+(declare-function org-attach-expand "org-attach" (file))
+(declare-function org-attach-reveal "org-attach" ())
+(declare-function org-attach-reveal-in-emacs "org-attach" ())
(declare-function org-gnus-follow-link "org-gnus" (&optional group article))
(declare-function org-indent-mode "org-indent" (&optional arg))
(declare-function org-inlinetask-goto-beginning "org-inlinetask" ())
(declare-function org-inlinetask-goto-end "org-inlinetask" ())
(declare-function org-inlinetask-in-task-p "org-inlinetask" ())
(declare-function org-inlinetask-remove-END-maybe "org-inlinetask" ())
-(declare-function orgtbl-send-table "org-table" (&optional maybe))
(declare-function parse-time-string "parse-time" (string))
(defvar align-mode-rules-list)
@@ -4462,64 +3881,11 @@ This is needed for font-lock setup.")
(defvar remember-data-file)
(defvar texmathp-why)
-;;;###autoload
-(defun turn-on-orgtbl ()
- "Unconditionally turn on `orgtbl-mode'."
- (require 'org-table)
- (orgtbl-mode 1))
-
-(defun org-at-table-p (&optional table-type)
- "Non-nil if the cursor is inside an Org table.
-If TABLE-TYPE is non-nil, also check for table.el-type tables."
- (and (org-match-line (if table-type "[ \t]*[|+]" "[ \t]*|"))
- (or (not (derived-mode-p 'org-mode))
- (let ((e (org-element-lineage (org-element-at-point) '(table) t)))
- (and e (or table-type
- (eq 'org (org-element-property :type e))))))))
-
-(defun org-at-table.el-p ()
- "Non-nil when point is at a table.el table."
- (and (org-match-line "[ \t]*[|+]")
- (let ((element (org-element-at-point)))
- (and (eq (org-element-type element) 'table)
- (eq (org-element-property :type element) 'table.el)))))
-
-(defun org-at-table-hline-p ()
- "Non-nil when point is inside a hline in a table.
-Assume point is already in a table."
- (org-match-line org-table-hline-regexp))
-
-(defun org-table-map-tables (function &optional quietly)
- "Apply FUNCTION to the start of all tables in the buffer."
- (org-with-wide-buffer
- (goto-char (point-min))
- (while (re-search-forward org-table-any-line-regexp nil t)
- (unless quietly
- (message "Mapping tables: %d%%"
- (floor (* 100.0 (point)) (buffer-size))))
- (beginning-of-line 1)
- (when (and (looking-at org-table-line-regexp)
- ;; Exclude tables in src/example/verbatim/clocktable blocks
- (not (org-in-block-p '("src" "example" "verbatim" "clocktable"))))
- (save-excursion (funcall function))
- (or (looking-at org-table-line-regexp)
- (forward-char 1)))
- (re-search-forward org-table-any-border-regexp nil 1)))
- (unless quietly (message "Mapping tables: done")))
-
(declare-function org-clock-save-markers-for-cut-and-paste "org-clock" (beg end))
(declare-function org-clock-update-mode-line "org-clock" (&optional refresh))
(declare-function org-resolve-clocks "org-clock"
(&optional also-non-dangling-p prompt last-valid))
-(defun org-at-TBLFM-p (&optional pos)
- "Non-nil when point (or POS) is in #+TBLFM line."
- (save-excursion
- (goto-char (or pos (point)))
- (beginning-of-line)
- (and (let ((case-fold-search t)) (looking-at org-TBLFM-regexp))
- (eq (org-element-type (org-element-at-point)) 'table))))
-
(defvar org-clock-start-time)
(defvar org-clock-marker (make-marker)
"Marker recording the last clock-in.")
@@ -5406,12 +4772,6 @@ This is for getting out of special buffers like capture.")
;;;; Define the Org mode
-;; We use a before-change function to check if a table might need
-;; an update.
-(defvar org-table-may-need-update t
- "Indicates that a table might need an update.
-This variable is set by `org-before-change-function'.
-`org-table-align' sets it back to nil.")
(defun org-before-change-function (_beg _end)
"Every change indicates that a table might need an update."
(setq org-table-may-need-update t))
@@ -5420,7 +4780,6 @@ This variable is set by `org-before-change-function'.
(defvar org-agenda-keep-modes nil) ; Dynamically-scoped param.
(defvar org-inhibit-logging nil) ; Dynamically-scoped param.
(defvar org-inhibit-blocking nil) ; Dynamically-scoped param.
-(defvar org-table-buffer-is-an nil)
(defvar bidi-paragraph-direction)
(defvar buffer-face-mode-face)
@@ -5466,18 +4825,9 @@ can be exported as a structured ASCII or HTML file.
The following commands are available:
\\{org-mode-map}"
-
- ;; Get rid of Outline menus, they are not needed
- ;; Need to do this here because define-derived-mode sets up
- ;; the keymap so late. Still, it is a waste to call this each time
- ;; we switch another buffer into Org mode.
- (define-key org-mode-map [menu-bar headings] 'undefined)
- (define-key org-mode-map [menu-bar hide] 'undefined)
- (define-key org-mode-map [menu-bar show] 'undefined)
-
(org-load-modules-maybe)
(org-install-agenda-files-menu)
- (when org-descriptive-links (add-to-invisibility-spec '(org-link)))
+ (when org-link-descriptive (add-to-invisibility-spec '(org-link)))
(add-to-invisibility-spec '(org-hide-block . t))
(add-to-invisibility-spec '(org-hide-drawer . t))
(setq-local outline-regexp org-outline-regexp)
@@ -5560,11 +4910,13 @@ The following commands are available:
(lambda (&rest _) (org-show-context 'isearch)))
;; Setup the pcomplete hooks
- (setq-local pcomplete-command-completion-function 'org-pcomplete-initial)
- (setq-local pcomplete-command-name-function 'org-command-at-point)
- (setq-local pcomplete-default-completion-function 'ignore)
- (setq-local pcomplete-parse-arguments-function 'org-parse-arguments)
+ (setq-local pcomplete-command-completion-function #'org-pcomplete-initial)
+ (setq-local pcomplete-command-name-function #'org-command-at-point)
+ (setq-local pcomplete-default-completion-function #'ignore)
+ (setq-local pcomplete-parse-arguments-function #'org-parse-arguments)
(setq-local pcomplete-termination-string "")
+ (add-hook 'completion-at-point-functions
+ #'pcomplete-completions-at-point nil t)
(setq-local buffer-face-mode-face 'org-default)
;; If empty file that did not turn on Org mode automatically, make
@@ -5585,11 +4937,10 @@ The following commands are available:
(t #'org-table-shrink))
t))
(when org-startup-with-inline-images (org-display-inline-images))
- (when org-startup-with-latex-preview (org-toggle-latex-fragment '(16)))
+ (when org-startup-with-latex-preview (org-latex-preview '(16)))
(unless org-inhibit-startup-visibility-stuff (org-set-startup-visibility))
(when org-startup-truncated (setq truncate-lines t))
- (when org-startup-indented (require 'org-indent) (org-indent-mode 1))
- (org-refresh-effort-properties)))
+ (when org-startup-indented (require 'org-indent) (org-indent-mode 1))))
;; Try to set `org-hide' face correctly.
(let ((foreground (org-find-invisible-foreground)))
(when foreground
@@ -5653,45 +5004,8 @@ the rounding returns a past time."
;;;; Font-Lock stuff, including the activators
-(defvar org-mouse-map (make-sparse-keymap))
-(org-defkey org-mouse-map [mouse-2] 'org-open-at-mouse)
-(org-defkey org-mouse-map [mouse-3] 'org-find-file-at-mouse)
-(when org-mouse-1-follows-link
- (org-defkey org-mouse-map [follow-link] 'mouse-face))
-(when org-tab-follows-link
- (org-defkey org-mouse-map (kbd "<tab>") #'org-open-at-point)
- (org-defkey org-mouse-map (kbd "TAB") #'org-open-at-point))
-
(require 'font-lock)
-(defconst org-non-link-chars "]\t\n\r<>")
-(defvar org-link-types-re nil
- "Matches a link that has a url-like prefix like \"http:\"")
-(defvar org-link-re-with-space nil
- "Matches a link with spaces, optional angular brackets around it.")
-(defvar org-link-re-with-space2 nil
- "Matches a link with spaces, optional angular brackets around it.")
-(defvar org-link-re-with-space3 nil
- "Matches a link with spaces, only for internal part in bracket links.")
-(defvar org-angle-link-re nil
- "Matches link with angular brackets, spaces are allowed.")
-(defvar org-plain-link-re nil
- "Matches plain link, without spaces.")
-(defvar org-bracket-link-regexp nil
- "Matches a link in double brackets.")
-(defvar org-bracket-link-analytic-regexp nil
- "Regular expression used to analyze links.
-Here is what the match groups contain after a match:
-1: http:
-2: http
-3: path
-4: [desc]
-5: desc")
-(defvar org-bracket-link-analytic-regexp++ nil
- "Like `org-bracket-link-analytic-regexp', but include coderef internal type.")
-(defvar org-any-link-re nil
- "Regular expression matching any link.")
-
(defconst org-match-sexp-depth 3
"Number of stacked braces for sub/superscript matching.")
@@ -5729,59 +5043,6 @@ stacked delimiters is N. Escaping delimiters is not possible."
"\\(" (org-create-multibrace-regexp "{" "}" org-match-sexp-depth) "\\)")
"The regular expression matching a sub- or superscript, forcing braces.")
-(defun org-make-link-regexps ()
- "Update the link regular expressions.
-This should be called after the variable `org-link-parameters' has changed."
- (let ((types-re (regexp-opt (org-link-types) t)))
- (setq org-link-types-re
- (concat "\\`" types-re ":")
- org-link-re-with-space
- (concat "<?" types-re ":"
- "\\([^" org-non-link-chars " ]"
- "[^" org-non-link-chars "]*"
- "[^" org-non-link-chars " ]\\)>?")
- org-link-re-with-space2
- (concat "<?" types-re ":"
- "\\([^" org-non-link-chars " ]"
- "[^\t\n\r]*"
- "[^" org-non-link-chars " ]\\)>?")
- org-link-re-with-space3
- (concat "<?" types-re ":"
- "\\([^" org-non-link-chars " ]"
- "[^\t\n\r]*\\)")
- org-angle-link-re
- (format "<%s:\\([^>\n]*\\(?:\n[ \t]*[^> \t\n][^>\n]*\\)*\\)>"
- types-re)
- org-plain-link-re
- (concat
- "\\<" types-re ":"
- "\\([^][ \t\n()<>]+\\(?:([[:word:]0-9_]+)\\|\\([^[:punct:] \t\n]\\|/\\)\\)\\)")
- ;; "\\([^]\t\n\r<>() ]+[^]\t\n\r<>,.;() ]\\)")
- org-bracket-link-regexp
- "\\[\\[\\([^][]+\\)\\]\\(\\[\\([^][]+\\)\\]\\)?\\]"
- org-bracket-link-analytic-regexp
- (concat
- "\\[\\["
- "\\(" types-re ":\\)?"
- "\\([^]]+\\)"
- "\\]"
- "\\(\\[" "\\([^]]+\\)" "\\]\\)?"
- "\\]")
- org-bracket-link-analytic-regexp++
- (concat
- "\\[\\["
- "\\(" (regexp-opt (cons "coderef" (org-link-types)) t) ":\\)?"
- "\\([^]]+\\)"
- "\\]"
- "\\(\\[" "\\([^]]+\\)" "\\]\\)?"
- "\\]")
- org-any-link-re
- (concat "\\(" org-bracket-link-regexp "\\)\\|\\("
- org-angle-link-re "\\)\\|\\("
- org-plain-link-re "\\)"))))
-
-(org-make-link-regexps)
-
(defvar org-emph-face nil)
(defun org-do-emphasis-faces (limit)
@@ -5887,13 +5148,18 @@ prompted for."
"Add link properties to links.
This includes angle, plain, and bracket links."
(catch :exit
- (while (re-search-forward org-any-link-re limit t)
+ (while (re-search-forward org-link-any-re limit t)
(let* ((start (match-beginning 0))
(end (match-end 0))
+ (visible-start (or (match-beginning 3) (match-beginning 2)))
+ (visible-end (or (match-end 3) (match-end 2)))
(style (cond ((eq ?< (char-after start)) 'angle)
((eq ?\[ (char-after (1+ start))) 'bracket)
(t 'plain))))
(when (and (memq style org-highlight-links)
+ ;; Do not span over paragraph boundaries.
+ (not (string-match-p org-element-paragraph-separate
+ (match-string 0)))
;; Do not confuse plain links with tags.
(not (and (eq style 'plain)
(let ((face (get-text-property
@@ -5936,9 +5202,7 @@ This includes angle, plain, and bracket links."
(append `(invisible
,(or (org-link-get-parameter type :display)
'org-link))
- properties))
- (visible-start (or (match-beginning 4) (match-beginning 2)))
- (visible-end (or (match-end 4) (match-end 2))))
+ properties)))
(add-text-properties start visible-start hidden)
(add-text-properties visible-start visible-end properties)
(add-text-properties visible-end end hidden)
@@ -5988,57 +5252,64 @@ by a #."
"^\\([ \t]*#\\(\\(\\+[a-zA-Z]+:?\\| \\|$\\)\\(_\\([a-zA-Z]+\\)\\)?\\)[ \t]*\\(\\([^ \t\n]*\\)[ \t]*\\(.*\\)\\)\\)"
limit t)
(let ((beg (match-beginning 0))
- (block-start (match-end 0))
- (block-end nil)
- (lang (match-string 7))
- (beg1 (line-beginning-position 2))
+ (end-of-beginline (match-end 0))
+ (block-start (match-end 0)) ; includes the \n at end of #+begin line
+ (block-end nil) ; will include \n after end of block content
+ (lang (match-string 7)) ; the language, if it is an src block
+ (bol-after-beginline (line-beginning-position 2))
(dc1 (downcase (match-string 2)))
(dc3 (downcase (match-string 3)))
- end end1 quoting block-type)
+ (whole-blockline org-fontify-whole-block-delimiter-line)
+ beg-of-endline end-of-endline nl-before-endline quoting block-type)
(cond
((and (match-end 4) (equal dc3 "+begin"))
;; Truly a block
(setq block-type (downcase (match-string 5))
- quoting (member block-type org-protecting-blocks))
+ quoting (member block-type org-protecting-blocks)) ; src, example, export, maybe more
(when (re-search-forward
(concat "^[ \t]*#\\+end" (match-string 4) "\\>.*")
nil t) ;; on purpose, we look further than LIMIT
- (setq end (min (point-max) (match-end 0))
- end1 (min (point-max) (1- (match-beginning 0))))
- (setq block-end (match-beginning 0))
+ ;; We do have a matching #+end line
+ (setq beg-of-endline (match-beginning 0)
+ end-of-endline (match-end 0)
+ nl-before-endline (1- (match-beginning 0)))
+ (setq block-end (match-beginning 0)) ; includes the final newline.
(when quoting
- (org-remove-flyspell-overlays-in beg1 end1)
- (remove-text-properties beg end
+ (org-remove-flyspell-overlays-in bol-after-beginline nl-before-endline)
+ (remove-text-properties beg end-of-endline
'(display t invisible t intangible t)))
(add-text-properties
- beg end '(font-lock-fontified t font-lock-multiline t))
- (add-text-properties beg beg1 '(face org-meta-line))
- (org-remove-flyspell-overlays-in beg beg1)
- (add-text-properties ; For end_src
- end1 (min (point-max) (1+ end)) '(face org-meta-line))
- (org-remove-flyspell-overlays-in end1 end)
+ beg end-of-endline '(font-lock-fontified t font-lock-multiline t))
+ (org-remove-flyspell-overlays-in beg bol-after-beginline)
+ (org-remove-flyspell-overlays-in nl-before-endline end-of-endline)
(cond
((and lang (not (string= lang "")) org-src-fontify-natively)
(org-src-font-lock-fontify-block lang block-start block-end)
- (add-text-properties beg1 block-end '(src-block t)))
+ (add-text-properties bol-after-beginline block-end '(src-block t)))
(quoting
- (add-text-properties beg1 (min (point-max) (1+ end1))
- (list 'face
- (list :inherit
- (let ((face-name
- (intern (format "org-block-%s" lang))))
- (append (and (facep face-name) (list face-name))
- '(org-block))))))) ; end of source block
+ (add-text-properties
+ bol-after-beginline beg-of-endline
+ (list 'face
+ (list :inherit
+ (let ((face-name
+ (intern (format "org-block-%s" lang))))
+ (append (and (facep face-name) (list face-name))
+ '(org-block)))))))
((not org-fontify-quote-and-verse-blocks))
((string= block-type "quote")
(add-face-text-property
- beg1 (min (point-max) (1+ end1)) 'org-quote t))
+ bol-after-beginline beg-of-endline 'org-quote t))
((string= block-type "verse")
(add-face-text-property
- beg1 (min (point-max) (1+ end1)) 'org-verse t)))
- (add-text-properties beg beg1 '(face org-block-begin-line))
- (add-text-properties (min (point-max) (1+ end)) (min (point-max) (1+ end1))
- '(face org-block-end-line))
+ bol-after-beginline beg-of-endline 'org-verse t)))
+ ;; Fontify the #+begin and #+end lines of the blocks
+ (add-text-properties
+ beg (if whole-blockline bol-after-beginline end-of-beginline)
+ '(face org-block-begin-line))
+ (add-text-properties
+ beg-of-endline
+ (min (point-max) (if whole-blockline (min (point-max) (1+ end-of-endline)) end-of-endline))
+ '(face org-block-end-line))
t))
((member dc1 '("+title:" "+author:" "+email:" "+date:"))
(org-remove-flyspell-overlays-in
@@ -6068,6 +5339,7 @@ by a #."
'(font-lock-fontified t face org-block))
t)
((member dc3 '(" " ""))
+ ; Just a comment, the plus was not there
(org-remove-flyspell-overlays-in beg (match-end 0))
(add-text-properties
beg (match-end 0)
@@ -6084,9 +5356,10 @@ by a #."
"Fontify drawers."
(when (re-search-forward org-drawer-regexp limit t)
(add-text-properties
- (match-beginning 0) (match-end 0)
- '(font-lock-fontified t face org-special-keyword))
- (org-remove-flyspell-overlays-in (match-beginning 0) (match-end 0))
+ (line-beginning-position) (line-beginning-position 2)
+ '(font-lock-fontified t face org-drawer))
+ (org-remove-flyspell-overlays-in
+ (line-beginning-position) (line-beginning-position 2))
t))
(defun org-fontify-macros (limit)
@@ -6107,6 +5380,24 @@ by a #."
(add-text-properties closing-start end '(invisible t)))
t)))))
+(defun org-fontify-extend-region (beg end _old-len)
+ (let ((begin-re "\\(\\\\\\[\\|\\(#\\+begin_\\|\\\\begin{\\)\\S-+\\)")
+ (end-re "\\(\\\\\\]\\|\\(#\\+end_\\|\\\\end{\\)\\S-+\\)")
+ (extend (lambda (r1 r2 dir)
+ (let ((re (replace-regexp-in-string "\\(begin\\|end\\)" r1
+ (replace-regexp-in-string "[][]" r2
+ (match-string-no-properties 0)))))
+ (re-search-forward (regexp-quote re) nil t dir)))))
+ (save-match-data
+ (save-excursion
+ (goto-char beg)
+ (back-to-indentation)
+ (cond ((looking-at end-re)
+ (cons (or (funcall extend "begin" "[" -1) beg) end))
+ ((looking-at begin-re)
+ (cons beg (or (funcall extend "end" "]" 1) end)))
+ (t (cons beg end)))))))
+
(defun org-activate-footnote-links (limit)
"Add text properties for footnotes."
(let ((fn (org-footnote-next-reference-or-definition limit)))
@@ -6146,21 +5437,6 @@ by a #."
(org-display-custom-time (match-beginning 1) (match-end 1)))
t))
-(defvar-local org-target-link-regexp nil
- "Regular expression matching radio targets in plain text.")
-
-(defconst org-target-regexp (let ((border "[^<>\n\r \t]"))
- (format "<<\\(%s\\|%s[^<>\n\r]*%s\\)>>"
- border border border))
- "Regular expression matching a link target.")
-
-(defconst org-radio-target-regexp (format "<%s>" org-target-regexp)
- "Regular expression matching a radio target.")
-
-(defconst org-any-target-regexp
- (format "%s\\|%s" org-radio-target-regexp org-target-regexp)
- "Regular expression matching any target.")
-
(defun org-activate-target-links (limit)
"Add text properties for target matches."
(when org-target-link-regexp
@@ -6178,59 +5454,6 @@ by a #."
(org-rear-nonsticky-at (match-end 1))
t))))
-(defun org-update-radio-target-regexp ()
- "Find all radio targets in this file and update the regular expression.
-Also refresh fontification if needed."
- (interactive)
- (let ((old-regexp org-target-link-regexp)
- ;; Some languages, e.g., Chinese, do not use spaces to
- ;; separate words. Also allow to surround radio targets with
- ;; line-breakable characters.
- (before-re "\\(?:^\\|[^[:alnum:]]\\|\\c|\\)\\(")
- (after-re "\\)\\(?:$\\|[^[:alnum:]]\\|\\c|\\)")
- (targets
- (org-with-wide-buffer
- (goto-char (point-min))
- (let (rtn)
- (while (re-search-forward org-radio-target-regexp nil t)
- ;; Make sure point is really within the object.
- (backward-char)
- (let ((obj (org-element-context)))
- (when (eq (org-element-type obj) 'radio-target)
- (cl-pushnew (org-element-property :value obj) rtn
- :test #'equal))))
- rtn))))
- (setq org-target-link-regexp
- (and targets
- (concat before-re
- (mapconcat
- (lambda (x)
- (replace-regexp-in-string
- " +" "\\s-+" (regexp-quote x) t t))
- targets
- "\\|")
- after-re)))
- (unless (equal old-regexp org-target-link-regexp)
- ;; Clean-up cache.
- (let ((regexp (cond ((not old-regexp) org-target-link-regexp)
- ((not org-target-link-regexp) old-regexp)
- (t
- (concat before-re
- (mapconcat
- (lambda (re)
- (substring re (length before-re)
- (- (length after-re))))
- (list old-regexp org-target-link-regexp)
- "\\|")
- after-re)))))
- (org-with-wide-buffer
- (goto-char (point-min))
- (while (re-search-forward regexp nil t)
- (org-element-cache-refresh (match-beginning 1)))))
- ;; Re fontify buffer.
- (when (memq 'radio org-highlight-links)
- (org-restart-font-lock)))))
-
(defvar org-latex-and-related-regexp nil
"Regular expression for highlighting LaTeX, entities and sub/superscript.")
@@ -6243,17 +5466,13 @@ Result depends on variable `org-highlight-latex-and-related'."
(list org-match-substring-with-braces-regexp))
(org-use-sub-superscripts (list org-match-substring-regexp))))
(re-latex
- (when (memq 'latex org-highlight-latex-and-related)
- (let* ((matchers (plist-get org-format-latex-options :matchers))
- (regexps (and (member "begin" matchers)
- '("\\\\end{[a-zA-Z0-9\\*]+}[ \t]*$"))))
- (dolist (matcher matchers)
- (pcase (assoc matcher org-latex-regexps)
- (`("begin" . ,_) (push "^[ \t]*\\\\begin{[a-zA-Z0-9\\*]+}"
- regexps))
- (`(,_ ,regexp . ,_) (push regexp regexps))
- (_ nil)))
- (nreverse regexps))))
+ (when (or (memq 'latex org-highlight-latex-and-related)
+ (memq 'native org-highlight-latex-and-related))
+ (let ((matchers (plist-get org-format-latex-options :matchers)))
+ (delq nil
+ (mapcar (lambda (x)
+ (and (member (car x) matchers) (nth 1 x)))
+ org-latex-regexps)))))
(re-entities
(when (memq 'entities org-highlight-latex-and-related)
(list "\\\\\\(there4\\|sup[123]\\|frac[13][24]\\|[a-zA-Z]+\\)\
@@ -6263,46 +5482,31 @@ Result depends on variable `org-highlight-latex-and-related'."
(append re-latex re-entities re-sub)
"\\|"))))
-(defun org-do-latex-and-related (limit)
+(defun org-do-latex-and-related (_limit)
"Highlight LaTeX snippets and environments, entities and sub/superscript.
-LIMIT bounds the search for syntax to highlight. Stop at first
-highlighted object, if any. Return t if some highlighting was
-done, nil otherwise."
+Stop at first highlighted object, if any. Return t if some
+highlighting was done, nil otherwise."
(when (org-string-nw-p org-latex-and-related-regexp)
(catch 'found
- (while (re-search-forward org-latex-and-related-regexp limit t)
+ (while (re-search-forward org-latex-and-related-regexp
+ nil t) ;; on purpose, we ignore LIMIT
(unless (cl-some (lambda (f) (memq f '(org-code org-verbatim underline
- org-special-keyword)))
+ org-special-keyword)))
(save-excursion
(goto-char (1+ (match-beginning 0)))
(face-at-point nil t)))
- (let* ((start (if (memq (char-after (1+ (match-beginning 0)))
- '(?_ ?^))
- (1+ (match-beginning 0))
- (match-beginning 0)))
- (end
- (let* ((b (match-beginning 0))
- (e (match-end 0))
- (m (buffer-substring-no-properties b e)))
- (cond
- ((string-match "\\`[ \t]*\\\\begin{\\([a-zA-Z0-9\\*]+\\)}"
- m)
- (let ((re (format "\\\\end{%s}[ \t]*$"
- (regexp-quote (match-string 1 m)))))
- (or (re-search-forward re nil t) e)))
- ((string-match "\\\\end{\\([a-zA-Z0-9\\*]+\\)}[ \t]*\\'" m)
- (let ((re (format "^[ \t]*\\\\begin{%s}"
- (regexp-quote (match-string 1 m)))))
- (setq start
- (or (save-excursion (re-search-backward re nil t))
- b))
- (line-end-position)))
- ((string-match "\\`\\\\[a-zA-Z]+\\*?{\\'" m)
- (search-forward "}" nil t))
- (t e)))))
- (font-lock-prepend-text-property
- start end 'face 'org-latex-and-related)
- (add-text-properties start end '(font-lock-multiline t)))
+ (let* ((offset (if (memq (char-after (1+ (match-beginning 0)))
+ '(?_ ?^))
+ 1
+ 0))
+ (start (+ offset (match-beginning 0)))
+ (end (match-end 0)))
+ (if (memq 'native org-highlight-latex-and-related)
+ (org-src-font-lock-fontify-block "latex" start end)
+ (font-lock-prepend-text-property start end
+ 'face 'org-latex-and-related))
+ (add-text-properties (+ offset (match-beginning 0)) (match-end 0)
+ '(font-lock-multiline t)))
(throw 'found t)))
nil)))
@@ -6409,12 +5613,12 @@ needs to be inserted at a specific position in the font-lock sequence.")
'("^[ \t]*| *\\([#*]\\) *|" (1 'org-formula t))
'("^[ \t]*|\\( *\\([$!_^/]\\) *|.*\\)|" (1 'org-formula t))
'("| *\\(<[lrc]?[0-9]*>\\)" (1 'org-formula t))
- ;; Drawers
- '(org-fontify-drawers)
;; Properties
(list org-property-re
'(1 'org-special-keyword t)
'(3 'org-property-value t))
+ ;; Drawers
+ '(org-fontify-drawers)
;; Link related fontification.
'(org-activate-links)
(when (memq 'tag lk) '(org-activate-tags (1 'org-tag prepend)))
@@ -6422,7 +5626,8 @@ needs to be inserted at a specific position in the font-lock sequence.")
(when (memq 'date lk) '(org-activate-dates (0 'org-date t)))
(when (memq 'footnote lk) '(org-activate-footnote-links))
;; Targets.
- (list org-any-target-regexp '(0 'org-target t))
+ (list org-radio-target-regexp '(0 'org-target t))
+ (list org-target-regexp '(0 'org-target t))
;; Diary sexps.
'("^&?%%(.*\\|<%%([^>\n]*?>" (0 'org-sexp-date t))
;; Macro
@@ -6491,6 +5696,8 @@ needs to be inserted at a specific position in the font-lock sequence.")
(setq-local org-font-lock-keywords org-font-lock-extra-keywords)
(setq-local font-lock-defaults
'(org-font-lock-keywords t nil nil backward-paragraph))
+ (setq-local font-lock-extend-after-change-region-function
+ #'org-fontify-extend-region)
(kill-local-variable 'font-lock-keywords)
nil))
@@ -6899,28 +6106,33 @@ a list of strings specifying which drawers should not be hidden."
;; `org-drawer-regexp'.
(goto-char (org-element-property :end drawer))))))))))
-(defun org-flag-drawer (flag &optional element)
+(defun org-flag-drawer (flag &optional element beg end)
"When FLAG is non-nil, hide the drawer we are at.
-Otherwise make it visible. When optional argument ELEMENT is
-a parsed drawer, as returned by `org-element-at-point', hide or
-show that drawer instead."
- (let ((drawer (or element
- (and (save-excursion
- (beginning-of-line)
- (looking-at-p org-drawer-regexp))
- (org-element-at-point)))))
- (when (memq (org-element-type drawer) '(drawer property-drawer))
- (let ((post (org-element-property :post-affiliated drawer)))
- (org-flag-region
- (save-excursion (goto-char post) (line-end-position))
- (save-excursion (goto-char (org-element-property :end drawer))
- (skip-chars-backward " \t\n")
- (line-end-position))
- flag 'org-hide-drawer)
- ;; When the drawer is hidden away, make sure point lies in
- ;; a visible part of the buffer.
- (when (invisible-p (max (1- (point)) (point-min)))
- (goto-char post))))))
+Otherwise make it visible.
+
+When optional argument ELEMENT is a parsed drawer, as returned by
+`org-element-at-point', hide or show that drawer instead.
+
+When buffer positions BEG and END are provided, hide or show that
+region as a drawer without further ado."
+ (if (and beg end) (org-flag-region beg end flag 'org-hide-drawer)
+ (let ((drawer (or element
+ (and (save-excursion
+ (beginning-of-line)
+ (looking-at-p org-drawer-regexp))
+ (org-element-at-point)))))
+ (when (memq (org-element-type drawer) '(drawer property-drawer))
+ (let ((post (org-element-property :post-affiliated drawer)))
+ (org-flag-region
+ (save-excursion (goto-char post) (line-end-position))
+ (save-excursion (goto-char (org-element-property :end drawer))
+ (skip-chars-backward " \t\n")
+ (line-end-position))
+ flag 'org-hide-drawer)
+ ;; When the drawer is hidden away, make sure point lies in
+ ;; a visible part of the buffer.
+ (when (invisible-p (max (1- (point)) (point-min)))
+ (goto-char post)))))))
;;;; Visibility cycling
@@ -7295,11 +6507,11 @@ With a numeric prefix, show all headlines up to that level."
(if (not (org-at-property-p)) (outline-next-heading)
(save-excursion
(org-back-to-heading t)
- (outline-hide-subtree)
+ (org-flag-subtree t)
(org-reveal)
(pcase state
("folded"
- (outline-hide-subtree))
+ (org-flag-subtree t))
("children"
(org-show-hidden-entry)
(org-show-children))
@@ -8305,7 +7517,7 @@ case."
(org-skip-whitespace)
(move-marker ins-point nil)
(if folded
- (outline-hide-subtree)
+ (org-flag-subtree t)
(org-show-entry)
(org-show-children))
(org-clean-visibility-after-subtree-move)
@@ -8471,7 +7683,7 @@ When REMOVE is non-nil, remove the subtree from the clipboard."
(equal org-subtree-clip (current-kill 0))
org-subtree-clip-folded)
;; The tree was folded before it was killed/copied
- (outline-hide-subtree))
+ (org-flag-subtree t))
(when for-yank (goto-char newend))
(when remove (pop kill-ring)))))
@@ -8613,7 +7825,7 @@ with the original repeater."
""))) ;No time shift
(doshift
(and (org-string-nw-p shift)
- (or (string-match "\\`[ \t]*\\+?\\([0-9]+\\)\\([dwmy]\\)[ \t]*\\'"
+ (or (string-match "\\`[ \t]*\\([\\+\\-]?[0-9]+\\)\\([dwmy]\\)[ \t]*\\'"
shift)
(user-error "Invalid shift specification %s" shift)))))
(goto-char end-of-tree)
@@ -8927,6 +8139,7 @@ function is being called interactively."
"(empty for default `sort-subr' predicate): ")
'allow-empty))))
((member dcst '(?p ?t ?s ?d ?c ?k)) '<))))
+ (org-cycle-hide-drawers 'all)
(when restore-clock?
(move-marker org-clock-marker
(1+ (next-single-property-change
@@ -9143,921 +8356,12 @@ sub-tree if optional argument INHERIT is non-nil."
'org-stats stats)))))))
(defun org-refresh-effort-properties ()
- "Refresh effort properties"
+ "Refresh effort properties."
(org-refresh-properties
org-effort-property
'((effort . identity)
(effort-minutes . org-duration-to-minutes))))
-;;;; Link Stuff
-
-;;; Link abbreviations
-
-(defun org-link-expand-abbrev (link)
- "Apply replacements as defined in `org-link-abbrev-alist'."
- (if (string-match "^\\([^:]*\\)\\(::?\\(.*\\)\\)?$" link)
- (let* ((key (match-string 1 link))
- (as (or (assoc key org-link-abbrev-alist-local)
- (assoc key org-link-abbrev-alist)))
- (tag (and (match-end 2) (match-string 3 link)))
- rpl)
- (if (not as)
- link
- (setq rpl (cdr as))
- (cond
- ((symbolp rpl) (funcall rpl tag))
- ((string-match "%(\\([^)]+\\))" rpl)
- (replace-match
- (save-match-data
- (funcall (intern-soft (match-string 1 rpl)) tag)) t t rpl))
- ((string-match "%s" rpl) (replace-match (or tag "") t t rpl))
- ((string-match "%h" rpl)
- (replace-match (url-hexify-string (or tag "")) t t rpl))
- (t (concat rpl tag)))))
- link))
-
-;;; Storing and inserting links
-
-(defvar org-insert-link-history nil
- "Minibuffer history for links inserted with `org-insert-link'.")
-
-(defvar org-stored-links nil
- "Contains the links stored with `org-store-link'.")
-
-(defvar org-store-link-plist nil
- "Plist with info about the most recently link created with `org-store-link'.")
-
-(defun org-store-link-functions ()
- "Return a list of functions that are called to create and store a link.
-
-The functions are defined in the `:store' property of
-`org-link-parameters'.
-
-Each function is called in turn until one returns a non-nil
-value. Each function should check if it is responsible for
-creating this link (for example by looking at the major mode).
-If not, it must exit and return nil. If yes, it should return
-a non-nil value after calling `org-store-link-props' with a list
-of properties and values. Special properties are:
-
-:type The link prefix, like \"http\". This must be given.
-:link The link, like \"http://www.astro.uva.nl/~dominik\".
- This is obligatory as well.
-:description Optional default description for the second pair
- of brackets in an Org mode link. The user can still change
- this when inserting this link into an Org mode buffer.
-
-In addition to these, any additional properties can be specified
-and then used in capture templates."
- (cl-loop for link in org-link-parameters
- with store-func
- do (setq store-func (org-link-get-parameter (car link) :store))
- if store-func
- collect store-func))
-
-(defvar org-agenda-buffer-name) ; Defined in org-agenda.el
-(defvar org-id-link-to-org-use-id) ; Defined in org-id.el
-
-;;;###autoload
-(defun org-store-link (arg &optional interactive?)
- "Store a link to the current location.
-\\<org-mode-map>
-This link is added to `org-stored-links' and can later be inserted
-into an Org buffer with `org-insert-link' (`\\[org-insert-link]').
-
-For some link types, a `\\[universal-argument]' prefix ARG is interpreted. \
-A single
-`\\[universal-argument]' negates `org-context-in-file-links' for file links or
-`org-gnus-prefer-web-links' for links to Usenet articles.
-
-A `\\[universal-argument] \\[universal-argument]' prefix ARG forces \
-skipping storing functions that are not
-part of Org core.
-
-A `\\[universal-argument] \\[universal-argument] \\[universal-argument]' \
-prefix ARG forces storing a link for each line in the
-active region.
-
-Assume the function is called interactively if INTERACTIVE? is
-non-nil."
- (interactive "P\np")
- (org-load-modules-maybe)
- (if (and (equal arg '(64)) (org-region-active-p))
- (save-excursion
- (let ((end (region-end)))
- (goto-char (region-beginning))
- (set-mark (point))
- (while (< (point-at-eol) end)
- (move-end-of-line 1) (activate-mark)
- (let (current-prefix-arg)
- (call-interactively 'org-store-link))
- (move-beginning-of-line 2)
- (set-mark (point)))))
- (setq org-store-link-plist nil)
- (let (link cpltxt desc description search txt custom-id agenda-link)
- (cond
- ;; Store a link using an external link type, if any function is
- ;; available. If more than one can generate a link from current
- ;; location, ask which one to use.
- ((and (not (equal arg '(16)))
- (let ((results-alist nil))
- (dolist (f (org-store-link-functions))
- (when (funcall f)
- ;; XXX: return value is not link's plist, so we
- ;; store the new value before it is modified. It
- ;; would be cleaner to ask store link functions to
- ;; return the plist instead.
- (push (cons f (copy-sequence org-store-link-plist))
- results-alist)))
- (pcase results-alist
- (`nil nil)
- (`((,_ . ,_)) t) ;single choice: nothing to do
- (`((,name . ,_) . ,_)
- ;; Reinstate link plist associated to the chosen
- ;; function.
- (apply #'org-store-link-props
- (cdr (assoc-string
- (completing-read
- "Which function for creating the link? "
- (mapcar #'car results-alist)
- nil t (symbol-name name))
- results-alist)))
- t))))
- (setq link (plist-get org-store-link-plist :link))
- (setq desc (or (plist-get org-store-link-plist :description)
- link)))
-
- ;; Store a link from a remote editing buffer.
- ((org-src-edit-buffer-p)
- (let ((coderef-format (org-src-coderef-format))
- (format-link
- (lambda (label)
- (if org-src-source-file-name
- (format "file:%s::(%s)" org-src-source-file-name label)
- (format "(%s)" label)))))
- (cond
- ;; Code references do not exist in this type of buffer.
- ;; Pretend we're linking from the source buffer directly.
- ((not (memq (org-src-source-type) '(example-block src-block)))
- (with-current-buffer (org-src-source-buffer)
- (org-store-link arg interactive?))
- (setq link nil))
- ;; A code reference exists. Use it.
- ((save-excursion
- (beginning-of-line)
- (re-search-forward (org-src-coderef-regexp coderef-format)
- (line-end-position)
- t))
- (setq link (funcall format-link (match-string-no-properties 3))))
- ;; No code reference. Create a new one then store the link
- ;; to it, but only in the function is called interactively.
- (interactive?
- (end-of-line)
- (let* ((label (read-string "Code line label: "))
- (reference (format coderef-format label))
- (gc (- 79 (length reference))))
- (if (< (current-column) gc)
- (org-move-to-column gc t)
- (insert " "))
- (insert reference)
- (setq link (funcall format-link label))))
- ;; No code reference, and non-interactive call. Don't know
- ;; what to do. Give up.
- (t (setq link nil)))))
-
- ;; We are in the agenda, link to referenced location
- ((equal (bound-and-true-p org-agenda-buffer-name) (buffer-name))
- (let ((m (or (get-text-property (point) 'org-hd-marker)
- (get-text-property (point) 'org-marker))))
- (when m
- (org-with-point-at m
- (setq agenda-link (org-store-link nil interactive?))))))
-
- ((eq major-mode 'calendar-mode)
- (let ((cd (calendar-cursor-to-date)))
- (setq link
- (format-time-string
- (car org-time-stamp-formats)
- (encode-time 0 0 0 (nth 1 cd) (nth 0 cd) (nth 2 cd))))
- (org-store-link-props :type "calendar" :date cd)))
-
- ((eq major-mode 'help-mode)
- (setq link (concat "help:" (save-excursion
- (goto-char (point-min))
- (looking-at "^[^ ]+")
- (match-string 0))))
- (org-store-link-props :type "help"))
-
- ((eq major-mode 'w3-mode)
- (setq cpltxt (if (and (buffer-name)
- (not (string-match "Untitled" (buffer-name))))
- (buffer-name)
- (url-view-url t))
- link (url-view-url t))
- (org-store-link-props :type "w3" :url (url-view-url t)))
-
- ((eq major-mode 'image-mode)
- (setq cpltxt (concat "file:"
- (abbreviate-file-name buffer-file-name))
- link cpltxt)
- (org-store-link-props :type "image" :file buffer-file-name))
-
- ;; In dired, store a link to the file of the current line
- ((derived-mode-p 'dired-mode)
- (let ((file (dired-get-filename nil t)))
- (setq file (if file
- (abbreviate-file-name
- (expand-file-name (dired-get-filename nil t)))
- ;; otherwise, no file so use current directory.
- default-directory))
- (setq cpltxt (concat "file:" file)
- link cpltxt)))
-
- ((setq search (run-hook-with-args-until-success
- 'org-create-file-search-functions))
- (setq link (concat "file:" (abbreviate-file-name buffer-file-name)
- "::" search))
- (setq cpltxt (or description link)))
-
- ((and (buffer-file-name (buffer-base-buffer)) (derived-mode-p 'org-mode))
- (org-with-limited-levels
- (setq custom-id (org-entry-get nil "CUSTOM_ID"))
- (cond
- ;; Store a link using the target at point
- ((org-in-regexp "[^<]<<\\([^<>]+\\)>>[^>]" 1)
- (setq cpltxt
- (concat "file:"
- (abbreviate-file-name
- (buffer-file-name (buffer-base-buffer)))
- "::" (match-string 1))
- link cpltxt))
- ((and (featurep 'org-id)
- (or (eq org-id-link-to-org-use-id t)
- (and interactive?
- (or (eq org-id-link-to-org-use-id 'create-if-interactive)
- (and (eq org-id-link-to-org-use-id
- 'create-if-interactive-and-no-custom-id)
- (not custom-id))))
- (and org-id-link-to-org-use-id (org-entry-get nil "ID"))))
- ;; Store a link using the ID at point
- (setq link (condition-case nil
- (prog1 (org-id-store-link)
- (setq desc (or (plist-get org-store-link-plist
- :description)
- "")))
- (error
- ;; Probably before first headline, link only to file
- (concat "file:"
- (abbreviate-file-name
- (buffer-file-name (buffer-base-buffer))))))))
- (t
- ;; Just link to current headline
- (setq cpltxt (concat "file:"
- (abbreviate-file-name
- (buffer-file-name (buffer-base-buffer)))))
- ;; Add a context search string
- (when (org-xor org-context-in-file-links
- (equal arg '(4)))
- (let* ((element (org-element-at-point))
- (name (org-element-property :name element)))
- (setq txt (cond
- ((org-at-heading-p) nil)
- (name)
- ((org-region-active-p)
- (buffer-substring (region-beginning) (region-end)))))
- (when (or (null txt) (string-match "\\S-" txt))
- (setq cpltxt
- (concat cpltxt "::"
- (condition-case nil
- (org-make-org-heading-search-string txt)
- (error "")))
- desc (or name
- (nth 4 (ignore-errors (org-heading-components)))
- "NONE")))))
- (when (string-match "::\\'" cpltxt)
- (setq cpltxt (substring cpltxt 0 -2)))
- (setq link cpltxt)))))
-
- ((buffer-file-name (buffer-base-buffer))
- ;; Just link to this file here.
- (setq cpltxt (concat "file:"
- (abbreviate-file-name
- (buffer-file-name (buffer-base-buffer)))))
- ;; Add a context string.
- (when (org-xor org-context-in-file-links
- (equal arg '(4)))
- (setq txt (if (org-region-active-p)
- (buffer-substring (region-beginning) (region-end))
- (buffer-substring (point-at-bol) (point-at-eol))))
- ;; Only use search option if there is some text.
- (when (string-match "\\S-" txt)
- (setq cpltxt
- (concat cpltxt "::" (org-make-org-heading-search-string txt))
- desc "NONE")))
- (setq link cpltxt))
-
- (interactive?
- (user-error "No method for storing a link from this buffer"))
-
- (t (setq link nil)))
-
- ;; We're done setting link and desc, clean up
- (when (consp link) (setq cpltxt (car link) link (cdr link)))
- (setq link (or link cpltxt)
- desc (or desc cpltxt))
- (cond ((not desc))
- ((equal desc "NONE") (setq desc nil))
- (t (setq desc
- (replace-regexp-in-string
- org-bracket-link-analytic-regexp
- (lambda (m) (or (match-string 5 m) (match-string 3 m)))
- desc))))
- ;; Return the link
- (if (not (and interactive? link))
- (or agenda-link (and link (org-make-link-string link desc)))
- (push (list link desc) org-stored-links)
- (message "Stored: %s" (or desc link))
- (when custom-id
- (setq link (concat "file:" (abbreviate-file-name
- (buffer-file-name)) "::#" custom-id))
- (push (list link desc) org-stored-links))
- (car org-stored-links)))))
-
-(defun org-store-link-props (&rest plist)
- "Store link properties.
-The properties are pre-processed by extracting names, addresses
-and dates."
- (let ((x (plist-get plist :from)))
- (when x
- (let ((adr (mail-extract-address-components x)))
- (setq plist (plist-put plist :fromname (car adr)))
- (setq plist (plist-put plist :fromaddress (nth 1 adr))))))
- (let ((x (plist-get plist :to)))
- (when x
- (let ((adr (mail-extract-address-components x)))
- (setq plist (plist-put plist :toname (car adr)))
- (setq plist (plist-put plist :toaddress (nth 1 adr))))))
- (let ((x (ignore-errors (date-to-time (plist-get plist :date)))))
- (when x
- (setq plist (plist-put plist :date-timestamp
- (format-time-string
- (org-time-stamp-format t) x)))
- (setq plist (plist-put plist :date-timestamp-inactive
- (format-time-string
- (org-time-stamp-format t t) x)))))
- (let ((from (plist-get plist :from))
- (to (plist-get plist :to)))
- (when (and from to org-from-is-user-regexp)
- (setq plist
- (plist-put plist :fromto
- (if (string-match org-from-is-user-regexp from)
- (concat "to %t")
- (concat "from %f"))))))
- (setq org-store-link-plist plist))
-
-(defun org-add-link-props (&rest plist)
- "Add these properties to the link property list."
- (let (key value)
- (while plist
- (setq key (pop plist) value (pop plist))
- (setq org-store-link-plist
- (plist-put org-store-link-plist key value)))))
-
-(defun org-email-link-description (&optional fmt)
- "Return the description part of an email link.
-This takes information from `org-store-link-plist' and formats it
-according to FMT (default from `org-email-link-description-format')."
- (setq fmt (or fmt org-email-link-description-format))
- (let* ((p org-store-link-plist)
- (to (plist-get p :toaddress))
- (from (plist-get p :fromaddress))
- (table
- (list
- (cons "%c" (plist-get p :fromto))
- (cons "%F" (plist-get p :from))
- (cons "%f" (or (plist-get p :fromname) (plist-get p :fromaddress) "?"))
- (cons "%T" (plist-get p :to))
- (cons "%t" (or (plist-get p :toname) (plist-get p :toaddress) "?"))
- (cons "%s" (plist-get p :subject))
- (cons "%d" (plist-get p :date))
- (cons "%m" (plist-get p :message-id)))))
- (when (string-match "%c" fmt)
- ;; Check if the user wrote this message
- (if (and org-from-is-user-regexp from to
- (save-match-data (string-match org-from-is-user-regexp from)))
- (setq fmt (replace-match "to %t" t t fmt))
- (setq fmt (replace-match "from %f" t t fmt))))
- (org-replace-escapes fmt table)))
-
-(defun org-make-org-heading-search-string (&optional string)
- "Make search string for the current headline or STRING."
- (let ((s (or string
- (and (derived-mode-p 'org-mode)
- (save-excursion
- (org-back-to-heading t)
- (org-element-property :raw-value (org-element-at-point))))))
- (lines org-context-in-file-links))
- (unless string (setq s (concat "*" s))) ;Add * for headlines
- (setq s (replace-regexp-in-string "\\[[0-9]+%\\]\\|\\[[0-9]+/[0-9]+\\]" "" s))
- (when (and string (integerp lines) (> lines 0))
- (let ((slines (org-split-string s "\n")))
- (when (< lines (length slines))
- (setq s (mapconcat
- 'identity
- (reverse (nthcdr (- (length slines) lines)
- (reverse slines))) "\n")))))
- (mapconcat #'identity (split-string s) " ")))
-
-(defconst org-link-escape-chars
- ;;%20 %5B %5D %25
- '(?\s ?\[ ?\] ?%)
- "List of characters that should be escaped in a link when stored to Org.
-This is the list that is used for internal purposes.")
-
-(defun org-make-link-string (link &optional description)
- "Make a link with brackets, consisting of LINK and DESCRIPTION."
- (unless (org-string-nw-p link) (error "Empty link"))
- (let ((uri (cond ((string-match org-link-types-re link)
- (concat (match-string 1 link)
- (org-link-escape (substring link (match-end 1)))))
- ((or (file-name-absolute-p link)
- (string-match-p "\\`\\.\\.?/" link))
- (org-link-escape link))
- ;; For readability, do not encode space characters
- ;; in fuzzy links.
- (t (org-link-escape link (remq ?\s org-link-escape-chars)))))
- (description
- (and (org-string-nw-p description)
- ;; Remove brackets from description, as they are fatal.
- (replace-regexp-in-string
- "[][]" (lambda (m) (if (equal "[" m) "{" "}"))
- (org-trim description)))))
- (format "[[%s]%s]"
- uri
- (if description (format "[%s]" description) ""))))
-
-(defun org-link-escape (text &optional table merge)
- "Return percent escaped representation of TEXT.
-TEXT is a string with the text to escape.
-Optional argument TABLE is a list with characters that should be
-escaped. When nil, `org-link-escape-chars' is used.
-If optional argument MERGE is set, merge TABLE into
-`org-link-escape-chars'."
- (let ((characters-to-encode
- (cond ((null table) org-link-escape-chars)
- (merge (append org-link-escape-chars table))
- (t table))))
- (mapconcat
- (lambda (c)
- (if (or (memq c characters-to-encode)
- (and org-url-hexify-p (or (< c 32) (> c 126))))
- (mapconcat (lambda (e) (format "%%%.2X" e))
- (or (encode-coding-char c 'utf-8)
- (error "Unable to percent escape character: %c" c))
- "")
- (char-to-string c)))
- text "")))
-
-(defun org-link-unescape (str)
- "Unhex hexified Unicode parts in string STR.
-E.g. `%C3%B6' becomes the german o-Umlaut. This is the
-reciprocal of `org-link-escape', which see."
- (if (org-string-nw-p str)
- (replace-regexp-in-string
- "\\(%[0-9A-Za-z]\\{2\\}\\)+" #'org-link-unescape-compound str t t)
- str))
-
-(defun org-link-unescape-compound (hex)
- "Unhexify Unicode hex-chars. E.g. `%C3%B6' is the German o-Umlaut.
-Note: this function also decodes single byte encodings like
-`%E1' (a-acute) if not followed by another `%[A-F0-9]{2}' group."
- (save-match-data
- (let* ((bytes (cdr (split-string hex "%")))
- (ret "")
- (eat 0)
- (sum 0))
- (while bytes
- (let* ((val (string-to-number (pop bytes) 16))
- (shift-xor
- (if (= 0 eat)
- (cond
- ((>= val 252) (cons 6 252))
- ((>= val 248) (cons 5 248))
- ((>= val 240) (cons 4 240))
- ((>= val 224) (cons 3 224))
- ((>= val 192) (cons 2 192))
- (t (cons 0 0)))
- (cons 6 128))))
- (when (>= val 192) (setq eat (car shift-xor)))
- (setq val (logxor val (cdr shift-xor)))
- (setq sum (+ (ash sum (car shift-xor)) val))
- (when (> eat 0) (setq eat (- eat 1)))
- (cond
- ((= 0 eat) ;multi byte
- (setq ret (concat ret (char-to-string sum)))
- (setq sum 0))
- ((not bytes) ; single byte(s)
- (setq ret (org-link-unescape-single-byte-sequence hex))))))
- ret)))
-
-(defun org-link-unescape-single-byte-sequence (hex)
- "Unhexify hex-encoded single byte character sequences."
- (mapconcat (lambda (byte)
- (char-to-string (string-to-number byte 16)))
- (cdr (split-string hex "%")) ""))
-
-(defun org-fixup-message-id-for-http (s)
- "Replace special characters in a message id, so it can be used in an http query."
- (when (string-match "%" s)
- (setq s (mapconcat (lambda (c)
- (if (eq c ?%)
- "%25"
- (char-to-string c)))
- s "")))
- (while (string-match "<" s)
- (setq s (replace-match "%3C" t t s)))
- (while (string-match ">" s)
- (setq s (replace-match "%3E" t t s)))
- (while (string-match "@" s)
- (setq s (replace-match "%40" t t s)))
- s)
-
-(defun org-link-prettify (link)
- "Return a human-readable representation of LINK.
-The car of LINK must be a raw link.
-The cdr of LINK must be either a link description or nil."
- (let ((desc (or (cadr link) "<no description>")))
- (concat (format "%-45s" (substring desc 0 (min (length desc) 40)))
- "<" (car link) ">")))
-
-;;;###autoload
-(defun org-insert-link-global ()
- "Insert a link like Org mode does.
-This command can be called in any mode to insert a link in Org syntax."
- (interactive)
- (org-load-modules-maybe)
- (org-run-like-in-org-mode 'org-insert-link))
-
-(defun org-insert-all-links (arg &optional pre post)
- "Insert all links in `org-stored-links'.
-When a universal prefix, do not delete the links from `org-stored-links'.
-When `ARG' is a number, insert the last N link(s).
-`PRE' and `POST' are optional arguments to define a string to
-prepend or to append."
- (interactive "P")
- (let ((org-keep-stored-link-after-insertion (equal arg '(4)))
- (links (copy-sequence org-stored-links))
- (pr (or pre "- "))
- (po (or post "\n"))
- (cnt 1) l)
- (if (null org-stored-links)
- (message "No link to insert")
- (while (and (or (listp arg) (>= arg cnt))
- (setq l (if (listp arg)
- (pop links)
- (pop org-stored-links))))
- (setq cnt (1+ cnt))
- (insert pr)
- (org-insert-link nil (car l) (or (cadr l) "<no description>"))
- (insert po)))))
-
-(defun org-insert-last-stored-link (arg)
- "Insert the last link stored in `org-stored-links'."
- (interactive "p")
- (org-insert-all-links arg "" "\n"))
-
-(defun org-link-fontify-links-to-this-file ()
- "Fontify links to the current file in `org-stored-links'."
- (let ((f (buffer-file-name)) a b)
- (setq a (mapcar (lambda(l)
- (let ((ll (car l)))
- (when (and (string-match "^file:\\(.+\\)::" ll)
- (equal f (expand-file-name (match-string 1 ll))))
- ll)))
- org-stored-links))
- (when (featurep 'org-id)
- (setq b (mapcar (lambda(l)
- (let ((ll (car l)))
- (when (and (string-match "^id:\\(.+\\)$" ll)
- (equal f (expand-file-name
- (or (org-id-find-id-file
- (match-string 1 ll)) ""))))
- ll)))
- org-stored-links)))
- (mapcar (lambda(l)
- (put-text-property 0 (length l) 'face 'font-lock-comment-face l))
- (delq nil (append a b)))))
-
-(defvar org--links-history nil)
-(defun org-insert-link (&optional complete-file link-location default-description)
- "Insert a link. At the prompt, enter the link.
-
-Completion can be used to insert any of the link protocol prefixes in use.
-
-The history can be used to select a link previously stored with
-`org-store-link'. When the empty string is entered (i.e. if you just
-press `RET' at the prompt), the link defaults to the most recently
-stored link. As `SPC' triggers completion in the minibuffer, you need to
-use `M-SPC' or `C-q SPC' to force the insertion of a space character.
-
-You will also be prompted for a description, and if one is given, it will
-be displayed in the buffer instead of the link.
-
-If there is already a link at point, this command will allow you to edit
-link and description parts.
-
-With a `\\[universal-argument]' prefix, prompts for a file to link to. The \
-file name can be
-selected using completion. The path to the file will be relative to the
-current directory if the file is in the current directory or a subdirectory.
-Otherwise, the link will be the absolute path as completed in the minibuffer
-\(i.e. normally ~/path/to/file). You can configure this behavior using the
-option `org-link-file-path-type'.
-
-With a `\\[universal-argument] \\[universal-argument]' prefix, enforce an \
-absolute path even if the file is in
-the current directory or below.
-
-A `\\[universal-argument] \\[universal-argument] \\[universal-argument]' \
-prefix negates `org-keep-stored-link-after-insertion'.
-
-If the LINK-LOCATION parameter is non-nil, this value will be used as
-the link location instead of reading one interactively.
-
-If the DEFAULT-DESCRIPTION parameter is non-nil, this value will
-be used as the default description. Otherwise, if
-`org-make-link-description-function' is non-nil, this function
-will be called with the link target, and the result will be the
-default link description. When called non-interactively, don't
-allow to edit the default description."
- (interactive "P")
- (let* ((wcf (current-window-configuration))
- (origbuf (current-buffer))
- (region (when (org-region-active-p)
- (buffer-substring (region-beginning) (region-end))))
- (remove (and region (list (region-beginning) (region-end))))
- (desc region)
- (link link-location)
- (abbrevs org-link-abbrev-alist-local)
- entry all-prefixes auto-desc)
- (cond
- (link-location) ; specified by arg, just use it.
- ((org-in-regexp org-bracket-link-regexp 1)
- ;; We do have a link at point, and we are going to edit it.
- (setq remove (list (match-beginning 0) (match-end 0)))
- (setq desc (when (match-end 3) (match-string-no-properties 3)))
- (setq link (read-string "Link: "
- (org-link-unescape
- (match-string-no-properties 1)))))
- ((or (org-in-regexp org-angle-link-re)
- (org-in-regexp org-plain-link-re))
- ;; Convert to bracket link
- (setq remove (list (match-beginning 0) (match-end 0))
- link (read-string "Link: "
- (org-unbracket-string "<" ">" (match-string 0)))))
- ((member complete-file '((4) (16)))
- ;; Completing read for file names.
- (setq link (org-file-complete-link complete-file)))
- (t
- ;; Read link, with completion for stored links.
- (org-link-fontify-links-to-this-file)
- (org-switch-to-buffer-other-window "*Org Links*")
- (with-current-buffer "*Org Links*"
- (erase-buffer)
- (insert "Insert a link.
-Use TAB to complete link prefixes, then RET for type-specific completion support\n")
- (when org-stored-links
- (insert "\nStored links are available with <up>/<down> or M-p/n (most recent with RET):\n\n")
- (insert (mapconcat 'org-link-prettify
- (reverse org-stored-links) "\n")))
- (goto-char (point-min)))
- (let ((cw (selected-window)))
- (select-window (get-buffer-window "*Org Links*" 'visible))
- (with-current-buffer "*Org Links*" (setq truncate-lines t))
- (unless (pos-visible-in-window-p (point-max))
- (org-fit-window-to-buffer))
- (and (window-live-p cw) (select-window cw)))
- (setq all-prefixes (append (mapcar 'car abbrevs)
- (mapcar 'car org-link-abbrev-alist)
- (org-link-types)))
- (unwind-protect
- ;; Fake a link history, containing the stored links.
- (let ((org--links-history
- (append (mapcar #'car org-stored-links)
- org-insert-link-history)))
- (setq link
- (org-completing-read
- "Link: "
- (append
- (mapcar (lambda (x) (concat x ":")) all-prefixes)
- (mapcar #'car org-stored-links))
- nil nil nil
- 'org--links-history
- (caar org-stored-links)))
- (unless (org-string-nw-p link) (user-error "No link selected"))
- (dolist (l org-stored-links)
- (when (equal link (cadr l))
- (setq link (car l))
- (setq auto-desc t)))
- (when (or (member link all-prefixes)
- (and (equal ":" (substring link -1))
- (member (substring link 0 -1) all-prefixes)
- (setq link (substring link 0 -1))))
- (setq link (with-current-buffer origbuf
- (org-link-try-special-completion link)))))
- (set-window-configuration wcf)
- (kill-buffer "*Org Links*"))
- (setq entry (assoc link org-stored-links))
- (or entry (push link org-insert-link-history))
- (setq desc (or desc (nth 1 entry)))))
-
- (when (funcall (if (equal complete-file '(64)) 'not 'identity)
- (not org-keep-stored-link-after-insertion))
- (setq org-stored-links (delq (assoc link org-stored-links)
- org-stored-links)))
-
- (when (and (string-match org-plain-link-re link)
- (not (string-match org-ts-regexp link)))
- ;; URL-like link, normalize the use of angular brackets.
- (setq link (org-unbracket-string "<" ">" link)))
-
- ;; Check if we are linking to the current file with a search
- ;; option If yes, simplify the link by using only the search
- ;; option.
- (when (and buffer-file-name
- (let ((case-fold-search nil))
- (string-match "\\`file:\\(.+?\\)::" link)))
- (let ((path (match-string-no-properties 1 link))
- (search (substring-no-properties link (match-end 0))))
- (save-match-data
- (when (equal (file-truename buffer-file-name) (file-truename path))
- ;; We are linking to this same file, with a search option
- (setq link search)))))
-
- ;; Check if we can/should use a relative path. If yes, simplify
- ;; the link.
- (let ((case-fold-search nil))
- (when (string-match "\\`\\(file\\|docview\\):" link)
- (let* ((type (match-string-no-properties 0 link))
- (path-start (match-end 0))
- (search (and (string-match "::\\(.*\\)\\'" link)
- (match-string 1 link)))
- (path
- (if search
- (substring-no-properties
- link path-start (match-beginning 0))
- (substring-no-properties link (match-end 0))))
- (origpath path))
- (cond
- ((or (eq org-link-file-path-type 'absolute)
- (equal complete-file '(16)))
- (setq path (abbreviate-file-name (expand-file-name path))))
- ((eq org-link-file-path-type 'noabbrev)
- (setq path (expand-file-name path)))
- ((eq org-link-file-path-type 'relative)
- (setq path (file-relative-name path)))
- (t
- (save-match-data
- (if (string-match (concat "^" (regexp-quote
- (expand-file-name
- (file-name-as-directory
- default-directory))))
- (expand-file-name path))
- ;; We are linking a file with relative path name.
- (setq path (substring (expand-file-name path)
- (match-end 0)))
- (setq path (abbreviate-file-name (expand-file-name path)))))))
- (setq link (concat type path (and search (concat "::" search))))
- (when (equal desc origpath)
- (setq desc path)))))
-
- (unless auto-desc
- (let ((initial-input
- (cond
- (default-description)
- ((not org-make-link-description-function) desc)
- (t (condition-case nil
- (funcall org-make-link-description-function link desc)
- (error
- (message "Can't get link description from `%s'"
- (symbol-name org-make-link-description-function))
- (sit-for 2)
- nil))))))
- (setq desc (if (called-interactively-p 'any)
- (read-string "Description: " initial-input)
- initial-input))))
-
- (unless (org-string-nw-p desc) (setq desc nil))
- (when remove (apply 'delete-region remove))
- (insert (org-make-link-string link desc))
- ;; Redisplay so as the new link has proper invisible characters.
- (sit-for 0)))
-
-(defun org-link-try-special-completion (type)
- "If there is completion support for link type TYPE, offer it."
- (let ((fun (org-link-get-parameter type :complete)))
- (if (functionp fun)
- (funcall fun)
- (read-string "Link (no completion support): " (concat type ":")))))
-
-(defun org-file-complete-link (&optional arg)
- "Create a file link using completion."
- (let ((file (read-file-name "File: "))
- (pwd (file-name-as-directory (expand-file-name ".")))
- (pwd1 (file-name-as-directory (abbreviate-file-name
- (expand-file-name ".")))))
- (cond ((equal arg '(16))
- (concat "file:"
- (abbreviate-file-name (expand-file-name file))))
- ((string-match
- (concat "^" (regexp-quote pwd1) "\\(.+\\)") file)
- (concat "file:" (match-string 1 file)))
- ((string-match
- (concat "^" (regexp-quote pwd) "\\(.+\\)")
- (expand-file-name file))
- (concat "file:"
- (match-string 1 (expand-file-name file))))
- (t (concat "file:" file)))))
-
-
-;;; Opening/following a link
-
-(defvar org-link-search-failed nil)
-
-(defvar org-open-link-functions nil
- "Hook for functions finding a plain text link.
-These functions must take a single argument, the link content.
-They will be called for links that look like [[link text][description]]
-when LINK TEXT does not have a protocol like \"http:\" and does not look
-like a filename (e.g. \"./blue.png\").
-
-These functions will be called *before* Org attempts to resolve the
-link by doing text searches in the current buffer - so if you want a
-link \"[[target]]\" to still find \"<<target>>\", your function should
-handle this as a special case.
-
-When the function does handle the link, it must return a non-nil value.
-If it decides that it is not responsible for this link, it must return
-nil to indicate that that Org can continue with other options like
-exact and fuzzy text search.")
-
-(defun org-next-link (&optional search-backward)
- "Move forward to the next link.
-If the link is in hidden text, expose it."
- (interactive "P")
- (when (and org-link-search-failed (eq this-command last-command))
- (goto-char (point-min))
- (message "Link search wrapped back to beginning of buffer"))
- (setq org-link-search-failed nil)
- (let* ((pos (point))
- (ct (org-context))
- (a (assq :link ct))
- (srch-fun (if search-backward 're-search-backward 're-search-forward)))
- (cond (a (goto-char (nth (if search-backward 1 2) a)))
- ((looking-at org-any-link-re)
- ;; Don't stay stuck at link without an org-link face
- (forward-char (if search-backward -1 1))))
- (if (funcall srch-fun org-any-link-re nil t)
- (progn
- (goto-char (match-beginning 0))
- (when (org-invisible-p) (org-show-context)))
- (goto-char pos)
- (setq org-link-search-failed t)
- (message "No further link found"))))
-
-(defun org-previous-link ()
- "Move backward to the previous link.
-If the link is in hidden text, expose it."
- (interactive)
- (org-next-link t))
-
-(defun org-translate-link (s)
- "Translate a link string if a translation function has been defined."
- (with-temp-buffer
- (insert (org-trim s))
- (org-trim (org-element-interpret-data (org-element-context)))))
-
-(defun org-translate-link-from-planner (type path)
- "Translate a link from Emacs Planner syntax so that Org can follow it.
-This is still an experimental function, your mileage may vary."
- (cond
- ((member type '("http" "https" "news" "ftp"))
- ;; standard Internet links are the same.
- nil)
- ((and (equal type "irc") (string-match "^//" path))
- ;; Planner has two / at the beginning of an irc link, we have 1.
- ;; We should have zero, actually....
- (setq path (substring path 1)))
- ((and (equal type "lisp") (string-match "^/" path))
- ;; Planner has a slash, we do not.
- (setq type "elisp" path (substring path 1)))
- ((string-match "^//\\(.*\\)/\\(<.*>\\)$" path)
- ;; A typical message link. Planner has the id after the final slash,
- ;; we separate it with a hash mark
- (setq path (concat (match-string 1 path) "#"
- (org-unbracket-string "<" ">" (match-string 2 path))))))
- (cons type path))
-
(defun org-find-file-at-mouse (ev)
"Open file link or URL at mouse."
(interactive "e")
@@ -10077,6 +8381,206 @@ See the docstring of `org-open-file' for details."
"The window configuration before following a link.
This is saved in case the need arises to restore it.")
+(defun org--file-default-apps ()
+ "Return the default applications for this operating system."
+ (pcase system-type
+ (`darwin org-file-apps-macos)
+ (`windows-nt org-file-apps-windowsnt)
+ (_ org-file-apps-gnu)))
+
+(defun org--file-apps-entry-dlink-p (entry)
+ "Non-nil if ENTRY should be matched against the link by `org-open-file'.
+
+It assumes that is the case when the entry uses a regular
+expression which has at least one grouping construct and the
+action is either a Lisp form or a command string containing
+\"%1\", i.e., using at least one subexpression match as
+a parameter."
+ (pcase entry
+ (`(,selector . ,action)
+ (and (stringp selector)
+ (> (regexp-opt-depth selector) 0)
+ (or (and (stringp action)
+ (string-match "%[0-9]" action))
+ (consp action))))
+ (_ nil)))
+
+(defun org--file-apps-regexp-alist (list &optional add-auto-mode)
+ "Convert extensions to regular expressions in the cars of LIST.
+
+Also, weed out any non-string entries, because the return value
+is used only for regexp matching.
+
+When ADD-AUTO-MODE is non-nil, make all matches in `auto-mode-alist'
+point to the symbol `emacs', indicating that the file should be
+opened in Emacs."
+ (append
+ (delq nil
+ (mapcar (lambda (x)
+ (unless (not (stringp (car x)))
+ (if (string-match "\\W" (car x))
+ x
+ (cons (concat "\\." (car x) "\\'") (cdr x)))))
+ list))
+ (when add-auto-mode
+ (mapcar (lambda (x) (cons (car x) 'emacs)) auto-mode-alist))))
+
+;;;###autoload
+(defun org-open-file (path &optional in-emacs line search)
+ "Open the file at PATH.
+First, this expands any special file name abbreviations. Then the
+configuration variable `org-file-apps' is checked if it contains an
+entry for this file type, and if yes, the corresponding command is launched.
+
+If no application is found, Emacs simply visits the file.
+
+With optional prefix argument IN-EMACS, Emacs will visit the file.
+With a double \\[universal-argument] \\[universal-argument] \
+prefix arg, Org tries to avoid opening in Emacs
+and to use an external application to visit the file.
+
+Optional LINE specifies a line to go to, optional SEARCH a string
+to search for. If LINE or SEARCH is given, the file will be
+opened in Emacs, unless an entry from `org-file-apps' that makes
+use of groups in a regexp matches.
+
+If you want to change the way frames are used when following a
+link, please customize `org-link-frame-setup'.
+
+If the file does not exist, throw an error."
+ (let* ((file (if (equal path "") buffer-file-name
+ (substitute-in-file-name (expand-file-name path))))
+ (file-apps (append org-file-apps (org--file-default-apps)))
+ (apps (cl-remove-if #'org--file-apps-entry-dlink-p file-apps))
+ (apps-dlink (cl-remove-if-not #'org--file-apps-entry-dlink-p
+ file-apps))
+ (remp (and (assq 'remote apps) (file-remote-p file)))
+ (dirp (unless remp (file-directory-p file)))
+ (file (if (and dirp org-open-directory-means-index-dot-org)
+ (concat (file-name-as-directory file) "index.org")
+ file))
+ (a-m-a-p (assq 'auto-mode apps))
+ (dfile (downcase file))
+ ;; Reconstruct the original link from the PATH, LINE and
+ ;; SEARCH args.
+ (link (cond (line (concat file "::" (number-to-string line)))
+ (search (concat file "::" search))
+ (t file)))
+ (dlink (downcase link))
+ (ext
+ (and (string-match "\\`.*?\\.\\([a-zA-Z0-9]+\\(\\.gz\\)?\\)\\'" dfile)
+ (match-string 1 dfile)))
+ (save-position-maybe
+ (let ((old-buffer (current-buffer))
+ (old-pos (point))
+ (old-mode major-mode))
+ (lambda ()
+ (and (derived-mode-p 'org-mode)
+ (eq old-mode 'org-mode)
+ (or (not (eq old-buffer (current-buffer)))
+ (not (eq old-pos (point))))
+ (org-mark-ring-push old-pos old-buffer)))))
+ cmd link-match-data)
+ (cond
+ ((member in-emacs '((16) system))
+ (setq cmd (cdr (assq 'system apps))))
+ (in-emacs (setq cmd 'emacs))
+ (t
+ (setq cmd (or (and remp (cdr (assq 'remote apps)))
+ (and dirp (cdr (assq 'directory apps)))
+ ;; First, try matching against apps-dlink if we
+ ;; get a match here, store the match data for
+ ;; later.
+ (let ((match (assoc-default dlink apps-dlink
+ 'string-match)))
+ (if match
+ (progn (setq link-match-data (match-data))
+ match)
+ (progn (setq in-emacs (or in-emacs line search))
+ nil))) ; if we have no match in apps-dlink,
+ ; always open the file in emacs if line or search
+ ; is given (for backwards compatibility)
+ (assoc-default dfile
+ (org--file-apps-regexp-alist apps a-m-a-p)
+ 'string-match)
+ (cdr (assoc ext apps))
+ (cdr (assq t apps))))))
+ (when (eq cmd 'system)
+ (setq cmd (cdr (assq 'system apps))))
+ (when (eq cmd 'default)
+ (setq cmd (cdr (assoc t apps))))
+ (when (eq cmd 'mailcap)
+ (require 'mailcap)
+ (mailcap-parse-mailcaps)
+ (let* ((mime-type (mailcap-extension-to-mime (or ext "")))
+ (command (mailcap-mime-info mime-type)))
+ (if (stringp command)
+ (setq cmd command)
+ (setq cmd 'emacs))))
+ (when (and (not (eq cmd 'emacs)) ; Emacs has no problems with non-ex files
+ (not (file-exists-p file))
+ (not org-open-non-existing-files))
+ (user-error "No such file: %s" file))
+ (cond
+ ((and (stringp cmd) (not (string-match "^\\s-*$" cmd)))
+ ;; Remove quotes around the file name - we'll use shell-quote-argument.
+ (while (string-match "['\"]%s['\"]" cmd)
+ (setq cmd (replace-match "%s" t t cmd)))
+ (setq cmd (replace-regexp-in-string
+ "%s"
+ (shell-quote-argument (convert-standard-filename file))
+ cmd
+ nil t))
+
+ ;; Replace "%1", "%2" etc. in command with group matches from regex
+ (save-match-data
+ (let ((match-index 1)
+ (number-of-groups (- (/ (length link-match-data) 2) 1)))
+ (set-match-data link-match-data)
+ (while (<= match-index number-of-groups)
+ (let ((regex (concat "%" (number-to-string match-index)))
+ (replace-with (match-string match-index dlink)))
+ (while (string-match regex cmd)
+ (setq cmd (replace-match replace-with t t cmd))))
+ (setq match-index (+ match-index 1)))))
+
+ (save-window-excursion
+ (message "Running %s...done" cmd)
+ (start-process-shell-command cmd nil cmd)
+ (and (boundp 'org-wait) (numberp org-wait) (sit-for org-wait))))
+ ((or (stringp cmd)
+ (eq cmd 'emacs))
+ (funcall (cdr (assq 'file org-link-frame-setup)) file)
+ (widen)
+ (cond (line (org-goto-line line)
+ (when (derived-mode-p 'org-mode) (org-reveal)))
+ (search (condition-case err
+ (org-link-search search)
+ ;; Save position before error-ing out so user
+ ;; can easily move back to the original buffer.
+ (error (funcall save-position-maybe)
+ (error (nth 1 err)))))))
+ ((functionp cmd)
+ (save-match-data
+ (set-match-data link-match-data)
+ (condition-case nil
+ (funcall cmd file link)
+ ;; FIXME: Remove this check when most default installations
+ ;; of Emacs have at least Org 9.0.
+ ((debug wrong-number-of-arguments wrong-type-argument
+ invalid-function)
+ (user-error "Please see Org News for version 9.0 about \
+`org-file-apps'--Lisp error: %S" cmd)))))
+ ((consp cmd)
+ ;; FIXME: Remove this check when most default installations of
+ ;; Emacs have at least Org 9.0. Heads-up instead of silently
+ ;; fall back to `org-link-frame-setup' for an old usage of
+ ;; `org-file-apps' with sexp instead of a function for `cmd'.
+ (user-error "Please see Org News for version 9.0 about \
+`org-file-apps'--Error: Deprecated usage of %S" cmd))
+ (t (funcall (cdr (assq 'file org-link-frame-setup)) file)))
+ (funcall save-position-maybe)))
+
;;;###autoload
(defun org-open-at-point-global ()
"Follow a link or a time-stamp like Org mode does.
@@ -10088,32 +8592,16 @@ Raise a user error when there is nothing to follow."
(interactive)
(let ((tap-url (thing-at-point 'url))
(tap-email (thing-at-point 'email)))
- (cond ((org-in-regexp org-any-link-re)
- (org-open-link-from-string (match-string-no-properties 0)))
+ (cond ((org-in-regexp org-link-any-re)
+ (org-link-open-from-string (match-string-no-properties 0)))
((or (org-in-regexp org-ts-regexp-both nil t)
(org-in-regexp org-tsr-regexp-both nil t))
(org-follow-timestamp-link))
- (tap-url (org-open-link-from-string tap-url))
- (tap-email (org-open-link-from-string
+ (tap-url (org-link-open-from-string tap-url))
+ (tap-email (org-link-open-from-string
(concat "mailto:" tap-email)))
(t (user-error "No link found")))))
-;;;###autoload
-(defun org-open-link-from-string (s &optional arg reference-buffer)
- "Open a link in the string S, as if it was in Org mode."
- (interactive "sLink: \nP")
- (let ((reference-buffer (or reference-buffer (current-buffer))))
- (with-temp-buffer
- (let ((org-inhibit-startup (not reference-buffer)))
- (org-mode)
- (insert s)
- (goto-char (point-min))
- (when reference-buffer
- (setq org-link-abbrev-alist-local
- (with-current-buffer reference-buffer
- org-link-abbrev-alist-local)))
- (org-open-at-point arg reference-buffer)))))
-
(defvar org-open-at-point-functions nil
"Hook that is run when following a link at point.
@@ -10121,62 +8609,7 @@ Functions in this hook must return t if they identify and follow
a link at point. If they don't find anything interesting at point,
they must return nil.")
-(defvar org-link-search-inhibit-query nil)
-(defvar clean-buffer-list-kill-buffer-names) ;Defined in midnight.el
-(defun org--open-doi-link (path)
- "Open a \"doi\" type link.
-PATH is a the path to search for, as a string."
- (browse-url (url-encode-url (concat org-doi-server-url path))))
-
-(defun org--open-elisp-link (path)
- "Open a \"elisp\" type link.
-PATH is the sexp to evaluate, as a string."
- (let ((cmd path))
- (if (or (and (org-string-nw-p
- org-confirm-elisp-link-not-regexp)
- (string-match-p org-confirm-elisp-link-not-regexp cmd))
- (not org-confirm-elisp-link-function)
- (funcall org-confirm-elisp-link-function
- (format "Execute \"%s\" as elisp? "
- (org-add-props cmd nil 'face 'org-warning))))
- (message "%s => %s" cmd
- (if (eq (string-to-char cmd) ?\()
- (eval (read cmd))
- (call-interactively (read cmd))))
- (user-error "Abort"))))
-
-(defun org--open-help-link (path)
- "Open a \"help\" type link.
-PATH is a symbol name, as a string."
- (pcase (intern path)
- ((and (pred fboundp) variable) (describe-function variable))
- ((and (pred boundp) function) (describe-variable function))
- (name (user-error "Unknown function or variable: %s" name))))
-
-(defun org--open-shell-link (path)
- "Open a \"shell\" type link.
-PATH is the command to execute, as a string."
- (let ((buf (generate-new-buffer "*Org Shell Output*"))
- (cmd path))
- (if (or (and (org-string-nw-p
- org-confirm-shell-link-not-regexp)
- (string-match
- org-confirm-shell-link-not-regexp cmd))
- (not org-confirm-shell-link-function)
- (funcall org-confirm-shell-link-function
- (format "Execute \"%s\" in shell? "
- (org-add-props cmd nil
- 'face 'org-warning))))
- (progn
- (message "Executing %s" cmd)
- (shell-command cmd buf)
- (when (featurep 'midnight)
- (setq clean-buffer-list-kill-buffer-names
- (cons (buffer-name buf)
- clean-buffer-list-kill-buffer-names))))
- (user-error "Abort"))))
-
-(defun org-open-at-point (&optional arg reference-buffer)
+(defun org-open-at-point (&optional arg)
"Open link, timestamp, footnote or tags at point.
When point is on a link, follow it. Normally, files will be
@@ -10196,10 +8629,6 @@ When point is on a headline, display a list of every link in the
entry, so it is possible to pick one, or all, of them. If point
is on a tag, call `org-tags-view' instead.
-When optional argument REFERENCE-BUFFER is non-nil, it should
-specify a buffer from where the link search should happen. This
-is used internally by `org-open-link-from-string'.
-
On top of syntactically correct links, this function also tries
to open links and time-stamps in comments, node properties, and
keywords if point is on something looking like a timestamp or
@@ -10234,17 +8663,27 @@ a link."
(>= (point) (match-beginning 5))
(< (point) (match-end 5)))
;; On tags.
- (org-tags-view arg (substring (match-string 5) 0 -1))
+ (org-tags-view
+ arg
+ (save-excursion
+ (let* ((beg (match-beginning 5))
+ (end (match-end 5))
+ (beg-tag (or (search-backward ":" beg 'at-limit) (point)))
+ (end-tag (search-forward ":" end nil 2)))
+ (buffer-substring (1+ beg-tag) (1- end-tag)))))
;; Not on tags.
(pcase (org-offer-links-in-entry (current-buffer) (point) arg)
(`(nil . ,_)
(require 'org-attach)
- (org-attach-reveal 'if-exists))
+ (message "Opening attachment-dir")
+ (if (equal arg '(4))
+ (org-attach-reveal-in-emacs)
+ (org-attach-reveal)))
(`(,links . ,links-end)
(dolist (link (if (stringp links) (list links) links))
(search-forward link nil links-end)
(goto-char (match-beginning 0))
- (org-open-at-point))))))
+ (org-open-at-point arg))))))
;; On a footnote reference or at definition's label.
((or (eq type 'footnote-reference)
(and (eq type 'footnote-definition)
@@ -10280,73 +8719,11 @@ a link."
(user-error "No link found"))
((eq type 'inline-src-block) (org-babel-open-src-block-result))
((eq type 'timestamp) (org-follow-timestamp-link))
- ((eq type 'link)
- (let ((type (org-element-property :type context))
- (path (org-element-property :path context)))
- ;; Switch back to REFERENCE-BUFFER needed when called in
- ;; a temporary buffer through `org-open-link-from-string'.
- (with-current-buffer (or reference-buffer (current-buffer))
- (cond
- ((equal type "file")
- (if (string-match "[*?{]" (file-name-nondirectory path))
- (dired path)
- ;; Look into `org-link-parameters' in order to find
- ;; a DEDICATED-FUNCTION to open file. The function
- ;; will be applied on raw link instead of parsed link
- ;; due to the limitation in `org-add-link-type'
- ;; ("open" function called with a single argument).
- ;; If no such function is found, fallback to
- ;; `org-open-file'.
- (let* ((option (org-element-property :search-option context))
- (app (org-element-property :application context))
- (dedicated-function
- (org-link-get-parameter
- (if app (concat type "+" app) type)
- :follow)))
- (if dedicated-function
- (funcall dedicated-function
- (concat path
- (and option (concat "::" option))))
- (apply #'org-open-file
- path
- (cond (arg)
- ((equal app "emacs") 'emacs)
- ((equal app "sys") 'system))
- (cond ((not option) nil)
- ((string-match-p "\\`[0-9]+\\'" option)
- (list (string-to-number option)))
- (t (list nil option))))))))
- ((functionp (org-link-get-parameter type :follow))
- (funcall (org-link-get-parameter type :follow) path))
- ((member type '("coderef" "custom-id" "fuzzy" "radio"))
- (unless (run-hook-with-args-until-success
- 'org-open-link-functions path)
- (if (not arg) (org-mark-ring-push)
- (switch-to-buffer-other-window
- (org-get-buffer-for-internal-link (current-buffer))))
- (let ((destination
- (org-with-wide-buffer
- (if (equal type "radio")
- (org-search-radio-target
- (org-element-property :path context))
- (org-link-search
- (pcase type
- ("custom-id" (concat "#" path))
- ("coderef" (format "(%s)" path))
- (_ path))
- ;; Prevent fuzzy links from matching
- ;; themselves.
- (and (equal type "fuzzy")
- (+ 2 (org-element-property :begin context)))))
- (point))))
- (unless (and (<= (point-min) destination)
- (>= (point-max) destination))
- (widen))
- (goto-char destination))))
- (t (browse-url-at-point))))))
+ ((eq type 'link) (org-link-open context arg))
(t (user-error "No link found")))))
(run-hook-with-args 'org-follow-link-hook))
+;;;###autoload
(defun org-offer-links-in-entry (buffer marker &optional nth zero)
"Offer links in the current entry and return the selected link.
If there is only one link, return it.
@@ -10358,13 +8735,13 @@ there is one, return it."
(goto-char marker)
(let ((cnt ?0)
have-zero end links link c)
- (when (and (stringp zero) (string-match org-bracket-link-regexp zero))
+ (when (and (stringp zero) (string-match org-link-bracket-re zero))
(push (match-string 0 zero) links)
(setq cnt (1- cnt) have-zero t))
(save-excursion
(org-back-to-heading t)
(setq end (save-excursion (outline-next-heading) (point)))
- (while (re-search-forward org-any-link-re end t)
+ (while (re-search-forward org-link-any-re end t)
(push (match-string 0) links))
(setq links (org-uniquify (reverse links))))
(cond
@@ -10381,12 +8758,12 @@ there is one, return it."
(with-output-to-temp-buffer "*Select Link*"
(dolist (l links)
(cond
- ((not (string-match org-bracket-link-regexp l))
+ ((not (string-match org-link-bracket-re l))
(princ (format "[%c] %s\n" (cl-incf cnt)
(org-unbracket-string "<" ">" l))))
- ((match-end 3)
+ ((match-end 2)
(princ (format "[%c] %s (%s)\n" (cl-incf cnt)
- (match-string 3 l) (match-string 1 l))))
+ (match-string 2 l) (match-string 1 l))))
(t (princ (format "[%c] %s\n" (cl-incf cnt)
(match-string 1 l)))))))
(org-fit-window-to-buffer (get-buffer-window "*Select Link*"))
@@ -10403,262 +8780,8 @@ there is one, return it."
(setq link (nth (1- nth) links)))))
(cons link end)))))
-;; TODO: These functions are deprecated since `org-open-at-point'
-;; hard-codes behavior for "file+emacs" and "file+sys" types.
-(defun org-open-file-with-system (path)
- "Open file at PATH using the system way of opening it."
- (org-open-file path 'system))
-(defun org-open-file-with-emacs (path)
- "Open file at PATH in Emacs."
- (org-open-file path 'emacs))
-
-
;;; File search
-(defvar org-create-file-search-functions nil
- "List of functions to construct the right search string for a file link.
-These functions are called in turn with point at the location to
-which the link should point.
-
-A function in the hook should first test if it would like to
-handle this file type, for example by checking the `major-mode'
-or the file extension. If it decides not to handle this file, it
-should just return nil to give other functions a chance. If it
-does handle the file, it must return the search string to be used
-when following the link. The search string will be part of the
-file link, given after a double colon, and `org-open-at-point'
-will automatically search for it. If special measures must be
-taken to make the search successful, another function should be
-added to the companion hook `org-execute-file-search-functions',
-which see.
-
-A function in this hook may also use `setq' to set the variable
-`description' to provide a suggestion for the descriptive text to
-be used for this link when it gets inserted into an Org buffer
-with \\[org-insert-link].")
-
-(defvar org-execute-file-search-functions nil
- "List of functions to execute a file search triggered by a link.
-
-Functions added to this hook must accept a single argument, the
-search string that was part of the file link, the part after the
-double colon. The function must first check if it would like to
-handle this search, for example by checking the `major-mode' or
-the file extension. If it decides not to handle this search, it
-should just return nil to give other functions a chance. If it
-does handle the search, it must return a non-nil value to keep
-other functions from trying.
-
-Each function can access the current prefix argument through the
-variable `current-prefix-arg'. Note that a single prefix is used
-to force opening a link in Emacs, so it may be good to only use a
-numeric or double prefix to guide the search function.
-
-In case this is needed, a function in this hook can also restore
-the window configuration before `org-open-at-point' was called using:
-
- (set-window-configuration org-window-config-before-follow-link)")
-
-(defun org-search-radio-target (target)
- "Search a radio target matching TARGET in current buffer.
-White spaces are not significant."
- (let ((re (format "<<<%s>>>"
- (mapconcat #'regexp-quote
- (split-string target)
- "[ \t]+\\(?:\n[ \t]*\\)?")))
- (origin (point)))
- (goto-char (point-min))
- (catch :radio-match
- (while (re-search-forward re nil t)
- (backward-char)
- (let ((object (org-element-context)))
- (when (eq (org-element-type object) 'radio-target)
- (goto-char (org-element-property :begin object))
- (org-show-context 'link-search)
- (throw :radio-match nil))))
- (goto-char origin)
- (user-error "No match for radio target: %s" target))))
-
-(defun org-link-search (s &optional avoid-pos stealth)
- "Search for a search string S.
-
-If S starts with \"#\", it triggers a custom ID search.
-
-If S is enclosed within parenthesis, it initiates a coderef
-search.
-
-If S is surrounded by forward slashes, it is interpreted as
-a regular expression. In Org mode files, this will create an
-`org-occur' sparse tree. In ordinary files, `occur' will be used
-to list matches. If the current buffer is in `dired-mode', grep
-will be used to search in all files.
-
-When AVOID-POS is given, ignore matches near that position.
-
-When optional argument STEALTH is non-nil, do not modify
-visibility around point, thus ignoring `org-show-context-detail'
-variable.
-
-Search is case-insensitive and ignores white spaces. Return type
-of matched result, which is either `dedicated' or `fuzzy'."
- (unless (org-string-nw-p s) (error "Invalid search string \"%s\"" s))
- (let* ((case-fold-search t)
- (origin (point))
- (normalized (replace-regexp-in-string "\n[ \t]*" " " s))
- (starred (eq (string-to-char normalized) ?*))
- (words (split-string (if starred (substring s 1) s)))
- (s-multi-re (mapconcat #'regexp-quote words "\\(?:[ \t\n]+\\)"))
- (s-single-re (mapconcat #'regexp-quote words "[ \t]+"))
- type)
- (cond
- ;; Check if there are any special search functions.
- ((run-hook-with-args-until-success 'org-execute-file-search-functions s))
- ((eq (string-to-char s) ?#)
- ;; Look for a custom ID S if S starts with "#".
- (let* ((id (substring normalized 1))
- (match (org-find-property "CUSTOM_ID" id)))
- (if match (progn (goto-char match) (setf type 'dedicated))
- (error "No match for custom ID: %s" id))))
- ((string-match "\\`(\\(.*\\))\\'" normalized)
- ;; Look for coderef targets if S is enclosed within parenthesis.
- (let ((coderef (match-string-no-properties 1 normalized))
- (re (substring s-single-re 1 -1)))
- (goto-char (point-min))
- (catch :coderef-match
- (while (re-search-forward re nil t)
- (let ((element (org-element-at-point)))
- (when (and (memq (org-element-type element)
- '(example-block src-block))
- (org-match-line
- (concat ".*?" (org-src-coderef-regexp
- (org-src-coderef-format element)
- coderef))))
- (setq type 'dedicated)
- (goto-char (match-beginning 2))
- (throw :coderef-match nil))))
- (goto-char origin)
- (error "No match for coderef: %s" coderef))))
- ((string-match "\\`/\\(.*\\)/\\'" normalized)
- ;; Look for a regular expression.
- (funcall (if (derived-mode-p 'org-mode) #'org-occur #'org-do-occur)
- (match-string 1 s)))
- ;; From here, we handle fuzzy links.
- ;;
- ;; Look for targets, only if not in a headline search.
- ((and (not starred)
- (let ((target (format "<<%s>>" s-multi-re)))
- (catch :target-match
- (goto-char (point-min))
- (while (re-search-forward target nil t)
- (backward-char)
- (let ((context (org-element-context)))
- (when (eq (org-element-type context) 'target)
- (setq type 'dedicated)
- (goto-char (org-element-property :begin context))
- (throw :target-match t))))
- nil))))
- ;; Look for elements named after S, only if not in a headline
- ;; search.
- ((and (not starred)
- (let ((name (format "^[ \t]*#\\+NAME: +%s[ \t]*$" s-single-re)))
- (catch :name-match
- (goto-char (point-min))
- (while (re-search-forward name nil t)
- (let ((element (org-element-at-point)))
- (when (equal words
- (split-string
- (org-element-property :name element)))
- (setq type 'dedicated)
- (beginning-of-line)
- (throw :name-match t))))
- nil))))
- ;; Regular text search. Prefer headlines in Org mode buffers.
- ;; Ignore COMMENT keyword, TODO keywords, priority cookies,
- ;; statistics cookies and tags.
- ((and (derived-mode-p 'org-mode)
- (let ((title-re
- (format "%s.*\\(?:%s[ \t]\\)?.*%s"
- org-outline-regexp-bol
- org-comment-string
- (mapconcat #'regexp-quote words ".+")))
- (cookie-re "\\[[0-9]*\\(?:%\\|/[0-9]*\\)\\]")
- (comment-re (eval-when-compile
- (format "\\`%s[ \t]+" org-comment-string))))
- (goto-char (point-min))
- (catch :found
- (while (re-search-forward title-re nil t)
- (when (equal words
- (split-string
- (replace-regexp-in-string
- cookie-re ""
- (replace-regexp-in-string
- comment-re "" (org-get-heading t t t)))))
- (throw :found t)))
- nil)))
- (beginning-of-line)
- (setq type 'dedicated))
- ;; Offer to create non-existent headline depending on
- ;; `org-link-search-must-match-exact-headline'.
- ((and (derived-mode-p 'org-mode)
- (not org-link-search-inhibit-query)
- (eq org-link-search-must-match-exact-headline 'query-to-create)
- (yes-or-no-p "No match - create this as a new heading? "))
- (goto-char (point-max))
- (unless (bolp) (newline))
- (org-insert-heading nil t t)
- (insert s "\n")
- (beginning-of-line 0))
- ;; Only headlines are looked after. No need to process
- ;; further: throw an error.
- ((and (derived-mode-p 'org-mode)
- (or starred org-link-search-must-match-exact-headline))
- (goto-char origin)
- (error "No match for fuzzy expression: %s" normalized))
- ;; Regular text search.
- ((catch :fuzzy-match
- (goto-char (point-min))
- (while (re-search-forward s-multi-re nil t)
- ;; Skip match if it contains AVOID-POS or it is included in
- ;; a link with a description but outside the description.
- (unless (or (and avoid-pos
- (<= (match-beginning 0) avoid-pos)
- (> (match-end 0) avoid-pos))
- (and (save-match-data
- (org-in-regexp org-bracket-link-regexp))
- (match-beginning 3)
- (or (> (match-beginning 3) (point))
- (<= (match-end 3) (point)))
- (org-element-lineage
- (save-match-data (org-element-context))
- '(link) t)))
- (goto-char (match-beginning 0))
- (setq type 'fuzzy)
- (throw :fuzzy-match t)))
- nil))
- ;; All failed. Throw an error.
- (t (goto-char origin)
- (error "No match for fuzzy expression: %s" normalized)))
- ;; Disclose surroundings of match, if appropriate.
- (when (and (derived-mode-p 'org-mode) (not stealth))
- (org-show-context 'link-search))
- type))
-
-(defun org-get-buffer-for-internal-link (buffer)
- "Return a buffer to be used for displaying the link target of internal links."
- (cond
- ((not org-display-internal-link-with-indirect-buffer)
- buffer)
- ((string-suffix-p "(Clone)" (buffer-name buffer))
- (message "Buffer is already a clone, not making another one")
- ;; we also do not modify visibility in this case
- buffer)
- (t ; make a new indirect buffer for displaying the link
- (let* ((bn (buffer-name buffer))
- (ibn (concat bn "(Clone)"))
- (ib (or (get-buffer ibn) (make-indirect-buffer buffer ibn 'clone))))
- (with-current-buffer ib (org-overview))
- ib))))
-
(defun org-do-occur (regexp &optional cleanup)
"Call the Emacs command `occur'.
If CLEANUP is non-nil, remove the printout of the regular expression
@@ -10727,11 +8850,6 @@ or to another Org file, automatically push the old position onto the ring."
(goto-char m)
(when (or (org-invisible-p) (org-invisible-p2)) (org-show-context 'mark-goto))))
-(defun org-add-angle-brackets (s)
- (unless (equal (substring s 0 1) "<") (setq s (concat "<" s)))
- (unless (equal (substring s -1) ">") (setq s (concat s ">")))
- s)
-
;;; Following specific links
(defvar org-agenda-buffer-tmp-name)
@@ -10764,208 +8882,6 @@ or to another Org file, automatically push the old position onto the ring."
(declare-function mailcap-mime-info
"mailcap" (string &optional request no-decode))
(defvar org-wait nil)
-(defun org-open-file (path &optional in-emacs line search)
- "Open the file at PATH.
-First, this expands any special file name abbreviations. Then the
-configuration variable `org-file-apps' is checked if it contains an
-entry for this file type, and if yes, the corresponding command is launched.
-
-If no application is found, Emacs simply visits the file.
-
-With optional prefix argument IN-EMACS, Emacs will visit the file.
-With a double \\[universal-argument] \\[universal-argument] \
-prefix arg, Org tries to avoid opening in Emacs
-and to use an external application to visit the file.
-
-Optional LINE specifies a line to go to, optional SEARCH a string
-to search for. If LINE or SEARCH is given, the file will be
-opened in Emacs, unless an entry from org-file-apps that makes
-use of groups in a regexp matches.
-
-If you want to change the way frames are used when following a
-link, please customize `org-link-frame-setup'.
-
-If the file does not exist, an error is thrown."
- (let* ((file (if (equal path "")
- buffer-file-name
- (substitute-in-file-name (expand-file-name path))))
- (file-apps (append org-file-apps (org-default-apps)))
- (apps (cl-remove-if
- 'org-file-apps-entry-match-against-dlink-p file-apps))
- (apps-dlink (cl-remove-if-not
- 'org-file-apps-entry-match-against-dlink-p file-apps))
- (remp (and (assq 'remote apps) (file-remote-p file)))
- (dirp (unless remp (file-directory-p file)))
- (file (if (and dirp org-open-directory-means-index-dot-org)
- (concat (file-name-as-directory file) "index.org")
- file))
- (a-m-a-p (assq 'auto-mode apps))
- (dfile (downcase file))
- ;; Reconstruct the original link from the PATH, LINE and
- ;; SEARCH args.
- (link (cond (line (concat file "::" (number-to-string line)))
- (search (concat file "::" search))
- (t file)))
- (dlink (downcase link))
- (ext
- (and (string-match "\\`.*?\\.\\([a-zA-Z0-9]+\\(\\.gz\\)?\\)\\'" dfile)
- (match-string 1 dfile)))
- (save-position-maybe
- (let ((old-buffer (current-buffer))
- (old-pos (point))
- (old-mode major-mode))
- (lambda ()
- (and (derived-mode-p 'org-mode)
- (eq old-mode 'org-mode)
- (or (not (eq old-buffer (current-buffer)))
- (not (eq old-pos (point))))
- (org-mark-ring-push old-pos old-buffer)))))
- cmd link-match-data)
- (cond
- ((member in-emacs '((16) system))
- (setq cmd (cdr (assq 'system apps))))
- (in-emacs (setq cmd 'emacs))
- (t
- (setq cmd (or (and remp (cdr (assq 'remote apps)))
- (and dirp (cdr (assq 'directory apps)))
- ;; First, try matching against apps-dlink if we
- ;; get a match here, store the match data for
- ;; later.
- (let ((match (assoc-default dlink apps-dlink
- 'string-match)))
- (if match
- (progn (setq link-match-data (match-data))
- match)
- (progn (setq in-emacs (or in-emacs line search))
- nil))) ; if we have no match in apps-dlink,
- ; always open the file in emacs if line or search
- ; is given (for backwards compatibility)
- (assoc-default dfile (org-apps-regexp-alist apps a-m-a-p)
- 'string-match)
- (cdr (assoc ext apps))
- (cdr (assq t apps))))))
- (when (eq cmd 'system)
- (setq cmd (cdr (assq 'system apps))))
- (when (eq cmd 'default)
- (setq cmd (cdr (assoc t apps))))
- (when (eq cmd 'mailcap)
- (require 'mailcap)
- (mailcap-parse-mailcaps)
- (let* ((mime-type (mailcap-extension-to-mime (or ext "")))
- (command (mailcap-mime-info mime-type)))
- (if (stringp command)
- (setq cmd command)
- (setq cmd 'emacs))))
- (when (and (not (eq cmd 'emacs)) ; Emacs has no problems with non-ex files
- (not (file-exists-p file))
- (not org-open-non-existing-files))
- (user-error "No such file: %s" file))
- (cond
- ((and (stringp cmd) (not (string-match "^\\s-*$" cmd)))
- ;; Remove quotes around the file name - we'll use shell-quote-argument.
- (while (string-match "['\"]%s['\"]" cmd)
- (setq cmd (replace-match "%s" t t cmd)))
- (setq cmd (replace-regexp-in-string
- "%s"
- (shell-quote-argument (convert-standard-filename file))
- cmd
- nil t))
-
- ;; Replace "%1", "%2" etc. in command with group matches from regex
- (save-match-data
- (let ((match-index 1)
- (number-of-groups (- (/ (length link-match-data) 2) 1)))
- (set-match-data link-match-data)
- (while (<= match-index number-of-groups)
- (let ((regex (concat "%" (number-to-string match-index)))
- (replace-with (match-string match-index dlink)))
- (while (string-match regex cmd)
- (setq cmd (replace-match replace-with t t cmd))))
- (setq match-index (+ match-index 1)))))
-
- (save-window-excursion
- (message "Running %s...done" cmd)
- (start-process-shell-command cmd nil cmd)
- (and (boundp 'org-wait) (numberp org-wait) (sit-for org-wait))))
- ((or (stringp cmd)
- (eq cmd 'emacs))
- (funcall (cdr (assq 'file org-link-frame-setup)) file)
- (widen)
- (cond (line (org-goto-line line)
- (when (derived-mode-p 'org-mode) (org-reveal)))
- (search (condition-case err
- (org-link-search search)
- ;; Save position before error-ing out so user
- ;; can easily move back to the original buffer.
- (error (funcall save-position-maybe)
- (error (nth 1 err)))))))
- ((functionp cmd)
- (save-match-data
- (set-match-data link-match-data)
- (condition-case nil
- (funcall cmd file link)
- ;; FIXME: Remove this check when most default installations
- ;; of Emacs have at least Org 9.0.
- ((debug wrong-number-of-arguments wrong-type-argument
- invalid-function)
- (user-error "Please see Org News for version 9.0 about \
-`org-file-apps'--Lisp error: %S" cmd)))))
- ((consp cmd)
- ;; FIXME: Remove this check when most default installations of
- ;; Emacs have at least Org 9.0. Heads-up instead of silently
- ;; fall back to `org-link-frame-setup' for an old usage of
- ;; `org-file-apps' with sexp instead of a function for `cmd'.
- (user-error "Please see Org News for version 9.0 about \
-`org-file-apps'--Error: Deprecated usage of %S" cmd))
- (t (funcall (cdr (assq 'file org-link-frame-setup)) file)))
- (funcall save-position-maybe)))
-
-(defun org-file-apps-entry-match-against-dlink-p (entry)
- "This function returns non-nil if `entry' uses a regular
-expression which should be matched against the whole link by
-org-open-file.
-
-It assumes that is the case when the entry uses a regular
-expression which has at least one grouping construct and the
-action is either a lisp form or a command string containing
-`%1', i.e. using at least one subexpression match as a
-parameter."
- (let ((selector (car entry))
- (action (cdr entry)))
- (if (stringp selector)
- (and (> (regexp-opt-depth selector) 0)
- (or (and (stringp action)
- (string-match "%[0-9]" action))
- (consp action)))
- nil)))
-
-(defun org-default-apps ()
- "Return the default applications for this operating system."
- (cond
- ((eq system-type 'darwin)
- org-file-apps-defaults-macosx)
- ((eq system-type 'windows-nt)
- org-file-apps-defaults-windowsnt)
- (t org-file-apps-defaults-gnu)))
-
-(defun org-apps-regexp-alist (list &optional add-auto-mode)
- "Convert extensions to regular expressions in the cars of LIST.
-Also, weed out any non-string entries, because the return value is used
-only for regexp matching.
-When ADD-AUTO-MODE is set, make all matches in `auto-mode-alist'
-point to the symbol `emacs', indicating that the file should
-be opened in Emacs."
- (append
- (delq nil
- (mapcar (lambda (x)
- (unless (not (stringp (car x)))
- (if (string-match "\\W" (car x))
- x
- (cons (concat "\\." (car x) "\\'") (cdr x)))))
- list))
- (when add-auto-mode
- (mapcar (lambda (x) (cons (car x) 'emacs)) auto-mode-alist))))
-
;;;; Refiling
@@ -11366,8 +9282,8 @@ prefix argument (`C-u C-u C-u C-c C-w')."
(org-back-to-heading t)
(setq heading-text
(replace-regexp-in-string
- org-bracket-link-regexp
- "\\3"
+ org-link-bracket-re
+ "\\2"
(or (nth 4 (org-heading-components))
""))))
(org-refile-get-location
@@ -11690,6 +9606,42 @@ If COMMAND is not given, use `org-update-dblock'."
(unless (re-search-forward org-dblock-end-re nil t)
(error "Dynamic block not terminated"))))))
+(defvar org-dynamic-block-alist nil
+ "Alist defining all the Org dynamic blocks.
+
+The key is the dynamic block type name, as a string. The value
+is the function used to insert the dynamic block.
+
+Use `org-dynamic-block-define' to populate it.")
+
+(defun org-dynamic-block-function (type)
+ "Return function associated to a given dynamic block type.
+TYPE is the dynamic block type, as a string."
+ (cdr (assoc type org-dynamic-block-alist)))
+
+(defun org-dynamic-block-types ()
+ "List all defined dynamic block types."
+ (mapcar #'car org-dynamic-block-alist))
+
+(defun org-dynamic-block-define (type func)
+ "Define dynamic block TYPE with FUNC.
+TYPE is a string. FUNC is the function creating the dynamic
+block of such type."
+ (pcase (assoc type org-dynamic-block-alist)
+ (`nil (push (cons type func) org-dynamic-block-alist))
+ (def (setcdr def func))))
+
+(defun org-dynamic-block-insert-dblock (type)
+ "Insert a dynamic block of type TYPE.
+When used interactively, select the dynamic block types among
+defined types, per `org-dynamic-block-define'."
+ (interactive (list (completing-read "Dynamic block: "
+ (org-dynamic-block-types))))
+ (pcase (org-dynamic-block-function type)
+ (`nil (error "No such dynamic block: %S" type))
+ ((and f (pred functionp)) (funcall f))
+ (_ (error "Invalid function for dynamic block %S" type))))
+
(defun org-dblock-update (&optional arg)
"User command for updating dynamic blocks.
Update the dynamic block at point. With prefix ARG, update all dynamic
@@ -12056,15 +10008,20 @@ By default the available states are \"TODO\" and \"DONE\". So, for this
example: when the item starts with TODO, it is changed to DONE.
When it starts with DONE, the DONE is removed. And when neither TODO nor
DONE are present, add TODO at the beginning of the heading.
+You can set up single-charcter keys to fast-select the new state. See the
+`org-todo-keywords' and `org-use-fast-todo-selection' for details.
-With `\\[universal-argument]' prefix ARG, use completion to determine the new \
-state.
-With numeric prefix ARG, switch to that state.
+With `\\[universal-argument]' prefix ARG, force logging the state change \
+and take a
+logging note.
With a `\\[universal-argument] \\[universal-argument]' prefix, switch to the \
next set of TODO \
keywords (nextset).
+Another way to achieve this is `S-C-<right>'.
With a `\\[universal-argument] \\[universal-argument] \\[universal-argument]' \
prefix, circumvent any state blocking.
+With numeric prefix arg, switch to the Nth state.
+
With a numeric prefix arg of 0, inhibit note taking for the change.
With a numeric prefix arg of -1, cancel repeater to allow marking as DONE.
@@ -12107,6 +10064,7 @@ When called through ELisp, arg is also interpreted in the following way:
(looking-at "\\(?: *\\|[ \t]*$\\)"))
(let* ((match-data (match-data))
(startpos (copy-marker (line-beginning-position)))
+ (force-log (and (equal arg '(4)) (prog1 t (setq arg nil))))
(logging (save-match-data (org-entry-get nil "LOGGING" t t)))
(org-log-done org-log-done)
(org-log-repeat org-log-repeat)
@@ -12126,34 +10084,19 @@ When called through ELisp, arg is also interpreted in the following way:
(member (member this org-todo-keywords-1))
(tail (cdr member))
(org-state (cond
- ((and org-todo-key-trigger
- (or (and (equal arg '(4))
- (eq org-use-fast-todo-selection 'prefix))
- (and (not arg) org-use-fast-todo-selection
- (not (eq org-use-fast-todo-selection
- 'prefix)))))
- ;; Use fast selection.
- (org-fast-todo-selection))
- ((and (equal arg '(4))
- (or (not org-use-fast-todo-selection)
- (not org-todo-key-trigger)))
- ;; Read a state with completion.
- (completing-read
- "State: " (mapcar #'list org-todo-keywords-1)
- nil t))
((eq arg 'right)
+ ;; Next state
(if this
(if tail (car tail) nil)
(car org-todo-keywords-1)))
((eq arg 'left)
+ ;; Previous state
(unless (equal member org-todo-keywords-1)
(if this
(nth (- (length org-todo-keywords-1)
(length tail) 2)
org-todo-keywords-1)
(org-last org-todo-keywords-1))))
- ((and (eq org-use-fast-todo-selection t) (equal arg '(4))
- (setq arg nil))) ;hack to fall back to cycling
(arg
;; User or caller requests a specific state.
(cond
@@ -12172,6 +10115,9 @@ When called through ELisp, arg is also interpreted in the following way:
(user-error "State `%s' not valid in this file" arg))
((nth (1- (prefix-numeric-value arg))
org-todo-keywords-1))))
+ ((and org-todo-key-trigger org-use-fast-todo-selection)
+ ;; Use fast selection.
+ (org-fast-todo-selection this))
((null member) (or head (car org-todo-keywords-1)))
((equal this final-done-word) nil) ;-> make empty
((null tail) nil) ;-> first entry
@@ -12233,11 +10179,13 @@ When called through ELisp, arg is also interpreted in the following way:
(setq now-done-p (and (member org-state org-done-keywords)
(not (member this org-done-keywords))))
(and logging (org-local-logging logging))
- (when (and (or org-todo-log-states org-log-done)
- (not (eq org-inhibit-logging t))
- (not (memq arg '(nextset previousset))))
+ (when (or (and (or org-todo-log-states org-log-done)
+ (not (eq org-inhibit-logging t))
+ (not (memq arg '(nextset previousset))))
+ force-log)
;; We need to look at recording a time and note.
- (setq dolog (or (nth 1 (assoc org-state org-todo-log-states))
+ (setq dolog (or (if force-log 'note)
+ (nth 1 (assoc org-state org-todo-log-states))
(nth 2 (assoc this org-todo-log-states))))
(when (and (eq dolog 'note) (eq org-inhibit-logging 'note))
(setq dolog 'time))
@@ -12282,7 +10230,9 @@ When called through ELisp, arg is also interpreted in the following way:
(looking-at org-todo-line-regexp))
(< (point) (+ 2 (or (match-end 2) (match-end 1)))))
(goto-char (or (match-end 2) (match-end 1)))
- (and (looking-at " ") (just-one-space)))
+ (and (looking-at " ")
+ (not (looking-at " *:"))
+ (just-one-space)))
(when org-trigger-hook
(save-excursion
(run-hook-with-args 'org-trigger-hook change-plist)))
@@ -12368,7 +10318,7 @@ not relevant for the behavior, but it makes things more visible.
Note that toggling the tag with tags commands will not change the property
and therefore not influence behavior!
-This can be t, meaning the tag ORDERED should be used, It can also be a
+This can be t, meaning the tag ORDERED should be used. It can also be a
string to select a different tag for this task."
:group 'org-todo
:type '(choice
@@ -12639,25 +10589,31 @@ right sequence."
(car org-todo-keywords-1))
(t (nth 2 (assoc kwd org-todo-kwd-alist))))))
-(defun org-fast-todo-selection ()
+(defun org-fast-todo-selection (&optional current-state)
"Fast TODO keyword selection with single keys.
-Returns the new TODO keyword, or nil if no state change should occur."
+Returns the new TODO keyword, or nil if no state change should occur.
+When CURRENT-STATE is given and selection letters are not unique globally,
+prefer a state in the current sequence over on in another sequence."
(let* ((fulltable org-todo-key-alist)
+ (head (org-get-todo-sequence-head current-state))
(done-keywords org-done-keywords) ;; needed for the faces.
(maxlen (apply 'max (mapcar
(lambda (x)
(if (stringp (car x)) (string-width (car x)) 0))
fulltable)))
- (expert nil)
+ (expert (equal org-use-fast-todo-selection 'expert))
+ (prompt "")
(fwidth (+ maxlen 3 1 3))
(ncol (/ (- (window-width) 4) fwidth))
- tg cnt e c tbl
- groups ingroup)
+ tg cnt e c tbl subtable
+ groups ingroup in-current-sequence)
(save-excursion
(save-window-excursion
(if expert
(set-buffer (get-buffer-create " *Org todo*"))
- (org-switch-to-buffer-other-window (get-buffer-create " *Org todo*")))
+ (delete-other-windows)
+ (set-window-buffer (split-window-vertically) (get-buffer-create " *Org todo*"))
+ (org-switch-to-buffer-other-window " *Org todo*"))
(erase-buffer)
(setq-local org-done-keywords done-keywords)
(setq tbl fulltable cnt 0)
@@ -12668,9 +10624,11 @@ Returns the new TODO keyword, or nil if no state change should occur."
(unless (= cnt 0)
(setq cnt 0)
(insert "\n"))
+ (setq prompt (concat prompt "{"))
(insert "{ "))
((equal e '(:endgroup))
- (setq ingroup nil cnt 0)
+ (setq ingroup nil cnt 0 in-current-sequence nil)
+ (setq prompt (concat prompt "}"))
(insert "}\n"))
((equal e '(:newline))
(unless (= cnt 0)
@@ -12682,10 +10640,13 @@ Returns the new TODO keyword, or nil if no state change should occur."
(setq tbl (cdr tbl)))))
(t
(setq tg (car e) c (cdr e))
+ (if (equal tg head) (setq in-current-sequence t))
(when ingroup (push tg (car groups)))
+ (when in-current-sequence (push e subtable))
(setq tg (org-add-props tg nil 'face
(org-get-todo-face tg)))
(when (and (= cnt 0) (not ingroup)) (insert " "))
+ (setq prompt (concat prompt "[" (char-to-string c) "] " tg " "))
(insert "[" c "] " tg (make-string
(- fwidth 4 (length tg)) ?\ ))
(when (and (= (setq cnt (1+ cnt)) ncol)
@@ -12697,14 +10658,17 @@ Returns the new TODO keyword, or nil if no state change should occur."
(insert "\n")
(goto-char (point-min))
(unless expert (org-fit-window-to-buffer))
- (message "[a-z..]:Set [SPC]:clear")
+ (message (concat "[a-z..]:Set [SPC]:clear"
+ (if expert (concat "\n" prompt) "")))
(setq c (let ((inhibit-quit t)) (read-char-exclusive)))
+ (setq subtable (nreverse subtable))
(cond
((or (= c ?\C-g)
(and (= c ?q) (not (rassoc c fulltable))))
(setq quit-flag t))
((= c ?\ ) nil)
- ((setq e (rassoc c fulltable) tg (car e))
+ ((setq e (or (rassoc c subtable) (rassoc c fulltable))
+ tg (car e))
tg)
(t (setq quit-flag t)))))))
@@ -12905,7 +10869,7 @@ of `org-todo-keywords-1'."
(interactive "P")
(let ((case-fold-search nil)
(kwd-re
- (cond ((null arg) org-not-done-regexp)
+ (cond ((null arg) (concat org-not-done-regexp "\\s-"))
((equal arg '(4))
(let ((kwd
(completing-read "Keyword (or KWD1|KWD2|...): "
@@ -13610,7 +11574,7 @@ from the `before-change-functions' in the current buffer."
When called interactively with a `\\[universal-argument]' prefix,
show the priority in the minibuffer instead of changing it.
-When called programatically, ACTION can be `set', `up', `down',
+When called programmatically, ACTION can be `set', `up', `down',
or a character."
(interactive "P")
(when show
@@ -13714,7 +11678,7 @@ and by additional input from the age of a schedules or deadline entry."
"Find priority cookie and return priority."
(save-match-data
(if (functionp org-get-priority-function)
- (funcall org-get-priority-function)
+ (funcall org-get-priority-function s)
(if (not (string-match org-priority-regexp s))
(* 1000 (- org-lowest-priority org-default-priority))
(* 1000 (- org-lowest-priority
@@ -14308,60 +12272,66 @@ tags."
When called with `\\[universal-argument]' prefix argument ARG, \
realign all tags
-in the current buffer. If a region is active, set tags for
-all headlines in the region.
+in the current buffer.
+
+When called with `\\[universal-argument] \\[universal-argument]' prefix argument, \
+unconditionally do not
+offer the fast tag selection interface.
+
+If a region is active, set tags in the region according to the
+setting of `org-loop-over-headlines-in-active-region'.
This function is for interactive use only;
in Lisp code use `org-set-tags' instead."
(interactive "P")
- (cond
- (arg (org-align-tags t))
- ((and (org-region-active-p) org-loop-over-headlines-in-active-region)
- ;; Disable `org-loop-over-headlines-in-active-region' for
- ;; successive calls.
- (let (org-loop-over-headlines-in-active-region)
- (org-map-entries
- #'org-set-tags-command
- nil
- (if (eq org-loop-over-headlines-in-active-region 'start-level)
- 'region-start-level
- 'region)
- (lambda () (when (org-invisible-p) (org-end-of-subtree nil t))))))
- (t
- (save-excursion
- (org-back-to-heading)
- (let* ((all-tags (org-get-tags))
- (table (setq org-last-tags-completion-table
- (org--tag-add-to-alist
- (and org-complete-tags-always-offer-all-agenda-tags
- (org-global-tags-completion-table
- (org-agenda-files)))
- (or org-current-tag-alist (org-get-buffer-tags)))))
- (current-tags
- (cl-remove-if (lambda (tag) (get-text-property 0 'inherited tag))
- all-tags))
- (inherited-tags
- (cl-remove-if-not (lambda (tag) (get-text-property 0 'inherited tag))
- all-tags))
- (tags
- (replace-regexp-in-string
- ;; Ignore all forbidden characters in tags.
- "[^[:alnum:]_@#%]+" ":"
- (if (or (eq t org-use-fast-tag-selection)
- (and org-use-fast-tag-selection
- (delq nil (mapcar #'cdr table))))
- (org-fast-tag-selection
- current-tags
- inherited-tags
- table
- (and org-fast-tag-selection-include-todo org-todo-key-alist))
- (let ((org-add-colon-after-tag-completion (< 1 (length table))))
- (org-trim (completing-read
- "Tags: "
- #'org-tags-completion-function
- nil nil (org-make-tag-string current-tags)
- 'org-tags-history)))))))
- (org-set-tags tags))))))
+ (let ((org-use-fast-tag-selection
+ (unless (equal '(16) arg) org-use-fast-tag-selection)))
+ (cond
+ ((equal '(4) arg) (org-align-tags t))
+ ((and (org-region-active-p) org-loop-over-headlines-in-active-region)
+ (let (org-loop-over-headlines-in-active-region) ; hint: infinite recursion.
+ (org-map-entries
+ #'org-set-tags-command
+ nil
+ (if (eq org-loop-over-headlines-in-active-region 'start-level)
+ 'region-start-level
+ 'region)
+ (lambda () (when (org-invisible-p) (org-end-of-subtree nil t))))))
+ (t
+ (save-excursion
+ (org-back-to-heading)
+ (let* ((all-tags (org-get-tags))
+ (table (setq org-last-tags-completion-table
+ (org--tag-add-to-alist
+ (and org-complete-tags-always-offer-all-agenda-tags
+ (org-global-tags-completion-table
+ (org-agenda-files)))
+ (or org-current-tag-alist (org-get-buffer-tags)))))
+ (current-tags
+ (cl-remove-if (lambda (tag) (get-text-property 0 'inherited tag))
+ all-tags))
+ (inherited-tags
+ (cl-remove-if-not (lambda (tag) (get-text-property 0 'inherited tag))
+ all-tags))
+ (tags
+ (replace-regexp-in-string
+ ;; Ignore all forbidden characters in tags.
+ "[^[:alnum:]_@#%]+" ":"
+ (if (or (eq t org-use-fast-tag-selection)
+ (and org-use-fast-tag-selection
+ (delq nil (mapcar #'cdr table))))
+ (org-fast-tag-selection
+ current-tags
+ inherited-tags
+ table
+ (and org-fast-tag-selection-include-todo org-todo-key-alist))
+ (let ((org-add-colon-after-tag-completion (< 1 (length table))))
+ (org-trim (completing-read
+ "Tags: "
+ #'org-tags-completion-function
+ nil nil (org-make-tag-string current-tags)
+ 'org-tags-history)))))))
+ (org-set-tags tags)))))))
(defun org-align-tags (&optional all)
"Align tags in current entry.
@@ -14934,7 +12904,7 @@ but in some other way.")
Being in this list makes sure that they are offered for completion.")
(defun org--valid-property-p (property)
- "Non nil when string PROPERTY is a valid property name."
+ "Non-nil when string PROPERTY is a valid property name."
(not
(or (equal property "")
(string-match-p "\\s-" property))))
@@ -15037,7 +13007,7 @@ variables is set."
value)
(when (equal (org-get-heading t t t t)
(bound-and-true-p org-clock-current-task))
- (setq org-clock-effort (org-get-at-bol 'effort))
+ (setq org-clock-effort value)
(org-clock-update-mode-line))
(message "%s is now %s" org-effort-property value)))
@@ -15593,7 +13563,9 @@ COLUMN formats in the current buffer."
(delete-dups values))))
(defun org-insert-property-drawer ()
- "Insert a property drawer into the current entry."
+ "Insert a property drawer into the current entry.
+Do nothing if the drawer already exists. The newly created
+drawer is immediately hidden."
(org-with-wide-buffer
(if (or (not (featurep 'org-inlinetask)) (org-inlinetask-in-task-p))
(org-back-to-heading t)
@@ -15608,6 +13580,7 @@ COLUMN formats in the current buffer."
(let ((begin (1+ (point)))
(inhibit-read-only t))
(insert "\n:PROPERTIES:\n:END:")
+ (org-flag-drawer t nil (line-end-position 0) (point))
(when (eobp) (insert "\n"))
(org-indent-region begin (point))))))
@@ -16139,78 +14112,6 @@ with the current time without prompting the user."
(defvar org-read-date-analyze-futurep nil)
(defvar org-read-date-analyze-forced-year nil)
(defvar org-read-date-inactive)
-
-(defvar org-read-date-minibuffer-local-map
- (let* ((map (make-sparse-keymap)))
- (set-keymap-parent map minibuffer-local-map)
- (org-defkey map (kbd ".")
- (lambda () (interactive)
- ;; Are we at the beginning of the prompt?
- (if (looking-back "^[^:]+: "
- (let ((inhibit-field-text-motion t))
- (line-beginning-position)))
- (org-eval-in-calendar '(calendar-goto-today))
- (insert "."))))
- (org-defkey map (kbd "C-.")
- (lambda () (interactive)
- (org-eval-in-calendar '(calendar-goto-today))))
- (org-defkey map (kbd "M-S-<left>")
- (lambda () (interactive)
- (org-eval-in-calendar '(calendar-backward-month 1))))
- (org-defkey map (kbd "ESC S-<left>")
- (lambda () (interactive)
- (org-eval-in-calendar '(calendar-backward-month 1))))
- (org-defkey map (kbd "M-S-<right>")
- (lambda () (interactive)
- (org-eval-in-calendar '(calendar-forward-month 1))))
- (org-defkey map (kbd "ESC S-<right>")
- (lambda () (interactive)
- (org-eval-in-calendar '(calendar-forward-month 1))))
- (org-defkey map (kbd "M-S-<up>")
- (lambda () (interactive)
- (org-eval-in-calendar '(calendar-backward-year 1))))
- (org-defkey map (kbd "ESC S-<up>")
- (lambda () (interactive)
- (org-eval-in-calendar '(calendar-backward-year 1))))
- (org-defkey map (kbd "M-S-<down>")
- (lambda () (interactive)
- (org-eval-in-calendar '(calendar-forward-year 1))))
- (org-defkey map (kbd "ESC S-<down>")
- (lambda () (interactive)
- (org-eval-in-calendar '(calendar-forward-year 1))))
- (org-defkey map (kbd "S-<up>")
- (lambda () (interactive)
- (org-eval-in-calendar '(calendar-backward-week 1))))
- (org-defkey map (kbd "S-<down>")
- (lambda () (interactive)
- (org-eval-in-calendar '(calendar-forward-week 1))))
- (org-defkey map (kbd "S-<left>")
- (lambda () (interactive)
- (org-eval-in-calendar '(calendar-backward-day 1))))
- (org-defkey map (kbd "S-<right>")
- (lambda () (interactive)
- (org-eval-in-calendar '(calendar-forward-day 1))))
- (org-defkey map (kbd "!")
- (lambda () (interactive)
- (org-eval-in-calendar '(diary-view-entries))
- (message "")))
- (org-defkey map (kbd ">")
- (lambda () (interactive)
- (org-eval-in-calendar '(calendar-scroll-left 1))))
- (org-defkey map (kbd "<")
- (lambda () (interactive)
- (org-eval-in-calendar '(calendar-scroll-right 1))))
- (org-defkey map (kbd "C-v")
- (lambda () (interactive)
- (org-eval-in-calendar
- '(calendar-scroll-left-three-months 1))))
- (org-defkey map (kbd "M-v")
- (lambda () (interactive)
- (org-eval-in-calendar
- '(calendar-scroll-right-three-months 1))))
- map)
- "Keymap for minibuffer commands when using `org-read-date'.")
-
(defvar org-def)
(defvar org-defdecode)
(defvar org-with-time)
@@ -17596,12 +15497,10 @@ If there is already a time stamp at the cursor position, update it."
(encode-time 0 0 0 (nth 1 cal-date) (car cal-date) (nth 2 cal-date))))))
(defcustom org-image-actual-width t
- "Should we use the actual width of images when inlining them?
-
-When set to t, always use the image width.
+ "When non-nil, use the actual width of images when inlining them.
-When set to a number, use imagemagick (when available) to set
-the image's width to this value.
+When set to a number, use imagemagick (when available) to set the
+image's width to this value.
When set to a number in a list, try to get the width from any
#+ATTR.* keyword if it matches a width specification like
@@ -17613,7 +15512,9 @@ and fall back on that number if none is found.
When set to nil, try to get the width from an #+ATTR.* keyword
and fall back on the original width if none is found.
-This requires Emacs >= 24.1, build with imagemagick support."
+When set to any other non-nil value, always use the image width.
+
+This requires Emacs >= 24.1, built with imagemagick support."
:group 'org-appearance
:version "24.4"
:package-version '(Org . "8.0")
@@ -18214,7 +16115,7 @@ looks only before point, not after."
(org-in-regexp
"\\\\[a-zA-Z]+\\*?\\(\\(\\[[^][\n{}]*\\]\\)\\|\\({[^{}\n]*}\\)\\)*")))
-(defun org--format-latex-make-overlay (beg end image &optional imagetype)
+(defun org--make-preview-overlay (beg end image &optional imagetype)
"Build an overlay between BEG and END using IMAGE file.
Argument IMAGETYPE is the extension of the displayed image,
as a string. It defaults to \"png\"."
@@ -18230,88 +16131,91 @@ as a string. It defaults to \"png\"."
'display
(list 'image :type imagetype :file image :ascent 'center))))
-(defun org--list-latex-overlays (&optional beg end)
- "List all Org LaTeX overlays in current buffer.
-Limit to overlays between BEG and END when those are provided."
- (cl-remove-if-not
- (lambda (o) (eq (overlay-get o 'org-overlay-type) 'org-latex-overlay))
- (overlays-in (or beg (point-min)) (or end (point-max)))))
-
-(defun org-remove-latex-fragment-image-overlays (&optional beg end)
+(defun org-clear-latex-preview (&optional beg end)
"Remove all overlays with LaTeX fragment images in current buffer.
When optional arguments BEG and END are non-nil, remove all
overlays between them instead. Return a non-nil value when some
overlays were removed, nil otherwise."
- (let ((overlays (org--list-latex-overlays beg end)))
+ (let ((overlays
+ (cl-remove-if-not
+ (lambda (o) (eq (overlay-get o 'org-overlay-type) 'org-latex-overlay))
+ (overlays-in (or beg (point-min)) (or end (point-max))))))
(mapc #'delete-overlay overlays)
overlays))
-(defun org-toggle-latex-fragment (&optional arg)
- "Preview the LaTeX fragment at point, or all locally or globally.
-
-If the cursor is on a LaTeX fragment, create the image and overlay
-it over the source code, if there is none. Remove it otherwise.
-If there is no fragment at point, display all fragments in the
-current section.
+(defun org--latex-preview-region (beg end)
+ "Preview LaTeX fragments between BEG and END.
+BEG and END are buffer positions."
+ (let ((file (buffer-file-name (buffer-base-buffer))))
+ (save-excursion
+ (org-format-latex
+ (concat org-preview-latex-image-directory "org-ltximg")
+ beg end
+ ;; Emacs cannot overlay images from remote hosts. Create it in
+ ;; `temporary-file-directory' instead.
+ (if (or (not file) (file-remote-p file))
+ temporary-file-directory
+ default-directory)
+ 'overlays nil 'forbuffer org-preview-latex-default-process))))
+
+(defun org-latex-preview (&optional arg)
+ "Toggle preview of the LaTeX fragment at point.
+
+If the cursor is on a LaTeX fragment, create the image and
+overlay it over the source code, if there is none. Remove it
+otherwise. If there is no fragment at point, display images for
+all fragments in the current section.
+
+With a `\\[universal-argument]' prefix argument ARG, clear images \
+for all fragments
+in the current section.
+
+With a `\\[universal-argument] \\[universal-argument]' prefix \
+argument ARG, display image for all
+fragments in the buffer.
-With prefix ARG, preview or clear image for all fragments in the
-current subtree or in the whole buffer when used before the first
-headline. With a prefix ARG `\\[universal-argument] \
-\\[universal-argument]' preview or clear images
-for all fragments in the buffer."
+With a `\\[universal-argument] \\[universal-argument] \
+\\[universal-argument]' prefix argument ARG, clear image for all
+fragments in the buffer."
(interactive "P")
- (when (display-graphic-p)
- (catch 'exit
- (save-excursion
- (let (beg end msg)
- (cond
- ((or (equal arg '(16))
- (and (equal arg '(4))
- (org-with-limited-levels (org-before-first-heading-p))))
- (if (org-remove-latex-fragment-image-overlays)
- (progn (message "LaTeX fragments images removed from buffer")
- (throw 'exit nil))
- (setq msg "Creating images for buffer...")))
- ((equal arg '(4))
- (org-with-limited-levels (org-back-to-heading t))
- (setq beg (point))
- (setq end (progn (org-end-of-subtree t) (point)))
- (if (org-remove-latex-fragment-image-overlays beg end)
- (progn
- (message "LaTeX fragment images removed from subtree")
- (throw 'exit nil))
- (setq msg "Creating images for subtree...")))
- ((let ((datum (org-element-context)))
- (when (memq (org-element-type datum)
- '(latex-environment latex-fragment))
- (setq beg (org-element-property :begin datum))
- (setq end (org-element-property :end datum))
- (if (org-remove-latex-fragment-image-overlays beg end)
- (progn (message "LaTeX fragment image removed")
- (throw 'exit nil))
- (setq msg "Creating image...")))))
- (t
- (org-with-limited-levels
- (setq beg (if (org-at-heading-p) (line-beginning-position)
- (outline-previous-heading)
- (point)))
- (setq end (progn (outline-next-heading) (point)))
- (if (org-remove-latex-fragment-image-overlays beg end)
- (progn
- (message "LaTeX fragment images removed from section")
- (throw 'exit nil))
- (setq msg "Creating images for section...")))))
- (let ((file (buffer-file-name (buffer-base-buffer))))
- (org-format-latex
- (concat org-preview-latex-image-directory "org-ltximg")
- beg end
- ;; Emacs cannot overlay images from remote hosts. Create
- ;; it in `temporary-file-directory' instead.
- (if (or (not file) (file-remote-p file))
- temporary-file-directory
- default-directory)
- 'overlays msg 'forbuffer org-preview-latex-default-process))
- (message (concat msg "done")))))))
+ (cond
+ ((not (display-graphic-p)) nil)
+ ;; Clear whole buffer.
+ ((equal arg '(64))
+ (org-clear-latex-preview (point-min) (point-max))
+ (message "LaTeX previews removed from buffer"))
+ ;; Preview whole buffer.
+ ((equal arg '(16))
+ (message "Creating LaTeX previews in buffer...")
+ (org--latex-preview-region (point-min) (point-max))
+ (message "Creating LaTeX previews in buffer... done."))
+ ;; Clear current section.
+ ((equal arg '(4))
+ (org-clear-latex-preview
+ (if (org-before-first-heading-p) (point-min)
+ (save-excursion
+ (org-with-limited-levels (org-back-to-heading t) (point))))
+ (org-with-limited-levels (org-entry-end-position))))
+ ;; Toggle preview on LaTeX code at point.
+ ((let ((datum (org-element-context)))
+ (and (memq (org-element-type datum) '(latex-environment latex-fragment))
+ (let ((beg (org-element-property :begin datum))
+ (end (org-element-property :end datum)))
+ (if (org-clear-latex-preview beg end)
+ (message "LaTeX preview removed")
+ (message "Creating LaTeX preview...")
+ (org--latex-preview-region beg end)
+ (message "Creating LaTeX preview... done."))
+ t))))
+ ;; Preview current section.
+ (t
+ (let ((beg (if (org-before-first-heading-p) (point-min)
+ (save-excursion
+ (org-with-limited-levels (org-back-to-heading t) (point)))))
+ (end (org-with-limited-levels (org-entry-end-position))))
+ (message "Creating LaTeX previews in section...")
+ (org--latex-preview-region beg end)
+ (message "Creating LaTeX previews in section... done.")))))
(defun org-format-latex
(prefix &optional beg end dir overlays msg forbuffer processing-type)
@@ -18412,7 +16316,7 @@ Some of the options can be changed using the variable
(when (eq (overlay-get o 'org-overlay-type)
'org-latex-overlay)
(delete-overlay o)))
- (org--format-latex-make-overlay beg end movefile imagetype)
+ (org--make-preview-overlay beg end movefile imagetype)
(goto-char end))
(delete-region beg end)
(insert
@@ -18438,7 +16342,7 @@ Some of the options can be changed using the variable
(defun org-create-math-formula (latex-frag &optional mathml-file)
"Convert LATEX-FRAG to MathML and store it in MATHML-FILE.
Use `org-latex-to-mathml-convert-command'. If the conversion is
-sucessful, return the portion between \"<math...> </math>\"
+successful, return the portion between \"<math...> </math>\"
elements otherwise return nil. When MATHML-FILE is specified,
write the results in to that file. When invoked as an
interactive command, prompt for LATEX-FRAG, with initial value
@@ -18558,7 +16462,6 @@ a HTML file."
(cdr (assq processing-type org-preview-latex-process-alist)))
(programs (plist-get processing-info :programs))
(error-message (or (plist-get processing-info :message) ""))
- (use-xcolor (plist-get processing-info :use-xcolor))
(image-input-type (plist-get processing-info :image-input-type))
(image-output-type (plist-get processing-info :image-output-type))
(post-clean (or (plist-get processing-info :post-clean)
@@ -18589,36 +16492,23 @@ a HTML file."
(resize-mini-windows nil)) ;Fix Emacs flicker when creating image.
(dolist (program programs)
(org-check-external-command program error-message))
- (if use-xcolor
- (progn (if (eq fg 'default)
- (setq fg (org-latex-color :foreground))
- (setq fg (org-latex-color-format fg)))
- (if (eq bg 'default)
- (setq bg (org-latex-color :background))
- (setq bg (org-latex-color-format
- (if (string= bg "Transparent") "white" bg))))
- (with-temp-file texfile
- (insert latex-header)
- (insert "\n\\begin{document}\n"
- "\\definecolor{fg}{rgb}{" fg "}\n"
- "\\definecolor{bg}{rgb}{" bg "}\n"
- "\n\\pagecolor{bg}\n"
- "\n{\\color{fg}\n"
- string
- "\n}\n"
- "\n\\end{document}\n")))
- (if (eq fg 'default)
- (setq fg (org-dvipng-color :foreground))
- (unless (string= fg "Transparent")
- (setq fg (org-dvipng-color-format fg))))
- (if (eq bg 'default)
- (setq bg (org-dvipng-color :background))
- (unless (string= bg "Transparent")
- (setq bg (org-dvipng-color-format bg))))
- (with-temp-file texfile
- (insert latex-header)
- (insert "\n\\begin{document}\n" string "\n\\end{document}\n")))
-
+ (if (eq fg 'default)
+ (setq fg (org-latex-color :foreground))
+ (setq fg (org-latex-color-format fg)))
+ (if (eq bg 'default)
+ (setq bg (org-latex-color :background))
+ (setq bg (org-latex-color-format
+ (if (string= bg "Transparent") "white" bg))))
+ (with-temp-file texfile
+ (insert latex-header)
+ (insert "\n\\begin{document}\n"
+ "\\definecolor{fg}{rgb}{" fg "}\n"
+ "\\definecolor{bg}{rgb}{" bg "}\n"
+ "\n\\pagecolor{bg}\n"
+ "\n{\\color{fg}\n"
+ string
+ "\n}\n"
+ "\n\\end{document}\n"))
(let* ((err-msg (format "Please adjust `%s' part of \
`org-preview-latex-process-alist'."
processing-type))
@@ -18628,9 +16518,7 @@ a HTML file."
(image-output-file
(org-compile-file
image-input-file image-converter image-output-type err-msg log-buf
- `((?F . ,(shell-quote-argument fg))
- (?B . ,(shell-quote-argument bg))
- (?D . ,(shell-quote-argument (format "%s" dpi)))
+ `((?D . ,(shell-quote-argument (format "%s" dpi)))
(?S . ,(shell-quote-argument (format "%s" (/ dpi 140.0))))))))
(copy-file image-output-file tofile 'replace)
(dolist (e post-clean)
@@ -18766,6 +16654,8 @@ conventions:
type. In this case, that link must be a well-formed plain
or angle link, i.e., it must have an explicit \"file\" type.
+Equip each image with the key-map `image-map'.
+
When optional argument INCLUDE-LINKED is non-nil, also links with
a text description part will be inlined. This can be nice for
a quick look at those images, but it does not reflect what
@@ -18773,119 +16663,123 @@ exported files will look like.
When optional argument REFRESH is non-nil, refresh existing
images between BEG and END. This will create new image displays
-only if necessary. BEG and END default to the buffer
-boundaries."
+only if necessary.
+
+BEG and END define the considered part. They default to the
+buffer boundaries with possible narrowing."
(interactive "P")
(when (display-graphic-p)
(unless refresh
(org-remove-inline-images)
(when (fboundp 'clear-image-cache) (clear-image-cache)))
- (org-with-point-at (or beg 1)
- (let* ((case-fold-search t)
- (file-extension-re (image-file-name-regexp))
- (link-abbrevs (mapcar #'car
- (append org-link-abbrev-alist-local
- org-link-abbrev-alist)))
- ;; Check absolute, relative file names and explicit
- ;; "file:" links. Also check link abbreviations since
- ;; some might expand to "file" links.
- (file-types-re
- (format "\\[\\[\\(?:file%s:\\|[./~]\\)\\|\\]\\[\\(<?file:\\)"
- (if (not link-abbrevs) ""
- (concat "\\|" (regexp-opt link-abbrevs))))))
- (while (re-search-forward file-types-re end t)
- (let* ((link (org-element-lineage
- (save-match-data (org-element-context))
- '(link) t))
- (inner-start (match-beginning 1))
- (path
- (cond
- ;; No link at point; no inline image.
- ((not link) nil)
- ;; File link without a description. Also handle
- ;; INCLUDE-LINKED here since it should have
- ;; precedence over the next case. I.e., if link
- ;; contains filenames in both the path and the
- ;; description, prioritize the path only when
- ;; INCLUDE-LINKED is non-nil.
- ((or (not (org-element-property :contents-begin link))
- include-linked)
- (and (equal "file" (org-element-property :type link))
- (org-element-property :path link)))
- ;; Link with a description. Check if description
- ;; is a filename. Even if Org doesn't have syntax
- ;; for those -- clickable image -- constructs, fake
- ;; them, as in `org-export-insert-image-links'.
- ((not inner-start) nil)
- (t
- (org-with-point-at inner-start
- (and (looking-at
- (if (char-equal ?< (char-after inner-start))
- org-angle-link-re
- org-plain-link-re))
- ;; File name must fill the whole
- ;; description.
- (= (org-element-property :contents-end link)
- (match-end 0))
- (match-string 2)))))))
- (when (and path (string-match-p file-extension-re path))
- (let ((file (expand-file-name path)))
- (when (file-exists-p file)
- (let ((width
- ;; Apply `org-image-actual-width' specifications.
- (cond
- ((not (image-type-available-p 'imagemagick)) nil)
- ((eq org-image-actual-width t) nil)
- ((listp org-image-actual-width)
- (or
- ;; First try to find a width among
- ;; attributes associated to the paragraph
- ;; containing link.
- (let ((paragraph
- (let ((e link))
- (while (and (setq e (org-element-property
- :parent e))
- (not (eq (org-element-type e)
- 'paragraph))))
- e)))
- (when paragraph
- (save-excursion
- (goto-char (org-element-property :begin paragraph))
- (when
- (re-search-forward
- "^[ \t]*#\\+attr_.*?: +.*?:width +\\(\\S-+\\)"
- (org-element-property
- :post-affiliated paragraph)
- t)
- (string-to-number (match-string 1))))))
- ;; Otherwise, fall-back to provided number.
- (car org-image-actual-width)))
- ((numberp org-image-actual-width)
- org-image-actual-width)))
- (old (get-char-property-and-overlay
- (org-element-property :begin link)
- 'org-image-overlay)))
- (if (and (car-safe old) refresh)
- (image-refresh (overlay-get (cdr old) 'display))
- (let ((image (create-image file
- (and width 'imagemagick)
- nil
- :width width)))
- (when image
- (let ((ov (make-overlay
- (org-element-property :begin link)
- (progn
- (goto-char
- (org-element-property :end link))
- (skip-chars-backward " \t")
- (point)))))
- (overlay-put ov 'display image)
- (overlay-put ov 'face 'default)
- (overlay-put ov 'org-image-overlay t)
- (overlay-put
- ov 'modification-hooks
- (list 'org-display-inline-remove-overlay))
- (push ov org-inline-image-overlays)))))))))))))))
+ (let ((end (or end (point-max))))
+ (org-with-point-at (or beg (point-min))
+ (let* ((case-fold-search t)
+ (file-extension-re (image-file-name-regexp))
+ (link-abbrevs (mapcar #'car
+ (append org-link-abbrev-alist-local
+ org-link-abbrev-alist)))
+ ;; Check absolute, relative file names and explicit
+ ;; "file:" links. Also check link abbreviations since
+ ;; some might expand to "file" links.
+ (file-types-re
+ (format "\\[\\[\\(?:file%s:\\|attachment:\\|[./~]\\)\\|\\]\\[\\(<?file:\\)"
+ (if (not link-abbrevs) ""
+ (concat "\\|" (regexp-opt link-abbrevs))))))
+ (while (re-search-forward file-types-re end t)
+ (let* ((link (org-element-lineage
+ (save-match-data (org-element-context))
+ '(link) t))
+ (linktype (org-element-property :type link))
+ (inner-start (match-beginning 1))
+ (path
+ (cond
+ ;; No link at point; no inline image.
+ ((not link) nil)
+ ;; File link without a description. Also handle
+ ;; INCLUDE-LINKED here since it should have
+ ;; precedence over the next case. I.e., if link
+ ;; contains filenames in both the path and the
+ ;; description, prioritize the path only when
+ ;; INCLUDE-LINKED is non-nil.
+ ((or (not (org-element-property :contents-begin link))
+ include-linked)
+ (and (or (equal "file" linktype)
+ (equal "attachment" linktype))
+ (org-element-property :path link)))
+ ;; Link with a description. Check if description
+ ;; is a filename. Even if Org doesn't have syntax
+ ;; for those -- clickable image -- constructs, fake
+ ;; them, as in `org-export-insert-image-links'.
+ ((not inner-start) nil)
+ (t
+ (org-with-point-at inner-start
+ (and (looking-at
+ (if (char-equal ?< (char-after inner-start))
+ org-link-angle-re
+ org-link-plain-re))
+ ;; File name must fill the whole
+ ;; description.
+ (= (org-element-property :contents-end link)
+ (match-end 0))
+ (match-string 2)))))))
+ (when (and path (string-match-p file-extension-re path))
+ (let ((file (if (equal "attachment" linktype)
+ (progn
+ (require 'org-attach)
+ (ignore-errors (org-attach-expand path)))
+ (expand-file-name path))))
+ (when (and file (file-exists-p file))
+ (let ((width
+ ;; Apply `org-image-actual-width' specifications.
+ (cond
+ ((eq org-image-actual-width t) nil)
+ ((listp org-image-actual-width)
+ (or
+ ;; First try to find a width among
+ ;; attributes associated to the paragraph
+ ;; containing link.
+ (pcase (org-element-lineage link '(paragraph))
+ (`nil nil)
+ (p
+ (let* ((case-fold-search t)
+ (end (org-element-property :post-affiliated p))
+ (re "^[ \t]*#\\+attr_.*?: +.*?:width +\\(\\S-+\\)"))
+ (when (org-with-point-at
+ (org-element-property :begin p)
+ (re-search-forward re end t))
+ (string-to-number (match-string 1))))))
+ ;; Otherwise, fall-back to provided number.
+ (car org-image-actual-width)))
+ ((numberp org-image-actual-width)
+ org-image-actual-width)
+ (t nil)))
+ (old (get-char-property-and-overlay
+ (org-element-property :begin link)
+ 'org-image-overlay)))
+ (if (and (car-safe old) refresh)
+ (image-refresh (overlay-get (cdr old) 'display))
+ (let ((image (create-image file
+ (and (image-type-available-p 'imagemagick)
+ width 'imagemagick)
+ nil
+ :width width)))
+ (when image
+ (let ((ov (make-overlay
+ (org-element-property :begin link)
+ (progn
+ (goto-char
+ (org-element-property :end link))
+ (skip-chars-backward " \t")
+ (point)))))
+ (overlay-put ov 'display image)
+ (overlay-put ov 'face 'default)
+ (overlay-put ov 'org-image-overlay t)
+ (overlay-put
+ ov 'modification-hooks
+ (list 'org-display-inline-remove-overlay))
+ (overlay-put ov 'keymap image-map)
+ (push ov org-inline-image-overlays))))))))))))))))
(defun org-display-inline-remove-overlay (ov after _beg _end &optional _len)
"Remove inline-display overlay if a corresponding region is modified."
@@ -18900,412 +16794,9 @@ boundaries."
(mapc #'delete-overlay org-inline-image-overlays)
(setq org-inline-image-overlays nil))
-
-;;; Key bindings
-
-(defun org-remap (map &rest commands)
- "In MAP, remap the functions given in COMMANDS.
-COMMANDS is a list of alternating OLDDEF NEWDEF command names."
- (let (new old)
- (while commands
- (setq old (pop commands) new (pop commands))
- (org-defkey map (vector 'remap old) new))))
-
-;;;; Outline functions that can be remapped in Org
-(define-key org-mode-map [remap outline-mark-subtree] #'org-mark-subtree)
-(define-key org-mode-map [remap outline-show-subtree] #'org-show-subtree)
-(define-key org-mode-map [remap outline-forward-same-level]
- #'org-forward-heading-same-level)
-(define-key org-mode-map [remap outline-backward-same-level]
- #'org-backward-heading-same-level)
-(define-key org-mode-map [remap outline-show-branches]
- #'org-kill-note-or-show-branches)
-(define-key org-mode-map [remap outline-promote] #'org-promote-subtree)
-(define-key org-mode-map [remap outline-demote] #'org-demote-subtree)
-(define-key org-mode-map [remap outline-insert-heading] #'org-ctrl-c-ret)
-(define-key org-mode-map [remap outline-next-visible-heading]
- #'org-next-visible-heading)
-(define-key org-mode-map [remap outline-previous-visible-heading]
- #'org-previous-visible-heading)
-(define-key org-mode-map [remap show-children] #'org-show-children)
-
-;;;; Make `C-c C-x' a prefix key
-(org-defkey org-mode-map (kbd "C-c C-x") (make-sparse-keymap))
-
-;;;; TAB key with modifiers
-(org-defkey org-mode-map (kbd "C-i") #'org-cycle)
-(org-defkey org-mode-map (kbd "<tab>") #'org-cycle)
-(org-defkey org-mode-map (kbd "C-<tab>") #'org-force-cycle-archived)
-(org-defkey org-mode-map (kbd "M-<tab>") #'pcomplete)
-(org-defkey org-mode-map (kbd "M-TAB") #'pcomplete)
-(org-defkey org-mode-map (kbd "ESC <tab>") #'pcomplete)
-(org-defkey org-mode-map (kbd "ESC TAB") #'pcomplete)
-
-(org-defkey org-mode-map (kbd "<S-iso-leftab>") #'org-shifttab)
-(org-defkey org-mode-map (kbd "S-<tab>") #'org-shifttab)
-(define-key org-mode-map (kbd "<backtab>") #'org-shifttab)
-
-;;;; RET key with modifiers
-(org-defkey org-mode-map (kbd "S-<return>") #'org-table-copy-down)
-(org-defkey org-mode-map (kbd "M-S-<return>") #'org-insert-todo-heading)
-(org-defkey org-mode-map (kbd "ESC S-<return>") #'org-insert-todo-heading)
-(org-defkey org-mode-map (kbd "M-RET") #'org-meta-return)
-(org-defkey org-mode-map (kbd "ESC RET") #'org-meta-return)
-
-;;;; Cursor keys with modifiers
-(org-defkey org-mode-map (kbd "M-<left>") #'org-metaleft)
-(org-defkey org-mode-map (kbd "M-<right>") #'org-metaright)
-(org-defkey org-mode-map (kbd "ESC <right>") #'org-metaright)
-(org-defkey org-mode-map (kbd "M-<up>") #'org-metaup)
-(org-defkey org-mode-map (kbd "ESC <up>") #'org-metaup)
-(org-defkey org-mode-map (kbd "M-<down>") #'org-metadown)
-(org-defkey org-mode-map (kbd "ESC <down>") #'org-metadown)
-
-(org-defkey org-mode-map (kbd "C-M-S-<right>") #'org-increase-number-at-point)
-(org-defkey org-mode-map (kbd "C-M-S-<left>") #'org-decrease-number-at-point)
-(org-defkey org-mode-map (kbd "M-S-<left>") #'org-shiftmetaleft)
-(org-defkey org-mode-map (kbd "ESC S-<left>") #'org-shiftmetaleft)
-(org-defkey org-mode-map (kbd "M-S-<right>") #'org-shiftmetaright)
-(org-defkey org-mode-map (kbd "ESC S-<right>") #'org-shiftmetaright)
-(org-defkey org-mode-map (kbd "M-S-<up>") #'org-shiftmetaup)
-(org-defkey org-mode-map (kbd "ESC S-<up>") #'org-shiftmetaup)
-(org-defkey org-mode-map (kbd "M-S-<down>") #'org-shiftmetadown)
-(org-defkey org-mode-map (kbd "ESC S-<down>") #'org-shiftmetadown)
-
-(org-defkey org-mode-map (kbd "S-<up>") #'org-shiftup)
-(org-defkey org-mode-map (kbd "S-<down>") #'org-shiftdown)
-(org-defkey org-mode-map (kbd "S-<left>") #'org-shiftleft)
-(org-defkey org-mode-map (kbd "S-<right>") #'org-shiftright)
-
-(org-defkey org-mode-map (kbd "C-S-<right>") #'org-shiftcontrolright)
-(org-defkey org-mode-map (kbd "C-S-<left>") #'org-shiftcontrolleft)
-(org-defkey org-mode-map (kbd "C-S-<up>") #'org-shiftcontrolup)
-(org-defkey org-mode-map (kbd "C-S-<down>") #'org-shiftcontroldown)
-
-;;;; Babel keys
-(define-key org-mode-map org-babel-key-prefix org-babel-map)
-(pcase-dolist (`(,key . ,def) org-babel-key-bindings)
- (define-key org-babel-map key def))
-
-;;;; Extra keys for TTY access.
-
-;; We only set them when really needed because otherwise the
-;; menus don't show the simple keys
-
-(when (or org-use-extra-keys (not window-system))
- (org-defkey org-mode-map (kbd "C-c C-x c") #'org-table-copy-down)
- (org-defkey org-mode-map (kbd "C-c C-x m") #'org-meta-return)
- (org-defkey org-mode-map (kbd "C-c C-x M") #'org-insert-todo-heading)
- (org-defkey org-mode-map (kbd "C-c C-x RET") #'org-meta-return)
- (org-defkey org-mode-map (kbd "ESC RET") #'org-meta-return)
- (org-defkey org-mode-map (kbd "ESC <left>") #'org-metaleft)
- (org-defkey org-mode-map (kbd "C-c C-x l") #'org-metaleft)
- (org-defkey org-mode-map (kbd "ESC <right>") #'org-metaright)
- (org-defkey org-mode-map (kbd "C-c C-x r") #'org-metaright)
- (org-defkey org-mode-map (kbd "C-c C-x u") #'org-metaup)
- (org-defkey org-mode-map (kbd "C-c C-x d") #'org-metadown)
- (org-defkey org-mode-map (kbd "C-c C-x L") #'org-shiftmetaleft)
- (org-defkey org-mode-map (kbd "C-c C-x R") #'org-shiftmetaright)
- (org-defkey org-mode-map (kbd "C-c C-x U") #'org-shiftmetaup)
- (org-defkey org-mode-map (kbd "C-c C-x D") #'org-shiftmetadown)
- (org-defkey org-mode-map (kbd "C-c <up>") #'org-shiftup)
- (org-defkey org-mode-map (kbd "C-c <down>") #'org-shiftdown)
- (org-defkey org-mode-map (kbd "C-c <left>") #'org-shiftleft)
- (org-defkey org-mode-map (kbd "C-c <right>") #'org-shiftright)
- (org-defkey org-mode-map (kbd "C-c C-x <right>") #'org-shiftcontrolright)
- (org-defkey org-mode-map (kbd "C-c C-x <left>") #'org-shiftcontrolleft))
-
-;;;; Narrow map
-(org-defkey narrow-map "s" #'org-narrow-to-subtree)
-(org-defkey narrow-map "b" #'org-narrow-to-block)
-(org-defkey narrow-map "e" #'org-narrow-to-element)
-
-;;;; Remap usual Emacs bindings
-(org-remap org-mode-map
- 'self-insert-command 'org-self-insert-command
- 'delete-char 'org-delete-char
- 'delete-backward-char 'org-delete-backward-char
- 'kill-line 'org-kill-line
- 'open-line 'org-open-line
- 'yank 'org-yank
- 'comment-dwim 'org-comment-dwim
- 'move-beginning-of-line 'org-beginning-of-line
- 'move-end-of-line 'org-end-of-line
- 'forward-paragraph 'org-forward-paragraph
- 'backward-paragraph 'org-backward-paragraph
- 'backward-sentence 'org-backward-sentence
- 'forward-sentence 'org-forward-sentence
- 'fill-paragraph 'org-fill-paragraph
- 'delete-indentation 'org-delete-indentation
- 'transpose-words 'org-transpose-words)
-
-;;;; All the other keys
-(org-defkey org-mode-map (kbd "|") #'org-force-self-insert)
-(org-defkey org-mode-map (kbd "C-c C-r") #'org-reveal)
-(org-defkey org-mode-map (kbd "C-M-t") #'org-transpose-element)
-(org-defkey org-mode-map (kbd "M-}") #'org-forward-element)
-(org-defkey org-mode-map (kbd "ESC }") #'org-forward-element)
-(org-defkey org-mode-map (kbd "M-{") #'org-backward-element)
-(org-defkey org-mode-map (kbd "ESC {") #'org-backward-element)
-(org-defkey org-mode-map (kbd "C-c C-^") #'org-up-element)
-(org-defkey org-mode-map (kbd "C-c C-_") #'org-down-element)
-(org-defkey org-mode-map (kbd "C-c C-f") #'org-forward-heading-same-level)
-(org-defkey org-mode-map (kbd "C-c C-b") #'org-backward-heading-same-level)
-(org-defkey org-mode-map (kbd "C-c M-f") #'org-next-block)
-(org-defkey org-mode-map (kbd "C-c M-b") #'org-previous-block)
-(org-defkey org-mode-map (kbd "C-c $") #'org-archive-subtree)
-(org-defkey org-mode-map (kbd "C-c C-x C-s") #'org-archive-subtree)
-(org-defkey org-mode-map (kbd "C-c C-x C-a") #'org-archive-subtree-default)
-(org-defkey org-mode-map (kbd "C-c C-x d") #'org-insert-drawer)
-(org-defkey org-mode-map (kbd "C-c C-x a") #'org-toggle-archive-tag)
-(org-defkey org-mode-map (kbd "C-c C-x A") #'org-archive-to-archive-sibling)
-(org-defkey org-mode-map (kbd "C-c C-x b") #'org-tree-to-indirect-buffer)
-(org-defkey org-mode-map (kbd "C-c C-x q") #'org-toggle-tags-groups)
-(org-defkey org-mode-map (kbd "C-c C-j") #'org-goto)
-(org-defkey org-mode-map (kbd "C-c C-t") #'org-todo)
-(org-defkey org-mode-map (kbd "C-c C-q") #'org-set-tags-command)
-(org-defkey org-mode-map (kbd "C-c C-s") #'org-schedule)
-(org-defkey org-mode-map (kbd "C-c C-d") #'org-deadline)
-(org-defkey org-mode-map (kbd "C-c ;") #'org-toggle-comment)
-(org-defkey org-mode-map (kbd "C-c C-w") #'org-refile)
-(org-defkey org-mode-map (kbd "C-c M-w") #'org-copy)
-(org-defkey org-mode-map (kbd "C-c /") #'org-sparse-tree) ;minor-mode reserved
-(org-defkey org-mode-map (kbd "C-c \\") #'org-match-sparse-tree) ;minor-mode r.
-(org-defkey org-mode-map (kbd "C-c RET") #'org-ctrl-c-ret)
-(org-defkey org-mode-map (kbd "C-c C-x c") #'org-clone-subtree-with-time-shift)
-(org-defkey org-mode-map (kbd "C-c C-x v") #'org-copy-visible)
-(org-defkey org-mode-map (kbd "C-<return>") #'org-insert-heading-respect-content)
-(org-defkey org-mode-map (kbd "C-S-<return>") #'org-insert-todo-heading-respect-content)
-(org-defkey org-mode-map (kbd "C-c C-x C-n") #'org-next-link)
-(org-defkey org-mode-map (kbd "C-c C-x C-p") #'org-previous-link)
-(org-defkey org-mode-map (kbd "C-c C-l") #'org-insert-link)
-(org-defkey org-mode-map (kbd "C-c M-l") #'org-insert-last-stored-link)
-(org-defkey org-mode-map (kbd "C-c C-M-l") #'org-insert-all-links)
-(org-defkey org-mode-map (kbd "C-c C-o") #'org-open-at-point)
-(org-defkey org-mode-map (kbd "C-c %") #'org-mark-ring-push)
-(org-defkey org-mode-map (kbd "C-c &") #'org-mark-ring-goto)
-(org-defkey org-mode-map (kbd "C-c C-z") #'org-add-note) ;alternative binding
-(org-defkey org-mode-map (kbd "C-c .") #'org-time-stamp) ;minor-mode reserved
-(org-defkey org-mode-map (kbd "C-c !") #'org-time-stamp-inactive) ;minor-mode r.
-(org-defkey org-mode-map (kbd "C-c ,") #'org-priority) ;minor-mode reserved
-(org-defkey org-mode-map (kbd "C-c C-y") #'org-evaluate-time-range)
-(org-defkey org-mode-map (kbd "C-c >") #'org-goto-calendar)
-(org-defkey org-mode-map (kbd "C-c <") #'org-date-from-calendar)
-(org-defkey org-mode-map (kbd "C-,") #'org-cycle-agenda-files)
-(org-defkey org-mode-map (kbd "C-'") #'org-cycle-agenda-files)
-(org-defkey org-mode-map (kbd "C-c [") #'org-agenda-file-to-front)
-(org-defkey org-mode-map (kbd "C-c ]") #'org-remove-file)
-(org-defkey org-mode-map (kbd "C-c C-x <") #'org-agenda-set-restriction-lock)
-(org-defkey org-mode-map (kbd "C-c C-x >") #'org-agenda-remove-restriction-lock)
-(org-defkey org-mode-map (kbd "C-c -") #'org-ctrl-c-minus)
-(org-defkey org-mode-map (kbd "C-c *") #'org-ctrl-c-star)
-(org-defkey org-mode-map (kbd "C-c TAB") #'org-ctrl-c-tab)
-(org-defkey org-mode-map (kbd "C-c ^") #'org-sort)
-(org-defkey org-mode-map (kbd "C-c C-c") #'org-ctrl-c-ctrl-c)
-(org-defkey org-mode-map (kbd "C-c C-k") #'org-kill-note-or-show-branches)
-(org-defkey org-mode-map (kbd "C-c #") #'org-update-statistics-cookies)
-(org-defkey org-mode-map (kbd "RET") #'org-return)
-(org-defkey org-mode-map (kbd "C-j") #'org-return-indent)
-(org-defkey org-mode-map (kbd "C-c ?") #'org-table-field-info)
-(org-defkey org-mode-map (kbd "C-c SPC") #'org-table-blank-field)
-(org-defkey org-mode-map (kbd "C-c +") #'org-table-sum)
-(org-defkey org-mode-map (kbd "C-c =") #'org-table-eval-formula)
-(org-defkey org-mode-map (kbd "C-c '") #'org-edit-special)
-(org-defkey org-mode-map (kbd "C-c `") #'org-table-edit-field)
-(org-defkey org-mode-map (kbd "C-c \" a") #'orgtbl-ascii-plot)
-(org-defkey org-mode-map (kbd "C-c \" g") #'org-plot/gnuplot)
-(org-defkey org-mode-map (kbd "C-c |") #'org-table-create-or-convert-from-region)
-(org-defkey org-mode-map (kbd "C-#") #'org-table-rotate-recalc-marks)
-(org-defkey org-mode-map (kbd "C-c ~") #'org-table-create-with-table.el)
-(org-defkey org-mode-map (kbd "C-c C-a") #'org-attach)
-(org-defkey org-mode-map (kbd "C-c }") #'org-table-toggle-coordinate-overlays)
-(org-defkey org-mode-map (kbd "C-c {") #'org-table-toggle-formula-debugger)
-(org-defkey org-mode-map (kbd "C-c C-e") #'org-export-dispatch)
-(org-defkey org-mode-map (kbd "C-c :") #'org-toggle-fixed-width)
-(org-defkey org-mode-map (kbd "C-c C-x C-f") #'org-emphasize)
-(org-defkey org-mode-map (kbd "C-c C-x f") #'org-footnote-action)
-(org-defkey org-mode-map (kbd "C-c @") #'org-mark-subtree)
-(org-defkey org-mode-map (kbd "M-h") #'org-mark-element)
-(org-defkey org-mode-map (kbd "ESC h") #'org-mark-element)
-(org-defkey org-mode-map (kbd "C-c C-*") #'org-list-make-subtree)
-(org-defkey org-mode-map (kbd "C-c C-x C-w") #'org-cut-special)
-(org-defkey org-mode-map (kbd "C-c C-x M-w") #'org-copy-special)
-(org-defkey org-mode-map (kbd "C-c C-x C-y") #'org-paste-special)
-(org-defkey org-mode-map (kbd "C-c C-x C-t") #'org-toggle-time-stamp-overlays)
-(org-defkey org-mode-map (kbd "C-c C-x C-i") #'org-clock-in)
-(org-defkey org-mode-map (kbd "C-c C-x C-x") #'org-clock-in-last)
-(org-defkey org-mode-map (kbd "C-c C-x C-z") #'org-resolve-clocks)
-(org-defkey org-mode-map (kbd "C-c C-x C-o") #'org-clock-out)
-(org-defkey org-mode-map (kbd "C-c C-x C-j") #'org-clock-goto)
-(org-defkey org-mode-map (kbd "C-c C-x C-q") #'org-clock-cancel)
-(org-defkey org-mode-map (kbd "C-c C-x C-d") #'org-clock-display)
-(org-defkey org-mode-map (kbd "C-c C-x C-r") #'org-clock-report)
-(org-defkey org-mode-map (kbd "C-c C-x C-u") #'org-dblock-update)
-(org-defkey org-mode-map (kbd "C-c C-x C-l") #'org-toggle-latex-fragment)
-(org-defkey org-mode-map (kbd "C-c C-x C-v") #'org-toggle-inline-images)
-(org-defkey org-mode-map (kbd "C-c C-x C-M-v") #'org-redisplay-inline-images)
-(org-defkey org-mode-map (kbd "C-c C-x \\") #'org-toggle-pretty-entities)
-(org-defkey org-mode-map (kbd "C-c C-x C-b") #'org-toggle-checkbox)
-(org-defkey org-mode-map (kbd "C-c C-x p") #'org-set-property)
-(org-defkey org-mode-map (kbd "C-c C-x P") #'org-set-property-and-value)
-(org-defkey org-mode-map (kbd "C-c C-x e") #'org-set-effort)
-(org-defkey org-mode-map (kbd "C-c C-x E") #'org-inc-effort)
-(org-defkey org-mode-map (kbd "C-c C-x o") #'org-toggle-ordered-property)
-(org-defkey org-mode-map (kbd "C-c C-x i") #'org-columns-insert-dblock)
-(org-defkey org-mode-map (kbd "C-c C-,") #'org-insert-structure-template)
-(org-defkey org-mode-map (kbd "C-c C-x .") #'org-timer)
-(org-defkey org-mode-map (kbd "C-c C-x -") #'org-timer-item)
-(org-defkey org-mode-map (kbd "C-c C-x 0") #'org-timer-start)
-(org-defkey org-mode-map (kbd "C-c C-x _") #'org-timer-stop)
-(org-defkey org-mode-map (kbd "C-c C-x ;") #'org-timer-set-timer)
-(org-defkey org-mode-map (kbd "C-c C-x ,") #'org-timer-pause-or-continue)
-(org-defkey org-mode-map (kbd "C-c C-x C-c") #'org-columns)
-(org-defkey org-mode-map (kbd "C-c C-x !") #'org-reload)
-(org-defkey org-mode-map (kbd "C-c C-x g") #'org-feed-update-all)
-(org-defkey org-mode-map (kbd "C-c C-x G") #'org-feed-goto-inbox)
-(org-defkey org-mode-map (kbd "C-c C-x [") #'org-reftex-citation)
-(org-defkey org-mode-map (kbd "C-c C-x I") #'org-info-find-node)
-
-
-;;; Speed commands
-
-(defconst org-speed-commands-default
- '(
- ("Outline Navigation")
- ("n" . (org-speed-move-safe 'org-next-visible-heading))
- ("p" . (org-speed-move-safe 'org-previous-visible-heading))
- ("f" . (org-speed-move-safe 'org-forward-heading-same-level))
- ("b" . (org-speed-move-safe 'org-backward-heading-same-level))
- ("F" . org-next-block)
- ("B" . org-previous-block)
- ("u" . (org-speed-move-safe 'outline-up-heading))
- ("j" . org-goto)
- ("g" . (org-refile t))
- ("Outline Visibility")
- ("c" . org-cycle)
- ("C" . org-shifttab)
- (" " . org-display-outline-path)
- ("s" . org-toggle-narrow-to-subtree)
- ("k" . org-cut-subtree)
- ("=" . org-columns)
- ("Outline Structure Editing")
- ("U" . org-metaup)
- ("D" . org-metadown)
- ("r" . org-metaright)
- ("l" . org-metaleft)
- ("R" . org-shiftmetaright)
- ("L" . org-shiftmetaleft)
- ("i" . (progn (forward-char 1) (call-interactively
- 'org-insert-heading-respect-content)))
- ("^" . org-sort)
- ("w" . org-refile)
- ("a" . org-archive-subtree-default-with-confirmation)
- ("@" . org-mark-subtree)
- ("#" . org-toggle-comment)
- ("Clock Commands")
- ("I" . org-clock-in)
- ("O" . org-clock-out)
- ("Meta Data Editing")
- ("t" . org-todo)
- ("," . (org-priority))
- ("0" . (org-priority ?\ ))
- ("1" . (org-priority ?A))
- ("2" . (org-priority ?B))
- ("3" . (org-priority ?C))
- (":" . org-set-tags-command)
- ("e" . org-set-effort)
- ("E" . org-inc-effort)
- ("W" . (lambda(m) (interactive "sMinutes before warning: ")
- (org-entry-put (point) "APPT_WARNTIME" m)))
- ("Agenda Views etc")
- ("v" . org-agenda)
- ("/" . org-sparse-tree)
- ("Misc")
- ("o" . org-open-at-point)
- ("?" . org-speed-command-help)
- ("<" . (org-agenda-set-restriction-lock 'subtree))
- (">" . (org-agenda-remove-restriction-lock))
- )
- "The default speed commands.")
-
-(defun org-print-speed-command (e)
- (if (> (length (car e)) 1)
- (progn
- (princ "\n")
- (princ (car e))
- (princ "\n")
- (princ (make-string (length (car e)) ?-))
- (princ "\n"))
- (princ (car e))
- (princ " ")
- (if (symbolp (cdr e))
- (princ (symbol-name (cdr e)))
- (prin1 (cdr e)))
- (princ "\n")))
-
-(defun org-speed-command-help ()
- "Show the available speed commands."
- (interactive)
- (if (not org-use-speed-commands)
- (user-error "Speed commands are not activated, customize `org-use-speed-commands'")
- (with-output-to-temp-buffer "*Help*"
- (princ "User-defined Speed commands\n===========================\n")
- (mapc #'org-print-speed-command org-speed-commands-user)
- (princ "\n")
- (princ "Built-in Speed commands\n=======================\n")
- (mapc #'org-print-speed-command org-speed-commands-default))
- (with-current-buffer "*Help*"
- (setq truncate-lines t))))
-
-(defun org-speed-move-safe (cmd)
- "Execute CMD, but make sure that the cursor always ends up in a headline.
-If not, return to the original position and throw an error."
- (interactive)
- (let ((pos (point)))
- (call-interactively cmd)
- (unless (and (bolp) (org-at-heading-p))
- (goto-char pos)
- (error "Boundary reached while executing %s" cmd))))
-
(defvar org-self-insert-command-undo-counter 0)
-
-(defvar org-table-auto-blank-field) ; defined in org-table.el
(defvar org-speed-command nil)
-(defun org-speed-command-activate (keys)
- "Hook for activating single-letter speed commands.
-`org-speed-commands-default' specifies a minimal command set.
-Use `org-speed-commands-user' for further customization."
- (when (or (and (bolp) (looking-at org-outline-regexp))
- (and (functionp org-use-speed-commands)
- (funcall org-use-speed-commands)))
- (cdr (assoc keys (append org-speed-commands-user
- org-speed-commands-default)))))
-
-(defun org-babel-speed-command-activate (keys)
- "Hook for activating single-letter code block commands."
- (when (and (bolp) (looking-at org-babel-src-block-regexp))
- (cdr (assoc keys org-babel-key-bindings))))
-
-(defcustom org-speed-command-hook
- '(org-speed-command-activate org-babel-speed-command-activate)
- "Hook for activating speed commands at strategic locations.
-Hook functions are called in sequence until a valid handler is
-found.
-
-Each hook takes a single argument, a user-pressed command key
-which is also a `self-insert-command' from the global map.
-
-Within the hook, examine the cursor position and the command key
-and return nil or a valid handler as appropriate. Handler could
-be one of an interactive command, a function, or a form.
-
-Set `org-use-speed-commands' to non-nil value to enable this
-hook. The default setting is `org-speed-command-activate'."
- :group 'org-structure
- :version "24.1"
- :type 'hook)
-
(defun org-self-insert-command (N)
"Like `self-insert-command', use overwrite-mode for whitespace in tables.
If the cursor is in a table looking at whitespace, the whitespace is
@@ -19899,9 +17390,10 @@ commands for more information."
(t (org-drag-element-forward))))
(defun org-shiftup (&optional arg)
- "Increase item in timestamp or increase priority of current headline.
-Calls `org-timestamp-up' or `org-priority-up', or `org-previous-item',
-depending on context. See the individual commands for more information."
+ "Act on current element according to context.
+Call `org-timestamp-up' or `org-priority-up', or
+`org-previous-item', or `org-table-move-cell-up'. See the
+individual commands for more information."
(interactive "P")
(cond
((run-hook-with-args-until-success 'org-shiftup-hook))
@@ -19917,15 +17409,17 @@ depending on context. See the individual commands for more information."
((and (not org-support-shift-select) (org-at-item-p))
(call-interactively 'org-previous-item))
((org-clocktable-try-shift 'up arg))
+ ((org-at-table-p) (org-table-move-cell-up))
((run-hook-with-args-until-success 'org-shiftup-final-hook))
(org-support-shift-select
(org-call-for-shift-select 'previous-line))
(t (org-shiftselect-error))))
(defun org-shiftdown (&optional arg)
- "Decrease item in timestamp or decrease priority of current headline.
-Calls `org-timestamp-down' or `org-priority-down', or `org-next-item'
-depending on context. See the individual commands for more information."
+ "Act on current element according to context.
+Call `org-timestamp-down' or `org-priority-down', or
+`org-next-item', or `org-table-move-cell-down'. See the
+individual commands for more information."
(interactive "P")
(cond
((run-hook-with-args-until-success 'org-shiftdown-hook))
@@ -19941,20 +17435,22 @@ depending on context. See the individual commands for more information."
((and (not org-support-shift-select) (org-at-item-p))
(call-interactively 'org-next-item))
((org-clocktable-try-shift 'down arg))
+ ((org-at-table-p) (org-table-move-cell-down))
((run-hook-with-args-until-success 'org-shiftdown-final-hook))
(org-support-shift-select
(org-call-for-shift-select 'next-line))
(t (org-shiftselect-error))))
(defun org-shiftright (&optional arg)
- "Cycle the thing at point or in the current line, depending on context.
-Depending on context, this does one of the following:
+ "Act on the current element according to context.
+This does one of the following:
- switch a timestamp at point one day into the future
-- on a headline, switch to the next TODO keyword.
+- on a headline, switch to the next TODO keyword
- on an item, switch entire list to the next bullet type
- on a property line, switch to the next allowed value
-- on a clocktable definition line, move time block into the future"
+- on a clocktable definition line, move time block into the future
+- in a table, move a single cell right"
(interactive "P")
(cond
((run-hook-with-args-until-success 'org-shiftright-hook))
@@ -19977,20 +17473,22 @@ Depending on context, this does one of the following:
(org-at-property-p))
(call-interactively 'org-property-next-allowed-value))
((org-clocktable-try-shift 'right arg))
+ ((org-at-table-p) (org-table-move-cell-right))
((run-hook-with-args-until-success 'org-shiftright-final-hook))
(org-support-shift-select
(org-call-for-shift-select 'forward-char))
(t (org-shiftselect-error))))
(defun org-shiftleft (&optional arg)
- "Cycle the thing at point or in the current line, depending on context.
-Depending on context, this does one of the following:
+ "Act on current element according to context.
+This does one of the following:
- switch a timestamp at point one day into the past
- on a headline, switch to the previous TODO keyword.
- on an item, switch entire list to the previous bullet type
- on a property line, switch to the previous allowed value
-- on a clocktable definition line, move time block into the past"
+- on a clocktable definition line, move time block into the past
+- in a table, move a single cell left"
(interactive "P")
(cond
((run-hook-with-args-until-success 'org-shiftleft-hook))
@@ -20013,6 +17511,7 @@ Depending on context, this does one of the following:
(org-at-property-p))
(call-interactively 'org-property-previous-allowed-value))
((org-clocktable-try-shift 'left arg))
+ ((org-at-table-p) (org-table-move-cell-left))
((run-hook-with-args-until-success 'org-shiftleft-final-hook))
(org-support-shift-select
(org-call-for-shift-select 'backward-char))
@@ -20187,7 +17686,7 @@ Otherwise, return a user error."
(match-string 0 value)))))
(when (org-file-url-p file)
(user-error "Files located with a URL cannot be edited"))
- (org-open-link-from-string
+ (org-link-open-from-string
(format "[[%s]]" (expand-file-name file))))))
(`table
(if (eq (org-element-property :type element) 'table.el)
@@ -20219,7 +17718,6 @@ Otherwise, return a user error."
(`link (call-interactively #'ffap))
(_ (user-error "No special environment to edit here"))))))))
-(defvar org-table-coordinate-overlays) ; defined in org-table.el
(defun org-ctrl-c-ctrl-c (&optional arg)
"Set tags in headline, or update according to changed information at point.
@@ -20460,18 +17958,35 @@ Use `\\[org-edit-special]' to edit table.el tables"))
(org-reset-file-cache))
(message "%s restarted" major-mode))
+(defun org-flag-above-first-heading (&optional arg)
+ "Hide from bob up to the first heading.
+Move point to the beginning of first heading or end of buffer."
+ (goto-char (point-min))
+ (unless (org-at-heading-p)
+ (outline-next-heading))
+ (unless (bobp)
+ (org-flag-region 1 (1- (point)) (not arg) 'outline)))
+
+(defun org-show-branches-buffer ()
+ "Show all branches in the buffer."
+ (org-flag-above-first-heading)
+ (outline-hide-sublevels 1)
+ (unless (eobp)
+ (outline-show-branches)
+ (while (outline-get-next-sibling)
+ (outline-show-branches)))
+ (goto-char (point-min)))
+
(defun org-kill-note-or-show-branches ()
- "Abort storing current note, or call `outline-show-branches'."
+ "Abort storing current note, or show just branches."
(interactive)
- (if (not org-finish-function)
- (save-excursion
- (save-restriction
- (org-narrow-to-subtree)
- (org-flag-subtree t)
- (call-interactively 'outline-show-branches)
- (org-hide-archived-subtrees (point-min) (point-max))))
- (let ((org-note-abort t))
- (funcall org-finish-function))))
+ (if org-finish-function
+ (let ((org-note-abort t))
+ (funcall org-finish-function))
+ (if (org-before-first-heading-p)
+ (org-show-branches-buffer)
+ (outline-hide-subtree)
+ (outline-show-branches))))
(defun org-delete-indentation (&optional arg)
"Join current line to previous and fix whitespace at join.
@@ -20558,7 +18073,7 @@ object (e.g., within a comment). In these case, you need to use
(> (point) origin))))
(org-in-regexp org-ts-regexp-both nil t)
(org-in-regexp org-tsr-regexp-both nil t)
- (org-in-regexp org-any-link-re nil t)))
+ (org-in-regexp org-link-any-re nil t)))
(call-interactively #'org-open-at-point))
;; Insert newline in heading, but preserve tags.
((and (not (bolp))
@@ -20605,14 +18120,20 @@ context. See the individual commands for more information."
(interactive)
(org-return t))
-(defun org-ctrl-c-tab (&optional _arg)
+(defun org-ctrl-c-tab (&optional arg)
"Toggle columns width in a table, or show children.
Call `org-table-toggle-column-width' if point is in a table.
-Otherwise, call `org-show-children'."
+Otherwise, call `org-show-children'. ARG is the level to hide."
(interactive "p")
- (call-interactively
- (if (org-at-table-p) #'org-table-toggle-column-width
- #'org-show-children)))
+ (if (org-at-table-p)
+ (call-interactively #'org-table-toggle-column-width)
+ (if (org-before-first-heading-p)
+ (progn
+ (org-flag-above-first-heading)
+ (outline-hide-sublevels (or arg 1))
+ (goto-char (point-min)))
+ (outline-hide-subtree)
+ (org-show-children arg))))
(defun org-ctrl-c-star ()
"Compute table, or change heading status of lines.
@@ -20715,7 +18236,12 @@ number of stars to add."
(min (org-list-get-bottom-point struct) (1+ end))))
(save-restriction
(narrow-to-region (point) list-end)
- (insert (org-list-to-subtree (org-list-to-lisp t)) "\n")))
+ (insert (org-list-to-subtree
+ (org-list-to-lisp t)
+ (pcase (org-current-level)
+ (`nil 1)
+ (l (1+ (org-reduced-level l)))))
+ "\n")))
(setq toggled t))
(forward-line)))
;; Case 3. Started at normal text: make every line an heading,
@@ -20724,10 +18250,10 @@ number of stars to add."
(make-string
(if (numberp nstars) nstars (or (org-current-level) 0)) ?*))
(add-stars
- (cond (nstars "") ; stars from prefix only
- ((equal stars "") "*") ; before first heading
+ (cond (nstars "") ; stars from prefix only
+ ((equal stars "") "*") ; before first heading
(org-odd-levels-only "**") ; inside heading, odd
- (t "*"))) ; inside heading, oddeven
+ (t "*"))) ; inside heading, oddeven
(rpl (concat stars add-stars " "))
(lend (when (listp nstars) (save-excursion (end-of-line) (point)))))
(while (< (point) (if (equal nstars '(4)) lend end))
@@ -21200,26 +18726,6 @@ With prefix arg UNCOMPILED, load the uncompiled versions."
;;; Generally useful functions
-(defun org-link-display-format (s)
- "Replace links in string S with their description.
-If there is no description, use the link target."
- (save-match-data
- (replace-regexp-in-string
- org-bracket-link-analytic-regexp
- (lambda (m)
- (if (match-end 5) (match-string 5 m)
- (concat (match-string 1 m) (match-string 3 m))))
- s nil t)))
-
-(defun org-toggle-link-display ()
- "Toggle the literal or descriptive display of links."
- (interactive)
- (if org-descriptive-links
- (remove-from-invisibility-spec '(org-link))
- (add-to-invisibility-spec '(org-link)))
- (org-restart-font-lock)
- (setq org-descriptive-links (not org-descriptive-links)))
-
(defun org-in-clocktable-p ()
"Check if the cursor is in a clocktable."
(let ((pos (point)) start)
@@ -21262,17 +18768,6 @@ If there is no description, use the link target."
(interactive "p")
(self-insert-command N))
-(defun org-fill-template (template alist)
- "Find each %key of ALIST in TEMPLATE and replace it."
- (let ((case-fold-search nil))
- (dolist (entry (sort (copy-sequence alist)
- (lambda (a b) (< (length (car a)) (length (car b))))))
- (setq template
- (replace-regexp-in-string
- (concat "%" (regexp-quote (car entry)))
- (or (cdr entry) "") template t t)))
- template))
-
(defun org-quote-vert (s)
"Replace \"|\" with \"\\vert\"."
(while (string-match "|" s)
@@ -21317,8 +18812,6 @@ contexts are:
:src-block in a source block
:link on a hyperlink
:keyword on a keyword: SCHEDULED, DEADLINE, CLOSE, COMMENT.
-:target on a <<target>>
-:radio-target on a <<<radio-target>>>
:latex-fragment on a LaTeX fragment
:latex-preview on a LaTeX fragment with overlaid preview image
@@ -21392,12 +18885,6 @@ and :keyword."
(push (list :keyword
(previous-single-property-change p 'face)
(next-single-property-change p 'face)) clist))
- ((org-at-target-p)
- (push (org-point-in-group p 0 :target) clist)
- (goto-char (1- (match-beginning 0)))
- (when (looking-at org-radio-target-regexp)
- (push (org-point-in-group p 0 :radio-target) clist))
- (goto-char p))
((setq o (cl-some
(lambda (o)
(and (eq (overlay-get o 'org-overlay-type) 'org-latex-overlay)
@@ -21517,33 +19004,6 @@ Returns the number of empty lines passed."
(goto-char (min (point) pos))
(count-lines (point) pos)))
-(defun org-replace-escapes (string table)
- "Replace %-escapes in STRING with values in TABLE.
-TABLE is an association list with keys like \"%a\" and string values.
-The sequences in STRING may contain normal field width and padding information,
-for example \"%-5s\". Replacements happen in the sequence given by TABLE,
-so values can contain further %-escapes if they are define later in TABLE."
- (let ((tbl (copy-alist table))
- (case-fold-search nil)
- (pchg 0)
- re rpl)
- (dolist (e tbl)
- (setq re (concat "%-?[0-9.]*" (substring (car e) 1)))
- (when (and (cdr e) (string-match re (cdr e)))
- (let ((sref (substring (cdr e) (match-beginning 0) (match-end 0)))
- (safe "SREF"))
- (add-text-properties 0 3 (list 'sref sref) safe)
- (setcdr e (replace-match safe t t (cdr e)))))
- (while (string-match re string)
- (setq rpl (format (concat (substring (match-string 0 string) 0 -1) "s")
- (cdr e)))
- (setq string (replace-match rpl t t string))))
- (while (setq pchg (next-property-change pchg string))
- (let ((sref (get-text-property pchg 'sref string)))
- (when (and sref (string-match "SREF" string pchg))
- (setq string (replace-match sref t t string)))))
- string))
-
;;; TODO: Only called once, from ox-odt which should probably use
;;; org-export-inline-image-p or something.
(defun org-file-image-p (file)
@@ -21556,7 +19016,9 @@ so values can contain further %-escapes if they are define later in TABLE."
This works in the calendar and in the agenda, anywhere else it just
returns the current time.
If WITH-TIME is non-nil, returns the time of the event at point (in
-the agenda) or the current time of the day."
+the agenda) or the current time of the day; otherwise returns the
+earliest time on the cursor date that Org treats as that date
+(bearing in mind `org-extend-today-until')."
(let (date day defd tp hod mod)
(when with-time
(setq tp (get-text-property (point) 'time))
@@ -21569,13 +19031,13 @@ the agenda) or the current time of the day."
(cond
((eq major-mode 'calendar-mode)
(setq date (calendar-cursor-to-date)
- defd (encode-time 0 (or mod 0) (or hod 0)
+ defd (encode-time 0 (or mod 0) (or hod org-extend-today-until)
(nth 1 date) (nth 0 date) (nth 2 date))))
((eq major-mode 'org-agenda-mode)
(setq day (get-text-property (point) 'day))
(when day
(setq date (calendar-gregorian-from-absolute day)
- defd (encode-time 0 (or mod 0) (or hod 0)
+ defd (encode-time 0 (or mod 0) (or hod org-extend-today-until)
(nth 1 date) (nth 0 date) (nth 2 date))))))
(or defd (current-time))))
@@ -21727,10 +19189,8 @@ Indentation is done according to the following rules:
definitions and inline tasks, indent like its first line.
2. If element has a parent, indent like its contents. More
- precisely, if parent is an item, indent after the
- description part, if any, or the bullet (see
- `org-list-description-max-indent'). Else, indent like
- parent's first line.
+ precisely, if parent is an item, indent after the bullet.
+ Else, indent like parent's first line.
3. Otherwise, indent relatively to current level, if
`org-adapt-indentation' is non-nil, or to left margin.
@@ -22008,7 +19468,6 @@ assumed to be significant there."
;; parenthesis can end up being parsed as a new list item.
(looking-at-p "[ \t]*{{{n\\(?:([^\n)]*)\\)?}}}[.)]\\(?:$\\| \\)"))
-(defvar orgtbl-line-start-regexp) ; From org-table.el
(defun org-adaptive-fill-function ()
"Compute a fill prefix for the current line.
Return fill prefix, as a string, or nil if current line isn't
@@ -22200,20 +19659,27 @@ filling the current element."
(interactive (progn
(barf-if-buffer-read-only)
(list (when current-prefix-arg 'full) t)))
- (cond
- ((and region transient-mark-mode mark-active
- (not (eq (region-beginning) (region-end))))
- (let ((origin (point-marker))
- (start (region-beginning)))
- (unwind-protect
- (progn
- (goto-char (region-end))
- (while (> (point) start)
- (org-backward-paragraph)
- (org-fill-element justify)))
- (goto-char origin)
- (set-marker origin nil))))
- (t (org-fill-element justify))))
+ (let ((hash (and (not (buffer-modified-p))
+ (org-buffer-hash))))
+ (cond
+ ((and region transient-mark-mode mark-active
+ (not (eq (region-beginning) (region-end))))
+ (let ((origin (point-marker))
+ (start (region-beginning)))
+ (unwind-protect
+ (progn
+ (goto-char (region-end))
+ (while (> (point) start)
+ (org-backward-paragraph)
+ (org-fill-element justify)))
+ (goto-char origin)
+ (set-marker origin nil))))
+ (t (org-fill-element justify)))
+ ;; If we didn't change anything in the buffer (and the buffer was
+ ;; previously unmodified), then flip the modification status back
+ ;; to "unchanged".
+ (when (and hash (equal hash (org-buffer-hash)))
+ (set-buffer-modified-p nil))))
(defun org-auto-fill-function ()
"Auto-fill function."
@@ -22980,7 +20446,7 @@ interactive command with similar behavior."
(or (looking-at org-outline-regexp)
(re-search-forward org-outline-regexp-bol end t))
(while (and (< (point) end) (looking-at org-outline-regexp))
- (outline-hide-subtree)
+ (org-flag-subtree t)
(org-cycle-show-empty-lines 'folded)
(condition-case nil
(outline-forward-same-level 1)
@@ -23049,20 +20515,20 @@ unless optional argument NO-INHERITANCE is non-nil."
(save-excursion (and (org-up-heading-safe) (org-in-commented-heading-p))))))
(defun org-at-comment-p nil
- "Is cursor in a commented line?"
+ "Return t if cursor is in a commented line."
(save-excursion
(save-match-data
(beginning-of-line)
(looking-at "^[ \t]*# "))))
(defun org-at-drawer-p nil
- "Is cursor at a drawer keyword?"
+ "Return t if cursor is at a drawer keyword."
(save-excursion
(move-beginning-of-line 1)
(looking-at org-drawer-regexp)))
(defun org-at-block-p nil
- "Is cursor at a block keyword?"
+ "Return t if cursor is at a block keyword."
(save-excursion
(move-beginning-of-line 1)
(looking-at org-block-regexp)))
@@ -23082,10 +20548,6 @@ empty."
(defun org-at-heading-or-item-p ()
(or (org-at-heading-p) (org-at-item-p)))
-(defun org-at-target-p ()
- (or (org-in-regexp org-radio-target-regexp)
- (org-in-regexp org-target-regexp)))
-
(defun org-up-heading-all (arg)
"Move to the heading line of which the present line is a subheading.
This function considers both visible and invisible heading lines.
diff --git a/lisp/ox-ascii.el b/lisp/ox-ascii.el
index 7917e3d..6e6c17c 100644
--- a/lisp/ox-ascii.el
+++ b/lisp/ox-ascii.el
@@ -731,7 +731,7 @@ caption keyword."
(org-export-data caption info))
(org-ascii--current-text-width element info) info)))))
-(defun org-ascii--build-toc (info &optional n keyword local)
+(defun org-ascii--build-toc (info &optional n keyword scope)
"Return a table of contents.
INFO is a plist used as a communication channel.
@@ -742,10 +742,10 @@ depth of the table.
Optional argument KEYWORD specifies the TOC keyword, if any, from
which the table of contents generation has been initiated.
-When optional argument LOCAL is non-nil, build a table of
-contents according to the current headline."
+When optional argument SCOPE is non-nil, build a table of
+contents according to the specified scope."
(concat
- (unless local
+ (unless scope
(let ((title (org-ascii--translate "Table of Contents" info)))
(concat title "\n"
(make-string
@@ -767,7 +767,7 @@ contents according to the current headline."
(or (not (plist-get info :with-tags))
(eq (plist-get info :with-tags) 'not-in-toc))
'toc))))
- (org-export-collect-headlines info n (and local keyword)) "\n"))))
+ (org-export-collect-headlines info n scope) "\n"))))
(defun org-ascii--list-listings (keyword info)
"Return a list of listings.
@@ -1516,8 +1516,13 @@ information."
((string-match-p "\\<headlines\\>" value)
(let ((depth (and (string-match "\\<[0-9]+\\>" value)
(string-to-number (match-string 0 value))))
- (localp (string-match-p "\\<local\\>" value)))
- (org-ascii--build-toc info depth keyword localp)))
+ (scope
+ (cond
+ ((string-match ":target +\\(\".+?\"\\|\\S-+\\)" value) ;link
+ (org-export-resolve-link
+ (org-strip-quotes (match-string 1 value)) info))
+ ((string-match-p "\\<local\\>" value) keyword)))) ;local
+ (org-ascii--build-toc info depth keyword scope)))
((string-match-p "\\<tables\\>" value)
(org-ascii--list-tables keyword info))
((string-match-p "\\<listings\\>" value)
diff --git a/lisp/ox-beamer.el b/lisp/ox-beamer.el
index 05894ff..0de5e47 100644
--- a/lisp/ox-beamer.el
+++ b/lisp/ox-beamer.el
@@ -326,7 +326,7 @@ INFO is a plist used as a communication channel.
The value is either the label specified in \"BEAMER_opt\"
property, the custom ID, if there is one and
-`:latex-prefer-user-labels' property has a non nil value, or
+`:latex-prefer-user-labels' property has a non-nil value, or
a unique internal label. This function assumes HEADLINE will be
treated as a frame."
(cond
@@ -645,13 +645,22 @@ as a communication channel."
contents))
;; Case 4: HEADLINE is a note.
((member environment '("note" "noteNH"))
- (format "\\note{%s}"
- (concat (and (equal environment "note")
- (concat
- (org-export-data
- (org-element-property :title headline) info)
- "\n"))
- (org-trim contents))))
+ (concat "\\note"
+ ;; Overlay specification.
+ (let ((overlay (org-element-property :BEAMER_ACT headline)))
+ (when overlay
+ (org-beamer--normalize-argument
+ overlay
+ (if (string-match "\\`\\[.*\\]\\'" overlay)
+ 'defaction 'action))))
+ (format "{%s}"
+ (concat (and (equal environment "note")
+ (concat
+ (org-export-data
+ (org-element-property :title headline)
+ info)
+ "\n"))
+ (org-trim contents)))))
;; Case 5: HEADLINE is a frame.
((= level frame-level)
(org-beamer--format-frame headline contents info))
diff --git a/lisp/ox-html.el b/lisp/ox-html.el
index 9e4f07d..83d0fd2 100644
--- a/lisp/ox-html.el
+++ b/lisp/ox-html.el
@@ -152,6 +152,7 @@
(:html-metadata-timestamp-format nil nil org-html-metadata-timestamp-format)
(:html-postamble-format nil nil org-html-postamble-format)
(:html-preamble-format nil nil org-html-preamble-format)
+ (:html-self-link-headlines nil nil org-html-self-link-headlines)
(:html-table-align-individual-fields
nil nil org-html-table-align-individual-fields)
(:html-table-caption-above nil nil org-html-table-caption-above)
@@ -171,6 +172,7 @@
(:html-table-row-open-tag nil nil org-html-table-row-open-tag)
(:html-table-row-close-tag nil nil org-html-table-row-close-tag)
(:html-xml-declaration nil nil org-html-xml-declaration)
+ (:html-wrap-src-lines nil nil org-html-wrap-src-lines)
(:html-klipsify-src nil nil org-html-klipsify-src)
(:html-klipse-css nil nil org-html-klipse-css)
(:html-klipse-js nil nil org-html-klipse-js)
@@ -802,6 +804,13 @@ but without \"name\" attribute."
:package-version '(Org . "8.0")
:type 'boolean)
+(defcustom org-html-self-link-headlines nil
+ "When non-nil, the headlines contain a hyperlink to themselves."
+ :group 'org-export-html
+ :package-version '(Org . "9.3")
+ :type 'boolean
+ :safe #'booleanp)
+
;;;; Inlinetasks
(defcustom org-html-format-inlinetask-function
@@ -876,6 +885,7 @@ link to the image."
(defcustom org-html-inline-image-rules
'(("file" . "\\.\\(jpeg\\|jpg\\|png\\|gif\\|svg\\)\\'")
+ ("attachment" . "\\.\\(jpeg\\|jpg\\|png\\|gif\\|svg\\)\\'")
("http" . "\\.\\(jpeg\\|jpg\\|png\\|gif\\|svg\\)\\'")
("https" . "\\.\\(jpeg\\|jpg\\|png\\|gif\\|svg\\)\\'"))
"Rules characterizing image files that can be inlined into HTML.
@@ -923,6 +933,15 @@ in all modes you want. Then, use the command
:group 'org-export-html
:type 'string)
+(defcustom org-html-wrap-src-lines nil
+ "If non-nil, wrap individual lines of source blocks in \"code\" elements.
+In this case, add line number in attribute \"data-ox-html-linenr\" when line
+numbers are enabled."
+ :group 'org-export-html
+ :package-version '(Org . "9.3")
+ :type 'boolean
+ :safe t)
+
;;;; Table
(defcustom org-html-table-default-attributes
@@ -1151,7 +1170,7 @@ checkboxes. The other two use the `off' checkbox for `trans'.")
(defcustom org-html-checkbox-type 'ascii
"The type of checkboxes to use for HTML export.
-See `org-html-checkbox-types' for for the values used for each
+See `org-html-checkbox-types' for the values used for each
option."
:group 'org-export-html
:version "24.4"
@@ -1975,32 +1994,33 @@ communication channel."
(creator (cdr (assq ?c spec)))
(validation-link (cdr (assq ?v spec))))
(concat
- (when (and (plist-get info :with-date)
- (org-string-nw-p date))
- (format "<p class=\"date\">%s: %s</p>\n"
- (org-html--translate "Date" info)
- date))
- (when (and (plist-get info :with-author)
- (org-string-nw-p author))
- (format "<p class=\"author\">%s: %s</p>\n"
- (org-html--translate "Author" info)
- author))
- (when (and (plist-get info :with-email)
- (org-string-nw-p email))
- (format "<p class=\"email\">%s: %s</p>\n"
- (org-html--translate "Email" info)
- email))
- (when (plist-get info :time-stamp-file)
- (format
- "<p class=\"date\">%s: %s</p>\n"
- (org-html--translate "Created" info)
- (format-time-string
- (plist-get info :html-metadata-timestamp-format))))
- (when (plist-get info :with-creator)
- (format "<p class=\"creator\">%s</p>\n" creator))
- (when (org-string-nw-p validation-link)
- (format "<p class=\"validation\">%s</p>\n"
- validation-link)))))
+ (and (plist-get info :with-date)
+ (org-string-nw-p date)
+ (format "<p class=\"date\">%s: %s</p>\n"
+ (org-html--translate "Date" info)
+ date))
+ (and (plist-get info :with-author)
+ (org-string-nw-p author)
+ (format "<p class=\"author\">%s: %s</p>\n"
+ (org-html--translate "Author" info)
+ author))
+ (and (plist-get info :with-email)
+ (org-string-nw-p email)
+ (format "<p class=\"email\">%s: %s</p>\n"
+ (org-html--translate "Email" info)
+ email))
+ (and (plist-get info :time-stamp-file)
+ (format
+ "<p class=\"date\">%s: %s</p>\n"
+ (org-html--translate "Created" info)
+ (format-time-string
+ (plist-get info :html-metadata-timestamp-format))))
+ (and (plist-get info :with-creator)
+ (org-string-nw-p creator)
+ (format "<p class=\"creator\">%s</p>\n" creator))
+ (and (org-string-nw-p validation-link)
+ (format "<p class=\"validation\">%s</p>\n"
+ validation-link)))))
(t
(let ((formats (plist-get info (if (eq type 'preamble)
:html-preamble-format
@@ -2221,14 +2241,15 @@ is the language used for CODE, as a string, or nil."
(if (and beg end) (substring code beg end) code)))))))))
(defun org-html-do-format-code
- (code &optional lang refs retain-labels num-start)
+ (code &optional lang refs retain-labels num-start wrap-lines)
"Format CODE string as source code.
-Optional arguments LANG, REFS, RETAIN-LABELS and NUM-START are,
-respectively, the language of the source code, as a string, an
+Optional arguments LANG, REFS, RETAIN-LABELS, NUM-START, WRAP-LINES
+are, respectively, the language of the source code, as a string, an
alist between line numbers and references (as returned by
`org-export-unravel-code'), a boolean specifying if labels should
-appear in the source code, and the number associated to the first
-line of code."
+appear in the source code, the number associated to the first
+line of code, and a boolean specifying if lines of code should be
+wrapped in code elements."
(let* ((code-lines (split-string code "\n"))
(code-length (length code-lines))
(num-fmt
@@ -2246,7 +2267,13 @@ line of code."
(format "<span class=\"linenr\">%s</span>"
(format num-fmt line-num)))
;; Transcoded src line.
- loc
+ (if wrap-lines
+ (format "<code%s>%s</code>"
+ (if num-start
+ (format " data-ox-html-linenr=\"%s\"" line-num)
+ "")
+ loc)
+ loc)
;; Add label, if needed.
(when (and ref retain-labels) (format " (%s)" ref))))
;; Mark transcoded line as an anchor, if needed.
@@ -2267,8 +2294,10 @@ used as a communication channel."
;; Does the source block contain labels?
(retain-labels (org-element-property :retain-labels element))
;; Does it have line numbers?
- (num-start (org-export-get-loc element info)))
- (org-html-do-format-code code lang refs retain-labels num-start)))
+ (num-start (org-export-get-loc element info))
+ ;; Should lines be wrapped in code elements?
+ (wrap-lines (plist-get info :html-wrap-src-lines)))
+ (org-html-do-format-code code lang refs retain-labels num-start wrap-lines)))
;;; Tables of Contents
@@ -2594,7 +2623,11 @@ holding contextual information."
todo todo-type priority text tags info))
(contents (or contents ""))
(id (or (org-element-property :CUSTOM_ID headline)
- (org-export-get-reference headline info))))
+ (org-export-get-reference headline info)))
+ (formatted-text
+ (if (plist-get info :html-self-link-headlines)
+ (format "<a href=\"#%s\">%s</a>" id full-text)
+ full-text)))
(if (org-export-low-level-p headline info)
;; This is a deep sub-tree: export it as a list item.
(let* ((html-type (if numberedp "ol" "ul")))
@@ -2605,11 +2638,14 @@ holding contextual information."
(org-html-format-list-item
contents (if numberedp 'ordered 'unordered)
nil info nil
- (concat (org-html--anchor id nil nil info) full-text)) "\n"
+ (concat (org-html--anchor id nil nil info) formatted-text)) "\n"
(and (org-export-last-sibling-p headline info)
(format "</%s>\n" html-type))))
;; Standard headline. Export it as a section.
- (let ((extra-class (org-element-property :HTML_CONTAINER_CLASS headline))
+ (let ((extra-class
+ (org-element-property :HTML_CONTAINER_CLASS headline))
+ (headline-class
+ (org-element-property :HTML_HEADLINE_CLASS headline))
(first-content (car (org-element-contents headline))))
(format "<%s id=\"%s\" class=\"%s\">%s%s</%s>\n"
(org-html--container headline info)
@@ -2618,16 +2654,18 @@ holding contextual information."
(concat (format "outline-%d" level)
(and extra-class " ")
extra-class)
- (format "\n<h%d id=\"%s\">%s</h%d>\n"
+ (format "\n<h%d id=\"%s\"%s>%s</h%d>\n"
level
id
+ (if (not headline-class) ""
+ (format " class=\"%s\"" headline-class))
(concat
(and numberedp
(format
"<span class=\"section-number-%d\">%s</span> "
level
(mapconcat #'number-to-string numbers ".")))
- full-text)
+ formatted-text)
level)
;; When there is no section, pretend there is an
;; empty one to get the correct <div
@@ -2795,8 +2833,13 @@ CONTENTS is nil. INFO is a plist holding contextual information."
((string-match "\\<headlines\\>" value)
(let ((depth (and (string-match "\\<[0-9]+\\>" value)
(string-to-number (match-string 0 value))))
- (localp (string-match-p "\\<local\\>" value)))
- (org-html-toc depth info (and localp keyword))))
+ (scope
+ (cond
+ ((string-match ":target +\\(\".+?\"\\|\\S-+\\)" value) ;link
+ (org-export-resolve-link
+ (org-strip-quotes (match-string 1 value)) info))
+ ((string-match-p "\\<local\\>" value) keyword)))) ;local
+ (org-html-toc depth info scope)))
((string= "listings" value) (org-html-list-of-listings info))
((string= "tables" value) (org-html-list-of-tables info))))))))
diff --git a/lisp/ox-icalendar.el b/lisp/ox-icalendar.el
index 297d624..15c572d 100644
--- a/lisp/ox-icalendar.el
+++ b/lisp/ox-icalendar.el
@@ -33,7 +33,7 @@
(require 'cl-lib)
(require 'ox-ascii)
-(declare-function org-bbdb-anniv-export-ical "org-bbdb" nil)
+(declare-function org-bbdb-anniv-export-ical "ol-bbdb" nil)
@@ -87,37 +87,66 @@ keyword."
This is a list with possibly several symbols in it. Valid symbols are:
-`event-if-todo' Deadlines in TODO entries become calendar events.
-`event-if-not-todo' Deadlines in non-TODO entries become calendar events.
-`todo-due' Use deadlines in TODO entries as due-dates."
+`event-if-todo'
+
+ Deadlines in TODO entries become calendar events.
+
+`event-if-todo-not-done'
+
+ Deadlines in TODO entries with not-DONE state become events.
+
+`event-if-not-todo'
+
+ Deadlines in non-TODO entries become calendar events.
+
+`todo-due'
+
+ Use deadlines in TODO entries as due-dates."
:group 'org-export-icalendar
- :type '(set :greedy t
- (const :tag "Deadlines in non-TODO entries become events"
- event-if-not-todo)
- (const :tag "Deadline in TODO entries become events"
- event-if-todo)
- (const :tag "Deadlines in TODO entries become due-dates"
- todo-due)))
+ :type
+ '(set :greedy t
+ (const :tag "DEADLINE in non-TODO entries become events"
+ event-if-not-todo)
+ (const :tag "DEADLINE in TODO entries become events"
+ event-if-todo)
+ (const :tag "DEADLINE in TODO entries with not-DONE state become events"
+ event-if-todo-not-done)
+ (const :tag "DEADLINE in TODO entries become due-dates"
+ todo-due)))
(defcustom org-icalendar-use-scheduled '(todo-start)
"Contexts where iCalendar export should use a scheduling time stamp.
This is a list with possibly several symbols in it. Valid symbols are:
-`event-if-todo' Scheduling time stamps in TODO entries become an event.
-`event-if-not-todo' Scheduling time stamps in non-TODO entries become an event.
-`todo-start' Scheduling time stamps in TODO entries become start date.
- Some calendar applications show TODO entries only after
- that date."
+`event-if-todo'
+
+ Scheduling time stamps in TODO entries become an event.
+
+`event-if-todo-not-done'
+
+ Scheduling time stamps in TODO entries with not-DONE state
+ become events.
+
+`event-if-not-todo'
+
+ Scheduling time stamps in non-TODO entries become an event.
+
+`todo-start'
+
+ Scheduling time stamps in TODO entries become start date. Some
+ calendar applications show TODO entries only after that date."
:group 'org-export-icalendar
- :type '(set :greedy t
- (const :tag
- "SCHEDULED timestamps in non-TODO entries become events"
- event-if-not-todo)
- (const :tag "SCHEDULED timestamps in TODO entries become events"
- event-if-todo)
- (const :tag "SCHEDULED in TODO entries become start date"
- todo-start)))
+ :type
+ '(set :greedy t
+ (const :tag "SCHEDULED timestamps in non-TODO entries become events"
+ event-if-not-todo)
+ (const :tag "SCHEDULED timestamps in TODO entries become events"
+ event-if-todo)
+ (const :tag "SCHEDULED in TODO entries with not-DONE state become events"
+ event-if-todo-not-done)
+ (const :tag "SCHEDULED in TODO entries become start date"
+ todo-start)))
(defcustom org-icalendar-categories '(local-tags category)
"Items that should be entered into the \"categories\" field.
@@ -540,6 +569,10 @@ inlinetask within the section."
(org-export-get-node-property
:LOCATION entry
(org-property-inherit-p "LOCATION"))))
+ (class (org-icalendar-cleanup-string
+ (org-export-get-node-property
+ :CLASS entry
+ (org-property-inherit-p "CLASS"))))
;; Build description of the entry from associated section
;; (headline) or contents (inlinetask).
(desc
@@ -562,20 +595,28 @@ inlinetask within the section."
;; Events: Delegate to `org-icalendar--vevent' to generate
;; "VEVENT" component from scheduled, deadline, or any
;; timestamp in the entry.
- (let ((deadline (org-element-property :deadline entry)))
+ (let ((deadline (org-element-property :deadline entry))
+ (use-deadline (plist-get info :icalendar-use-deadline)))
(and deadline
- (memq (if todo-type 'event-if-todo 'event-if-not-todo)
- org-icalendar-use-deadline)
+ (pcase todo-type
+ (`todo (or (memq 'event-if-todo-not-done use-deadline)
+ (memq 'event-if-todo use-deadline)))
+ (`done (memq 'event-if-todo use-deadline))
+ (_ (memq 'event-if-not-todo use-deadline)))
(org-icalendar--vevent
entry deadline (concat "DL-" uid)
- (concat "DL: " summary) loc desc cat tz)))
- (let ((scheduled (org-element-property :scheduled entry)))
+ (concat "DL: " summary) loc desc cat tz class)))
+ (let ((scheduled (org-element-property :scheduled entry))
+ (use-scheduled (plist-get info :icalendar-use-scheduled)))
(and scheduled
- (memq (if todo-type 'event-if-todo 'event-if-not-todo)
- org-icalendar-use-scheduled)
+ (pcase todo-type
+ (`todo (or (memq 'event-if-todo-not-done use-scheduled)
+ (memq 'event-if-todo use-scheduled)))
+ (`done (memq 'event-if-todo use-scheduled))
+ (_ (memq 'event-if-not-todo use-scheduled)))
(org-icalendar--vevent
entry scheduled (concat "SC-" uid)
- (concat "S: " summary) loc desc cat tz)))
+ (concat "S: " summary) loc desc cat tz class)))
;; When collecting plain timestamps from a headline and its
;; title, skip inlinetasks since collection will happen once
;; ENTRY is one of them.
@@ -593,7 +634,7 @@ inlinetask within the section."
((t) t)))
(let ((uid (format "TS%d-%s" (cl-incf counter) uid)))
(org-icalendar--vevent
- entry ts uid summary loc desc cat tz))))
+ entry ts uid summary loc desc cat tz class))))
info nil (and (eq type 'headline) 'inlinetask))
""))
;; Task: First check if it is appropriate to export it. If
@@ -607,7 +648,7 @@ inlinetask within the section."
(not (org-icalendar-blocked-headline-p
entry info))))
((t) (eq todo-type 'todo))))
- (org-icalendar--vtodo entry uid summary loc desc cat tz))
+ (org-icalendar--vtodo entry uid summary loc desc cat tz class))
;; Diary-sexp: Collect every diary-sexp element within ENTRY
;; and its title, and transcode them. If ENTRY is
;; a headline, skip inlinetasks: they will be handled
@@ -638,7 +679,7 @@ inlinetask within the section."
contents))))
(defun org-icalendar--vevent
- (entry timestamp uid summary location description categories timezone)
+ (entry timestamp uid summary location description categories timezone class)
"Create a VEVENT component.
ENTRY is either a headline or an inlinetask element. TIMESTAMP
@@ -648,7 +689,9 @@ summary or subject for the event. LOCATION defines the intended
venue for the event. DESCRIPTION provides the complete
description of the event. CATEGORIES defines the categories the
event belongs to. TIMEZONE specifies a time zone for this event
-only.
+only. CLASS contains the visibility attribute. Three of them
+(\"PUBLIC\", \"CONFIDENTIAL\", and \"PRIVATE\") are predefined, others
+should be treated as \"PRIVATE\" if they are unknown to the iCalendar server.
Return VEVENT component as a string."
(org-icalendar-fold-string
@@ -669,6 +712,7 @@ Return VEVENT component as a string."
(org-element-property :repeater-value timestamp)))
"SUMMARY:" summary "\n"
(and (org-string-nw-p location) (format "LOCATION:%s\n" location))
+ (and (org-string-nw-p class) (format "CLASS:%s\n" class))
(and (org-string-nw-p description)
(format "DESCRIPTION:%s\n" description))
"CATEGORIES:" categories "\n"
@@ -677,7 +721,7 @@ Return VEVENT component as a string."
"END:VEVENT"))))
(defun org-icalendar--vtodo
- (entry uid summary location description categories timezone)
+ (entry uid summary location description categories timezone class)
"Create a VTODO component.
ENTRY is either a headline or an inlinetask element. UID is the
@@ -712,6 +756,7 @@ Return VTODO component as a string."
"\n"))
"SUMMARY:" summary "\n"
(and (org-string-nw-p location) (format "LOCATION:%s\n" location))
+ (and (org-string-nw-p class) (format "CLASS:%s\n" class))
(and (org-string-nw-p description)
(format "DESCRIPTION:%s\n" description))
"CATEGORIES:" categories "\n"
@@ -963,7 +1008,7 @@ FILES is a list of files to build the calendar from."
files "")
;; BBDB anniversaries.
(when (and org-icalendar-include-bbdb-anniversaries
- (require 'org-bbdb nil t))
+ (require 'ol-bbdb nil t))
(with-output-to-string (org-bbdb-anniv-export-ical)))))))
(run-hook-with-args 'org-icalendar-after-save-hook
org-icalendar-combined-agenda-file))
diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el
index 4582ab9..65f40fb 100644
--- a/lisp/ox-latex.el
+++ b/lisp/ox-latex.el
@@ -127,6 +127,7 @@
(:latex-format-headline-function nil nil org-latex-format-headline-function)
(:latex-format-inlinetask-function nil nil org-latex-format-inlinetask-function)
(:latex-hyperref-template nil nil org-latex-hyperref-template t)
+ (:latex-image-default-scale nil nil org-latex-image-default-scale)
(:latex-image-default-height nil nil org-latex-image-default-height)
(:latex-image-default-option nil nil org-latex-image-default-option)
(:latex-image-default-width nil nil org-latex-image-default-width)
@@ -211,13 +212,12 @@
(defconst org-latex-polyglossia-language-alist
'(("am" "amharic")
- ("ast" "asturian")
("ar" "arabic")
- ("bo" "tibetan")
- ("bn" "bengali")
+ ("ast" "asturian")
("bg" "bulgarian")
+ ("bn" "bengali")
+ ("bo" "tibetan")
("br" "breton")
- ("bt-br" "brazilian")
("ca" "catalan")
("cop" "coptic")
("cs" "czech")
@@ -226,6 +226,7 @@
("de" "german" "german")
("de-at" "german" "austrian")
("de-de" "german" "german")
+ ("dsb" "lsorbian")
("dv" "divehi")
("el" "greek")
("en" "english" "usmax")
@@ -247,40 +248,40 @@
("he" "hebrew")
("hi" "hindi")
("hr" "croatian")
+ ("hsb" "usorbian")
("hu" "magyar")
("hy" "armenian")
- ("id" "bahasai")
("ia" "interlingua")
+ ("id" "bahasai")
("is" "icelandic")
("it" "italian")
("kn" "kannada")
("la" "latin" "modern")
- ("la-modern" "latin" "modern")
("la-classic" "latin" "classic")
("la-medieval" "latin" "medieval")
+ ("la-modern" "latin" "modern")
("lo" "lao")
("lt" "lithuanian")
("lv" "latvian")
- ("mr" "maranthi")
("ml" "malayalam")
- ("nl" "dutch")
+ ("mr" "maranthi")
("nb" "norsk")
- ("nn" "nynorsk")
("nko" "nko")
+ ("nl" "dutch")
+ ("nn" "nynorsk")
("no" "norsk")
("oc" "occitan")
("pl" "polish")
("pms" "piedmontese")
("pt" "portuges")
+ ("pt-br" "brazilian")
("rm" "romansh")
("ro" "romanian")
("ru" "russian")
("sa" "sanskrit")
- ("hsb" "usorbian")
- ("dsb" "lsorbian")
+ ("se" "samin")
("sk" "slovak")
("sl" "slovenian")
- ("se" "samin")
("sq" "albanian")
("sr" "serbian")
("sv" "swedish")
@@ -295,8 +296,6 @@
("vi" "vietnamese"))
"Alist between language code and corresponding Polyglossia option")
-
-
(defconst org-latex-table-matrix-macros '(("bordermatrix" . "\\cr")
("qbordermatrix" . "\\cr")
("kbordermatrix" . "\\\\"))
@@ -385,7 +384,7 @@ variable is non-nil, Org passes their value to \\label unchanged.
You are responsible for ensuring that the value is a valid LaTeX
\\label key, and that no other \\label commands with the same key
appear elsewhere in your document. (Keys may contain letters,
-numbers, and the following punctuation: '_' '.' '-' ':'.) There
+numbers, and the following punctuation: `_' `.' `-' `:'.) There
are no such limitations on CUSTOM_ID and NAME when this variable
is nil.
@@ -708,6 +707,16 @@ This value will not be used if a height is provided."
:package-version '(Org . "8.0")
:type 'string)
+(defcustom org-latex-image-default-scale ""
+ "Default scale for images.
+This value will not be used if a width or a scale is provided,
+or if the image is wrapped within a \"wrapfigure\" environment.
+Scale overrides width and height."
+ :group 'org-export-latex
+ :package-version '(Org . "9.3")
+ :type 'string
+ :safe #'stringp)
+
(defcustom org-latex-image-default-height ""
"Default height for images.
This value will not be used if a width is provided, or if the
@@ -1238,7 +1247,7 @@ calling `org-latex-compile'."
;;; Internal Functions
(defun org-latex--caption-above-p (element info)
- "Non nil when caption is expected to be located above ELEMENT.
+ "Non-nil when caption is expected to be located above ELEMENT.
INFO is a plist holding contextual information."
(let ((above (plist-get info :latex-caption-above)))
(if (symbolp above) above
@@ -1267,17 +1276,19 @@ Eventually, if FULL is non-nil, wrap label within \"\\label{}\"."
(and (or user-label force)
(if (and user-label (plist-get info :latex-prefer-user-labels))
user-label
- (concat (cl-case type
- (headline "sec:")
- (table "tab:")
- (latex-environment
+ (concat (pcase type
+ (`headline "sec:")
+ (`table "tab:")
+ (`latex-environment
(and (string-match-p
org-latex-math-environments-re
(org-element-property :value datum))
"eq:"))
- (paragraph
+ (`latex-matrices "eq:")
+ (`paragraph
(and (org-element-property :caption datum)
- "fig:")))
+ "fig:"))
+ (_ nil))
(org-export-get-reference datum info))))))
(cond ((not full) label)
(label (format "\\label{%s}%s"
@@ -1327,7 +1338,7 @@ For non-floats, see `org-latex--wrap-label'."
(t (symbol-name type*)))
""))
(if short (format "[%s]" (org-export-data short info)) "")
- label
+ (org-trim label)
(org-export-data main info))))))
(defun org-latex-guess-inputenc (header)
@@ -2374,13 +2385,18 @@ used as a communication channel."
(if (plist-member attr :center) (plist-get attr :center)
(plist-get info :latex-images-centered)))
(comment-include (if (plist-get attr :comment-include) "%" ""))
- ;; It is possible to specify width and height in the
- ;; ATTR_LATEX line, and also via default variables.
- (width (cond ((plist-get attr :width))
+ ;; It is possible to specify scale or width and height in
+ ;; the ATTR_LATEX line, and also via default variables.
+ (scale (cond ((eq float 'wrap) "")
+ ((plist-get attr :scale))
+ (t (plist-get info :latex-image-default-scale))))
+ (width (cond ((org-string-nw-p scale) "")
+ ((plist-get attr :width))
((plist-get attr :height) "")
((eq float 'wrap) "0.48\\textwidth")
(t (plist-get info :latex-image-default-width))))
- (height (cond ((plist-get attr :height))
+ (height (cond ((org-string-nw-p scale) "")
+ ((plist-get attr :height))
((or (plist-get attr :width)
(memq float '(figure wrap))) "")
(t (plist-get info :latex-image-default-height))))
@@ -2402,18 +2418,21 @@ used as a communication channel."
(format "\\begin{tikzpicture}[%s]\n%s\n\\end{tikzpicture}"
options
image-code)))
- (when (or (org-string-nw-p width) (org-string-nw-p height))
- (setq image-code (format "\\resizebox{%s}{%s}{%s}"
- (if (org-string-nw-p width) width "!")
- (if (org-string-nw-p height) height "!")
- image-code))))
+ (setq image-code
+ (cond ((org-string-nw-p scale)
+ (format "\\scalebox{%s}{%s}" scale image-code))
+ ((or (org-string-nw-p width) (org-string-nw-p height))
+ (format "\\resizebox{%s}{%s}{%s}"
+ (if (org-string-nw-p width) width "!")
+ (if (org-string-nw-p height) height "!")
+ image-code)))))
;; For other images:
- ;; - add width and height to options.
+ ;; - add scale, or width and height to options.
;; - include the image with \includegraphics.
- (when (org-string-nw-p width)
- (setq options (concat options ",width=" width)))
- (when (org-string-nw-p height)
- (setq options (concat options ",height=" height)))
+ (if (org-string-nw-p scale)
+ (setq options (concat options ",scale=" scale))
+ (when (org-string-nw-p width) (setq options (concat options ",width=" width)))
+ (when (org-string-nw-p height) (setq options (concat options ",height=" height))))
(let ((search-option (org-element-property :search-option link)))
(when (and search-option
(equal filetype "pdf")
@@ -2520,9 +2539,10 @@ INFO is a plist holding contextual information. See
;; Links pointing to a headline: Find destination and build
;; appropriate referencing command.
((member type '("custom-id" "fuzzy" "id"))
- (let ((destination (if (string= type "fuzzy")
- (org-export-resolve-fuzzy-link link info)
- (org-export-resolve-id-link link info))))
+ (let ((destination
+ (if (string= type "fuzzy")
+ (org-export-resolve-fuzzy-link link info 'latex-matrices)
+ (org-export-resolve-id-link link info))))
(cl-case (org-element-type destination)
;; Id link points to an external file.
(plain-text
@@ -2715,12 +2735,18 @@ it."
'latex-matrices)))
(let* ((caption (and (not (string= mode "inline-math"))
(org-element-property :caption table)))
+ (name (and (not (string= mode "inline-math"))
+ (org-element-property :name table)))
(matrices
(list 'latex-matrices
- (list :caption caption
+ ;; Inherit name from the first table.
+ (list :name name
+ ;; FIXME: what syntax for captions?
+ ;;
+ ;; :caption caption
:markup
(cond ((string= mode "inline-math") 'inline)
- (caption 'equation)
+ ((or caption name) 'equation)
(t 'math)))))
(previous table)
(next (org-export-get-next-element table info)))
@@ -2735,6 +2761,8 @@ it."
:attr_latex next :mode)
(plist-get info :latex-default-table-mode))
mode))
+ (org-element-put-property table :name nil)
+ (org-element-put-property table :caption nil)
(org-element-extract-element previous)
(org-element-adopt-elements matrices previous)
(setq previous next))
@@ -2744,20 +2772,29 @@ it."
(org-element-put-property
matrices :post-blank (org-element-property :post-blank previous))
(org-element-put-property previous :post-blank 0)
+ (org-element-put-property table :name nil)
+ (org-element-put-property table :caption nil)
(org-element-extract-element previous)
(org-element-adopt-elements matrices previous))))))
info)
data)
-(defun org-latex-matrices (matrices contents _info)
+(defun org-latex-matrices (matrices contents info)
"Transcode a MATRICES element from Org to LaTeX.
CONTENTS is a string. INFO is a plist used as a communication
channel."
- (format (cl-case (org-element-property :markup matrices)
- (inline "\\(%s\\)")
- (equation "\\begin{equation}\n%s\\end{equation}")
- (t "\\[\n%s\\]"))
- contents))
+ (pcase (org-element-property :markup matrices)
+ (`inline (format "\\(%s\\)" contents))
+ (`equation
+ (let ((caption (org-latex--caption/label-string matrices info))
+ (caption-above? (org-latex--caption-above-p matrices info)))
+ (concat "\\begin{equation}\n"
+ (and caption-above? caption)
+ contents
+ (and (not caption-above?) caption)
+ "\\end{equation}")))
+ (_
+ (format "\\[\n%s\\]" contents))))
;;;; Pseudo Object: LaTeX Math Block
@@ -2920,21 +2957,23 @@ contextual information."
;; Case 3. Use minted package.
((eq listings 'minted)
(let* ((caption-str (org-latex--caption/label-string src-block info))
+ (placement (or (org-unbracket-string "[" "]" (plist-get attributes :placement))
+ (plist-get info :latex-default-figure-position)))
(float-env
(cond
((string= "multicolumn" float)
(format "\\begin{listing*}[%s]\n%s%%s\n%s\\end{listing*}"
- (plist-get info :latex-default-figure-position)
+ placement
(if caption-above-p caption-str "")
(if caption-above-p "" caption-str)))
(caption
(format "\\begin{listing}[%s]\n%s%%s\n%s\\end{listing}"
- (plist-get info :latex-default-figure-position)
+ placement
(if caption-above-p caption-str "")
(if caption-above-p "" caption-str)))
((string= "t" float)
(concat (format "\\begin{listing}[%s]\n"
- (plist-get info :latex-default-figure-position))
+ placement)
"%s\n\\end{listing}"))
(t "%s")))
(options (plist-get info :latex-minted-options))
@@ -3142,6 +3181,56 @@ centered."
info)
(apply 'concat (nreverse align)))))
+(defun org-latex--decorate-table (table attributes caption above? info)
+ "Decorate TABLE string with caption and float environment.
+
+ATTRIBUTES is the plist containing is LaTeX attributes. CAPTION
+is its caption, as a string or nil. It is located above the
+table if ABOVE? is non-nil. INFO is the plist containing current
+export parameters.
+
+Return new environment, as a string."
+ (let* ((float-environment
+ (let ((float (plist-get attributes :float)))
+ (cond ((and (not float) (plist-member attributes :float)) nil)
+ ((member float '("sidewaystable" "sideways")) "sidewaystable")
+ ((equal float "multicolumn") "table*")
+ ((or float (org-string-nw-p caption)) "table")
+ (t nil))))
+ (placement
+ (or (plist-get attributes :placement)
+ (format "[%s]" (plist-get info :latex-default-figure-position))))
+ (center? (if (plist-member attributes :center)
+ (plist-get attributes :center)
+ (plist-get info :latex-tables-centered)))
+ (fontsize (let ((font (plist-get attributes :font)))
+ (and font (concat font "\n")))))
+ (concat (cond
+ (float-environment
+ (concat (format "\\begin{%s}%s\n" float-environment placement)
+ (if above? caption "")
+ (when center? "\\centering\n")
+ fontsize))
+ (caption
+ (concat (and center? "\\begin{center}\n" )
+ (if above? caption "")
+ (cond ((and fontsize center?) fontsize)
+ (fontsize (concat "{" fontsize))
+ (t nil))))
+ (center? (concat "\\begin{center}\n" fontsize))
+ (fontsize (concat "{" fontsize)))
+ table
+ (cond
+ (float-environment
+ (concat (if above? "" (concat "\n" caption))
+ (format "\n\\end{%s}" float-environment)))
+ (caption
+ (concat (if above? "" (concat "\n" caption))
+ (and center? "\n\\end{center}")
+ (and fontsize (not center?) "}")))
+ (center? "\n\\end{center}")
+ (fontsize "}")))))
+
(defun org-latex--org-table (table contents info)
"Return appropriate LaTeX code for an Org table.
@@ -3151,109 +3240,44 @@ channel.
This function assumes TABLE has `org' as its `:type' property and
`table' as its `:mode' attribute."
- (let* ((caption (org-latex--caption/label-string table info))
- (attr (org-export-read-attribute :attr_latex table))
- ;; Determine alignment string.
+ (let* ((attr (org-export-read-attribute :attr_latex table))
(alignment (org-latex--align-string table info))
- ;; Determine environment for the table: longtable, tabular...
(table-env (or (plist-get attr :environment)
(plist-get info :latex-default-table-environment)))
- ;; If table is a float, determine environment: table, table*
- ;; or sidewaystable.
- (float-env (unless (member table-env '("longtable" "longtabu"))
- (let ((float (plist-get attr :float)))
- (cond
- ((and (not float) (plist-member attr :float)) nil)
- ((or (string= float "sidewaystable")
- (string= float "sideways")) "sidewaystable")
- ((string= float "multicolumn") "table*")
- ((or float
- (org-element-property :caption table)
- (org-string-nw-p (plist-get attr :caption)))
- "table")))))
- ;; Extract others display options.
- (fontsize (let ((font (plist-get attr :font)))
- (and font (concat font "\n"))))
- ;; "tabular" environment doesn't allow to define a width.
- (width (and (not (equal table-env "tabular")) (plist-get attr :width)))
- (spreadp (plist-get attr :spread))
- (placement
- (or (plist-get attr :placement)
- (format "[%s]" (plist-get info :latex-default-figure-position))))
- (centerp (if (plist-member attr :center) (plist-get attr :center)
- (plist-get info :latex-tables-centered)))
- (caption-above-p (org-latex--caption-above-p table info)))
- ;; Prepare the final format string for the table.
+ (width
+ (let ((w (plist-get attr :width)))
+ (cond ((not w) "")
+ ((member table-env '("tabular" "longtable")) "")
+ ((member table-env '("tabu" "longtabu"))
+ (format (if (plist-get attr :spread) " spread %s "
+ " to %s ")
+ w))
+ (t (format "{%s}" w)))))
+ (caption (org-latex--caption/label-string table info))
+ (above? (org-latex--caption-above-p table info)))
(cond
- ;; Longtable.
- ((equal "longtable" table-env)
- (concat (and fontsize (concat "{" fontsize))
- (format "\\begin{longtable}{%s}\n" alignment)
- (and caption-above-p
- (org-string-nw-p caption)
- (concat caption "\\\\\n"))
- contents
- (and (not caption-above-p)
- (org-string-nw-p caption)
- (concat caption "\\\\\n"))
- "\\end{longtable}\n"
- (and fontsize "}")))
- ;; Longtabu
- ((equal "longtabu" table-env)
- (concat (and fontsize (concat "{" fontsize))
- (format "\\begin{longtabu}%s{%s}\n"
- (if width
- (format " %s %s "
- (if spreadp "spread" "to") width) "")
- alignment)
- (and caption-above-p
- (org-string-nw-p caption)
- (concat caption "\\\\\n"))
- contents
- (and (not caption-above-p)
- (org-string-nw-p caption)
- (concat caption "\\\\\n"))
- "\\end{longtabu}\n"
- (and fontsize "}")))
- ;; Others.
- (t (concat (cond
- (float-env
- (concat (format "\\begin{%s}%s\n" float-env placement)
- (if caption-above-p caption "")
- (when centerp "\\centering\n")
- fontsize))
- ((and (not float-env) caption)
- (concat
- (and centerp "\\begin{center}\n" )
- (if caption-above-p caption "")
- (cond ((and fontsize centerp) fontsize)
- (fontsize (concat "{" fontsize)))))
- (centerp (concat "\\begin{center}\n" fontsize))
- (fontsize (concat "{" fontsize)))
- (cond ((equal "tabu" table-env)
- (format "\\begin{tabu}%s{%s}\n%s\\end{tabu}"
- (if width (format
- (if spreadp " spread %s " " to %s ")
- width) "")
- alignment
- contents))
- (t (format "\\begin{%s}%s{%s}\n%s\\end{%s}"
- table-env
- (if width (format "{%s}" width) "")
- alignment
- contents
- table-env)))
- (cond
- (float-env
- (concat (if caption-above-p "" (concat "\n" caption))
- (format "\n\\end{%s}" float-env)))
- ((and (not float-env) caption)
- (concat
- (if caption-above-p "" (concat "\n" caption))
- (and centerp "\n\\end{center}")
- (and fontsize (not centerp) "}")))
- (centerp "\n\\end{center}")
- (fontsize "}")))))))
+ ((member table-env '("longtable" "longtabu"))
+ (let ((fontsize (let ((font (plist-get attr :font)))
+ (and font (concat font "\n")))))
+ (concat (and fontsize (concat "{" fontsize))
+ (format "\\begin{%s}%s{%s}\n" table-env width alignment)
+ (and above?
+ (org-string-nw-p caption)
+ (concat caption "\\\\\n"))
+ contents
+ (and (not above?)
+ (org-string-nw-p caption)
+ (concat caption "\\\\\n"))
+ (format "\\end{%s}" table-env)
+ (and fontsize "}"))))
+ (t
+ (let ((output (format "\\begin{%s}%s{%s}\n%s\\end{%s}"
+ table-env
+ width
+ alignment
+ contents
+ table-env)))
+ (org-latex--decorate-table output attr caption above? info))))))
(defun org-latex--table.el-table (table info)
"Return appropriate LaTeX code for a table.el table.
@@ -3267,30 +3291,29 @@ property."
;; Ensure "*org-export-table*" buffer is empty.
(with-current-buffer (get-buffer-create "*org-export-table*")
(erase-buffer))
- (let ((output (with-temp-buffer
- (insert (org-element-property :value table))
- (goto-char 1)
- (re-search-forward "^[ \t]*|[^|]" nil t)
- (table-generate-source 'latex "*org-export-table*")
- (with-current-buffer "*org-export-table*"
- (org-trim (buffer-string))))))
+ (let ((output
+ (replace-regexp-in-string
+ "^%.*\n" "" ;remove comments
+ (with-temp-buffer
+ (save-excursion (insert (org-element-property :value table)))
+ (re-search-forward "^[ \t]*|[^|]" nil t)
+ (table-generate-source 'latex "*org-export-table*")
+ (with-current-buffer "*org-export-table*"
+ (org-trim (buffer-string))))
+ t t)))
(kill-buffer (get-buffer "*org-export-table*"))
- ;; Remove left out comments.
- (while (string-match "^%.*\n" output)
- (setq output (replace-match "" t t output)))
- (let ((attr (org-export-read-attribute :attr_latex table)))
+ (let ((attr (org-export-read-attribute :attr_latex table))
+ (caption (org-latex--caption/label-string table info))
+ (above? (org-latex--caption-above-p table info)))
(when (plist-get attr :rmlines)
;; When the "rmlines" attribute is provided, remove all hlines
- ;; but the the one separating heading from the table body.
+ ;; but the one separating heading from the table body.
(let ((n 0) (pos 0))
(while (and (< (length output) pos)
(setq pos (string-match "^\\\\hline\n?" output pos)))
(cl-incf n)
(unless (= n 2) (setq output (replace-match "" nil nil output))))))
- (let ((centerp (if (plist-member attr :center) (plist-get attr :center)
- (plist-get info :latex-tables-centered))))
- (if (not centerp) output
- (format "\\begin{center}\n%s\n\\end{center}" output))))))
+ (org-latex--decorate-table output attr caption above? info))))
(defun org-latex--math-table (table info)
"Return appropriate LaTeX code for a matrix.
diff --git a/lisp/ox-man.el b/lisp/ox-man.el
index 950eadd..00698fc 100644
--- a/lisp/ox-man.el
+++ b/lisp/ox-man.el
@@ -159,7 +159,7 @@ When nil, no transformation is made."
;; Src blocks
(defcustom org-man-source-highlight nil
- "Use GNU source highlight to embellish source blocks "
+ "Use GNU source highlight to embellish source blocks."
:group 'org-export-man
:version "24.4"
:package-version '(Org . "8.0")
@@ -1042,7 +1042,7 @@ holding contextual information."
(defun org-man-verse-block (_verse-block contents _info)
"Transcode a VERSE-BLOCK element from Org to Man.
-CONTENTS is verse block contents. INFO is a plist holding
+CONTENTS is verse block contents. INFO is a plist holding
contextual information."
(format ".RS\n.ft I\n%s\n.ft\n.RE" contents))
diff --git a/lisp/ox-md.el b/lisp/ox-md.el
index d574e69..0a9441a 100644
--- a/lisp/ox-md.el
+++ b/lisp/ox-md.el
@@ -363,9 +363,14 @@ channel."
((string-match-p "\\<headlines\\>" value)
(let ((depth (and (string-match "\\<[0-9]+\\>" value)
(string-to-number (match-string 0 value))))
- (local? (string-match-p "\\<local\\>" value)))
+ (scope
+ (cond
+ ((string-match ":target +\\(\".+?\"\\|\\S-+\\)" value) ;link
+ (org-export-resolve-link
+ (org-strip-quotes (match-string 1 value)) info))
+ ((string-match-p "\\<local\\>" value) keyword)))) ;local
(org-remove-indentation
- (org-md--build-toc info depth keyword local?)))))))
+ (org-md--build-toc info depth keyword scope)))))))
(_ (org-export-with-backend 'html keyword contents info))))
@@ -550,7 +555,7 @@ a communication channel."
;;;; Template
-(defun org-md--build-toc (info &optional n keyword local)
+(defun org-md--build-toc (info &optional n _keyword scope)
"Return a table of contents.
INFO is a plist used as a communication channel.
@@ -558,13 +563,10 @@ INFO is a plist used as a communication channel.
Optional argument N, when non-nil, is an integer specifying the
depth of the table.
-Optional argument KEYWORD specifies the TOC keyword, if any, from
-which the table of contents generation has been initiated.
-
-When optional argument LOCAL is non-nil, build a table of
-contents according to the current headline."
+When optional argument SCOPE is non-nil, build a table of
+contents according to the specified element."
(concat
- (unless local
+ (unless scope
(let ((style (plist-get info :md-headline-style))
(title (org-html--translate "Table of Contents" info)))
(org-md--headline-title style 1 title nil)))
@@ -594,7 +596,7 @@ contents according to the current headline."
(org-make-tag-string
(org-export-get-tags headline info)))))
(concat indentation bullet title tags)))
- (org-export-collect-headlines info n (and local keyword)) "\n")
+ (org-export-collect-headlines info n scope) "\n")
"\n"))
(defun org-md--footnote-formatted (footnote info)
diff --git a/lisp/ox-odt.el b/lisp/ox-odt.el
index c14ee0b..f9c4a93 100644
--- a/lisp/ox-odt.el
+++ b/lisp/ox-odt.el
@@ -148,8 +148,7 @@
Use this to infer values of `org-odt-styles-dir' and
`org-odt-schema-dir'.")
-(defvar org-odt-data-dir
- (expand-file-name "../../etc/" org-odt-lib-dir)
+(defvar org-odt-data-dir (expand-file-name "../../etc/" org-odt-lib-dir)
"Data directory for ODT exporter.
Use this to infer values of `org-odt-styles-dir' and
`org-odt-schema-dir'.")
@@ -162,25 +161,17 @@ Use this to infer values of `org-odt-styles-dir' and
"Regular expressions for special string conversion.")
(defconst org-odt-schema-dir-list
- (list
- (and org-odt-data-dir
- (expand-file-name "./schema/" org-odt-data-dir)) ; bail out
- (eval-when-compile
- (and (boundp 'org-odt-data-dir) org-odt-data-dir ; see make install
- (expand-file-name "./schema/" org-odt-data-dir))))
+ (list (expand-file-name "./schema/" org-odt-data-dir))
"List of directories to search for OpenDocument schema files.
-Use this list to set the default value of
-`org-odt-schema-dir'. The entries in this list are
-populated heuristically based on the values of `org-odt-lib-dir'
-and `org-odt-data-dir'.")
+Use this list to set the default value of `org-odt-schema-dir'.
+The entries in this list are populated heuristically based on the
+values of `org-odt-lib-dir' and `org-odt-data-dir'.")
(defconst org-odt-styles-dir-list
(list
(and org-odt-data-dir
(expand-file-name "./styles/" org-odt-data-dir)) ; bail out
- (eval-when-compile
- (and (boundp 'org-odt-data-dir) org-odt-data-dir ; see make install
- (expand-file-name "./styles/" org-odt-data-dir)))
+ (expand-file-name "./styles/" org-odt-data-dir)
(expand-file-name "../etc/styles/" org-odt-lib-dir) ; git
(expand-file-name "./etc/styles/" org-odt-lib-dir) ; elpa
(expand-file-name "./org/" data-directory) ; system
@@ -823,7 +814,7 @@ form (TABLE-STYLE-NAME TABLE-TEMPLATE-NAME TABLE-CELL-OPTIONS).
TABLE-STYLE-NAME is the style associated with the table through
\"#+ATTR_ODT: :style TABLE-STYLE-NAME\" line.
-TABLE-TEMPLATE-NAME is a set of - upto 9 - automatic
+TABLE-TEMPLATE-NAME is a set of - up to 9 - automatic
TABLE-CELL-STYLE-NAMEs and PARAGRAPH-STYLE-NAMEs (as defined
below) that is included in `org-odt-content-template-file'.
@@ -1423,7 +1414,7 @@ original parsed data. INFO is a plist holding export options."
;; the resulting odt file.
(setq-local backup-inhibited t)
- ;; Outline numbering is retained only upto LEVEL.
+ ;; Outline numbering is retained only up to LEVEL.
;; To disable outline numbering pass a LEVEL of 0.
(goto-char (point-min))
@@ -1969,10 +1960,12 @@ contextual information."
CONTENTS holds the contents of the item. INFO is a plist holding
contextual information."
(let* ((plain-list (org-export-get-parent item))
+ (count (org-element-property :counter item))
(type (org-element-property :type plain-list)))
(unless (memq type '(ordered unordered descriptive-1 descriptive-2))
(error "Unknown list type: %S" type))
- (format "\n<text:list-item>\n%s\n%s"
+ (format "\n<text:list-item%s>\n%s\n%s"
+ (if count (format " text:start-value=\"%s\"" count) "")
contents
(if (org-element-map item 'table #'identity info 'first-match)
"</text:list-header>"
@@ -1998,8 +1991,13 @@ information."
(let ((depth (or (and (string-match "\\<[0-9]+\\>" value)
(string-to-number (match-string 0 value)))
(plist-get info :headline-levels)))
- (localp (string-match-p "\\<local\\>" value)))
- (org-odt-toc depth info (and localp keyword))))
+ (scope
+ (cond
+ ((string-match ":target +\\(\".+?\"\\|\\S-+\\)" value) ;link
+ (org-export-resolve-link
+ (org-strip-quotes (match-string 1 value)) info))
+ ((string-match-p "\\<local\\>" value) keyword)))) ;local
+ (org-odt-toc depth info scope)))
((string-match-p "tables\\|figures\\|listings" value)
;; FIXME
(ignore))))))))
@@ -2176,7 +2174,7 @@ SHORT-CAPTION are strings."
;;;; Links :: Inline Images
(defun org-odt--copy-image-file (path)
- "Returns the internal name of the file"
+ "Return the internal name of the file"
(let* ((image-type (file-name-extension path))
(media-type (format "image/%s" image-type))
(target-dir "Images/")
@@ -2381,7 +2379,7 @@ used as a communication channel."
(concat equation "<text:tab/>" label))))))
(defun org-odt--copy-formula-file (src-file)
- "Returns the internal name of the file"
+ "Return the internal name of the file"
(let* ((target-dir (format "Formula-%04d/"
(cl-incf org-odt-embedded-formulas-count)))
(target-file (concat target-dir "content.xml")))
@@ -3243,7 +3241,7 @@ styles congruent with the ODF-1.2 specification."
(when style-spec
;; LibreOffice - particularly the Writer - honors neither table
;; templates nor custom table-cell styles. Inorder to retain
- ;; inter-operability with LibreOffice, only automatic styles are
+ ;; interoperability with LibreOffice, only automatic styles are
;; used for styling of table-cells. The current implementation is
;; congruent with ODF-1.2 specification and hence is
;; future-compatible.
diff --git a/lisp/ox-publish.el b/lisp/ox-publish.el
index 0eefb0c..28d063e 100644
--- a/lisp/ox-publish.el
+++ b/lisp/ox-publish.el
@@ -909,7 +909,7 @@ PROJECT is the current project."
(defun org-publish-sitemap-default (title list)
"Default site map, as a string.
-TITLE is the the title of the site map. LIST is an internal
+TITLE is the title of the site map. LIST is an internal
representation for the files to include, as returned by
`org-list-to-lisp'. PROJECT is the current project."
(concat "#+TITLE: " title "\n\n"
@@ -1171,7 +1171,10 @@ references with `org-export-get-reference'."
(with-current-buffer (find-file-noselect file)
(org-with-point-at 1
(let ((org-link-search-must-match-exact-headline t))
- (org-link-search search nil t))
+ (condition-case err
+ (org-link-search search nil t)
+ (error
+ (signal 'org-link-broken (cdr err)))))
(and (org-at-heading-p)
(org-string-nw-p (org-entry-get (point) "CUSTOM_ID"))))))))
((not org-publish-cache)
@@ -1298,8 +1301,8 @@ the file including them will be republished as well."
(let* ((value (org-element-property :value element))
(filename
(and (string-match "\\`\\(\".+?\"\\|\\S-+\\)" value)
- (let ((m (org-unbracket-string
- "\"" "\"" (match-string 1 value))))
+ (let ((m (org-strip-quotes
+ (match-string 1 value))))
;; Ignore search suffix.
(if (string-match "::.*?\\'" m)
(substring m 0 (match-beginning 0))
diff --git a/lisp/ox-texinfo.el b/lisp/ox-texinfo.el
index 4f37a2a..5e74632 100644
--- a/lisp/ox-texinfo.el
+++ b/lisp/ox-texinfo.el
@@ -1253,12 +1253,14 @@ contextual information."
(if (string-prefix-p "@" i) i (concat "@" i))))
(table-type (plist-get attr :table-type))
(type (org-element-property :type plain-list))
- (initial-counter
- (and (eq type 'ordered)
- ;; Texinfo only supports initial counters, i.e., it
- ;; cannot change the numbering mid-list.
- (let ((first-item (car (org-element-contents plain-list))))
- (org-element-property :counter first-item))))
+ (enum
+ (cond ((not (eq type 'ordered)) nil)
+ ((plist-member attr :enum) (plist-get attr :enum))
+ (t
+ ;; Texinfo only supports initial counters, i.e., it
+ ;; cannot change the numbering mid-list.
+ (let ((first-item (car (org-element-contents plain-list))))
+ (org-element-property :counter first-item)))))
(list-type (cond
((eq type 'ordered) "enumerate")
((eq type 'unordered) "itemize")
@@ -1266,7 +1268,7 @@ contextual information."
(t "table"))))
(format "@%s\n%s@end %s"
(cond ((eq type 'descriptive) (concat list-type " " indic))
- (initial-counter (format "%s %d" list-type initial-counter))
+ (enum (format "%s %s" list-type enum))
(t list-type))
contents
list-type)))
diff --git a/lisp/ox.el b/lisp/ox.el
index b7751a7..5b4134e 100644
--- a/lisp/ox.el
+++ b/lisp/ox.el
@@ -73,6 +73,7 @@
(require 'cl-lib)
(require 'ob-exp)
+(require 'ol)
(require 'org-element)
(require 'org-macro)
(require 'tabulated-list)
@@ -804,7 +805,7 @@ also be set with the OPTIONS keyword, e.g. \"timestamp:nil\"."
:safe #'booleanp)
(defcustom org-export-with-timestamps t
- "Non nil means allow timestamps in export.
+ "Non-nil means allow timestamps in export.
It can be set to any of the following values:
t export all timestamps.
@@ -3270,6 +3271,11 @@ storing and resolving footnotes. It is created automatically."
(let* ((value (org-element-property :value element))
(ind (current-indentation))
location
+ (coding-system-for-read
+ (or (and (string-match ":coding +\\(\\S-+\\)>" value)
+ (prog1 (intern (match-string 1 value))
+ (setq value (replace-match "" nil nil value))))
+ coding-system-for-read))
(file
(and (string-match "^\\(\".+?\"\\|\\S-+\\)\\(?:\\s-+\\|$\\)"
value)
@@ -3517,8 +3523,8 @@ is to happen."
(goto-char (point-min))
(unless (eq major-mode 'org-mode)
(let ((org-inhibit-startup t)) (org-mode))) ;set regexps
- (let ((regexp (concat org-plain-link-re "\\|" org-angle-link-re)))
- (while (re-search-forward org-any-link-re nil t)
+ (let ((regexp (concat org-link-plain-re "\\|" org-link-angle-re)))
+ (while (re-search-forward org-link-any-re nil t)
(let ((link (save-excursion
(forward-char -1)
(save-match-data (org-element-context)))))
@@ -3701,18 +3707,24 @@ will become the empty string."
(cdr (nreverse (cons (funcall prepare-value s) result))))))))
(if property (plist-get attributes property) attributes)))
-(defun org-export-get-caption (element &optional shortp)
+(defun org-export-get-caption (element &optional short)
"Return caption from ELEMENT as a secondary string.
-When optional argument SHORTP is non-nil, return short caption,
-as a secondary string, instead.
+When optional argument SHORT is non-nil, return short caption, as
+a secondary string, instead.
Caption lines are separated by a white space."
- (let ((full-caption (org-element-property :caption element)) caption)
- (dolist (line full-caption (cdr caption))
- (let ((cap (funcall (if shortp 'cdr 'car) line)))
- (when cap
- (setq caption (nconc (list " ") (copy-sequence cap) caption)))))))
+ (let ((full-caption (org-element-property :caption element))
+ (get (if short #'cdr #'car))
+ caption)
+ (dolist (line full-caption)
+ (pcase (funcall get line)
+ (`nil nil)
+ (c
+ (setq caption
+ (nconc (list " ")
+ (copy-sequence c) caption)))))
+ (cdr caption)))
;;;; For Derived Back-ends
@@ -4156,6 +4168,9 @@ meant to be translated with `org-export-data' or alike."
;; specified id or custom-id in parse tree, the path to the external
;; file with the id.
;;
+;; `org-export-resolve-link' searches for the destination of a link
+;; within the parsed tree and returns the element.
+;;
;; `org-export-resolve-coderef' associates a reference to a line
;; number in the element it belongs, or returns the reference itself
;; when the element isn't numbered.
@@ -4243,8 +4258,8 @@ structure of RULES.
Return modified DATA."
(let ((link-re (format "\\`\\(?:%s\\|%s\\)\\'"
- org-plain-link-re
- org-angle-link-re))
+ org-link-plain-re
+ org-link-angle-re))
(case-fold-search t))
(org-element-map data 'link
(lambda (l)
@@ -4350,7 +4365,7 @@ as returned by `org-export-search-cells'."
(let ((targets (org-export-search-cells datum)))
(and targets (cl-some (lambda (cell) (member cell targets)) cells))))
-(defun org-export-resolve-fuzzy-link (link info)
+(defun org-export-resolve-fuzzy-link (link info &rest pseudo-types)
"Return LINK destination.
INFO is a plist holding contextual information.
@@ -4367,6 +4382,10 @@ Return value can be an object or an element:
- Otherwise, throw an error.
+PSEUDO-TYPES are pseudo-elements types, i.e., elements defined
+specifically in an export back-end, that could have a name
+affiliated keyword.
+
Assume LINK type is \"fuzzy\". White spaces are not
significant."
(let* ((search-cells (org-export-string-to-search-cell
@@ -4379,7 +4398,7 @@ significant."
(if (not (eq cached 'not-found)) cached
(let ((matches
(org-element-map (plist-get info :parse-tree)
- (cons 'target org-element-all-elements)
+ (append pseudo-types '(target) org-element-all-elements)
(lambda (datum)
(and (org-export-match-search-cell-p datum search-cells)
datum)))))
@@ -4438,6 +4457,31 @@ has type \"radio\"."
radio))
info 'first-match)))
+(defun org-export-resolve-link (link info)
+ "Return LINK destination.
+
+LINK is a string or a link object.
+
+INFO is a plist holding contextual information.
+
+Return value can be an object or an element:
+
+- If LINK path matches an ID or a custom ID, return the headline.
+
+- If LINK path matches a fuzzy link, return its destination.
+
+- Otherwise, throw an error."
+ ;; Convert string links to link objects.
+ (when (stringp link)
+ (setq link (with-temp-buffer
+ (save-excursion
+ (insert (org-link-make-string link)))
+ (org-element-link-parser))))
+ (pcase (org-element-property :type link)
+ ((or "custom-id" "id") (org-export-resolve-id-link link info))
+ ("fuzzy" (org-export-resolve-fuzzy-link link info))
+ (_ (signal 'org-link-broken (list (org-element-property :path link))))))
+
(defun org-export-file-uri (filename)
"Return file URI associated to FILENAME."
(cond ((string-prefix-p "//" filename) (concat "file:" filename))
@@ -4757,7 +4801,7 @@ code."
;;;; For Tables
;;
-;; `org-export-table-has-special-column-p' and and
+;; `org-export-table-has-special-column-p' and
;; `org-export-table-row-is-special-p' are predicates used to look for
;; meta-information about the table structure.
;;
diff --git a/mk/default.mk b/mk/default.mk
index 50d037d..fbfdaf5 100644
--- a/mk/default.mk
+++ b/mk/default.mk
@@ -75,7 +75,7 @@ BTEST = $(BATCH) $(BTEST_INIT) \
)' \
-l org-loaddefs.el \
-l cl -l testing/org-test.el \
- -l ert -l org -l ox \
+ -l ert -l org -l ox -l ol \
$(foreach req,$(BTEST_EXTRA),$(req-extra)) \
--eval '(org-test-run-batch-tests org-test-select-re)'
@@ -115,7 +115,7 @@ MAKE_ORG_INSTALL = $(BATCHL) \
MAKE_ORG_VERSION = $(BATCHL) \
--eval '(load "org-compat.el")' \
--eval '(load "../mk/org-fixup.el")' \
- --eval '(org-make-org-version "$(ORGVERSION)" "$(GITVERSION)" "'$(datadir)'")'
+ --eval '(org-make-org-version "$(ORGVERSION)" "$(GITVERSION)")'
# How to byte-compile the whole source directory
ELCDIR = $(BATCHL) \
diff --git a/mk/eldo.el b/mk/eldo.el
index 6a5675a..ba8c464 100644
--- a/mk/eldo.el
+++ b/mk/eldo.el
@@ -100,7 +100,7 @@
(goto-char (point-max))))
(defun eldo-write-commands (commands)
- "Write commands documentaiton in the current buffer."
+ "Write commands documentation in the current buffer."
(insert "\n* Commands\n")
(org-set-property "CUSTOM_ID" "commands")
(dolist (c commands)
diff --git a/mk/org-fixup.el b/mk/org-fixup.el
index d2bdf9c..760e73a 100644
--- a/mk/org-fixup.el
+++ b/mk/org-fixup.el
@@ -30,11 +30,11 @@
(defun org-make-manuals ()
"Generate the Texinfo files out of Org manuals."
(require 'ox-texinfo)
- (dolist (manual '("../doc/org-manual.org"))
+ (dolist (manual '("../doc/org-manual.org" "../doc/org-guide.org"))
(find-file manual)
(org-texinfo-export-to-texinfo)))
-(defun org-make-org-version (org-release org-git-version odt-dir)
+(defun org-make-org-version (org-release org-git-version)
"Make the file org-version.el in the current directory.
This function is internally used by the build system and should
be used by foreign build systems or installers to produce this
@@ -58,9 +58,6 @@ Inserted by installing Org mode or when a release is made.\"
Inserted by installing Org or when a release is made.\"
(let ((org-git-version \"" org-git-version "\"))
org-git-version))
-;;;\#\#\#autoload
-\(defvar org-odt-data-dir \"" odt-dir "\"
- \"The location of ODT styles.\")
\f\n\(provide 'org-version\)
\f\n;; Local Variables:\n;; version-control: never
;; no-byte-compile: t
@@ -93,17 +90,13 @@ Finds the install directory by looking for library \"org\".
Optionally byte-compile lisp files in the install directory or
force re-compilation. This function is provided for easier
manual install when the build system can't be used."
- (let* ((origin default-directory)
- (dirlisp (org-find-library-dir "org"))
- (dirorg (concat dirlisp "../" ))
- (dirodt (if (boundp 'org-odt-data-dir)
- org-odt-data-dir
- (concat dirorg "etc/"))))
+ (let ((origin default-directory)
+ (dirlisp (org-find-library-dir "org")))
(unwind-protect
(progn
(cd dirlisp)
(org-fixup)
- (org-make-org-version (org-release) (org-git-version) dirodt)
+ (org-make-org-version (org-release) (org-git-version))
(org-make-org-loaddefs)
(when compile (byte-recompile-directory dirlisp 0 force)))
(cd origin))))
diff --git a/mk/server.mk b/mk/server.mk
index deba7cd..94818bb 100644
--- a/mk/server.mk
+++ b/mk/server.mk
@@ -82,7 +82,7 @@ archive-contents:
echo " (org-plus-contrib . [($(PKG_TAG)) ($(PKG_REQ)) \"$(PKG_DOC)\" tar]))" >> $@
elpaplus: cleanall info card elpaplus-dirty
-elpaplus-dirty elpaplus-up: ORG_ADD_CONTRIB=org*.el ob-*.el ox-*.el
+elpaplus-dirty elpaplus-up: ORG_ADD_CONTRIB=org*.el ob-*.el ox-*.el ol-*.el
elpaplus-dirty elpaplus-up: ORGDIR=org-plus-contrib-$(PKG_TAG)
elpaplus-dirty:
@$(MAKE) GITVERSION=$(GITVERSION:release_%=%)-elpaplus version autoloads
diff --git a/testing/README b/testing/README
index add3c4f..2469d14 100644
--- a/testing/README
+++ b/testing/README
@@ -120,15 +120,15 @@ load and run the test suite with the following commands.
To run one test: Use this as a demo example of a failing test
#+BEGIN_SRC emacs-lisp
- (ert-deftest test-org/org-link-escape-ascii-character-demo-of-fail ()
+ (ert-deftest test-org/org-link-encode-ascii-character-demo-of-fail ()
(should (string= "%5B" ; Expecting %5B is correct.
- (org-link-escape "[")))
+ (org-link-encode "[")))
(should (string= "%5C" ; Expecting %5C is wrong, %5D correct.
- (org-link-escape "]"))))
+ (org-link-encode "]"))))
#+END_SRC
or evaluate the ~ert-deftest form~ of the test you want to run.
Then ~M-x ert RET
- test-org/org-link-escape-ascii-character-demo-of-fail RET~. When
+ test-org/org-link-encode-ascii-character-demo-of-fail RET~. When
not visible yet switch to the ERT results buffer named ~*ert*~.
When a test failed the ERT results buffer shows the details of the
first ~should~ that failed. See ~(info "(ert)Running Tests
diff --git a/testing/examples/agenda-file.org b/testing/examples/agenda-file.org
index 1c72649..b3b8725 100644
--- a/testing/examples/agenda-file.org
+++ b/testing/examples/agenda-file.org
@@ -4,3 +4,5 @@
* test agenda
SCHEDULED: <2017-07-19 Wed>
** subnote
+* test code 216bc1ff1d862e78183e38ee9a4da504919b9878
+<2019-01-08 Tue>
diff --git a/testing/examples/att1/fileA b/testing/examples/att1/fileA
new file mode 100644
index 0000000..9a0406c
--- /dev/null
+++ b/testing/examples/att1/fileA
@@ -0,0 +1 @@
+Text in fileA
diff --git a/testing/examples/att1/fileB b/testing/examples/att1/fileB
new file mode 100644
index 0000000..dd23318
--- /dev/null
+++ b/testing/examples/att1/fileB
@@ -0,0 +1 @@
+Text in fileB
diff --git a/testing/examples/att2/fileC b/testing/examples/att2/fileC
new file mode 100644
index 0000000..2c9a92b
--- /dev/null
+++ b/testing/examples/att2/fileC
@@ -0,0 +1 @@
+Text in fileC \ No newline at end of file
diff --git a/testing/examples/att2/fileD b/testing/examples/att2/fileD
new file mode 100644
index 0000000..c706556
--- /dev/null
+++ b/testing/examples/att2/fileD
@@ -0,0 +1 @@
+text in fileD
diff --git a/testing/examples/attachments.org b/testing/examples/attachments.org
new file mode 100644
index 0000000..ab4a4e5
--- /dev/null
+++ b/testing/examples/attachments.org
@@ -0,0 +1,32 @@
+#+TITLE: Org attach testfile
+Used to test and verify the functionality of org-attach.
+
+* H1
+ :PROPERTIES:
+ :DIR: att1
+ :END:
+A link to one attachment: [[attachment:fileA]]
+
+** H1.1
+A link to another attachment: [[attachment:fileB]]
+
+** H1.2
+ :PROPERTIES:
+ :DIR: att2
+ :END:
+
+* H2
+ :PROPERTIES:
+ :ID: abcd123
+ :END:
+
+* H3
+ :PROPERTIES:
+ :DIR: att1
+ :ID: abcd1234
+ :END:
+
+** H3.1
+ :PROPERTIES:
+ :ID: abcd12345
+ :END:
diff --git a/testing/examples/data/ab/cd123/fileE b/testing/examples/data/ab/cd123/fileE
new file mode 100644
index 0000000..80d3377
--- /dev/null
+++ b/testing/examples/data/ab/cd123/fileE
@@ -0,0 +1 @@
+peek-a-boo
diff --git a/testing/examples/diary-file b/testing/examples/diary-file
new file mode 100644
index 0000000..11745bc
--- /dev/null
+++ b/testing/examples/diary-file
@@ -0,0 +1 @@
+2019-01-08 test code: f0bcf0cd8bad93c1451bb6e1b2aaedef5cce7cbb
diff --git a/testing/examples/ob-awk-test.org b/testing/examples/ob-awk-test.org
index 63e070f..f9b7312 100644
--- a/testing/examples/ob-awk-test.org
+++ b/testing/examples/ob-awk-test.org
@@ -6,13 +6,13 @@
:ID: 9e998b2a-3581-43fe-b26d-07d3c507b86a
:END:
Run without input stream
-#+begin_src awk :ouput silent :results silent
+#+begin_src awk :output silent :results silent
BEGIN {
print 42
}
#+end_src
-Use a code block ouput as an input
+Use a code block output as an input
#+begin_src awk :stdin genseq :results silent
{
print 42+$1
diff --git a/testing/lisp/test-ob-clojure.el b/testing/lisp/test-ob-clojure.el
new file mode 100644
index 0000000..a5391dc
--- /dev/null
+++ b/testing/lisp/test-ob-clojure.el
@@ -0,0 +1,91 @@
+;;; test-ob-clojure.el
+
+;; Copyright (c) 2018-2022 Free Software Foundation, Inc.
+;; Authors: stardiviner
+
+;; This file is not part of GNU Emacs.
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Comments:
+
+;; Org tests for ob-clojure.el live here
+
+;;; Code:
+(org-test-for-executable "cider")
+(unless (featurep 'cider)
+ (signal 'missing-test-dependency "CIDER"))
+(unless (featurep 'ob-clojure)
+ (signal 'missing-test-dependency "Support for Clojure code blocks"))
+
+(ert-deftest ob-clojure/simple-session ()
+ (org-test-with-temp-text
+ "#+begin_src clojure :session
+(print \"hello, world\")
+#+end_src
+"
+ (should (string= "hello, world" (org-babel-execute-src-block)))))
+
+(ert-deftest ob-clojure/initiate-session ()
+ (org-test-with-temp-text
+ "#+begin_src clojure :session :var a=1 :results output
+(print \"hello, world\")
+#+end_src
+
+#+begin_src clojure :session :results output
+(print a)
+#+end_src"
+ (goto-char (point-min))
+ (org-babel-switch-to-session)
+ (sleep-for 2)
+ (org-babel-execute-maybe)
+ (org-babel-next-src-block)
+ (goto-char (org-babel-result-end))
+ (forward-line 2)
+ (should (string=
+ ": 1"
+ (buffer-substring-no-properties (point-at-bol) (point-at-eol))))))
+
+(ert-deftest ob-clojure/initiate-session-with-var ()
+ (org-test-with-temp-text
+ "#+begin_src clojure :session :var a=1 :results output
+(print a)
+#+end_src"
+ (org-babel-next-src-block)
+ (org-babel-initiate-session)
+ (sleep-for 2)
+ (org-babel-execute-maybe)
+ (goto-char (org-babel-result-end))
+ (forward-line 2)
+ (should (string=
+ ": 1"
+ (buffer-substring-no-properties (point-at-bol) (point-at-eol))))))
+(ert-deftest ob-clojure/tangle-without-ns ()
+ (org-test-with-temp-text
+ "#+begin_src clojure :tangle /tmp/test.clj
+(print 1)
+#+end_src"
+ (org-babel-next-src-block)
+ (org-babel-tangle)
+ (should
+ (string=
+ "(print 1)
+"
+ (with-temp-buffer
+ (insert-file-contents "/tmp/test.clj")
+ (buffer-substring-no-properties (point-min) (point-max)))))))
+
+(provide 'test-ob-clojure)
+
+ ;;; test-ob-clojure.el ends here
diff --git a/testing/lisp/test-ob-emacs-lisp.el b/testing/lisp/test-ob-emacs-lisp.el
index 078cad9..24a373f 100644
--- a/testing/lisp/test-ob-emacs-lisp.el
+++ b/testing/lisp/test-ob-emacs-lisp.el
@@ -76,6 +76,95 @@
(buffer-substring-no-properties (line-beginning-position 2)
(line-end-position 2))))))
+(ert-deftest ob-emacs-lisp/dynamic-lexical-execute ()
+ (cl-flet ((execute (text)
+ (org-test-with-temp-text-in-file text
+ (org-babel-next-src-block)
+ (org-babel-execute-maybe)
+ (re-search-forward "results" nil t)
+ (re-search-forward ": " nil t)
+ (buffer-substring-no-properties (point) (point-at-eol)))))
+
+ (should (string= "dynamic" (execute "
+#+begin_src emacs-lisp :lexical no :results verbatim
+(let ((x 'dynamic)) (funcall (let ((x 'lexical)) (lambda () x))))
+#+end_src")))
+
+ (should (string= "lexical" (execute "
+#+begin_src emacs-lisp :lexical yes :results verbatim
+(let ((x 'dynamic)) (funcall (let ((x 'lexical)) (lambda () x))))
+#+end_src")))
+
+ (should (string= "dynamic" (let ((x 'dynamic)) (execute "
+#+begin_src emacs-lisp :lexical no :results verbatim
+x
+#+end_src"))))
+
+ (should (string= "lexical" (let ((x 'dynamic)) (execute "
+#+begin_src emacs-lisp :lexical '((x . lexical)) :results verbatim
+x
+#+end_src"))))
+
+ ;; Src block execution uses `eval'. As of 2019-02-26, `eval' does
+ ;; not dynamically bind `lexical-binding' to the value of its
+ ;; LEXICAL parameter. Hence, (eval 'lexical-binding LEXICAL)
+ ;; evaluates to the same value that just `lexical-binding'
+ ;; evaluates to, even if LEXICAL is different. So tests like the
+ ;; following do not work here:
+ ;;
+ ;; (should (string= "t" (execute "
+ ;; #+begin_src emacs-lisp :lexical yes :results verbatim
+ ;; lexical-binding
+ ;; #+end_src")))
+ ;;
+ ;; However, the corresponding test in
+ ;; `ob-emacs-lisp/dynamic-lexical-edit' does work.
+ ))
+
+(ert-deftest ob-emacs-lisp/dynamic-lexical-edit ()
+ (cl-flet ((execute (text)
+ (org-test-with-temp-text-in-file text
+ (org-babel-next-src-block)
+ (org-edit-src-code)
+ (goto-char (point-max))
+ (prog1 (eval-last-sexp 0)
+ (org-edit-src-exit)))))
+
+ (should (eq 'dynamic (execute "
+#+begin_src emacs-lisp :lexical no :results verbatim
+(let ((x 'dynamic)) (funcall (let ((x 'lexical)) (lambda () x))))
+#+end_src")))
+
+ (should (eq 'lexical (execute "
+#+begin_src emacs-lisp :lexical yes :results verbatim
+(let ((x 'dynamic)) (funcall (let ((x 'lexical)) (lambda () x))))
+#+end_src")))
+
+ (should (eq 'dynamic (let ((x 'dynamic)) (execute "
+#+begin_src emacs-lisp :lexical no :results verbatim
+x
+#+end_src"))))
+
+ (should (eq 'lexical (let ((x 'dynamic)) (execute "
+#+begin_src emacs-lisp :lexical '((x . lexical)) :results verbatim
+x
+#+end_src"))))
+
+ (should (equal nil (execute "
+#+begin_src emacs-lisp :lexical no :results verbatim
+lexical-binding
+#+end_src")))
+
+ (should (equal t (execute "
+#+begin_src emacs-lisp :lexical yes :results verbatim
+lexical-binding
+#+end_src")))
+
+ (should (equal '((x . 0)) (execute "
+#+begin_src emacs-lisp :lexical '((x . 0)) :results verbatim
+lexical-binding
+#+end_src")))))
+
(provide 'test-ob-emacs-lisp)
;;; test-ob-emacs-lisp.el ends here
diff --git a/testing/lisp/test-ob-eshell.el b/testing/lisp/test-ob-eshell.el
new file mode 100644
index 0000000..5b0eb27
--- /dev/null
+++ b/testing/lisp/test-ob-eshell.el
@@ -0,0 +1,73 @@
+;;; test-ob-eshell.el
+
+;; Copyright (c) 2018 stardiviner
+;; Authors: stardiviner
+
+;; This file is not part of GNU Emacs.
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Comment:
+
+;; Template test file for Org tests
+
+;;; Code:
+(unless (featurep 'ob-eshell)
+ (signal 'missing-test-dependency "Support for Eshell code blocks"))
+
+(ert-deftest ob-eshell/execute ()
+ "Test ob-eshell execute."
+ (should
+ (string=
+ (org-test-with-temp-text
+ "#+begin_src eshell
+echo 2
+#+end_src"
+ (org-babel-execute-src-block))
+ ": 2")))
+
+(ert-deftest ob-eshell/variables-assignment ()
+ "Test ob-eshell variables assignment."
+ (should
+ (string=
+ (org-test-with-temp-text
+ "#+begin_src eshell :var hi=\"hello, world\"
+echo $hi
+#+end_src"
+ (org-babel-execute-src-block))
+ ": hello, world")))
+
+(ert-deftest ob-eshell/session ()
+ "Test ob-eshell session."
+ (should
+ (string=
+ (org-test-with-temp-text
+ "#+begin_src eshell :session
+(setq hi \"hello, world\")
+#+end_src
+
+#+begin_src eshell :session
+echo $hi
+#+end_src"
+ (org-babel-execute-src-block)
+ (org-babel-next-src-block)
+ (org-babel-execute-src-block)
+ (goto-char (org-babel-where-is-src-block-result))
+ (forward-line)
+ (buffer-substring-no-properties (point) (line-end-position)))
+ ": hello, world")))
+
+(provide 'test-ob-eshell)
+
+;;; test-ob-eshell.el ends here
diff --git a/testing/lisp/test-ob-sqlite.el b/testing/lisp/test-ob-sqlite.el
index 4a66a08..f6ffa6a 100644
--- a/testing/lisp/test-ob-sqlite.el
+++ b/testing/lisp/test-ob-sqlite.el
@@ -25,7 +25,7 @@
(signal 'missing-test-dependency "Support for sqlite code blocks"))
(ert-deftest ob-sqlite/table-variables-with-commas ()
- "Test of a table variable that contains commas. This garantees that this code path results in a valid CSV."
+ "Test of a table variable that contains commas. This guarantees that this code path results in a valid CSV."
(should
(equal '(("Mr Test A. Sql"
"Minister for Science, Eternal Happiness, and Finance"))
diff --git a/testing/lisp/test-ob-tangle.el b/testing/lisp/test-ob-tangle.el
index 47c31df..301f7af 100644
--- a/testing/lisp/test-ob-tangle.el
+++ b/testing/lisp/test-ob-tangle.el
@@ -296,6 +296,90 @@ another block
(org-split-string (buffer-string))))
(delete-file file))))))
+(ert-deftest ob-tangle/commented-src-blocks ()
+ "Test omission of commented src blocks."
+ (should
+ (equal '("A")
+ (let ((file (make-temp-file "org-tangle-")))
+ (unwind-protect
+ (progn
+ (org-test-with-temp-text-in-file
+ (format "#+property: header-args :tangle %S
+* A
+
+ #+begin_src emacs-lisp
+ A
+ #+end_src
+
+* COMMENT B
+
+ #+begin_src emacs-lisp
+ B
+ #+end_src
+
+* C
+
+ # #+begin_src emacs-lisp
+ # C
+ # #+end_src
+
+* D
+
+ #+begin_comment
+ #+begin_src emacs-lisp
+ D
+ #+end_src
+ #+end_comment"
+ file)
+ (org-babel-tangle))
+ (with-temp-buffer
+ (insert-file-contents file)
+ (org-split-string (buffer-string))))
+ (delete-file file)))))
+ (should
+ (equal '("A")
+ (let ((file (make-temp-file "org-tangle-")))
+ (unwind-protect
+ (progn
+ (org-test-with-temp-text-in-file
+ (format "#+property: header-args :tangle %S
+* A
+
+ #+begin_src elisp :noweb yes
+ A
+ <<B>>
+ <<C>>
+ <<D>>
+ #+end_src
+
+* COMMENT B
+
+ #+begin_src elisp :noweb-ref B
+ B
+ #+end_src
+
+* C
+
+ # #+begin_src elisp :noweb-ref C
+ # C
+ # #+end_src
+
+* D
+
+ #+begin_comment
+ #+begin_src elisp :noweb-ref D
+ D
+ #+end_src
+ #+end_comment"
+ file)
+ (let (org-babel-noweb-error-all-langs
+ org-babel-noweb-error-langs)
+ (org-babel-tangle)))
+ (with-temp-buffer
+ (insert-file-contents file)
+ (org-split-string (buffer-string))))
+ (delete-file file))))))
+
(provide 'test-ob-tangle)
;;; test-ob-tangle.el ends here
diff --git a/testing/lisp/test-ob.el b/testing/lisp/test-ob.el
index fc3451f..681f340 100644
--- a/testing/lisp/test-ob.el
+++ b/testing/lisp/test-ob.el
@@ -30,7 +30,7 @@ should still return the link."
(org-test-with-temp-text
"
* Test
- #+<point>BEGIN_SRC emacs-lisp :file test.txt :cache yes
+ #+<point>BEGIN_SRC emacs-lisp :results file :file test.txt :cache yes
(message \"test\")
#+END_SRC"
;; Execute twice as the first time creates the cache.
@@ -759,6 +759,30 @@ x
#+begin_src emacs-lisp
baz
#+end_src"
+ (org-babel-expand-noweb-references))))
+ ;; Respect COMMENT headlines
+ (should
+ (equal "C"
+ (org-test-with-temp-text "
+#+begin_src emacs-lisp :noweb yes<point>
+ <<foo>>
+#+end_src
+
+* COMMENT A
+#+name: foo
+#+begin_src emacs-lisp
+ A
+#+end_src
+
+* COMMENT B
+#+begin_src emacs-lisp :noweb-ref foo
+ B
+#+end_src
+
+* C
+#+begin_src emacs-lisp :noweb-ref foo
+ C
+#+end_src"
(org-babel-expand-noweb-references)))))
(ert-deftest test-ob/splitting-variable-lists-in-references ()
@@ -1003,30 +1027,48 @@ trying to find the :END: marker."
The file is just a link to `:file' value. Inhibit non-empty
result write to `:file' value."
(org-test-with-temp-text "
+<point>#+begin_src shell :results value file link :file \"/tmp/test.txt\"
+echo \"hello\" > /tmp/test.txt
+echo \"test\"
+#+end_src"
+ (org-babel-execute-src-block)
+ (should (search-forward "[[file:/tmp/test.txt]]" nil t))
+ (should (with-temp-buffer
+ (insert-file-contents "/tmp/test.txt")
+ (string= "hello\n" (buffer-string)))))
+ ;; Without "link" output type, the result is not a file.
+ (should-not
+ (org-test-with-temp-text "
<point>#+begin_src shell :results value link :file \"/tmp/test.txt\"
echo \"hello\" > /tmp/test.txt
echo \"test\"
#+end_src"
- (org-babel-execute-src-block)
- (should (search-forward "[[file:/tmp/test.txt]]" nil nil))
- (should (with-temp-buffer
- (insert-file-contents "/tmp/test.txt")
- (string= "hello\n" (buffer-string))))))
+ (org-babel-execute-src-block)
+ (search-forward "[[file:/tmp/test.txt]]" nil t))))
(ert-deftest test-ob/result-graphics-link-type-header-argument ()
"Ensure that the result is a link to a file.
The file is just a link to `:file' value. Inhibit non-empty
result write to `:file' value."
(org-test-with-temp-text "
+<point>#+begin_src shell :results value file graphics :file \"/tmp/test.txt\"
+echo \"hello\" > /tmp/test.txt
+echo \"test\"
+#+end_src"
+ (org-babel-execute-src-block)
+ (should (search-forward "[[file:/tmp/test.txt]]" nil nil))
+ (should (with-temp-buffer
+ (insert-file-contents "/tmp/test.txt")
+ (string= "hello\n" (buffer-string)))))
+ ;; Without "link" output type, the result is not a file.
+ (should-not
+ (org-test-with-temp-text "
<point>#+begin_src shell :results value graphics :file \"/tmp/test.txt\"
echo \"hello\" > /tmp/test.txt
echo \"test\"
#+end_src"
- (org-babel-execute-src-block)
- (should (search-forward "[[file:/tmp/test.txt]]" nil nil))
- (should (with-temp-buffer
- (insert-file-contents "/tmp/test.txt")
- (string= "hello\n" (buffer-string))))))
+ (org-babel-execute-src-block)
+ (search-forward "[[file:/tmp/test.txt]]" nil t))))
(ert-deftest test-ob/inline-src_blk-preceded-punct-preceded-by-point ()
(let ((test-line ".src_emacs-lisp[ :results verbatim ]{ \"x\" }")
@@ -1514,6 +1556,32 @@ echo \"$data\"
(buffer-substring-no-properties (line-beginning-position)
(point-max)))))))
+(ert-deftest test-ob/preserve-comma-escape ()
+ "Preserve comma escapes when inserting results."
+ (should
+ (equal
+ "#+begin_example
+line 1
+,* headline 2
+,* headline 3
+,* headline 4
+,* headline 5
+#+end_example
+"
+ (org-test-with-temp-text "#+begin_src emacs-lisp :wrap example
+\"line 1
+,* headline 2
+,* headline 3
+,* headline 4
+,* headline 5
+\"
+#+end_src
+"
+ (org-babel-execute-src-block)
+ (let ((case-fold-search t)) (search-forward "result" nil t))
+ (downcase (buffer-substring-no-properties (line-beginning-position 2)
+ (point-max)))))))
+
(ert-deftest test-ob/safe-header-args ()
"Detect safe and unsafe header args."
(let ((safe-args '((:cache . "foo")
@@ -1589,6 +1657,41 @@ echo \"$data\"
(cdr (assq :file (nth 2 (org-babel-get-src-block-info t))))))
))
+(ert-deftest test-ob-core/dir-mkdirp ()
+ "Test :mkdirp with :dir header combination."
+ (should-not
+ (org-test-with-temp-text-in-file
+ "#+begin_src emacs-lisp :dir \"data/code\"
+t
+#+end_src"
+ (org-babel-execute-src-block)
+ (message default-directory)
+ (file-directory-p "data/code")))
+ (should-not
+ (org-test-with-temp-text-in-file
+ "#+begin_src emacs-lisp :mkdirp no :dir \"data/code\"
+t
+#+end_src"
+ (org-babel-execute-src-block)
+ (message default-directory)
+ (file-directory-p "data/code")))
+ (should
+ (org-test-with-temp-text-in-file
+ "#+begin_src emacs-lisp :mkdirp yes :dir \"data/code\"
+t
+#+end_src"
+ (org-babel-execute-src-block)
+ (message default-directory)
+ (prog1 (file-directory-p "data/code")
+ (delete-directory "data" t))))
+ (should
+ (equal "/tmp/test-dir-no-mkdirp/"
+ (org-test-with-temp-text-in-file
+ "#+begin_src emacs-lisp :dir /tmp/test-dir-no-mkdirp
+default-directory
+#+end_src"
+ (org-babel-execute-src-block)))))
+
(ert-deftest test-ob/script-escape ()
;; Delimited lists of numbers
(should (equal '(1 2 3)
@@ -2016,6 +2119,16 @@ abc
(let ((org-coderef-label-format "#(ref:%s)"))
(org-babel-execute-src-block))))))
+(ert-deftest test-ob/string-to-number ()
+ (should (= 0 (org-babel--string-to-number "0")))
+ (should (= 1 (org-babel--string-to-number "1")))
+ (should (eq nil (org-babel--string-to-number "000")))
+ (should (eq nil (org-babel--string-to-number "001")))
+ (should (eq nil (org-babel--string-to-number "010")))
+ (should (= 100 (org-babel--string-to-number "100")))
+ (should (= 0.1 (org-babel--string-to-number "0.1")))
+ (should (= 1.0 (org-babel--string-to-number "1.0"))))
+
(provide 'test-ob)
;;; test-ob ends here
diff --git a/testing/lisp/test-org-bbdb.el b/testing/lisp/test-ol-bbdb.el
index 4dfc8ad..9c6885f 100644
--- a/testing/lisp/test-org-bbdb.el
+++ b/testing/lisp/test-ol-bbdb.el
@@ -24,13 +24,13 @@
;;; Code:
-(require 'org-bbdb)
+(require 'ol-bbdb)
(ert-deftest test-org-bbdb-anniv-extract-date ()
(should (equal nil (org-bbdb-anniv-extract-date "foo")))
(should (equal '(9 22 2018) (org-bbdb-anniv-extract-date "2018-09-22")))
(should (equal '(9 22 nil) (org-bbdb-anniv-extract-date "09-22"))))
-(provide 'test-org-bbdb)
+(provide 'test-ol-bbdb)
;;; test-org-bbdb.el ends here
diff --git a/testing/lisp/test-ol.el b/testing/lisp/test-ol.el
new file mode 100644
index 0000000..fd735dc
--- /dev/null
+++ b/testing/lisp/test-ol.el
@@ -0,0 +1,382 @@
+;;; test-ol.el --- Tests for Org Links library -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2019 Nicolas Goaziou
+
+;; Author: Nicolas Goaziou <mail@nicolasgoaziou.fr>
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Code:
+
+
+;;; Decode and Encode Links
+
+(ert-deftest test-ol/encode ()
+ "Test `org-link-encode' specifications."
+ ;; Regural test.
+ (should (string= "Foo%3A%42ar" (org-link-encode "Foo:Bar" '(?\: ?\B))))
+ ;; Encode an ASCII character.
+ (should (string= "%5B" (org-link-encode "[" '(?\[))))
+ ;; Encode an ASCII control character.
+ (should (string= "%09" (org-link-encode "\t" '(9))))
+ ;; Encode a Unicode multibyte character.
+ (should (string= "%E2%82%AC" (org-link-encode "€" '(?\€)))))
+
+(ert-deftest test-ol/decode ()
+ "Test `org-link-decode' specifications."
+ ;; Decode an ASCII character.
+ (should (string= "[" (org-link-decode "%5B")))
+ ;; Decode an ASCII control character.
+ (should (string= "\n" (org-link-decode "%0A")))
+ ;; Decode a Unicode multibyte character.
+ (should (string= "€" (org-link-decode "%E2%82%AC"))))
+
+(ert-deftest test-ol/encode-url-with-escaped-char ()
+ "Encode and decode a URL that includes an encoded char."
+ (should
+ (string= "http://some.host.com/form?&id=blah%2Bblah25"
+ (org-link-decode
+ (org-link-encode "http://some.host.com/form?&id=blah%2Bblah25"
+ '(?\s ?\[ ?\] ?%))))))
+
+
+;;; Escape and Unescape Links
+
+(ert-deftest test-ol/escape ()
+ "Test `org-link-escape' specifications."
+ ;; No-op when there is no backslash or closing square bracket.
+ (should (string= "foo[" (org-link-escape "foo[")))
+ ;; Escape closing square bracket at the end of the link.
+ (should (string= "[foo\\]" (org-link-escape "[foo]")))
+ ;; Escape closing square brackets followed by another square
+ ;; bracket.
+ (should (string= "foo\\][bar" (org-link-escape "foo][bar")))
+ (should (string= "foo\\]]bar" (org-link-escape "foo]]bar")))
+ ;; However, escaping closing square bracket at the end of the link
+ ;; has precedence over the previous rule.
+ (should (string= "foo]\\]" (org-link-escape "foo]]")))
+ ;; Escape backslashes at the end of the link.
+ (should (string= "foo\\\\" (org-link-escape "foo\\")))
+ ;; Escape backslashes that could be confused with escaping
+ ;; characters.
+ (should (string= "foo\\\\\\]" (org-link-escape "foo\\]")))
+ (should (string= "foo\\\\\\][" (org-link-escape "foo\\][")))
+ (should (string= "foo\\\\\\]]bar" (org-link-escape "foo\\]]bar")))
+ ;; Do not escape backslash characters when unnecessary.
+ (should (string= "foo\\bar" (org-link-escape "foo\\bar")))
+ (should (string= "foo\\]bar" (org-link-escape "foo\\]bar")))
+ ;; Pathological cases: consecutive closing square brackets.
+ (should (string= "[[[foo\\]]\\]" (org-link-escape "[[[foo]]]")))
+ (should (string= "[[[foo]\\]] bar" (org-link-escape "[[[foo]]] bar"))))
+
+(ert-deftest test-ol/unescape ()
+ "Test `org-link-unescape' specifications."
+ ;; No-op if there is no backslash.
+ (should (string= "foo[" (org-link-unescape "foo[")))
+ ;; No-op if backslashes are not escaping backslashes.
+ (should (string= "foo\\bar" (org-link-unescape "foo\\bar")))
+ (should (string= "foo\\]bar" (org-link-unescape "foo\\]bar")))
+ ;;
+ (should (string= "foo\\]" (org-link-unescape "foo\\\\\\]")))
+ (should (string= "foo\\][" (org-link-unescape "foo\\\\\\][")))
+ (should (string= "foo\\]]bar" (org-link-unescape "foo\\\\\\]]bar")))
+ ;; Unescape backslashes at the end of the link.
+ (should (string= "foo\\" (org-link-unescape "foo\\\\")))
+ ;; Unescape closing square bracket at the end of the link.
+ (should (string= "[foo]" (org-link-unescape "[foo\\]")))
+ ;; Pathological cases: consecutive closing square brackets.
+ (should (string= "[[[foo]]]" (org-link-unescape "[[[foo\\]]\\]")))
+ (should (string= "[[[foo]]] bar" (org-link-unescape "[[[foo]\\]] bar"))))
+
+(ert-deftest test-ol/make-string ()
+ "Test `org-link-make-string' specifications."
+ ;; Throw an error on empty URI.
+ (should-error (org-link-make-string ""))
+ ;; Empty description returns a [[URI]] construct.
+ (should (string= "[[uri]]"(org-link-make-string "uri")))
+ ;; Non-empty description returns a [[URI][DESCRIPTION]] construct.
+ (should
+ (string= "[[uri][description]]"
+ (org-link-make-string "uri" "description")))
+ ;; Escape "]]" strings in the description with zero-width spaces.
+ (should
+ (let ((zws (string ?\x200B)))
+ (string= (format "[[uri][foo]%s]bar]]" zws)
+ (org-link-make-string "uri" "foo]]bar"))))
+ ;; Prevent description from ending with a closing square bracket
+ ;; with a zero-width space.
+ (should
+ (let ((zws (string ?\x200B)))
+ (string= (format "[[uri][foo]%s]]" zws)
+ (org-link-make-string "uri" "foo]")))))
+
+
+;;; Store links
+
+(ert-deftest test-ol/store-link ()
+ "Test `org-store-link' specifications."
+ ;; On a headline, link to that headline. Use heading as the
+ ;; description of the link.
+ (should
+ (let (org-store-link-props org-stored-links)
+ (org-test-with-temp-text-in-file "* H1"
+ (let ((file (buffer-file-name)))
+ (equal (format "[[file:%s::*H1][H1]]" file)
+ (org-store-link nil))))))
+ ;; On a headline, remove any link from description.
+ (should
+ (let (org-store-link-props org-stored-links)
+ (org-test-with-temp-text-in-file "* [[#l][d]]"
+ (let ((file (buffer-file-name)))
+ (equal (format "[[file:%s::*%s][d]]"
+ file
+ (org-link-escape "[[#l][d]]"))
+ (org-store-link nil))))))
+ (should
+ (let (org-store-link-props org-stored-links)
+ (org-test-with-temp-text-in-file "* [[l]]"
+ (let ((file (buffer-file-name)))
+ (equal (format "[[file:%s::*%s][l]]" file (org-link-escape "[[l]]"))
+ (org-store-link nil))))))
+ (should
+ (let (org-store-link-props org-stored-links)
+ (org-test-with-temp-text-in-file "* [[l1][d1]] [[l2][d2]]"
+ (let ((file (buffer-file-name)))
+ (equal (format "[[file:%s::*%s][d1 d2]]"
+ file
+ (org-link-escape "[[l1][d1]] [[l2][d2]]"))
+ (org-store-link nil))))))
+ ;; On a named element, link to that element.
+ (should
+ (let (org-store-link-props org-stored-links)
+ (org-test-with-temp-text-in-file "#+NAME: foo\nParagraph"
+ (let ((file (buffer-file-name)))
+ (equal (format "[[file:%s::foo][foo]]" file)
+ (org-store-link nil))))))
+ ;; Store link to Org buffer, with context.
+ (should
+ (let ((org-stored-links nil)
+ (org-id-link-to-org-use-id nil)
+ (org-context-in-file-links t))
+ (org-test-with-temp-text-in-file "* h1"
+ (let ((file (buffer-file-name)))
+ (equal (format "[[file:%s::*h1][h1]]" file)
+ (org-store-link nil))))))
+ ;; Store link to Org buffer, without context.
+ (should
+ (let ((org-stored-links nil)
+ (org-id-link-to-org-use-id nil)
+ (org-context-in-file-links nil))
+ (org-test-with-temp-text-in-file "* h1"
+ (let ((file (buffer-file-name)))
+ (equal (format "[[file:%s][file:%s]]" file file)
+ (org-store-link nil))))))
+ ;; C-u prefix reverses `org-context-in-file-links' in Org buffer.
+ (should
+ (let ((org-stored-links nil)
+ (org-id-link-to-org-use-id nil)
+ (org-context-in-file-links nil))
+ (org-test-with-temp-text-in-file "* h1"
+ (let ((file (buffer-file-name)))
+ (equal (format "[[file:%s::*h1][h1]]" file)
+ (org-store-link '(4)))))))
+ ;; A C-u C-u does *not* reverse `org-context-in-file-links' in Org
+ ;; buffer.
+ (should
+ (let ((org-stored-links nil)
+ (org-id-link-to-org-use-id nil)
+ (org-context-in-file-links nil))
+ (org-test-with-temp-text-in-file "* h1"
+ (let ((file (buffer-file-name)))
+ (equal (format "[[file:%s][file:%s]]" file file)
+ (org-store-link '(16)))))))
+ ;; Store file link to non-Org buffer, with context.
+ (should
+ (let ((org-stored-links nil)
+ (org-context-in-file-links t))
+ (org-test-with-temp-text-in-file "one\n<point>two"
+ (fundamental-mode)
+ (let ((file (buffer-file-name)))
+ (equal (format "[[file:%s::one]]" file)
+ (org-store-link nil))))))
+ ;; Store file link to non-Org buffer, without context.
+ (should
+ (let ((org-stored-links nil)
+ (org-context-in-file-links nil))
+ (org-test-with-temp-text-in-file "one\n<point>two"
+ (fundamental-mode)
+ (let ((file (buffer-file-name)))
+ (equal (format "[[file:%s][file:%s]]" file file)
+ (org-store-link nil))))))
+ ;; C-u prefix reverses `org-context-in-file-links' in non-Org
+ ;; buffer.
+ (should
+ (let ((org-stored-links nil)
+ (org-context-in-file-links nil))
+ (org-test-with-temp-text-in-file "one\n<point>two"
+ (fundamental-mode)
+ (let ((file (buffer-file-name)))
+ (equal (format "[[file:%s::one]]" file)
+ (org-store-link '(4)))))))
+ ;; A C-u C-u does *not* reverse `org-context-in-file-links' in
+ ;; non-Org buffer.
+ (should
+ (let ((org-stored-links nil)
+ (org-context-in-file-links nil))
+ (org-test-with-temp-text-in-file "one\n<point>two"
+ (fundamental-mode)
+ (let ((file (buffer-file-name)))
+ (equal (format "[[file:%s][file:%s]]" file file)
+ (org-store-link '(16))))))))
+
+
+;;; Radio Targets
+
+(ert-deftest test-ol/update-radio-target-regexp ()
+ "Test `org-update-radio-target-regexp' specifications."
+ ;; Properly update cache with no previous radio target regexp.
+ (should
+ (eq 'link
+ (org-test-with-temp-text "radio\n\nParagraph\n\nradio"
+ (save-excursion (goto-char (point-max)) (org-element-context))
+ (insert "<<<")
+ (search-forward "o")
+ (insert ">>>")
+ (org-update-radio-target-regexp)
+ (goto-char (point-max))
+ (org-element-type (org-element-context)))))
+ ;; Properly update cache with previous radio target regexp.
+ (should
+ (eq 'link
+ (org-test-with-temp-text "radio\n\nParagraph\n\nradio"
+ (save-excursion (goto-char (point-max)) (org-element-context))
+ (insert "<<<")
+ (search-forward "o")
+ (insert ">>>")
+ (org-update-radio-target-regexp)
+ (search-backward "r")
+ (delete-char 5)
+ (insert "new")
+ (org-update-radio-target-regexp)
+ (goto-char (point-max))
+ (delete-region (line-beginning-position) (point))
+ (insert "new")
+ (org-element-type (org-element-context))))))
+
+
+;;; Navigation
+
+(ert-deftest test-ol/next-link ()
+ "Test `org-next-link' specifications."
+ ;; Move to any type of link.
+ (should
+ (equal "[[link]]"
+ (org-test-with-temp-text "foo [[link]]"
+ (org-next-link)
+ (buffer-substring (point) (line-end-position)))))
+ (should
+ (equal "http://link"
+ (org-test-with-temp-text "foo http://link"
+ (org-next-link)
+ (buffer-substring (point) (line-end-position)))))
+ (should
+ (equal "<http://link>"
+ (org-test-with-temp-text "foo <http://link>"
+ (org-next-link)
+ (buffer-substring (point) (line-end-position)))))
+ ;; Ignore link at point.
+ (should
+ (equal "[[link2]]"
+ (org-test-with-temp-text "[[link1]] [[link2]]"
+ (org-next-link)
+ (buffer-substring (point) (line-end-position)))))
+ ;; Ignore fake links.
+ (should
+ (equal "[[truelink]]"
+ (org-test-with-temp-text "foo\n: [[link]]\n[[truelink]]"
+ (org-next-link)
+ (buffer-substring (point) (line-end-position)))))
+ ;; Do not move point when there is no link.
+ (should
+ (org-test-with-temp-text "foo bar"
+ (org-next-link)
+ (bobp)))
+ ;; Wrap around after a failed search.
+ (should
+ (equal "[[link]]"
+ (org-test-with-temp-text "[[link]]\n<point>foo"
+ (org-next-link)
+ (let* ((this-command 'org-next-link)
+ (last-command this-command))
+ (org-next-link))
+ (buffer-substring (point) (line-end-position)))))
+ ;; Find links with item tags.
+ (should
+ (equal "[[link1]]"
+ (org-test-with-temp-text "- tag [[link1]] :: description"
+ (org-next-link)
+ (buffer-substring (point) (search-forward "]]" nil t))))))
+
+(ert-deftest test-ol/previous-link ()
+ "Test `org-previous-link' specifications."
+ ;; Move to any type of link.
+ (should
+ (equal "[[link]]"
+ (org-test-with-temp-text "[[link]]\nfoo<point>"
+ (org-previous-link)
+ (buffer-substring (point) (line-end-position)))))
+ (should
+ (equal "http://link"
+ (org-test-with-temp-text "http://link\nfoo<point>"
+ (org-previous-link)
+ (buffer-substring (point) (line-end-position)))))
+ (should
+ (equal "<http://link>"
+ (org-test-with-temp-text "<http://link>\nfoo<point>"
+ (org-previous-link)
+ (buffer-substring (point) (line-end-position)))))
+ ;; Ignore link at point.
+ (should
+ (equal "[[link1]]"
+ (org-test-with-temp-text "[[link1]]\n[[link2<point>]]"
+ (org-previous-link)
+ (buffer-substring (point) (line-end-position)))))
+ (should
+ (equal "[[link1]]"
+ (org-test-with-temp-text "line\n[[link1]]\n[[link2<point>]]"
+ (org-previous-link)
+ (buffer-substring (point) (line-end-position)))))
+ ;; Ignore fake links.
+ (should
+ (equal "[[truelink]]"
+ (org-test-with-temp-text "[[truelink]]\n: [[link]]\n<point>"
+ (org-previous-link)
+ (buffer-substring (point) (line-end-position)))))
+ ;; Do not move point when there is no link.
+ (should
+ (org-test-with-temp-text "foo bar<point>"
+ (org-previous-link)
+ (eobp)))
+ ;; Wrap around after a failed search.
+ (should
+ (equal "[[link]]"
+ (org-test-with-temp-text "foo\n[[link]]"
+ (org-previous-link)
+ (let* ((this-command 'org-previous-link)
+ (last-command this-command))
+ (org-previous-link))
+ (buffer-substring (point) (line-end-position))))))
+
+(provide 'test-ol)
+;;; test-ol.el ends here
diff --git a/testing/lisp/test-org-agenda.el b/testing/lisp/test-org-agenda.el
index a9cbcb8..1782227 100644
--- a/testing/lisp/test-org-agenda.el
+++ b/testing/lisp/test-org-agenda.el
@@ -28,7 +28,7 @@
(eval-and-compile (require 'cl-lib))
-;; General auxilliaries
+;; General auxiliaries
(defun org-test-agenda--agenda-buffers ()
"Return agenda buffers in a list."
@@ -162,6 +162,24 @@
(org-test-agenda--kill-all-agendas)))
+(ert-deftest test-org-agenda/diary-inclusion ()
+ "Diary inclusion happens."
+ (org-test-agenda--kill-all-agendas)
+ (let ((diary-file (expand-file-name "examples/diary-file" org-test-dir))
+ (org-agenda-files `(,(expand-file-name "examples/agenda-file.org"
+ org-test-dir)))
+ (diary-date-forms '((month "[-/]" day "[^-/0-9]")
+ (year "[-/]" month "[-/]" day "[^0-9]")
+ (monthname " *" day "[^-0-9]")
+ (year " *" monthname " *" day "[^0-9]")
+ (dayname "\\W")))
+ (org-agenda-span 'day)
+ (org-agenda-include-diary t))
+ (org-agenda-list nil "<2019-01-08>")
+ (should (search-forward "f0bcf0cd8bad93c1451bb6e1b2aaedef5cce7cbb" nil t))
+ (org-test-agenda--kill-all-agendas)))
+
+
(provide 'test-org-agenda)
;;; test-org-agenda.el ends here
diff --git a/testing/lisp/test-org-attach-annex.el b/testing/lisp/test-org-attach-git.el
index 7f27926..36cb83b 100644
--- a/testing/lisp/test-org-attach-annex.el
+++ b/testing/lisp/test-org-attach-git.el
@@ -20,37 +20,37 @@
;;; Code:
(org-test-for-executable "git-annex")
-(require 'org-attach)
+(require 'org-attach-git)
(require 'cl-lib)
-(defmacro test-org-attach-annex/with-annex (&rest body)
+(defmacro test-org-attach-git/with-annex (&rest body)
`(let ((tmpdir (make-temp-file "org-annex-test" t "/")))
(unwind-protect
(let ((default-directory tmpdir)
- (org-attach-directory tmpdir))
+ (org-attach-id-dir tmpdir))
(shell-command "git init")
(shell-command "git annex init")
,@body))))
-(ert-deftest test-org-attach/use-annex ()
- (test-org-attach-annex/with-annex
+(ert-deftest test-org-attach-git/use-annex ()
+ (test-org-attach-git/with-annex
(let ((org-attach-git-annex-cutoff 1))
- (should (org-attach-use-annex)))
+ (should (org-attach-git-use-annex)))
(let ((org-attach-git-annex-cutoff nil))
- (should-not (org-attach-use-annex))))
+ (should-not (org-attach-git-use-annex))))
;; test with non annex directory
(let ((tmpdir (make-temp-file "org-annex-test" t "/")))
(unwind-protect
(let ((default-directory tmpdir)
- (org-attach-directory tmpdir))
+ (org-attach-id-dir tmpdir))
(shell-command "git init")
- (should-not (org-attach-use-annex)))
+ (should-not (org-attach-git-use-annex)))
(delete-directory tmpdir 'recursive))))
-(ert-deftest test-org-attach/get-maybe ()
- (test-org-attach-annex/with-annex
+(ert-deftest test-org-attach-git/get-maybe ()
+ (test-org-attach-git/with-annex
(let ((path (expand-file-name "test-file"))
(annex-dup (make-temp-file "org-annex-test" t "/")))
(with-temp-buffer
@@ -71,21 +71,21 @@
(shell-command "git annex drop --force test-file")
;; test getting the file from the dup when we should ALWAYS get
(should (not (file-exists-p (file-symlink-p (expand-file-name "test-file")))))
- (let ((org-attach-annex-auto-get t))
- (org-attach-annex-get-maybe (expand-file-name "test-file"))
+ (let ((org-attach-git-annex-auto-get t))
+ (org-attach-git-annex-get-maybe (expand-file-name "test-file"))
;; check that the file has the right contents
(with-temp-buffer
(insert-file-contents path)
(should (string-equal "hello world\n" (buffer-string)))))
;; test getting the file from the dup when we should NEVER get
(shell-command "git annex drop --force test-file")
- (let ((org-attach-annex-auto-get nil))
- (should-error (org-attach-annex-get-maybe (expand-file-name "test-file"))))
- (let ((org-attach-annex-auto-get 'ask)
+ (let ((org-attach-git-annex-auto-get nil))
+ (should-error (org-attach-git-annex-get-maybe (expand-file-name "test-file"))))
+ (let ((org-attach-git-annex-auto-get 'ask)
(called nil))
(cl-letf (((symbol-function 'y-or-n-p)
(lambda (_) (setq called 'was-called) t)))
- (org-attach-annex-get-maybe (expand-file-name "test-file"))
+ (org-attach-git-annex-get-maybe (expand-file-name "test-file"))
;; check that the file has the right contents
(with-temp-buffer
(insert-file-contents path)
diff --git a/testing/lisp/test-org-attach.el b/testing/lisp/test-org-attach.el
index c2f2be3..f910526 100644
--- a/testing/lisp/test-org-attach.el
+++ b/testing/lisp/test-org-attach.el
@@ -28,59 +28,142 @@
(require 'org-attach)
(eval-and-compile (require 'cl-lib))
+(ert-deftest test-org-attach/dir ()
+ "Test `org-attach-get' specifications."
+ (should (equal "Text in fileA\n"
+ (org-test-in-example-file org-test-attachments-file
+ (goto-char 157) ;; First attachment link
+ (org-open-at-point)
+ (buffer-string))))
+ (should-not (equal "Text in fileB\n"
+ (org-test-in-example-file org-test-attachments-file
+ (goto-char 219) ;; Second attachment link
+ (let ((org-attach-use-inheritance nil))
+ (org-open-at-point)
+ (buffer-string)))))
+ (should (equal "Text in fileB\n"
+ (org-test-in-example-file org-test-attachments-file
+ (goto-char 219) ;; Second attachment link
+ (let ((org-attach-use-inheritance t))
+ (org-open-at-point)
+ (buffer-string)))))
+ (should-not (equal "att1"
+ (org-test-in-example-file org-test-attachments-file
+ (goto-char 179) ;; H1.1
+ (let ((org-attach-use-inheritance nil))
+ (org-attach-dir)))))
+ (should (equal "att1"
+ (org-test-in-example-file org-test-attachments-file
+ (goto-char 179) ;; H1.1
+ (let ((org-attach-use-inheritance t))
+ (org-attach-dir)))))
+ (should (equal '("fileC" "fileD")
+ (org-test-in-example-file org-test-attachments-file
+ (goto-char 239) ;; H1.2
+ (org-attach-file-list (org-attach-dir)))))
+ (should (equal '("fileC" "fileD")
+ (org-test-in-example-file org-test-attachments-file
+ (goto-char 239) ;; H1.2
+ (org-attach-file-list (org-attach-dir)))))
+ (should (equal '("fileE")
+ (org-test-in-example-file org-test-attachments-file
+ (goto-char 289) ;; H2
+ (let ((org-attach-id-dir "data/"))
+ (org-attach-file-list (org-attach-dir))))))
+ (should (equal "peek-a-boo\n"
+ (org-test-in-example-file org-test-attachments-file
+ (goto-char 289) ;; H2
+ (let ((org-attach-id-dir "data/"))
+ (org-attach-open-in-emacs)
+ (buffer-string)))))
+ (should (equal '("fileA" "fileB")
+ (org-test-in-example-file org-test-attachments-file
+ (goto-char 336) ;; H3
+ (org-attach-file-list (org-attach-dir)))))
+ ;; Test for folder not initialized in the filesystem
+ (should-not (org-test-in-example-file org-test-attachments-file
+ (goto-char 401) ;; H3.1
+ (let ((org-attach-use-inheritance nil)
+ (org-attach-id-dir "data/"))
+ (org-attach-dir))))
+ ;; Not yet initialized folder should be found if no-fs-check is
+ ;; non-nil
+ (should (equal "data/ab/cd12345"
+ (org-test-in-example-file org-test-attachments-file
+ (goto-char 401) ;; H3.1
+ (let ((org-attach-use-inheritance nil)
+ (org-attach-id-dir "data/"))
+ (file-relative-name (org-attach-dir nil t))))))
+ (should (equal '("fileA" "fileB")
+ (org-test-in-example-file org-test-attachments-file
+ (goto-char 401) ;; H3.1
+ (let ((org-attach-use-inheritance t))
+ ;; This is where it gets a bit sketchy...! DIR always has
+ ;; priority over ID, even if ID is declared "higher up" in the
+ ;; tree. This can potentially be revised. But it is also
+ ;; pretty clean. DIR is always higher in priority than ID right
+ ;; now, no matter the depth in the tree.
+ (org-attach-file-list (org-attach-dir)))))))
+
(ert-deftest test-org-attach/dired-attach-to-next-best-subtree/1 ()
"Attach file at point in dired to subtree."
(should
- (let ((a-filename (make-temp-file "a"))) ; file is an attach candidate.
+ (let ((a-filename (make-temp-file "a")) ; file is an attach candidate.
+ (org-attach-id-dir "data/"))
(unwind-protect
(org-test-with-temp-text-in-file
- "* foo :foo:"
- (split-window)
- (dired temporary-file-directory)
- (cl-assert (eq 'dired-mode major-mode))
- (revert-buffer)
- (dired-goto-file a-filename)
+ "* foo :foo:"
+ (split-window)
+ (let ((org-buffer (current-buffer))
+ (dired-buffer (dired temporary-file-directory)))
+ (cl-assert (eq 'dired-mode major-mode))
+ (revert-buffer)
+ (dired-goto-file a-filename)
; action
- (call-interactively #'org-attach-dired-to-subtree)
+ (call-interactively #'org-attach-dired-to-subtree)
; check
- (delete-window)
- (cl-assert (eq 'org-mode major-mode))
- (beginning-of-buffer)
- (search-forward "* foo")
+ (delete-window)
+ (switch-to-buffer org-buffer)
+ (cl-assert (eq 'org-mode major-mode)))
+ (beginning-of-buffer)
+ (search-forward "* foo")
; expectation. tag ATTACH has been appended.
- (cl-reduce (lambda (x y) (or x y))
- (mapcar (lambda (x) (string-equal "ATTACH" x))
- (plist-get
+ (cl-reduce (lambda (x y) (or x y))
+ (mapcar (lambda (x) (string-equal "ATTACH" x))
(plist-get
- (org-element-at-point) 'headline) :tags))))
+ (plist-get
+ (org-element-at-point) 'headline) :tags))))
(delete-file a-filename)))))
(ert-deftest test-org-attach/dired-attach-to-next-best-subtree/2 ()
"Attach 2 marked files."
(should
(let ((a-filename (make-temp-file "a"))
- (b-filename (make-temp-file "b"))) ; attach candidates.
+ (b-filename (make-temp-file "b")) ; attach candidates.
+ (org-attach-id-dir "data/"))
(unwind-protect
(org-test-with-temp-text-in-file
"* foo"
(split-window)
- (dired temporary-file-directory)
- (cl-assert (eq 'dired-mode major-mode))
- (revert-buffer)
- (dired-goto-file a-filename)
- (dired-mark 1)
- (dired-goto-file b-filename)
- (dired-mark 1)
+ (let ((org-buffer (current-buffer))
+ (dired-buffer (dired temporary-file-directory)))
+ (cl-assert (eq 'dired-mode major-mode))
+ (revert-buffer)
+ (dired-goto-file a-filename)
+ (dired-mark 1)
+ (dired-goto-file b-filename)
+ (dired-mark 1)
; action
- (call-interactively #'org-attach-dired-to-subtree)
+ (call-interactively #'org-attach-dired-to-subtree)
; check
- (delete-window)
+ (delete-window)
+ (switch-to-buffer org-buffer))
(cl-assert (eq 'org-mode major-mode))
(beginning-of-buffer)
(search-forward "* foo")
(and (file-exists-p (concat (org-attach-dir) "/"
(file-name-nondirectory a-filename)))
- (file-exists-p (concat (org-attach-dir) "/"
+ (file-exists-p (concat (org-attach-dir) "/"
(file-name-nondirectory b-filename)))))
(delete-file a-filename)
(delete-file b-filename)))))
diff --git a/testing/lisp/test-org-capture.el b/testing/lisp/test-org-capture.el
index d1474e2..faac760 100644
--- a/testing/lisp/test-org-capture.el
+++ b/testing/lisp/test-org-capture.el
@@ -232,7 +232,29 @@
`(("t" "Test" entry (file+headline ,file "A") "** "
:immediate-finish t))))
(org-capture nil "t")
- (buffer-string)))))
+ (buffer-string))))
+ ;; With a 0 prefix argument, ignore surrounding lists.
+ (should
+ (equal "Foo\n* X\nBar\n"
+ (org-test-with-temp-text-in-file "Foo\nBar"
+ (forward-line)
+ (let* ((file (buffer-file-name))
+ (org-capture-templates
+ `(("t" "Test" entry (file ,file) "* X"
+ :immediate-finish t))))
+ (org-capture 0 "t")
+ (buffer-string)))))
+ ;; With a 0 prefix argument, also obey to :empty-lines.
+ (should
+ (equal "Foo\n\n* X\n\nBar\n"
+ (org-test-with-temp-text-in-file "Foo\nBar"
+ (forward-line)
+ (let* ((file (buffer-file-name))
+ (org-capture-templates
+ `(("t" "Test" entry (file ,file) "* X"
+ :immediate-finish t :empty-lines 1))))
+ (org-capture 0 "t")
+ (buffer-string))))))
(ert-deftest test-org-capture/item ()
"Test `item' type in capture template."
@@ -450,7 +472,27 @@
(goto-char (point-max))
(insert "Foo")
(org-capture-finalize))
- (buffer-string)))))
+ (buffer-string))))
+ ;; With a 0 prefix argument, ignore surrounding lists.
+ (should
+ (equal "- X\nFoo\n\n- A\n"
+ (org-test-with-temp-text-in-file "Foo\n\n- A"
+ (let* ((file (buffer-file-name))
+ (org-capture-templates
+ `(("t" "Test" item (file ,file) "- X"
+ :immediate-finish t))))
+ (org-capture 0 "t")
+ (buffer-string)))))
+ ;; With a 0 prefix argument, also obey to `:empty-lines'.
+ (should
+ (equal "\n- X\n\nFoo\n\n- A\n"
+ (org-test-with-temp-text-in-file "Foo\n\n- A"
+ (let* ((file (buffer-file-name))
+ (org-capture-templates
+ `(("t" "Test" item (file ,file) "- X"
+ :immediate-finish t :empty-lines 1))))
+ (org-capture 0 "t")
+ (buffer-string))))))
(ert-deftest test-org-capture/table-line ()
"Test `table-line' type in capture template."
@@ -625,7 +667,17 @@
`(("t" "Table" table-line (file ,file)
"| 2 |" :immediate-finish t))))
(org-capture nil "t")
- (org-table-get-stored-formulas))))))
+ (org-table-get-stored-formulas)))))
+ ;; With a 0 prefix argument, ignore surrounding tables.
+ (should
+ (equal "| |\n|---|\n| B |\nFoo\n\n| A |\n"
+ (org-test-with-temp-text-in-file "Foo\n\n| A |"
+ (let* ((file (buffer-file-name))
+ (org-capture-templates
+ `(("t" "Test" table-line (file ,file) "| B |"
+ :immediate-finish t))))
+ (org-capture 0 "t")
+ (buffer-string))))))
(ert-deftest test-org-capture/plain ()
"Test `plain' type in capture template."
diff --git a/testing/lisp/test-org-clock.el b/testing/lisp/test-org-clock.el
index a427024..b4afe69 100644
--- a/testing/lisp/test-org-clock.el
+++ b/testing/lisp/test-org-clock.el
@@ -49,8 +49,8 @@ Return the clock line as a string."
(let* ((beg (org-test-clock-create-timestamp input1 t t))
(end (and input2 (org-test-clock-create-timestamp input2 t t)))
(sec-diff (and input2
- (floor (- (org-time-string-to-seconds end)
- (org-time-string-to-seconds beg))))))
+ (floor (- (org-time-string-to-seconds end)
+ (org-time-string-to-seconds beg))))))
(concat org-clock-string " " beg
(when end
(concat "--" end " => "
@@ -82,7 +82,7 @@ the buffer."
;; Skip caption.
(when (looking-at "#\\+CAPTION:") (forward-line))
(buffer-substring-no-properties
- (point) (progn (search-forward "#+END:") (line-end-position 0))))
+ (point) (progn (search-forward "#+END:") (line-end-position 0))))
;; Remove clocktable.
(delete-region (point) (search-forward "#+END:\n"))))
@@ -273,6 +273,30 @@ the buffer."
;;; Clocktable
+(ert-deftest test-org-clock/clocktable/insert ()
+ "Test insert clocktable dynamic block with `org-dynamic-block-insert-dblock'."
+ (should
+ (equal
+ "| Headline | Time |
+|--------------+--------|
+| *Total time* | *1:00* |
+|--------------+--------|
+| H1 | 1:00 |"
+ (org-test-with-temp-text "* H1\n<point>"
+ (insert (org-test-clock-create-clock ". 1:00" ". 2:00"))
+
+ (goto-line 2)
+ (require 'org-clock)
+ (org-dynamic-block-insert-dblock "clocktable")
+
+ (goto-line 1)
+ (unwind-protect
+ (save-excursion
+ (when (search-forward "#+CAPTION:") (forward-line))
+ (buffer-substring-no-properties
+ (point) (progn (search-forward "#+END:") (line-end-position 0))))
+ (delete-region (point) (search-forward "#+END:\n")))))))
+
(ert-deftest test-org-clock/clocktable/ranges ()
"Test ranges in Clock table."
;; Relative time: Previous two days.
@@ -369,18 +393,18 @@ the buffer."
"* Test
CLOCK: [2012-03-29 Thu 8:00]--[2012-03-29 Thu 16:40] => 8:40"
(test-org-clock-clocktable-contents ":scope file-with-archives"
- "#+TBLFM: $3=string(\"foo\")"))))
+ "#+TBLFM: $3=string(\"foo\")"))))
;; Test "function" scope.
(should
(string-match-p
(regexp-quote "| ALL *Total time* | *1:00* |")
(org-test-with-temp-text-in-file
- "* Test
+ "* Test
CLOCK: [2012-03-29 Thu 16:00]--[2012-03-29 Thu 17:00] => 1:00"
(let ((the-file (buffer-file-name)))
- (org-test-with-temp-text-in-file ""
- (test-org-clock-clocktable-contents
- (format ":scope (lambda () (list %S))" the-file))))))))
+ (org-test-with-temp-text-in-file ""
+ (test-org-clock-clocktable-contents
+ (format ":scope (lambda () (list %S))" the-file))))))))
(ert-deftest test-org-clock/clocktable/maxlevel ()
"Test \":maxlevel\" parameter in Clock table."
@@ -409,7 +433,7 @@ CLOCK: [2016-12-28 Wed 13:09]--[2016-12-28 Wed 15:09] => 2:00"
CLOCK: [2016-12-28 Wed 11:09]--[2016-12-28 Wed 15:09] => 4:00
** Bar
CLOCK: [2016-12-28 Wed 13:09]--[2016-12-28 Wed 15:09] => 2:00"
- (test-org-clock-clocktable-contents ":maxlevel 2"))))
+ (test-org-clock-clocktable-contents ":maxlevel 2"))))
(should
(equal "| Headline | Time |
|--------------+--------|
@@ -421,7 +445,7 @@ CLOCK: [2016-12-28 Wed 13:09]--[2016-12-28 Wed 15:09] => 2:00"
CLOCK: [2016-12-28 Wed 11:09]--[2016-12-28 Wed 15:09] => 4:00
** Bar
CLOCK: [2016-12-28 Wed 13:09]--[2016-12-28 Wed 15:09] => 2:00"
- (test-org-clock-clocktable-contents ":maxlevel 1"))))
+ (test-org-clock-clocktable-contents ":maxlevel 1"))))
;; Special ":maxlevel 0" case: only report total file time.
(should
(equal "| Headline | Time |
@@ -433,7 +457,7 @@ CLOCK: [2016-12-28 Wed 13:09]--[2016-12-28 Wed 15:09] => 2:00"
CLOCK: [2016-12-28 Wed 11:09]--[2016-12-28 Wed 15:09] => 4:00
** Bar
CLOCK: [2016-12-28 Wed 13:09]--[2016-12-28 Wed 15:09] => 2:00"
- (test-org-clock-clocktable-contents ":maxlevel 0")))))
+ (test-org-clock-clocktable-contents ":maxlevel 0")))))
(ert-deftest test-org-clock/clocktable/formula ()
"Test \":formula\" parameter in Clock table."
@@ -478,8 +502,8 @@ CLOCK: [2016-12-28 Wed 13:09]--[2016-12-28 Wed 15:09] => 2:00"
| \\_ sub3 | | 0:30 | | 50.0 |
| \\_ subsub1 | | | 0:15 | 25.0 |
| \\_ subsub1 | | | 0:15 | 25.0 |"
- (org-test-with-temp-text
- "* foo
+ (org-test-with-temp-text
+ "* foo
** sub
:LOGBOOK:
CLOCK: [2017-03-18 Sat 15:00]--[2017-03-18 Sat 15:15] => 0:15
@@ -497,7 +521,7 @@ CLOCK: [2016-12-28 Wed 13:09]--[2016-12-28 Wed 15:09] => 2:00"
:LOGBOOK:
CLOCK: [2017-03-18 Sat 14:00]--[2017-03-18 Sat 14:15] => 0:15
:END:"
- (test-org-clock-clocktable-contents ":maxlevel 3 :formula %")))))
+ (test-org-clock-clocktable-contents ":maxlevel 3 :formula %")))))
(ert-deftest test-org-clock/clocktable/lang ()
"Test \":lang\" parameter in Clock table."
@@ -552,125 +576,129 @@ CLOCK: [2016-12-28 Wed 13:09]--[2016-12-28 Wed 15:09] => 2:00"
"Test \":link\" parameter in Clock table."
;; If there is no file attached to the document, link directly to
;; the headline.
- (should
- (equal
- "| Headline | Time |
+ (let (org-link-descriptive)
+ (should
+ (equal
+ "| Headline | Time |
|--------------+---------|
| *Total time* | *26:00* |
|--------------+---------|
-| [[Foo][Foo]] | 26:00 |"
- (org-test-with-temp-text
- "* Foo
+| [[Foo][Foo]] | 26:00 |"
+ (org-test-with-temp-text
+ "* Foo
CLOCK: [2016-12-27 Wed 13:09]--[2016-12-28 Wed 15:09] => 26:00"
- (test-org-clock-clocktable-contents ":link t"))))
- ;; Otherwise, link to the headline in the current file.
- (should
- (equal
- "| Headline | Time |
-|--------------+---------|
-| *Total time* | *26:00* |
-|--------------+---------|
-| [[file:filename::Foo][Foo]] | 26:00 |"
- (org-test-with-temp-text-in-file
- "* Foo
+ (test-org-clock-clocktable-contents ":link t"))))
+ ;; Otherwise, link to the headline in the current file.
+ (should
+ (equal
+ "| Headline | Time |
+|-----------------------------+---------|
+| *Total time* | *26:00* |
+|-----------------------------+---------|
+| [[file:filename::Foo][Foo]] | 26:00 |"
+ (org-test-with-temp-text
+ (org-test-with-temp-text-in-file
+ "* Foo
CLOCK: [2016-12-27 Wed 13:09]--[2016-12-28 Wed 15:09] => 26:00"
- (let ((file (buffer-file-name)))
- (replace-regexp-in-string
- (regexp-quote file) "filename"
- (test-org-clock-clocktable-contents ":link t"))))))
- ;; Ignore TODO keyword, priority cookie, COMMENT and tags in
- ;; headline.
- (should
- (equal
- "| Headline | Time |
+ (let ((file (buffer-file-name)))
+ (replace-regexp-in-string
+ (regexp-quote file) "filename"
+ (test-org-clock-clocktable-contents ":link t :lang en"))))
+ (org-table-align)
+ (buffer-substring-no-properties (point-min) (point-max)))))
+ ;; Ignore TODO keyword, priority cookie, COMMENT and tags in
+ ;; headline.
+ (should
+ (equal
+ "| Headline | Time |
|--------------+---------|
| *Total time* | *26:00* |
|--------------+---------|
-| [[Foo][Foo]] | 26:00 |"
- (org-test-with-temp-text
- "* TODO Foo
+| [[Foo][Foo]] | 26:00 |"
+ (org-test-with-temp-text
+ "* TODO Foo
CLOCK: [2016-12-27 Wed 13:09]--[2016-12-28 Wed 15:09] => 26:00"
- (test-org-clock-clocktable-contents ":link t"))))
- (should
- (equal
- "| Headline | Time |
+ (test-org-clock-clocktable-contents ":link t :lang en"))))
+ (should
+ (equal
+ "| Headline | Time |
|--------------+---------|
| *Total time* | *26:00* |
|--------------+---------|
-| [[Foo][Foo]] | 26:00 |"
- (org-test-with-temp-text
- "* [#A] Foo
+| [[Foo][Foo]] | 26:00 |"
+ (org-test-with-temp-text
+ "* [#A] Foo
CLOCK: [2016-12-27 Wed 13:09]--[2016-12-28 Wed 15:09] => 26:00"
- (test-org-clock-clocktable-contents ":link t"))))
- (should
- (equal
- "| Headline | Time |
+ (test-org-clock-clocktable-contents ":link t :lang en"))))
+ (should
+ (equal
+ "| Headline | Time |
|--------------+---------|
| *Total time* | *26:00* |
|--------------+---------|
-| [[Foo][Foo]] | 26:00 |"
- (org-test-with-temp-text
- "* COMMENT Foo
+| [[Foo][Foo]] | 26:00 |"
+ (org-test-with-temp-text
+ "* COMMENT Foo
CLOCK: [2016-12-27 Wed 13:09]--[2016-12-28 Wed 15:09] => 26:00"
- (test-org-clock-clocktable-contents ":link t"))))
- (should
- (equal
- "| Headline | Time |
+ (test-org-clock-clocktable-contents ":link t"))))
+ (should
+ (equal
+ "| Headline | Time |
|--------------+---------|
| *Total time* | *26:00* |
|--------------+---------|
-| [[Foo][Foo]] | 26:00 |"
- (org-test-with-temp-text
- "* Foo :tag:
+| [[Foo][Foo]] | 26:00 |"
+ (org-test-with-temp-text
+ "* Foo :tag:
CLOCK: [2016-12-27 Wed 13:09]--[2016-12-28 Wed 15:09] => 26:00"
- (test-org-clock-clocktable-contents ":link t"))))
- ;; Remove statistics cookie from headline description.
- (should
- (equal
- "| Headline | Time |
+ (test-org-clock-clocktable-contents ":link t :lang en"))))
+ ;; Remove statistics cookie from headline description.
+ (should
+ (equal
+ "| Headline | Time |
|--------------+---------|
| *Total time* | *26:00* |
|--------------+---------|
-| [[Foo][Foo]] | 26:00 |"
- (org-test-with-temp-text
- "* Foo [50%]
+| [[Foo][Foo]] | 26:00 |"
+ (org-test-with-temp-text
+ "* Foo [50%]
CLOCK: [2016-12-27 Wed 13:09]--[2016-12-28 Wed 15:09] => 26:00"
- (test-org-clock-clocktable-contents ":link t"))))
- (should
- (equal
- "| Headline | Time |
+ (test-org-clock-clocktable-contents ":link t :lang en"))))
+ (should
+ (equal
+ "| Headline | Time |
|--------------+---------|
| *Total time* | *26:00* |
|--------------+---------|
-| [[Foo][Foo]] | 26:00 |"
- (org-test-with-temp-text
- "* Foo [1/2]
+| [[Foo][Foo]] | 26:00 |"
+ (org-test-with-temp-text
+ "* Foo [1/2]
CLOCK: [2016-12-27 Wed 13:09]--[2016-12-28 Wed 15:09] => 26:00"
- (test-org-clock-clocktable-contents ":link t"))))
- ;; Replace links with their description, or turn them into plain
- ;; links if there is no description.
- (should
- (equal
- "| Headline | Time |
-|--------------+---------|
-| *Total time* | *26:00* |
-|--------------+---------|
-| [[Foo %5B%5Bhttps://orgmode.org%5D%5BOrg mode%5D%5D][Foo Org mode]] | 26:00 |"
- (org-test-with-temp-text
- "* Foo [[https://orgmode.org][Org mode]]
+ (test-org-clock-clocktable-contents ":link t :lang en"))))
+ ;; Replace links with their description, or turn them into plain
+ ;; links if there is no description.
+ (should
+ (equal
+ "| Headline | Time |
+|-----------------------------------------------------------+---------|
+| *Total time* | *26:00* |
+|-----------------------------------------------------------+---------|
+| [[Foo [[https://orgmode.org\\][Org mode]\\]][Foo Org mode]] | 26:00 |"
+ (org-test-with-temp-text
+ "* Foo [[https://orgmode.org][Org mode]]
CLOCK: [2016-12-27 Wed 13:09]--[2016-12-28 Wed 15:09] => 26:00"
- (test-org-clock-clocktable-contents ":link t"))))
- (should
- (equal
- "| Headline | Time |
-|-------------------------+---------|
-| *Total time* | *26:00* |
-|-------------------------+---------|
-| [[Foo %5B%5Bhttps://orgmode.org%5D%5D][Foo https://orgmode.org]] | 26:00 |"
- (org-test-with-temp-text
- "* Foo [[https://orgmode.org]]
+ (test-org-clock-clocktable-contents ":link t :lang en"))))
+ (should
+ (equal
+ "| Headline | Time |
+|-----------------------------------------------------------+---------|
+| *Total time* | *26:00* |
+|-----------------------------------------------------------+---------|
+| [[Foo [[https://orgmode.org]\\]][Foo https://orgmode.org]] | 26:00 |"
+ (org-test-with-temp-text
+ "* Foo [[https://orgmode.org]]
CLOCK: [2016-12-27 Wed 13:09]--[2016-12-28 Wed 15:09] => 26:00"
- (test-org-clock-clocktable-contents ":link t")))))
+ (test-org-clock-clocktable-contents ":link t :lang en"))))))
(ert-deftest test-org-clock/clocktable/compact ()
"Test \":compact\" parameter in Clock table."
@@ -848,155 +876,270 @@ CLOCK: [2016-12-28 Wed 13:09]--[2016-12-28 Wed 13:09] => 0:00"
;; Regression test: week crossing month boundary before :wstart
;; day-of-week.
(should
- (equal "
-Weekly report starting on: [2017-09-25 Mon]
-| Headline | Time |
-|--------------+--------|
-| *Total time* | *1:00* |
-|--------------+--------|
-| Foo | 1:00 |"
- (org-test-with-temp-text
- "* Foo
+ (string-match-p
+ "
+.*?\\[2017-09-25 .*
+.*
+.*
+|.*?| \\*1:00\\* |
+.*
+| Foo +| 1:00 +|"
+ (org-test-with-temp-text
+ "* Foo
CLOCK: [2017-09-30 Sat 12:00]--[2017-09-30 Sat 13:00] => 1:00
CLOCK: [2017-10-01 Sun 11:00]--[2017-10-01 Sun 13:00] => 2:00
CLOCK: [2017-10-02 Mon 11:00]--[2017-10-02 Mon 14:00] => 3:00"
- (let ((system-time-locale "en_US"))
- (test-org-clock-clocktable-contents
- ":step week :block 2017-09 :stepskip0 t")))))
+ (let ((system-time-locale "en_US"))
+ (test-org-clock-clocktable-contents
+ ":step week :block 2017-09 :stepskip0 t")))))
(should
- (equal "
-Weekly report starting on: [2017-10-01 Sun]
-| Headline | Time |
-|--------------+--------|
-| *Total time* | *2:00* |
-|--------------+--------|
-| Foo | 2:00 |
+ (string-match-p
+ "
+.*?\\[2017-10-01 .*
+.*
+.*
+|.*?| \\*2:00\\* |
+.*
+| Foo +| 2:00 |
-Weekly report starting on: [2017-10-02 Mon]
-| Headline | Time |
-|--------------+--------|
-| *Total time* | *7:00* |
-|--------------+--------|
-| Foo | 7:00 |
+.*?\\[2017-10-02 .*
+.*
+.*
+|.*?| \\*7:00\\* |
+.*
+| Foo +| 7:00 +|
-Weekly report starting on: [2017-10-09 Mon]
-| Headline | Time |
-|--------------+--------|
-| *Total time* | *5:00* |
-|--------------+--------|
-| Foo | 5:00 |
+.*?\\[2017-10-09 .*
+.*
+.*
+|.*?| \\*5:00\\* |
+.*
+| Foo +| 5:00 +|
"
- (org-test-with-temp-text
- "* Foo
+ (org-test-with-temp-text
+ "* Foo
CLOCK: [2017-09-30 Sat 12:00]--[2017-09-30 Sat 13:00] => 1:00
CLOCK: [2017-10-01 Sun 11:00]--[2017-10-01 Sun 13:00] => 2:00
CLOCK: [2017-10-02 Mon 11:00]--[2017-10-02 Mon 14:00] => 3:00
CLOCK: [2017-10-08 Sun 09:00]--[2017-10-08 Sun 13:00] => 4:00
CLOCK: [2017-10-09 Mon 09:00]--[2017-10-09 Mon 14:00] => 5:00"
- (let ((system-time-locale "en_US"))
- (test-org-clock-clocktable-contents
- ":step week :block 2017-10 :stepskip0 t")))))
+ (let ((system-time-locale "en_US"))
+ (test-org-clock-clocktable-contents
+ ":step week :block 2017-10 :stepskip0 t")))))
;; :step day
(should
- (equal "
-Daily report: [2017-10-02 Mon]
-| Headline | Time |
-|--------------+--------|
-| *Total time* | *3:00* |
-|--------------+--------|
-| Foo | 3:00 |
+ (string-match-p
+ "
+.*?\\[2017-10-02 .*
+.*
+.*
+|.*?| \\*3:00\\* |
+.*
+| Foo +| 3:00 +|
-Daily report: [2017-10-03 Tue]
-| Headline | Time |
-|--------------+--------|
-| *Total time* | *0:00* |
+.*?\\[2017-10-03 .*
+.*
+.*
+|.*?| \\*0:00\\* |
-Daily report: [2017-10-04 Wed]
-| Headline | Time |
-|--------------+--------|
-| *Total time* | *0:00* |
+.*?\\[2017-10-04 .*
+.*
+.*
+|.*?| \\*0:00\\* |
-Daily report: [2017-10-05 Thu]
-| Headline | Time |
-|--------------+--------|
-| *Total time* | *0:00* |
+.*?\\[2017-10-05 .*
+.*
+.*
+|.*?| \\*0:00\\* |
-Daily report: [2017-10-06 Fri]
-| Headline | Time |
-|--------------+--------|
-| *Total time* | *0:00* |
+.*?\\[2017-10-06 .*
+.*
+.*
+|.*?| \\*0:00\\* |
-Daily report: [2017-10-07 Sat]
-| Headline | Time |
-|--------------+--------|
-| *Total time* | *0:00* |
+.*?\\[2017-10-07 .*
+.*
+.*
+|.*?| \\*0:00\\* |
-Daily report: [2017-10-08 Sun]
-| Headline | Time |
-|--------------+--------|
-| *Total time* | *4:00* |
-|--------------+--------|
-| Foo | 4:00 |"
- (org-test-with-temp-text
- "* Foo
+.*?\\[2017-10-08 .*
+.*
+.*
+|.*?| \\*4:00\\* |
+.*
+| Foo +| 4:00 +|"
+ (org-test-with-temp-text
+ "* Foo
CLOCK: [2017-09-30 Sat 12:00]--[2017-09-30 Sat 13:00] => 1:00
CLOCK: [2017-10-01 Sun 11:00]--[2017-10-01 Sun 13:00] => 2:00
CLOCK: [2017-10-02 Mon 11:00]--[2017-10-02 Mon 14:00] => 3:00
CLOCK: [2017-10-08 Sun 09:00]--[2017-10-08 Sun 13:00] => 4:00
CLOCK: [2017-10-09 Mon 09:00]--[2017-10-09 Mon 14:00] => 5:00"
- (let ((system-time-locale "en_US"))
- (test-org-clock-clocktable-contents
- ":step day :block 2017-W40")))))
+ (let ((system-time-locale "en_US"))
+ (test-org-clock-clocktable-contents
+ ":step day :block 2017-W40")))))
;; Regression test: take :tstart and :tend hours into consideration.
(should
- (equal "
-Weekly report starting on: [2017-12-25 Mon]
-| Headline | Time |
-|--------------+--------|
-| *Total time* | *8:00* |
-|--------------+--------|
-| Foo | 8:00 |"
- (org-test-with-temp-text
- "* Foo
+ (string-match-p
+ "
+.*?\\[2017-12-25 .*
+.*
+.*
+|.*?| \\*8:00\\* |
+.*
+| Foo +| 8:00 +|"
+ (org-test-with-temp-text
+ "* Foo
CLOCK: [2017-12-27 Wed 08:00]--[2017-12-27 Wed 16:00] => 8:00"
- (let ((system-time-locale "en_US"))
- (test-org-clock-clocktable-contents
- (concat ":step week :tstart \"<2017-12-25 Mon>\" "
- ":tend \"<2017-12-27 Wed 23:59>\""))))))
+ (let ((system-time-locale "en_US"))
+ (test-org-clock-clocktable-contents
+ (concat ":step week :tstart \"<2017-12-25 Mon>\" "
+ ":tend \"<2017-12-27 Wed 23:59>\""))))))
(should
- (equal "
-Daily report: [2017-12-27 Wed]
-| Headline | Time |
-|--------------+--------|
-| *Total time* | *8:00* |
-|--------------+--------|
-| Foo | 8:00 |"
- (org-test-with-temp-text
- "* Foo
+ (string-match-p
+ "
+.*?\\[2017-12-27 .*
+.*
+.*
+|.*?| \\*8:00\\* |
+.*
+| Foo +| 8:00 +|"
+ (org-test-with-temp-text
+ "* Foo
CLOCK: [2017-12-27 Wed 08:00]--[2017-12-27 Wed 16:00] => 8:00"
- (let ((system-time-locale "en_US"))
- (test-org-clock-clocktable-contents
- (concat ":step day :tstart \"<2017-12-25 Mon>\" "
- ":tend \"<2017-12-27 Wed 23:59>\" :stepskip0 t"))))))
+ (let ((system-time-locale "en_US"))
+ (test-org-clock-clocktable-contents
+ (concat ":step day :tstart \"<2017-12-25 Mon>\" "
+ ":tend \"<2017-12-27 Wed 23:59>\" :stepskip0 t"))))))
+ ;; Test :step week", without or with ":wstart" parameter.
+ (should
+ (string-match-p
+ "
+.*?\\[2012-03-26 .*
+.*
+.*
+|.*?| \\*8:00\\* |
+.*
+| Foo +| 8:00 +|
+
+.*?\\[2012-04-02 .*
+.*
+.*
+|.*?| \\*8:00\\* |
+.*
+| Foo +| 8:00 +|
+"
+ (org-test-with-temp-text
+ "* Foo
+CLOCK: [2012-03-29 Thu 08:00]--[2012-03-29 Thu 16:00] => 8:00
+CLOCK: [2012-04-03 Thu 08:00]--[2012-04-03 Thu 16:00] => 8:00"
+ (let ((system-time-locale "en_US"))
+ (test-org-clock-clocktable-contents
+ ":step week :block 2012 :stepskip0 t")))))
+ (should
+ (string-match-p
+ "
+.*?\\[2012-03-29 .*
+.*
+.*
+|.*?| \\*16:00\\* |
+.*
+| Foo +| 16:00 +|
+"
+ (org-test-with-temp-text
+ "* Foo
+CLOCK: [2012-03-29 Thu 08:00]--[2012-03-29 Thu 16:00] => 8:00
+CLOCK: [2012-04-03 Thu 08:00]--[2012-04-03 Thu 16:00] => 8:00"
+ (let ((system-time-locale "en_US"))
+ (test-org-clock-clocktable-contents
+ ":step week :wstart 4 :block 2012 :stepskip0 t")))))
+ ;; Test ":step month" without and with ":mstart".
+ (should
+ (string-match-p
+ "
+.*?\\[2014-03-01 .*
+.*
+.*
+|.*?| \\*8:00\\* |
+.*
+| Foo +| 8:00 +|
+
+.*?\\[2014-04-01 .*
+.*
+.*
+|.*?| \\*8:00\\* |
+.*
+| Foo +| 8:00 +|
+"
+ (org-test-with-temp-text
+ "* Foo
+CLOCK: [2014-03-04 Tue 08:00]--[2014-03-04 Tue 16:00] => 8:00
+CLOCK: [2014-04-03 Thu 08:00]--[2014-04-03 Thu 16:00] => 8:00"
+ (let ((system-time-locale "en_US"))
+ (test-org-clock-clocktable-contents
+ ":step month :block 2014 :stepskip0 t")))))
+ (should
+ (string-match-p
+ "
+.*?\\[2014-03-04 .*
+.*
+.*
+|.*?| \\*16:00\\* |
+.*
+| Foo +| 16:00 +|
+"
+ (org-test-with-temp-text
+ "* Foo
+CLOCK: [2014-03-04 Tue 08:00]--[2014-03-04 Tue 16:00] => 8:00
+CLOCK: [2014-04-03 Thu 08:00]--[2014-04-03 Thu 16:00] => 8:00"
+ (let ((system-time-locale "en_US"))
+ (test-org-clock-clocktable-contents
+ ":step month :mstart 4 :block 2014 :stepskip0 t")))))
+ ;; Test ":step year".
+ (should
+ (string-match-p
+ "
+.*?\\[2012-01-01 .*
+.*
+.*
+|.*?| \\*8:00\\* |
+.*
+| Foo +| 8:00 +|
+
+.*?\\[2014-01-01 .*
+.*
+.*
+|.*?| \\*8:00\\* |
+.*
+| Foo +| 8:00 +|
+"
+ (org-test-with-temp-text
+ "* Foo
+CLOCK: [2012-03-29 Thu 08:00]--[2012-03-29 Thu 16:00] => 8:00
+CLOCK: [2014-03-04 Tue 08:00]--[2014-03-04 Tue 16:00] => 8:00"
+ (let ((system-time-locale "en_US"))
+ (test-org-clock-clocktable-contents
+ ":step year :block untilnow :stepskip0 t")))))
;; Regression test: Respect DST
(should
- (equal "
-Daily report: [2018-10-29 Mon]
-| Headline | Time |
-|--------------+--------|
-| *Total time* | *8:00* |
-|--------------+--------|
-| Foo | 8:00 |
+ (string-match-p
+ "
+.*?\\[2018-10-29 .*
+.*
+.*
+|.*?| \\*8:00\\* |
+.*
+| Foo +| 8:00 +|
"
- (org-test-with-temp-text
- "* Foo
+ (org-test-with-temp-text
+ "* Foo
CLOCK: [2018-10-29 Mon 08:00]--[2018-10-29 Mon 16:00] => 8:00"
- (let ((system-time-locale "en_US"))
- (test-org-clock-clocktable-contents
- (concat ":step day "
- ":stepskip0 t "
- ":tstart \"2018-10-01\" "
- ":tend \"2018-11-01\"")))))))
+ (let ((system-time-locale "en_US"))
+ (test-org-clock-clocktable-contents
+ (concat ":step day "
+ ":stepskip0 t "
+ ":tstart \"2018-10-01\" "
+ ":tend \"2018-11-01\"")))))))
(ert-deftest test-org-clock/clocktable/extend-today-until ()
"Test assignment of clock time to days in presence of \"org-extend-today-until\"."
@@ -1009,44 +1152,61 @@ CLOCK: [2018-10-29 Mon 08:00]--[2018-10-29 Mon 16:00] => 8:00"
| *Total time* | *2:00* |
|--------------+--------|
| Foo | 2:00 |"
- (org-test-with-temp-text
- "* Foo
+ (org-test-with-temp-text
+ "* Foo
CLOCK: [2017-09-30 Sat 12:00]--[2017-09-30 Sat 13:00] => 1:00
CLOCK: [2017-10-01 Sun 02:00]--[2017-10-01 Sun 03:00] => 1:00
CLOCK: [2017-10-01 Sun 11:00]--[2017-10-01 Sun 13:00] => 2:00"
- (setq-local org-extend-today-until 4)
- (let ((system-time-locale "en_US"))
- (test-org-clock-clocktable-contents
- ":block 2017-09-30")))))
+ (setq-local org-extend-today-until 4)
+ (let ((system-time-locale "en_US"))
+ (test-org-clock-clocktable-contents
+ ":block 2017-09-30")))))
;; Week-length block - time on Monday before 04:00 should be
;; assigned to previous week.
(should
- (equal "
-Weekly report starting on: [2017-10-01 Sun]
-| Headline | Time |
-|--------------+--------|
-| *Total time* | *2:00* |
-|--------------+--------|
-| Foo | 2:00 |
+ (string-match-p "
+.*? \\[2017-10-01 .*
+.*
+.*
+|.*?| \\*2:00\\* |
+.*
+| Foo +| 2:00 |
-Weekly report starting on: [2017-10-02 Mon]
-| Headline | Time |
-|--------------+--------|
-| *Total time* | *2:00* |
-|--------------+--------|
-| Foo | 2:00 |
+.*? \\[2017-10-02 .*
+.*
+.*
+|.*?| \\*2:00\\* |
+.*
+| Foo +| 2:00 |
"
- (org-test-with-temp-text
- "* Foo
+ (org-test-with-temp-text
+ "* Foo
CLOCK: [2017-10-01 Sun 12:00]--[2017-10-01 Sun 13:00] => 1:00
CLOCK: [2017-10-02 Mon 02:00]--[2017-10-02 Mon 03:00] => 1:00
CLOCK: [2017-10-02 Mon 11:00]--[2017-10-02 Mon 13:00] => 2:00"
- (setq-local org-extend-today-until 4)
- (let ((system-time-locale "en_US"))
- (test-org-clock-clocktable-contents
- ":step week :block 2017-10 :stepskip0 t"))))))
+ (setq-local org-extend-today-until 4)
+ (let ((system-time-locale "en_US"))
+ (test-org-clock-clocktable-contents
+ ":step week :block 2017-10 :stepskip0 t"))))))
+(ert-deftest test-org-clock/clocktable/hidefiles ()
+ "Test \":hidefiles\" parameter in Clock table."
+ ;; Test that hidefiles removes the file column.
+ (should
+ (equal
+ "| Headline | Time |
+|--------------+--------|
+| *Total time* | *1:00* |
+|--------------+--------|
+| Test | 1:00 |"
+ (org-test-with-temp-text-in-file
+ "* Test
+CLOCK: [2012-03-29 Thu 16:00]--[2012-03-29 Thu 17:00] => 1:00"
+ (let ((the-file (buffer-file-name)))
+ (org-test-with-temp-text-in-file ""
+ (test-org-clock-clocktable-contents
+ (format ":hidefiles t :scope (lambda () (list %S))" the-file))))))))
(provide 'test-org-clock)
;;; test-org-clock.el end here
diff --git a/testing/lisp/test-org-colview.el b/testing/lisp/test-org-colview.el
index a575e72..ed75090 100644
--- a/testing/lisp/test-org-colview.el
+++ b/testing/lisp/test-org-colview.el
@@ -142,7 +142,7 @@
;; Special case: width takes into account link narrowing in ITEM.
(should
(equal
- '("* [123]" . 7)
+ '("* 123" . 5)
(org-test-with-temp-text "* [[https://orgmode.org][123]]"
(let ((org-columns-default-format "%ITEM")) (org-columns))
(cons (get-char-property (point) 'org-columns-value-modified)
@@ -224,7 +224,7 @@
:END:"
(let ((org-columns-default-format "%A{+;%.1f}")) (org-columns))
(get-char-property (point) 'org-columns-value-modified))))
- ;; {:} sums times. Plain numbers are hours.
+ ;; {:} sums times. Plain numbers are minutes.
(should
(equal
"4:10"
@@ -242,7 +242,7 @@
(get-char-property (point) 'org-columns-value-modified))))
(should
(equal
- "3:30"
+ "1:32"
(org-test-with-temp-text
"* H
** S1
@@ -1464,6 +1464,26 @@
:END:"
(let ((org-columns-default-format "%ITEM %A")) (org-update-dblock))
(buffer-substring-no-properties (point) (outline-next-heading)))))
+ ;; Test `:exclude-tags' parameter.
+ (should
+ (equal
+ "#+BEGIN: columnview :exclude-tags (\"excludeme\")
+| ITEM | A |
+|------+---|
+| H1 | |
+#+END:
+"
+ (org-test-with-temp-text
+ "
+* H1
+<point>#+BEGIN: columnview :exclude-tags (\"excludeme\")
+#+END:
+** H1.1 :excludeme:
+:PROPERTIES:
+:A: 1
+:END:"
+ (let ((org-columns-default-format "%ITEM %A")) (org-update-dblock))
+ (buffer-substring-no-properties (point) (outline-next-heading)))))
;; Test `:format' parameter.
(should
(equal
diff --git a/testing/lisp/test-org-element.el b/testing/lisp/test-org-element.el
index 8b4081e..f2ab380 100644
--- a/testing/lisp/test-org-element.el
+++ b/testing/lisp/test-org-element.el
@@ -376,12 +376,26 @@ Some other text
(org-test-with-temp-text
"#+ATTR_ASCII: line1\n#+ATTR_ASCII: line2\nParagraph"
(org-element-at-point)))))
- ;; Parse "parsed" keywords.
+ ;; Parse "parsed" keywords, unless granularity prevents it.
(should
(equal
'(("caption"))
(org-test-with-temp-text "#+CAPTION: caption\nParagraph"
(car (org-element-property :caption (org-element-at-point))))))
+ (should
+ (org-test-with-temp-text "#+CAPTION: *caption*\nParagraph"
+ (org-element-map (org-element-map (org-element-parse-buffer)
+ 'paragraph
+ (lambda (e) (org-element-property :caption e)) nil t)
+ 'bold
+ #'org-element-type nil t)))
+ (should-not
+ (org-test-with-temp-text "#+CAPTION: *caption*\nParagraph"
+ (org-element-map (org-element-map (org-element-parse-buffer 'element)
+ 'paragraph
+ (lambda (e) (org-element-property :caption e)) nil t)
+ 'bold
+ #'org-element-type nil t)))
;; Parse dual keywords.
(should
(equal
@@ -3250,8 +3264,8 @@ DEADLINE: <2012-03-29 thu.> SCHEDULED: <2012-03-29 thu.> CLOSED: [2012-03-29 thu
(ert-deftest test-org-element/granularity ()
"Test granularity impact on buffer parsing."
- (org-test-with-temp-text "
-* Head 1
+ (org-test-with-temp-text
+ "* Head 1
** Head 2
#+BEGIN_CENTER
Centered paragraph.
diff --git a/testing/lisp/test-org-inlinetask.el b/testing/lisp/test-org-inlinetask.el
index 1e8c9ff..7e9f7e3 100644
--- a/testing/lisp/test-org-inlinetask.el
+++ b/testing/lisp/test-org-inlinetask.el
@@ -148,7 +148,7 @@ p4
*************** END
"
- (outline-hide-subtree)
+ (org-flag-subtree t)
(org-cycle)
(and
(not (invisible-p (1- (search-forward "p1"))))
diff --git a/testing/lisp/test-org-lint.el b/testing/lisp/test-org-lint.el
index d96808a..ab8f674 100644
--- a/testing/lisp/test-org-lint.el
+++ b/testing/lisp/test-org-lint.el
@@ -418,6 +418,33 @@ SCHEDULED: <2012-03-29 thu.>"
(org-test-with-temp-text "[[file+emacs:foo.org]]"
(org-lint '(file-application)))))
+(ert-deftest test-org-lint/percenc-encoding-link-escape ()
+ "Test `org-lint-percent-encoding-link-escape' checker."
+ (should
+ (org-test-with-temp-text "[[A%20B]]"
+ (org-lint '(percent-encoding-link-escape))))
+ (should
+ (org-test-with-temp-text "[[%5Bfoo%5D]]"
+ (org-lint '(percent-encoding-link-escape))))
+ (should
+ (org-test-with-temp-text "[[A%2520B]]"
+ (org-lint '(percent-encoding-link-escape))))
+ (should-not
+ (org-test-with-temp-text "[[A B]]"
+ (org-lint '(percent-encoding-link-escape))))
+ (should-not
+ (org-test-with-temp-text "[[A%30B]]"
+ (org-lint '(percent-encoding-link-escape))))
+ (should-not
+ (org-test-with-temp-text "[[A%20%30B]]"
+ (org-lint '(percent-encoding-link-escape))))
+ (should-not
+ (org-test-with-temp-text "<file:A%20B>"
+ (org-lint '(percent-encoding-link-escape))))
+ (should-not
+ (org-test-with-temp-text "[[A B%]]"
+ (org-lint '(percent-encoding-link-escape)))))
+
(ert-deftest test-org-lint/wrong-header-argument ()
"Test `org-lint-wrong-header-argument' checker."
(should
diff --git a/testing/lisp/test-org-num.el b/testing/lisp/test-org-num.el
new file mode 100644
index 0000000..e4f3cbc
--- /dev/null
+++ b/testing/lisp/test-org-num.el
@@ -0,0 +1,261 @@
+;;; test-org-num.el --- Tests for Org Num library -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2018 Nicolas Goaziou
+
+;; Author: Nicolas Goaziou <mail@nicolasgoaziou.fr>
+
+;; This file is not part of GNU Emacs.
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Code:
+
+(require 'org-num)
+
+(ert-deftest test-org-num/face ()
+ "Test `org-num-face' parameter."
+ (should
+ (equal
+ '(foo)
+ (org-test-with-temp-text "* H1"
+ (let ((org-num-face 'foo)) (org-num-mode 1))
+ (mapcar (lambda (o)
+ (get-text-property 0 'face (overlay-get o 'after-string)))
+ (overlays-in (point-min) (point-max)))))))
+
+(ert-deftest test-org-num/format-function ()
+ "Test `org-num-format-function' parameter."
+ (should
+ (equal '("foo" "foo")
+ (org-test-with-temp-text "* H1\n** H2"
+ (let ((org-num-format-function (lambda (_) "foo")))
+ (org-num-mode 1))
+ (mapcar (lambda (o) (overlay-get o 'after-string))
+ (overlays-in (point-min) (point-max))))))
+ ;; Preserve face, when set.
+ (should
+ (equal-including-properties
+ '(#("foo" 0 3 (face bar)))
+ (org-test-with-temp-text "* H1"
+ (let ((org-num-format-function
+ (lambda (_) (org-add-props "foo" nil 'face 'bar))))
+ (org-num-mode 1))
+ (mapcar (lambda (o) (overlay-get o 'after-string))
+ (overlays-in (point-min) (point-max))))))
+ ;; Set face override `org-num-face'.
+ (should
+ (equal-including-properties
+ '(#("foo" 0 3 (face bar)))
+ (org-test-with-temp-text "* H1"
+ (let ((org-num-face 'baz)
+ (org-num-format-function
+ (lambda (_) (org-add-props "foo" nil 'face 'bar))))
+ (org-num-mode 1))
+ (mapcar (lambda (o) (overlay-get o 'after-string))
+ (overlays-in (point-min) (point-max)))))))
+
+(ert-deftest test-org-num/max-level ()
+ "Test `org-num-max-level' option."
+ (should
+ (equal '("1.1 " "1 ")
+ (org-test-with-temp-text "* H1\n** H2\n*** H3"
+ (let ((org-num-max-level 2)) (org-num-mode 1))
+ (mapcar (lambda (o) (overlay-get o 'after-string))
+ (overlays-in (point-min) (point-max)))))))
+
+(ert-deftest test-org-num/skip-numbering ()
+ "Test various skip numbering parameters."
+ ;; Skip commented headlines.
+ (should
+ (equal '(nil "1 ")
+ (org-test-with-temp-text "* H1\n* COMMENT H2"
+ (let ((org-num-skip-commented t)) (org-num-mode 1))
+ (mapcar (lambda (o) (overlay-get o 'after-string))
+ (overlays-in (point-min) (point-max))))))
+ (should
+ (equal '("2 " "1 ")
+ (org-test-with-temp-text "* H1\n* COMMENT H2"
+ (let ((org-num-skip-commented nil)) (org-num-mode 1))
+ (mapcar (lambda (o) (overlay-get o 'after-string))
+ (overlays-in (point-min) (point-max))))))
+ ;; Skip commented sub-trees.
+ (should
+ (equal '(nil nil)
+ (org-test-with-temp-text "* COMMENT H1\n** H2"
+ (let ((org-num-skip-commented t)) (org-num-mode 1))
+ (mapcar (lambda (o) (overlay-get o 'after-string))
+ (overlays-in (point-min) (point-max))))))
+ ;; Skip footnotes sections.
+ (should
+ (equal '(nil "1 ")
+ (org-test-with-temp-text "* H1\n* FN"
+ (let ((org-num-skip-footnotes t)
+ (org-footnote-section "FN"))
+ (org-num-mode 1))
+ (mapcar (lambda (o) (overlay-get o 'after-string))
+ (overlays-in (point-min) (point-max))))))
+ (should
+ (equal '("2 " "1 ")
+ (org-test-with-temp-text "* H1\n* FN"
+ (let ((org-num-skip-footnotes nil)
+ (org-footnote-section "FN"))
+ (org-num-mode 1))
+ (mapcar (lambda (o) (overlay-get o 'after-string))
+ (overlays-in (point-min) (point-max))))))
+ ;; Skip tags, recursively.
+ (should
+ (equal '(nil "1 ")
+ (org-test-with-temp-text "* H1\n* H2 :foo:"
+ (let ((org-num-skip-tags '("foo"))) (org-num-mode 1))
+ (mapcar (lambda (o) (overlay-get o 'after-string))
+ (overlays-in (point-min) (point-max))))))
+ (should
+ (equal '(nil nil)
+ (org-test-with-temp-text "* H1 :foo:\n** H2"
+ (let ((org-num-skip-tags '("foo"))) (org-num-mode 1))
+ (mapcar (lambda (o) (overlay-get o 'after-string))
+ (overlays-in (point-min) (point-max))))))
+ ;; Skip unnumbered sections.
+ (should
+ (equal '(nil "1 ")
+ (org-test-with-temp-text
+ "* H1\n* H2\n:PROPERTIES:\n:UNNUMBERED: t\n:END:"
+ (let ((org-num-skip-unnumbered t)) (org-num-mode 1))
+ (mapcar (lambda (o) (overlay-get o 'after-string))
+ (overlays-in (point-min) (point-max))))))
+ (should
+ (equal '("2 " "1 ")
+ (org-test-with-temp-text
+ "* H1\n* H2\n:PROPERTIES:\n:UNNUMBERED: t\n:END:"
+ (let ((org-num-skip-unnumbered nil)) (org-num-mode 1))
+ (mapcar (lambda (o) (overlay-get o 'after-string))
+ (overlays-in (point-min) (point-max))))))
+ (should
+ (equal '("2 " "1 ")
+ (org-test-with-temp-text
+ "* H1\n* H2\n:PROPERTIES:\n:UNNUMBERED: nil\n:END:"
+ (let ((org-num-skip-unnumbered t)) (org-num-mode 1))
+ (mapcar (lambda (o) (overlay-get o 'after-string))
+ (overlays-in (point-min) (point-max))))))
+ ;; Skip unnumbered sub-trees.
+ (should
+ (equal '(nil nil)
+ (org-test-with-temp-text
+ "* H1\n:PROPERTIES:\n:UNNUMBERED: t\n:END:\n** H2"
+ (let ((org-num-skip-unnumbered t)) (org-num-mode 1))
+ (mapcar (lambda (o) (overlay-get o 'after-string))
+ (overlays-in (point-min) (point-max)))))))
+
+(ert-deftest test-org-num/update ()
+ "Test numbering update after a buffer modification."
+ ;; Headlines created at BEG.
+ (should
+ (equal "1 "
+ (org-test-with-temp-text "X* H"
+ (org-num-mode 1)
+ (delete-char 1)
+ (overlay-get (car (overlays-at (line-beginning-position)))
+ 'after-string))))
+ (should
+ (equal "1 "
+ (org-test-with-temp-text "*<point>\n H"
+ (org-num-mode 1)
+ (delete-char 1)
+ (overlay-get (car (overlays-at (line-beginning-position)))
+ 'after-string))))
+ (should
+ (equal "1 "
+ (org-test-with-temp-text "*<point>bold*"
+ (org-num-mode 1)
+ (insert " ")
+ (overlay-get (car (overlays-at (line-beginning-position)))
+ 'after-string))))
+ ;; Headlines created at END.
+ (should
+ (equal '("1 ")
+ (org-test-with-temp-text "X<point> H"
+ (org-num-mode 1)
+ (insert "\n*")
+ (mapcar (lambda (o) (overlay-get o 'after-string))
+ (overlays-in (point-min) (point-max))))))
+ (should
+ (equal '("1 ")
+ (org-test-with-temp-text "X<point>* H"
+ (org-num-mode 1)
+ (insert "\n")
+ (mapcar (lambda (o) (overlay-get o 'after-string))
+ (overlays-in (point-min) (point-max))))))
+ ;; Headlines created between BEG and END.
+ (should
+ (equal '("1.1 " "1 ")
+ (org-test-with-temp-text ""
+ (org-num-mode 1)
+ (insert "\n* H\n** H2")
+ (mapcar (lambda (o) (overlay-get o 'after-string))
+ (overlays-in (point-min) (point-max))))))
+ ;; Change level of a headline.
+ (should
+ (equal '("0.1 ")
+ (org-test-with-temp-text "* H"
+ (org-num-mode 1)
+ (insert "*")
+ (mapcar (lambda (o) (overlay-get o 'after-string))
+ (overlays-in (point-min) (point-max))))))
+ (should
+ (equal '("1 ")
+ (org-test-with-temp-text "*<point>* H"
+ (org-num-mode 1)
+ (delete-char 1)
+ (mapcar (lambda (o) (overlay-get o 'after-string))
+ (overlays-in (point-min) (point-max))))))
+ ;; Alter skip state.
+ (should
+ (equal '("1 ")
+ (org-test-with-temp-text "* H :fo<point>o:"
+ (let ((org-num-skip-tags '("foo")))
+ (org-num-mode 1)
+ (delete-char 1))
+ (mapcar (lambda (o) (overlay-get o 'after-string))
+ (overlays-in (point-min) (point-max))))))
+ (should
+ (equal '(nil)
+ (org-test-with-temp-text "* H :fo<point>:"
+ (let ((org-num-skip-tags '("foo")))
+ (org-num-mode 1)
+ (insert "o"))
+ (mapcar (lambda (o) (overlay-get o 'after-string))
+ (overlays-in (point-min) (point-max))))))
+ ;; Invalidate an overlay and insert new headlines.
+ (should
+ (equal '("1.2 " "1.1 " "1 ")
+ (org-test-with-temp-text
+ "* H\n:PROPERTIES:\n:UNNUMBE<point>RED: t\n:END:"
+ (let ((org-num-skip-unnumbered t))
+ (org-num-mode 1)
+ (insert "\n** H2\n** H3\n")
+ (mapcar (lambda (o) (overlay-get o 'after-string))
+ (overlays-in (point-min) (point-max)))))))
+ ;; Invalidate two overlays: current headline and next one.
+ (should
+ (equal '("1 ")
+ (org-test-with-temp-text
+ "* H\n:PROPERTIES:\n:UNNUMBE<point>RED: t\n:END:\n** H2"
+ (let ((org-num-skip-unnumbered t))
+ (org-num-mode 1)
+ (delete-region (point) (line-beginning-position 3))
+ (mapcar (lambda (o) (overlay-get o 'after-string))
+ (overlays-in (point-min) (point-max))))))))
+
+(provide 'test-org-num)
+;;; org-test-num.el ends here
diff --git a/testing/lisp/test-org-table.el b/testing/lisp/test-org-table.el
index 19dd2b7..565f3ff 100644
--- a/testing/lisp/test-org-table.el
+++ b/testing/lisp/test-org-table.el
@@ -572,8 +572,7 @@ reference (with row). Mode string N."
"$8 = '(let ((l '(@0$1..@0$4))) "
"(if l (/ (apply '+ l) (length l)) \"\")); N :: "
"$9 = '(/ (+ $1..$4) (length '($1..$4))); EN :: "
- "$10 = '(/ (+ @0$1..@0$4) (length '(@0$1..@0$4))); EN")
-))
+ "$10 = '(/ (+ @0$1..@0$4) (length '(@0$1..@0$4))); EN")))
(ert-deftest test-org-table/copy-field ()
"Experiments on how to copy one field into another field.
@@ -626,6 +625,125 @@ See also `test-org-table/remote-reference-access'."
"
1 "#+TBLFM: $2 = if(\"$1\" == \"nan\", string(\"\"), $1); E")))
+(ert-deftest test-org-table/copy-down ()
+ "Test `org-table-copy-down' specifications."
+ ;; Error when there is nothing to copy in the current field or the
+ ;; field above.
+ (should-error
+ (org-test-with-temp-text "| |\n| <point> |"
+ (org-table-copy-down 1)))
+ ;; Error when there is nothing to copy in the Nth field.
+ (should-error
+ (org-test-with-temp-text "| |\n| foo |\n| <point> |"
+ (org-table-copy-down 2)))
+ ;; In an empty field, copy field above.
+ (should
+ (equal "| foo |\n| foo |"
+ (org-test-with-temp-text "| foo |\n| <point> |"
+ (org-table-copy-down 1)
+ (buffer-string))))
+ ;; In a non-empty field, copy it below.
+ (should
+ (equal "| foo |\n| foo |\n"
+ (org-test-with-temp-text "| <point>foo |"
+ (org-table-copy-down 1)
+ (buffer-string))))
+ ;; If field is a number or a timestamp, or is prefixed or suffixed
+ ;; with a number, increment it by one unit.
+ (should
+ (equal "| 1 |\n| 2 |\n"
+ (org-test-with-temp-text "| <point>1 |"
+ (let ((org-table-copy-increment t)) (org-table-copy-down 1))
+ (buffer-string))))
+ (should
+ (string-match-p "<2012-03-30"
+ (org-test-with-temp-text "| <point><2012-03-29> |"
+ (let ((org-table-copy-increment t))
+ (org-table-copy-down 1))
+ (buffer-string))))
+ (should
+ (equal "| A1 |\n| A2 |\n"
+ (org-test-with-temp-text "| <point>A1 |"
+ (let ((org-table-copy-increment t)) (org-table-copy-down 1))
+ (buffer-string))))
+ (should
+ (equal "| 1A |\n| 2A |\n"
+ (org-test-with-temp-text "| <point>1A |"
+ (let ((org-table-copy-increment t)) (org-table-copy-down 1))
+ (buffer-string))))
+ ;; When `org-table-copy-increment' is nil, or when argument is 0, do
+ ;; not increment.
+ (should
+ (equal "| 1 |\n| 1 |\n"
+ (org-test-with-temp-text "| <point>1 |"
+ (let ((org-table-copy-increment nil)) (org-table-copy-down 1))
+ (buffer-string))))
+ (should
+ (equal "| 1 |\n| 1 |\n"
+ (org-test-with-temp-text "| <point>1 |"
+ (let ((org-table-copy-increment t)) (org-table-copy-down 0))
+ (buffer-string))))
+ ;; When there is a field just above field being incremented, try to
+ ;; use it to guess increment step.
+ (should
+ (equal "| 4 |\n| 3 |\n| 2 |\n"
+ (org-test-with-temp-text "| 4 |\n| <point>3 |"
+ (let ((org-table-copy-increment t)) (org-table-copy-down 1))
+ (buffer-string))))
+ (should
+ (equal "| A0 |\n| A2 |\n| A4 |\n"
+ (org-test-with-temp-text "| A0 |\n| <point>A2 |"
+ (let ((org-table-copy-increment t)) (org-table-copy-down 1))
+ (buffer-string))))
+ ;; Both fields need to have the same type. In the special case of
+ ;; number-prefixed or suffixed fields, make sure both fields have
+ ;; the same pattern.
+ (should
+ (equal "| A4 |\n| 3 |\n| 4 |\n"
+ (org-test-with-temp-text "| A4 |\n| <point>3 |"
+ (let ((org-table-copy-increment t)) (org-table-copy-down 1))
+ (buffer-string))))
+ (should
+ (equal "| 0A |\n| A2 |\n| A3 |\n"
+ (org-test-with-temp-text "| 0A |\n| <point>A2 |"
+ (let ((org-table-copy-increment t)) (org-table-copy-down 1))
+ (buffer-string))))
+ (should
+ (equal "| A0 |\n| 2A |\n| 3A |\n"
+ (org-test-with-temp-text "| A0 |\n| <point>2A |"
+ (let ((org-table-copy-increment t)) (org-table-copy-down 1))
+ (buffer-string))))
+ ;; Do not search field above past blank fields and horizontal
+ ;; separators.
+ (should
+ (equal "| 4 |\n|---|\n| 3 |\n| 4 |\n"
+ (org-test-with-temp-text "| 4 |\n|---|\n| <point>3 |"
+ (let ((org-table-copy-increment t)) (org-table-copy-down 1))
+ (buffer-string))))
+ (should
+ (equal "| 4 |\n| |\n| 3 |\n| 4 |\n"
+ (org-test-with-temp-text "| 4 |\n| |\n| <point>3 |"
+ (let ((org-table-copy-increment t)) (org-table-copy-down 1))
+ (buffer-string))))
+ ;; When `org-table-copy-increment' is a number, use it as the
+ ;; increment step, ignoring any previous field.
+ (should
+ (equal "| 1 |\n| 3 |\n| 6 |\n"
+ (org-test-with-temp-text "| 1 |\n| <point>3 |"
+ (let ((org-table-copy-increment 3)) (org-table-copy-down 1))
+ (buffer-string))))
+ ;; However, if argument is 0, do not increment whatsoever.
+ (should
+ (equal "| 1 |\n| 3 |\n| 3 |\n"
+ (org-test-with-temp-text "| 1 |\n| <point>3 |"
+ (let ((org-table-copy-increment t)) (org-table-copy-down 0))
+ (buffer-string))))
+ (should
+ (equal "| 1 |\n| 3 |\n| 3 |\n"
+ (org-test-with-temp-text "| 1 |\n| <point>3 |"
+ (let ((org-table-copy-increment 3)) (org-table-copy-down 0))
+ (buffer-string)))))
+
(ert-deftest test-org-table/sub-total ()
"Grouped rows with sub-total.
Begin range with \"@II\" to handle multiline header. Convert
@@ -2278,6 +2396,391 @@ See also `test-org-table/copy-field'."
+;;; Moving single cells
+(ert-deftest test-org-table/move-cell-down ()
+ "Test `org-table-move-cell-down' specifications."
+ ;; Error out when cell cannot be moved due to not in table, in the
+ ;; last row of the table, or is on a hline.
+ (should-error
+ (org-test-with-temp-text "not in\na table\n"
+ (org-table-move-cell-down)))
+ (should-error
+ (org-test-with-temp-text "| a |"
+ (org-table-move-cell-down)))
+ (should-error
+ (org-test-with-temp-text "| a |\n"
+ (org-table-move-cell-down)))
+ (should-error
+ (org-test-with-temp-text "| a | <point>b |\n"
+ (org-table-move-cell-down)))
+ (should-error
+ (org-test-with-temp-text "| a | b |\n| <point>c | d |\n"
+ (org-table-move-cell-down)))
+ (should-error
+ (org-test-with-temp-text "| a | b |\n| c | <point>d |\n"
+ (org-table-move-cell-down)))
+ (should-error
+ (org-test-with-temp-text "| <point>a |\n|---|\n"
+ (org-table-move-cell-down)))
+ (should-error
+ (org-test-with-temp-text "|<point>---|\n| a |\n"
+ (org-table-move-cell-down)))
+ ;; Check for correct cell movement
+ (should (equal (concat "| c | b |\n"
+ "| a | d |\n"
+ "| e | f |\n")
+ (org-test-with-temp-text
+ (concat "| <point>a | b |\n"
+ "| c | d |\n"
+ "| e | f |\n")
+ (org-table-move-cell-down)
+ (buffer-string))))
+ (should (equal (concat "| a | d |\n"
+ "| c | b |\n"
+ "| e | f |\n")
+ (org-test-with-temp-text
+ (concat "| a | <point>b |\n"
+ "| c | d |\n"
+ "| e | f |\n")
+ (org-table-move-cell-down)
+ (buffer-string))))
+ (should (equal (concat "| a | b |\n"
+ "| e | d |\n"
+ "| c | f |\n")
+ (org-test-with-temp-text
+ (concat "| a | b |\n"
+ "| <point>c | d |\n"
+ "| e | f |\n")
+ (org-table-move-cell-down)
+ (buffer-string))))
+ (should (equal (concat "| a | d |\n"
+ "| c | f |\n"
+ "| e | b |\n")
+ (org-test-with-temp-text
+ (concat "| a |<point> b |\n"
+ "| c | d |\n"
+ "| e | f |\n")
+ (org-table-move-cell-down)
+ (org-table-move-cell-down)
+ (buffer-string))))
+ ;; Check for correct handling of hlines which should not change
+ ;; position on single cell moves.
+ (should (equal (concat "| c | b |\n"
+ "|---+---|\n"
+ "| a | d |\n"
+ "| e | f |\n")
+ (org-test-with-temp-text
+ (concat "| <point>a | b |\n"
+ "|---+---|\n"
+ "| c | d |\n"
+ "| e | f |\n")
+ (org-table-move-cell-down)
+ (buffer-string))))
+ (should (equal (concat "| a | d |\n"
+ "|---+---|\n"
+ "| c | f |\n"
+ "| e | b |\n")
+ (org-test-with-temp-text
+ (concat "| a | <point>b |\n"
+ "|---+---|\n"
+ "| c | d |\n"
+ "| e | f |\n")
+ (org-table-move-cell-down)
+ (org-table-move-cell-down)
+ (buffer-string))))
+ (should (equal (concat "| a | b |\n"
+ "|---+---|\n"
+ "| c | f |\n"
+ "| e | d |\n")
+ (org-test-with-temp-text
+ (concat "| a | b |\n"
+ "|---+---|\n"
+ "| c | <point>d |\n"
+ "| e | f |\n")
+ (org-table-move-cell-down)
+ (buffer-string))))
+ ;; Move single cell even without a final newline.
+ (should (equal (concat "| a | d |\n"
+ "|---+---|\n"
+ "| c | f |\n"
+ "| e | b |\n")
+ (org-test-with-temp-text
+ (concat "| a | <point>b |\n"
+ "|---+---|\n"
+ "| c | d |\n"
+ "| e | f |")
+ (org-table-move-cell-down)
+ (org-table-move-cell-down)
+ (buffer-string)))))
+
+(ert-deftest test-org-table/move-cell-up ()
+ "Test `org-table-move-cell-up' specifications."
+ ;; Error out when cell cannot be moved due to not in table, in the
+ ;; last row of the table, or is on a hline.
+ (should-error
+ (org-test-with-temp-text "not in\na table\n"
+ (org-table-move-cell-up)))
+ (should-error
+ (org-test-with-temp-text "| a |"
+ (org-table-move-cell-up)))
+ (should-error
+ (org-test-with-temp-text "| a |\n"
+ (org-table-move-cell-up)))
+ (should-error
+ (org-test-with-temp-text "| <point>a | b |\n"
+ (org-table-move-cell-up)))
+ (should-error
+ (org-test-with-temp-text "| a | <point>b |\n| c | d |\n"
+ (org-table-move-cell-up)))
+ (should-error
+ (org-test-with-temp-text "| <point>a |\n|---|\n"
+ (org-table-move-cell-up)))
+ (should-error
+ (org-test-with-temp-text "|<point>---|\n| a |\n"
+ (org-table-move-cell-up)))
+ ;; Check for correct cell movement.
+ (should (equal (concat "| c | b |\n"
+ "| a | d |\n"
+ "| e | f |\n")
+ (org-test-with-temp-text
+ (concat "| a | b |\n"
+ "| <point>c | d |\n"
+ "| e | f |\n")
+ (org-table-move-cell-up)
+ (buffer-string))))
+ (should (equal (concat "| a | d |\n"
+ "| c | b |\n"
+ "| e | f |\n")
+ (org-test-with-temp-text
+ (concat "| a | b |\n"
+ "| c | <point>d |\n"
+ "| e | f |\n")
+ (org-table-move-cell-up)
+ (buffer-string))))
+ (should (equal (concat "| a | b |\n"
+ "| e | d |\n"
+ "| c | f |\n")
+ (org-test-with-temp-text
+ (concat "| a | b |\n"
+ "| c | d |\n"
+ "| <point>e | f |\n")
+ (org-table-move-cell-up)
+ (buffer-string))))
+ (should (equal (concat "| a | f |\n"
+ "| c | b |\n"
+ "| e | d |\n")
+ (org-test-with-temp-text
+ (concat "| a | b |\n"
+ "| c | d |\n"
+ "| e |<point> f |\n")
+ (org-table-move-cell-up)
+ (org-table-move-cell-up)
+ (buffer-string))))
+ ;; Check for correct handling of hlines which should not change
+ ;; position on single cell moves.
+ (should (equal (concat "| c | b |\n"
+ "|---+---|\n"
+ "| a | d |\n"
+ "| e | f |\n")
+ (org-test-with-temp-text
+ (concat "| a | b |\n"
+ "|---+---|\n"
+ "| <point>c | d |\n"
+ "| e | f |\n")
+ (org-table-move-cell-up)
+ (buffer-string))))
+ (should (equal (concat "| a | f |\n"
+ "|---+---|\n"
+ "| c | b |\n"
+ "| e | d |\n")
+ (org-test-with-temp-text
+ (concat "| a | b |\n"
+ "|---+---|\n"
+ "| c | d |\n"
+ "| e | <point>f |\n")
+ (org-table-move-cell-up)
+ (org-table-move-cell-up)
+ (buffer-string))))
+ (should (equal (concat "| a | b |\n"
+ "|---+---|\n"
+ "| c | f |\n"
+ "| e | d |\n")
+ (org-test-with-temp-text
+ (concat "| a | b |\n"
+ "|---+---|\n"
+ "| c | d |\n"
+ "| e | <point>f |\n")
+ (org-table-move-cell-up)
+ (buffer-string))))
+ ;; Move single cell even without a final newline.
+ (should (equal (concat "| a | f |\n"
+ "|---+---|\n"
+ "| c | b |\n"
+ "| e | d |\n")
+ (org-test-with-temp-text
+ (concat "| a | b |\n"
+ "|---+---|\n"
+ "| c | d |\n"
+ "| e | <point>f |")
+ (org-table-move-cell-up)
+ (org-table-move-cell-up)
+ (buffer-string)))))
+
+(ert-deftest test-org-table/move-cell-right ()
+ "Test `org-table-move-cell-right' specifications."
+ ;; Error out when cell cannot be moved due to not in table, in the
+ ;; last col of the table, or is on a hline.
+ (should-error
+ (org-test-with-temp-text "not in\na table\n"
+ (org-table-move-cell-right)))
+ (should-error
+ (org-test-with-temp-text "| a |"
+ (org-table-move-cell-right)))
+ (should-error
+ (org-test-with-temp-text "| a |\n"
+ (org-table-move-cell-right)))
+ (should-error
+ (org-test-with-temp-text "| <point>a |\n| b |\n"
+ (org-table-move-cell-right)))
+ (should-error
+ (org-test-with-temp-text "| a | <point>b |\n| c | d |\n"
+ (org-table-move-cell-right)))
+ (should-error
+ (org-test-with-temp-text "| <point>a |\n|---|\n"
+ (org-table-move-cell-right)))
+ (should-error
+ (org-test-with-temp-text "|<point>---|\n| a |\n"
+ (org-table-move-cell-right)))
+ ;; Check for correct cell movement.
+ (should (equal (concat "| b | a | c |\n"
+ "| d | e | f |\n")
+ (org-test-with-temp-text
+ (concat "| <point>a | b | c |\n"
+ "| d | e | f |\n")
+ (org-table-move-cell-right)
+ (buffer-string))))
+ (should (equal (concat "| b | c | a |\n"
+ "| d | e | f |\n")
+ (org-test-with-temp-text
+ (concat "| <point>a | b | c |\n"
+ "| d | e | f |\n")
+ (org-table-move-cell-right)
+ (org-table-move-cell-right)
+ (buffer-string))))
+ (should (equal (concat "| a | b | c |\n"
+ "| e | f | d |\n")
+ (org-test-with-temp-text
+ (concat "| a | b | c |\n"
+ "| <point> d | e | f |\n")
+ (org-table-move-cell-right)
+ (org-table-move-cell-right)
+ (buffer-string))))
+ (should (equal (concat "| a | b | c |\n"
+ "| d | f | e |\n")
+ (org-test-with-temp-text
+ (concat "| a | b | c |\n"
+ "| d | <point>e | f |\n")
+ (org-table-move-cell-right)
+ (buffer-string))))
+ (should (equal (concat "| a | b | c |\n"
+ "|---+---+---|\n"
+ "| e | f | d |\n")
+ (org-test-with-temp-text
+ (concat "| a | b | c |\n"
+ "|---+---+---|\n"
+ "| <point>d | e | f |\n")
+ (org-table-move-cell-right)
+ (org-table-move-cell-right)
+ (buffer-string))))
+ ;; Move single cell even without a final newline.
+ (should (equal (concat "| a | b | c |\n"
+ "|---+---+---|\n"
+ "| e | d | f |\n")
+ (org-test-with-temp-text
+ (concat "| a | b | c |\n"
+ "|---+---+---|\n"
+ "| <point>d | e | f |")
+ (org-table-move-cell-right)
+ (buffer-string)))))
+
+(ert-deftest test-org-table/move-cell-left ()
+ "Test `org-table-move-cell-left' specifications."
+ ;; Error out when cell cannot be moved due to not in table, in the
+ ;; last col of the table, or is on a hline.
+ (should-error
+ (org-test-with-temp-text "not in\na table\n"
+ (org-table-move-cell-left)))
+ (should-error
+ (org-test-with-temp-text "| a |"
+ (org-table-move-cell-left)))
+ (should-error
+ (org-test-with-temp-text "| a |\n"
+ (org-table-move-cell-left)))
+ (should-error
+ (org-test-with-temp-text "| <point>a |\n| b |\n"
+ (org-table-move-cell-left)))
+ (should-error
+ (org-test-with-temp-text "| <point>a | b |\n| c | d |\n"
+ (org-table-move-cell-left)))
+ (should-error
+ (org-test-with-temp-text "| <point>a |\n|---|\n"
+ (org-table-move-cell-left)))
+ (should-error
+ (org-test-with-temp-text "|<point>---|\n| a |\n"
+ (org-table-move-cell-left)))
+ ;; Check for correct cell movement.
+ (should (equal (concat "| b | a | c |\n"
+ "| d | e | f |\n")
+ (org-test-with-temp-text
+ (concat "| a | <point>b | c |\n"
+ "| d | e | f |\n")
+ (org-table-move-cell-left)
+ (buffer-string))))
+ (should (equal (concat "| c | a | b |\n"
+ "| d | e | f |\n")
+ (org-test-with-temp-text
+ (concat "| a | b | <point>c |\n"
+ "| d | e | f |\n")
+ (org-table-move-cell-left)
+ (org-table-move-cell-left)
+ (buffer-string))))
+ (should (equal (concat "| a | b | c |\n"
+ "| f | d | e |\n")
+ (org-test-with-temp-text
+ (concat "| a | b | c |\n"
+ "| d | e | <point>f |\n")
+ (org-table-move-cell-left)
+ (org-table-move-cell-left)
+ (buffer-string))))
+ (should (equal (concat "| a | b | c |\n"
+ "| d | f | e |\n")
+ (org-test-with-temp-text
+ (concat "| a | b | c |\n"
+ "| d | e | <point>f |\n")
+ (org-table-move-cell-left)
+ (buffer-string))))
+ (should (equal (concat "| a | b | c |\n"
+ "|---+---+---|\n"
+ "| f | d | e |\n")
+ (org-test-with-temp-text
+ (concat "| a | b | c |\n"
+ "|---+---+---|\n"
+ "| d | e | <point>f |\n")
+ (org-table-move-cell-left)
+ (org-table-move-cell-left)
+ (buffer-string))))
+ ;; Move single cell even without a final newline.
+ (should (equal (concat "| a | b | c |\n"
+ "|---+---+---|\n"
+ "| e | d | f |\n")
+ (org-test-with-temp-text
+ (concat "| a | b | c |\n"
+ "|---+---+---|\n"
+ "| d | <point>e | f |")
+ (org-table-move-cell-left)
+ (buffer-string)))))
+
+
;;; Moving rows, moving columns
(ert-deftest test-org-table/move-row-down ()
diff --git a/testing/lisp/test-org.el b/testing/lisp/test-org.el
index 0b43dfd..29c6ed7 100644
--- a/testing/lisp/test-org.el
+++ b/testing/lisp/test-org.el
@@ -1474,6 +1474,18 @@
(replace-regexp-in-string
"\\( [.A-Za-z]+\\)\\( \\+[0-9][hdmwy]\\)?>" "" (buffer-string)
nil nil 1))))
+ ;; Clone repeating once in backward.
+ (should
+ (equal "\
+* H1\n<2015-06-21>
+* H1\n<2015-06-19>
+* H1\n<2015-06-17 +1w>
+"
+ (org-test-with-temp-text "* H1\n<2015-06-21 Sun +1w>"
+ (org-clone-subtree-with-time-shift 1 "-2d")
+ (replace-regexp-in-string
+ "\\( [.A-Za-z]+\\)\\( \\+[0-9][hdmwy]\\)?>" "" (buffer-string)
+ nil nil 1))))
;; Clone non-repeating zero times.
(should
(equal "\
@@ -2319,7 +2331,7 @@ SCHEDULED: <2014-03-04 tue.>"
;; Handle escape characters.
(should
(org-test-with-temp-text
- "* H1\n:PROPERTIES:\n:CUSTOM_ID: [%]\n:END:\n* H2\n[[#%5B%25%5D<point>]]"
+ "* H1\n:PROPERTIES:\n:CUSTOM_ID: [%]\n:END:\n* H2\n[[#[%\\]<point>]]"
(org-open-at-point)
(looking-at-p "\\* H1")))
;; Throw an error on false positives.
@@ -2413,13 +2425,9 @@ Foo Bar
(org-test-with-temp-text "[[*Test]]\n* TODO COMMENT Test"
(org-open-at-point)
(looking-at "\\* TODO COMMENT Test")))
- ;; Correctly un-hexify fuzzy links.
- (should
- (org-test-with-temp-text "* With space\n[[*With%20space][With space<point>]]"
- (org-open-at-point)
- (bobp)))
+ ;; Correctly un-escape fuzzy links.
(should
- (org-test-with-temp-text "* [1]\n[[*%5B1%5D<point>]]"
+ (org-test-with-temp-text "* [foo]\n[[*[foo\\]][With escaped characters]]"
(org-open-at-point)
(bobp)))
;; Match search strings containing newline characters, including
@@ -2443,81 +2451,6 @@ Foo Bar
(org-open-at-point 0))
(looking-at-p "line1")))))
-;;;; Link Escaping
-
-(ert-deftest test-org/org-link-escape-ascii-character ()
- "Escape an ascii character."
- (should
- (string=
- "%5B"
- (org-link-escape "["))))
-
-(ert-deftest test-org/org-link-escape-ascii-ctrl-character ()
- "Escape an ascii control character."
- (should
- (string=
- "%09"
- (org-link-escape "\t"))))
-
-(ert-deftest test-org/org-link-escape-multibyte-character ()
- "Escape an unicode multibyte character."
- (should
- (string=
- "%E2%82%AC"
- (org-link-escape "€"))))
-
-(ert-deftest test-org/org-link-escape-custom-table ()
- "Escape string with custom character table."
- (should
- (string=
- "Foo%3A%42ar%0A"
- (org-link-escape "Foo:Bar\n" '(?\: ?\B)))))
-
-(ert-deftest test-org/org-link-escape-custom-table-merge ()
- "Escape string with custom table merged with default table."
- (should
- (string=
- "%5BF%6F%6F%3A%42ar%0A%5D"
- (org-link-escape "[Foo:Bar\n]" '(?\: ?\B ?\o) t))))
-
-(ert-deftest test-org/org-link-unescape-ascii-character ()
- "Unescape an ascii character."
- (should
- (string=
- "["
- (org-link-unescape "%5B"))))
-
-(ert-deftest test-org/org-link-unescape-ascii-ctrl-character ()
- "Unescpae an ascii control character."
- (should
- (string=
- "\n"
- (org-link-unescape "%0A"))))
-
-(ert-deftest test-org/org-link-unescape-multibyte-character ()
- "Unescape unicode multibyte character."
- (should
- (string=
- "€"
- (org-link-unescape "%E2%82%AC"))))
-
-(ert-deftest test-org/org-link-unescape-ascii-extended-char ()
- "Unescape old style percent escaped character."
- (should
- (string=
- "àâçèéêîôùû"
- (decode-coding-string
- (org-link-unescape "%E0%E2%E7%E8%E9%EA%EE%F4%F9%FB") 'latin-1))))
-
-(ert-deftest test-org/org-link-escape-url-with-escaped-char ()
- "Escape and unescape a URL that includes an escaped char.
-http://article.gmane.org/gmane.emacs.orgmode/21459/"
- (should
- (string=
- "http://some.host.com/form?&id=blah%2Bblah25"
- (org-link-unescape
- (org-link-escape "http://some.host.com/form?&id=blah%2Bblah25")))))
-
;;;; Open at point
(ert-deftest test-org/open-at-point/keyword ()
@@ -2581,127 +2514,13 @@ http://article.gmane.org/gmane.emacs.orgmode/21459/"
(catch :result
(cl-letf (((symbol-function 'org-tags-view)
(lambda (&rest args) (throw :result t))))
- (org-open-at-point)
+ ;; When point isn't on a tag it's going to try other things,
+ ;; possibly trying to open attachments which will return an
+ ;; error if there isn't an attachment. Suppress that error.
+ (ignore-errors
+ (org-open-at-point))
nil)))))
-;;;; Stored links
-
-(ert-deftest test-org/store-link ()
- "Test `org-store-link' specifications."
- ;; On a headline, link to that headline. Use heading as the
- ;; description of the link.
- (should
- (let (org-store-link-props org-stored-links)
- (org-test-with-temp-text-in-file "* H1"
- (let ((file (buffer-file-name)))
- (equal (format "[[file:%s::*H1][H1]]" file)
- (org-store-link nil))))))
- ;; On a headline, remove any link from description.
- (should
- (let (org-store-link-props org-stored-links)
- (org-test-with-temp-text-in-file "* [[#l][d]]"
- (let ((file (buffer-file-name)))
- (equal (format "[[file:%s::*%s][d]]"
- file
- (org-link-escape "[[#l][d]]"))
- (org-store-link nil))))))
- (should
- (let (org-store-link-props org-stored-links)
- (org-test-with-temp-text-in-file "* [[l]]"
- (let ((file (buffer-file-name)))
- (equal (format "[[file:%s::*%s][l]]" file (org-link-escape "[[l]]"))
- (org-store-link nil))))))
- (should
- (let (org-store-link-props org-stored-links)
- (org-test-with-temp-text-in-file "* [[l1][d1]] [[l2][d2]]"
- (let ((file (buffer-file-name)))
- (equal (format "[[file:%s::*%s][d1 d2]]"
- file
- (org-link-escape "[[l1][d1]] [[l2][d2]]"))
- (org-store-link nil))))))
- ;; On a named element, link to that element.
- (should
- (let (org-store-link-props org-stored-links)
- (org-test-with-temp-text-in-file "#+NAME: foo\nParagraph"
- (let ((file (buffer-file-name)))
- (equal (format "[[file:%s::foo][foo]]" file)
- (org-store-link nil))))))
- ;; Store link to Org buffer, with context.
- (should
- (let ((org-stored-links nil)
- (org-id-link-to-org-use-id nil)
- (org-context-in-file-links t))
- (org-test-with-temp-text-in-file "* h1"
- (let ((file (buffer-file-name)))
- (equal (format "[[file:%s::*h1][h1]]" file)
- (org-store-link nil))))))
- ;; Store link to Org buffer, without context.
- (should
- (let ((org-stored-links nil)
- (org-id-link-to-org-use-id nil)
- (org-context-in-file-links nil))
- (org-test-with-temp-text-in-file "* h1"
- (let ((file (buffer-file-name)))
- (equal (format "[[file:%s][file:%s]]" file file)
- (org-store-link nil))))))
- ;; C-u prefix reverses `org-context-in-file-links' in Org buffer.
- (should
- (let ((org-stored-links nil)
- (org-id-link-to-org-use-id nil)
- (org-context-in-file-links nil))
- (org-test-with-temp-text-in-file "* h1"
- (let ((file (buffer-file-name)))
- (equal (format "[[file:%s::*h1][h1]]" file)
- (org-store-link '(4)))))))
- ;; A C-u C-u does *not* reverse `org-context-in-file-links' in Org
- ;; buffer.
- (should
- (let ((org-stored-links nil)
- (org-id-link-to-org-use-id nil)
- (org-context-in-file-links nil))
- (org-test-with-temp-text-in-file "* h1"
- (let ((file (buffer-file-name)))
- (equal (format "[[file:%s][file:%s]]" file file)
- (org-store-link '(16)))))))
- ;; Store file link to non-Org buffer, with context.
- (should
- (let ((org-stored-links nil)
- (org-context-in-file-links t))
- (org-test-with-temp-text-in-file "one\n<point>two"
- (fundamental-mode)
- (let ((file (buffer-file-name)))
- (equal (format "[[file:%s::one]]" file)
- (org-store-link nil))))))
- ;; Store file link to non-Org buffer, without context.
- (should
- (let ((org-stored-links nil)
- (org-context-in-file-links nil))
- (org-test-with-temp-text-in-file "one\n<point>two"
- (fundamental-mode)
- (let ((file (buffer-file-name)))
- (equal (format "[[file:%s][file:%s]]" file file)
- (org-store-link nil))))))
- ;; C-u prefix reverses `org-context-in-file-links' in non-Org
- ;; buffer.
- (should
- (let ((org-stored-links nil)
- (org-context-in-file-links nil))
- (org-test-with-temp-text-in-file "one\n<point>two"
- (fundamental-mode)
- (let ((file (buffer-file-name)))
- (equal (format "[[file:%s::one]]" file)
- (org-store-link '(4)))))))
- ;; A C-u C-u does *not* reverse `org-context-in-file-links' in
- ;; non-Org buffer.
- (should
- (let ((org-stored-links nil)
- (org-context-in-file-links nil))
- (org-test-with-temp-text-in-file "one\n<point>two"
- (fundamental-mode)
- (let ((file (buffer-file-name)))
- (equal (format "[[file:%s][file:%s]]" file file)
- (org-store-link '(16))))))))
-
;;; Node Properties
@@ -5043,7 +4862,7 @@ Paragraph<point>"
(ert-deftest test-org/buffer-property-keys ()
"Test `org-buffer-property-keys' specifications."
- ;; Retrieve properties accross siblings.
+ ;; Retrieve properties across siblings.
(should
(equal '("A" "B")
(org-test-with-temp-text "
@@ -5056,7 +4875,7 @@ Paragraph<point>"
:B: 1
:END:"
(org-buffer-property-keys))))
- ;; Retrieve properties accross children.
+ ;; Retrieve properties across children.
(should
(equal '("A" "B")
(org-test-with-temp-text "
@@ -5245,18 +5064,18 @@ Paragraph<point>"
(should
(equal
"1"
- (org-test-with-temp-text "* H\n:PROPERTIES:\n:A: 1\n:END:\n** <point>H2"
- (org-entry-get (point) "A" t))))
+ (org-test-with-temp-text "* H\n:PROPERTIES:\n:A: 1\n:END:\n** H2"
+ (org-entry-get (point-max) "A" t))))
(should
(equal
"1"
- (org-test-with-temp-text "* H\n:PROPERTIES:\n:A: 1\n:END:\n** <point>H2"
+ (org-test-with-temp-text "* H\n:PROPERTIES:\n:A: 1\n:END:\n** H2"
(let ((org-use-property-inheritance t))
- (org-entry-get (point) "A" 'selective)))))
+ (org-entry-get (point-max) "A" 'selective)))))
(should-not
- (org-test-with-temp-text "* H\n:PROPERTIES:\n:A: 1\n:END:\n** <point>H2"
+ (org-test-with-temp-text "* H\n:PROPERTIES:\n:A: 1\n:END:\n** H2"
(let ((org-use-property-inheritance nil))
- (org-entry-get (point) "A" 'selective))))
+ (org-entry-get (point-max) "A" 'selective))))
(should
(equal
"1 2"
@@ -5623,40 +5442,6 @@ Paragraph<point>"
(get-text-property (point) 'org-test)))))
-;;; Radio Targets
-
-(ert-deftest test-org/update-radio-target-regexp ()
- "Test `org-update-radio-target-regexp' specifications."
- ;; Properly update cache with no previous radio target regexp.
- (should
- (eq 'link
- (org-test-with-temp-text "radio\n\nParagraph\n\nradio"
- (save-excursion (goto-char (point-max)) (org-element-context))
- (insert "<<<")
- (search-forward "o")
- (insert ">>>")
- (org-update-radio-target-regexp)
- (goto-char (point-max))
- (org-element-type (org-element-context)))))
- ;; Properly update cache with previous radio target regexp.
- (should
- (eq 'link
- (org-test-with-temp-text "radio\n\nParagraph\n\nradio"
- (save-excursion (goto-char (point-max)) (org-element-context))
- (insert "<<<")
- (search-forward "o")
- (insert ">>>")
- (org-update-radio-target-regexp)
- (search-backward "r")
- (delete-char 5)
- (insert "new")
- (org-update-radio-target-regexp)
- (goto-char (point-max))
- (delete-region (line-beginning-position) (point))
- (insert "new")
- (org-element-type (org-element-context))))))
-
-
;;; Refile
(ert-deftest test-org/refile-get-targets ()
@@ -6394,11 +6179,11 @@ Paragraph<point>"
(goto-char (point-max))
(org-set-tags-command)))
(buffer-string))))
- ;; With a non-nil prefix argument, align all tags in the buffer.
+ ;; With a C-u prefix argument, align all tags in the buffer.
(should
(equal "* H1 :foo:\n* H2 :bar:"
(org-test-with-temp-text "* H1 :foo:\n* H2 :bar:"
- (let ((org-tags-column 1)) (org-set-tags-command t))
+ (let ((org-tags-column 1)) (org-set-tags-command '(4)))
(buffer-string)))))
(ert-deftest test-org/toggle-tag ()
@@ -6473,7 +6258,7 @@ Paragraph<point>"
(ert-deftest test-org/tags-expand ()
"Test `org-tags-expand' specifications."
- ;; Expand tag groups as a regexp enclosed withing curly brackets.
+ ;; Expand tag groups as a regexp enclosed within curly brackets.
(should
(equal "{\\<[ABC]\\>}"
(org-test-with-temp-text "#+TAGS: [ A : B C ]"
@@ -7039,46 +6824,44 @@ CLOCK: [2012-03-29 Thu 10:00]--[2012-03-29 Thu 16:40] => 6:40"
(should-not (org-timestamp-from-string "<2012-03-29"))
;; Otherwise, return a valid Org timestamp object.
(should
- (equal "<2012-03-29 Thu>"
- (let ((system-time-locale "en_US"))
- (org-element-interpret-data
- (org-timestamp-from-string "<2012-03-29 Thu>")))))
+ (string-match-p "<2012-03-29 .+>"
+ (org-element-interpret-data
+ (org-timestamp-from-string "<2012-03-29 Thu>"))))
(should
- (equal "[2014-03-04 Tue]"
- (let ((system-time-locale "en_US"))
- (org-element-interpret-data
- (org-timestamp-from-string "[2014-03-04 Tue]"))))))
+ (string-match-p "[2014-03-04 .+]"
+ (org-element-interpret-data
+ (org-timestamp-from-string "[2014-03-04 Tue]")))))
(ert-deftest test-org/timestamp-from-time ()
"Test `org-timestamp-from-time' specifications."
;; Standard test.
(should
- (equal "<2012-03-29 Thu>"
- (let ((system-time-locale "en_US"))
- (org-element-interpret-data
- (org-timestamp-from-time
- (apply #'encode-time
- (org-parse-time-string "<2012-03-29 Thu 16:40>")))))))
+ (string-match-p
+ "<2012-03-29 .+>"
+ (org-element-interpret-data
+ (org-timestamp-from-time
+ (apply #'encode-time
+ (org-parse-time-string "<2012-03-29 Thu 16:40>"))))))
;; When optional argument WITH-TIME is non-nil, provide time
;; information.
(should
- (equal "<2012-03-29 Thu 16:40>"
- (let ((system-time-locale "en_US"))
- (org-element-interpret-data
- (org-timestamp-from-time
- (apply #'encode-time
- (org-parse-time-string "<2012-03-29 Thu 16:40>"))
- t)))))
+ (string-match-p
+ "<2012-03-29 .+ 16:40>"
+ (org-element-interpret-data
+ (org-timestamp-from-time
+ (apply #'encode-time
+ (org-parse-time-string "<2012-03-29 Thu 16:40>"))
+ t))))
;; When optional argument INACTIVE is non-nil, return an inactive
;; timestamp.
(should
- (equal "[2012-03-29 Thu]"
- (let ((system-time-locale "en_US"))
- (org-element-interpret-data
- (org-timestamp-from-time
- (apply #'encode-time
- (org-parse-time-string "<2012-03-29 Thu 16:40>"))
- nil t))))))
+ (string-match-p
+ "[2012-03-29 .+]"
+ (org-element-interpret-data
+ (org-timestamp-from-time
+ (apply #'encode-time
+ (org-parse-time-string "<2012-03-29 Thu 16:40>"))
+ nil t)))))
(ert-deftest test-org/timestamp-to-time ()
"Test `org-timestamp-to-time' specifications."
diff --git a/testing/lisp/test-ox.el b/testing/lisp/test-ox.el
index b81449b..81f557a 100644
--- a/testing/lisp/test-ox.el
+++ b/testing/lisp/test-ox.el
@@ -1361,7 +1361,7 @@ Footnotes[fn:2], foot[fn:test] and [fn:inline:inline footnote]
org-test-dir)
(narrow-to-region (point) (point-max))
(org-export-expand-include-keyword)
- (eq 1 (org-current-level))))
+ (eq 2 (org-current-level))))
;; If :minlevel is present do not alter it.
(should
(org-test-with-temp-text
@@ -2012,8 +2012,8 @@ In particular, structure of the document mustn't be altered after
comments removal."
(should
(equal "Para1\n\nPara2\n"
- (org-test-with-temp-text "
-Para1
+ (org-test-with-temp-text
+ "Para1
# Comment
# Comment
@@ -2021,15 +2021,15 @@ Para2"
(org-export-as (org-test-default-backend)))))
(should
(equal "Para1\n\nPara2\n"
- (org-test-with-temp-text "
-Para1
+ (org-test-with-temp-text
+ "Para1
# Comment
Para2"
(org-export-as (org-test-default-backend)))))
(should
(equal "[fn:1] Para1\n\n\nPara2\n"
- (org-test-with-temp-text "
-\[fn:1] Para1
+ (org-test-with-temp-text
+ "[fn:1] Para1
# Inside definition
@@ -2038,8 +2038,8 @@ Para2"
(org-export-as (org-test-default-backend)))))
(should
(equal "[fn:1] Para1\n\nPara2\n"
- (org-test-with-temp-text "
-\[fn:1] Para1
+ (org-test-with-temp-text
+ "[fn:1] Para1
# Inside definition
@@ -2049,24 +2049,24 @@ Para2"
(org-export-as (org-test-default-backend)))))
(should
(equal "[fn:1] Para1\n\nPara2\n"
- (org-test-with-temp-text "
-\[fn:1] Para1
+ (org-test-with-temp-text
+ "[fn:1] Para1
# Inside definition
Para2"
(org-export-as (org-test-default-backend)))))
(should
(equal "[fn:1] Para1\n\nPara2\n"
- (org-test-with-temp-text "
-\[fn:1] Para1
+ (org-test-with-temp-text
+ "[fn:1] Para1
# Inside definition
Para2"
(org-export-as (org-test-default-backend)))))
(should
(equal "- item 1\n\n- item 2\n"
- (org-test-with-temp-text "
-- item 1
+ (org-test-with-temp-text
+ "- item 1
# Comment
@@ -3206,6 +3206,40 @@ Paragraph[fn:1][fn:2][fn:lbl3:C<<target>>][[test]][[target]]
(lambda (link) (org-export-resolve-fuzzy-link link info))
info t))))
+(ert-deftest test-org-export/resolve-link ()
+ "Test `org-export-resolve-link' specifications."
+ (should
+ ;; Match ID links
+ (equal
+ "Headline1"
+ (org-test-with-parsed-data "* Headline1
+:PROPERTIES:
+:ID: aaaa
+:END:
+* Headline2"
+ (org-element-property
+ :raw-value (org-export-resolve-link "#aaaa" info)))))
+ ;; Match Custom ID links
+ (should
+ (equal
+ "Headline1"
+ (org-test-with-parsed-data
+ "* Headline1
+:PROPERTIES:
+:CUSTOM_ID: test
+:END:
+* Headline2"
+ (org-element-property
+ :raw-value (org-export-resolve-link "#test" info)))))
+ ;; Match fuzzy links
+ (should
+ (equal
+ "B"
+ (org-test-with-parsed-data
+ "* A\n* B\n* C"
+ (org-element-property
+ :raw-value (org-export-resolve-link "B" info))))))
+
(defun test-org-gen-loc-list(text type)
(org-test-with-parsed-data text
(org-element-map tree type
@@ -3519,9 +3553,9 @@ Another text. (ref:text)
(org-element-type
(org-export-resolve-fuzzy-link
(org-element-map tree 'link 'identity info t) info)))))
- ;; Handle url-encoded fuzzy links.
+ ;; Handle escaped fuzzy links.
(should
- (org-test-with-parsed-data "* A B\n[[A%20B]]"
+ (org-test-with-parsed-data "* [foo]\n[[[foo\\]]]"
(org-export-resolve-fuzzy-link
(org-element-map tree 'link #'identity info t) info))))
@@ -4619,6 +4653,56 @@ Another text. (ref:text)
(let ((scope (org-element-map tree 'headline #'identity info t)))
(mapcar (lambda (h) (org-element-property :raw-value h))
(org-export-collect-headlines info nil scope))))))
+ ;; Collect headlines from a scope specified by a fuzzy match
+ (should
+ (equal '("H3" "H4")
+ (org-test-with-parsed-data "* HA
+** H1
+** H2
+* Target
+ :PROPERTIES:
+ :CUSTOM_ID: TargetSection
+ :END:
+** H3
+** H4
+* HB
+** H5
+"
+ (mapcar
+ (lambda (h) (org-element-property :raw-value h))
+ (org-export-collect-headlines
+ info
+ nil
+ (org-export-resolve-fuzzy-link
+ (with-temp-buffer
+ (save-excursion (insert "[[Target]]"))
+ (org-element-link-parser))
+ info))))))
+ ;; Collect headlines from a scope specified by CUSTOM_ID
+ (should
+ (equal '("H3" "H4")
+ (org-test-with-parsed-data "* Not this section
+** H1
+** H2
+* Target
+ :PROPERTIES:
+ :CUSTOM_ID: TargetSection
+ :END:
+** H3
+** H4
+* Another
+** H5
+"
+ (mapcar
+ (lambda (h) (org-element-property :raw-value h))
+ (org-export-collect-headlines
+ info
+ nil
+ (org-export-resolve-id-link
+ (with-temp-buffer
+ (save-excursion (insert "[[#TargetSection]]"))
+ (org-element-link-parser))
+ info))))))
;; When collecting locally, optional level is relative.
(should
(equal '("H2")
diff --git a/testing/lisp/test-property-inheritance.el b/testing/lisp/test-property-inheritance.el
index 0f803e5..1d0dcfb 100644
--- a/testing/lisp/test-property-inheritance.el
+++ b/testing/lisp/test-property-inheritance.el
@@ -1,4 +1,4 @@
-;;; test-ob-R.el --- tests for ob-R.el
+;;; test-property-inheritance.el --- tests for property-inheritance.el
;; Copyright (c) 2011-2014, 2019 Eric Schulte
;; Authors: Eric Schulte
@@ -47,4 +47,4 @@
(provide 'test-ob-R)
-;;; test-ob-R.el ends here
+;;; test-property-inheritance.el ends here
diff --git a/testing/org-test.el b/testing/org-test.el
index 39c3464..c3e21eb 100644
--- a/testing/org-test.el
+++ b/testing/org-test.el
@@ -87,6 +87,9 @@ org-test searches this directory up the directory tree.")
(defconst org-test-no-heading-file
(expand-file-name "no-heading.org" org-test-example-dir))
+(defconst org-test-attachments-file
+ (expand-file-name "attachments.org" org-test-example-dir))
+
(defconst org-test-link-in-heading-file
(expand-file-name "link-in-heading.org" org-test-dir))
@@ -146,7 +149,8 @@ currently executed.")
(declare (indent 1))
`(let* ((my-file (or ,file org-test-file))
(visited-p (get-file-buffer my-file))
- to-be-removed)
+ to-be-removed
+ results)
(save-window-excursion
(save-match-data
(find-file my-file)
@@ -160,9 +164,10 @@ currently executed.")
(org-show-subtree)
(org-show-all '(blocks)))
(error nil))
- (save-restriction ,@body)))
+ (setq results (save-restriction ,@body))))
(unless visited-p
- (kill-buffer to-be-removed))))
+ (kill-buffer to-be-removed))
+ results))
(def-edebug-spec org-test-in-example-file (form body))
(defmacro org-test-at-marker (file marker &rest body)
@@ -198,20 +203,30 @@ otherwise place the point at the beginning of the inserted text."
(def-edebug-spec org-test-with-temp-text (form body))
(defmacro org-test-with-temp-text-in-file (text &rest body)
- "Run body in a temporary file buffer with Org mode as the active mode."
+ "Run body in a temporary file buffer with Org mode as the active mode.
+If the string \"<point>\" appears in TEXT then remove it and
+place the point there before running BODY, otherwise place the
+point at the beginning of the buffer."
(declare (indent 1))
- (let ((results (cl-gensym)))
- `(let ((file (make-temp-file "org-test"))
- (kill-buffer-query-functions nil)
- (inside-text (if (stringp ,text) ,text (eval ,text)))
- ,results)
- (with-temp-file file (insert inside-text))
- (find-file file)
- (org-mode)
- (setq ,results (progn ,@body))
- (save-buffer) (kill-buffer (current-buffer))
- (delete-file file)
- ,results)))
+ `(let ((file (make-temp-file "org-test"))
+ (inside-text (if (stringp ,text) ,text (eval ,text)))
+ buffer)
+ (with-temp-file file (insert inside-text))
+ (unwind-protect
+ (progn
+ (setq buffer (find-file file))
+ (when (re-search-forward "<point>" nil t)
+ (replace-match ""))
+ (org-mode)
+ (progn ,@body))
+ (let ((kill-buffer-query-functions nil))
+ (when buffer
+ (set-buffer buffer)
+ ;; Ignore changes, we're deleting the file in the next step
+ ;; anyways.
+ (set-buffer-modified-p nil)
+ (kill-buffer))
+ (delete-file file)))))
(def-edebug-spec org-test-with-temp-text-in-file (form body))
(defun org-test-table-target-expect (target &optional expect laps