From dc39338eff39300127edddbe27f468b69d84ac24 Mon Sep 17 00:00:00 2001 From: Andreas Gerler Date: Sat, 20 Feb 2016 15:57:25 +0100 Subject: [PATCH] update org-mode. --- elpa/org-20150629/ob-C.el | 243 - elpa/org-20150629/org-element.el | 5024 -------- elpa/org-20150629/org-entities.el | 619 - elpa/org-20150629/org-pkg.el | 3 - elpa/org-20150629/org-src.el | 961 -- elpa/org-20160215.signed | 1 + elpa/{org-20150629 => org-20160215}/COPYING | 0 .../README_ELPA | 0 elpa/{org-20150629 => org-20160215}/dir | 0 elpa/org-20160215/etc/ORG-NEWS | 3119 +++++ .../etc/styles/OrgOdtContentTemplate.xml | 0 .../etc/styles/OrgOdtStyles.xml | 20 + .../etc/styles/README | 0 elpa/org-20160215/ob-C.el | 439 + elpa/org-20160215/ob-J.el | 179 + elpa/{org-20150629 => org-20160215}/ob-R.el | 208 +- elpa/org-20160215/ob-abc.el | 94 + .../ob-asymptote.el | 5 +- elpa/{org-20150629 => org-20160215}/ob-awk.el | 25 +- .../{org-20150629 => org-20160215}/ob-calc.el | 2 +- .../ob-clojure.el | 90 +- .../ob-comint.el | 85 +- elpa/org-20160215/ob-coq.el | 77 + .../{org-20150629 => org-20160215}/ob-core.el | 1100 +- elpa/{org-20150629 => org-20160215}/ob-css.el | 2 +- .../ob-ditaa.el | 20 +- elpa/{org-20150629 => org-20160215}/ob-dot.el | 8 +- elpa/org-20160215/ob-ebnf.el | 85 + .../ob-emacs-lisp.el | 7 +- .../{org-20150629 => org-20160215}/ob-eval.el | 9 +- elpa/{org-20150629 => org-20160215}/ob-exp.el | 357 +- elpa/org-20160215/ob-forth.el | 86 + .../ob-fortran.el | 17 +- .../ob-gnuplot.el | 23 +- elpa/org-20160215/ob-groovy.el | 118 + .../ob-haskell.el | 10 +- elpa/{org-20150629 => org-20160215}/ob-io.el | 16 +- .../{org-20150629 => org-20160215}/ob-java.el | 24 +- elpa/{org-20150629 => org-20160215}/ob-js.el | 9 +- .../{org-20150629 => org-20160215}/ob-keys.el | 3 +- .../ob-latex.el | 100 +- .../ob-ledger.el | 2 +- .../ob-lilypond.el | 155 +- .../{org-20150629 => org-20160215}/ob-lisp.el | 36 +- elpa/{org-20150629 => org-20160215}/ob-lob.el | 39 +- .../ob-makefile.el | 2 +- .../ob-matlab.el | 2 +- .../ob-maxima.el | 11 +- .../ob-mscgen.el | 2 +- .../ob-ocaml.el | 65 +- .../ob-octave.el | 22 +- elpa/{org-20150629 => org-20160215}/ob-org.el | 2 +- .../{org-20150629 => org-20160215}/ob-perl.el | 6 +- .../ob-picolisp.el | 2 +- .../ob-plantuml.el | 2 +- elpa/org-20160215/ob-processing.el | 197 + .../ob-python.el | 22 +- elpa/{org-20150629 => org-20160215}/ob-ref.el | 214 +- .../{org-20150629 => org-20160215}/ob-ruby.el | 55 +- .../{org-20150629 => org-20160215}/ob-sass.el | 2 +- .../ob-scala.el | 16 +- .../ob-scheme.el | 27 +- .../ob-screen.el | 2 +- elpa/org-20160215/ob-sed.el | 107 + .../ob-sh.el => org-20160215/ob-shell.el} | 136 +- .../{org-20150629 => org-20160215}/ob-shen.el | 2 +- elpa/{org-20150629 => org-20160215}/ob-sql.el | 30 +- .../ob-sqlite.el | 4 +- elpa/org-20160215/ob-stan.el | 0 .../ob-table.el | 36 +- .../ob-tangle.el | 215 +- elpa/{org-20150629 => org-20160215}/ob.el | 2 +- elpa/{org-20150629 => org-20160215}/org | 5810 +++++---- .../org-agenda.el | 1060 +- .../org-archive.el | 100 +- .../org-attach.el | 33 +- .../org-autoloads.el | 115 +- .../org-bbdb.el | 4 +- .../org-bibtex.el | 55 +- .../org-capture.el | 104 +- .../org-clock.el | 782 +- .../org-colview.el | 618 +- .../org-compat.el | 56 +- .../org-crypt.el | 17 +- .../org-ctags.el | 19 +- .../org-datetree.el | 74 +- .../org-docview.el | 23 +- elpa/org-20160215/org-element.el | 6042 +++++++++ elpa/org-20160215/org-entities.el | 611 + .../org-eshell.el | 2 +- .../org-faces.el | 113 +- .../org-feed.el | 26 +- .../org-footnote.el | 689 +- .../org-gnus.el | 20 +- .../org-habit.el | 68 +- elpa/{org-20150629 => org-20160215}/org-id.el | 5 +- .../org-indent.el | 195 +- .../org-info.el | 34 +- .../org-inlinetask.el | 26 +- .../org-install.el | 0 .../{org-20150629 => org-20160215}/org-irc.el | 6 +- elpa/org-20160215/org-lint.el | 1151 ++ .../org-list.el | 551 +- .../org-loaddefs.el | 609 +- .../org-macro.el | 153 +- .../org-macs.el | 26 +- .../{org-20150629 => org-20160215}/org-mhe.el | 2 +- .../org-mobile.el | 12 +- .../org-mouse.el | 30 +- .../org-pcomplete.el | 29 +- elpa/org-20160215/org-pkg.el | 3 + .../org-plot.el | 143 +- .../org-protocol.el | 28 +- .../org-rmail.el | 4 +- elpa/org-20160215/org-src.el | 979 ++ .../org-table.el | 4159 +++--- .../org-timer.el | 280 +- .../org-version.el | 4 +- .../{org-20150629 => org-20160215}/org-w3m.el | 2 +- elpa/{org-20150629 => org-20160215}/org.el | 10539 +++++++++------- .../orgcard.pdf | Bin 124864 -> 124864 bytes .../ox-ascii.el | 765 +- .../ox-beamer.el | 257 +- .../{org-20150629 => org-20160215}/ox-html.el | 1449 ++- .../ox-icalendar.el | 359 +- .../ox-latex.el | 1966 ++- elpa/{org-20150629 => org-20160215}/ox-man.el | 128 +- elpa/{org-20150629 => org-20160215}/ox-md.el | 189 +- elpa/{org-20150629 => org-20160215}/ox-odt.el | 762 +- elpa/{org-20150629 => org-20160215}/ox-org.el | 96 +- .../ox-publish.el | 218 +- .../ox-texinfo.el | 475 +- elpa/{org-20150629 => org-20160215}/ox.el | 2996 +++-- init.el | 4 +- 134 files changed, 35875 insertions(+), 23803 deletions(-) delete mode 100644 elpa/org-20150629/ob-C.el delete mode 100644 elpa/org-20150629/org-element.el delete mode 100644 elpa/org-20150629/org-entities.el delete mode 100644 elpa/org-20150629/org-pkg.el delete mode 100644 elpa/org-20150629/org-src.el create mode 100644 elpa/org-20160215.signed rename elpa/{org-20150629 => org-20160215}/COPYING (100%) rename elpa/{org-20150629 => org-20160215}/README_ELPA (100%) rename elpa/{org-20150629 => org-20160215}/dir (100%) create mode 100644 elpa/org-20160215/etc/ORG-NEWS rename elpa/{org-20150629 => org-20160215}/etc/styles/OrgOdtContentTemplate.xml (100%) rename elpa/{org-20150629 => org-20160215}/etc/styles/OrgOdtStyles.xml (97%) rename elpa/{org-20150629 => org-20160215}/etc/styles/README (100%) create mode 100644 elpa/org-20160215/ob-C.el create mode 100644 elpa/org-20160215/ob-J.el rename elpa/{org-20150629 => org-20160215}/ob-R.el (67%) create mode 100644 elpa/org-20160215/ob-abc.el rename elpa/{org-20150629 => org-20160215}/ob-asymptote.el (96%) rename elpa/{org-20150629 => org-20160215}/ob-awk.el (85%) rename elpa/{org-20150629 => org-20160215}/ob-calc.el (98%) rename elpa/{org-20150629 => org-20160215}/ob-clojure.el (50%) rename elpa/{org-20150629 => org-20160215}/ob-comint.el (73%) create mode 100644 elpa/org-20160215/ob-coq.el rename elpa/{org-20150629 => org-20160215}/ob-core.el (76%) rename elpa/{org-20150629 => org-20160215}/ob-css.el (96%) rename elpa/{org-20150629 => org-20160215}/ob-ditaa.el (92%) rename elpa/{org-20150629 => org-20160215}/ob-dot.el (96%) create mode 100644 elpa/org-20160215/ob-ebnf.el rename elpa/{org-20150629 => org-20160215}/ob-emacs-lisp.el (93%) rename elpa/{org-20150629 => org-20160215}/ob-eval.el (93%) rename elpa/{org-20150629 => org-20160215}/ob-exp.el (55%) create mode 100644 elpa/org-20160215/ob-forth.el rename elpa/{org-20150629 => org-20160215}/ob-fortran.el (92%) rename elpa/{org-20150629 => org-20160215}/ob-gnuplot.el (94%) create mode 100644 elpa/org-20160215/ob-groovy.el rename elpa/{org-20150629 => org-20160215}/ob-haskell.el (95%) rename elpa/{org-20150629 => org-20160215}/ob-io.el (88%) rename elpa/{org-20150629 => org-20160215}/ob-java.el (80%) rename elpa/{org-20150629 => org-20160215}/ob-js.el (95%) rename elpa/{org-20150629 => org-20160215}/ob-keys.el (97%) rename elpa/{org-20150629 => org-20160215}/ob-latex.el (86%) rename elpa/{org-20150629 => org-20160215}/ob-ledger.el (97%) rename elpa/{org-20150629 => org-20160215}/ob-lilypond.el (77%) rename elpa/{org-20150629 => org-20160215}/ob-lisp.el (76%) rename elpa/{org-20150629 => org-20160215}/ob-lob.el (82%) rename elpa/{org-20150629 => org-20160215}/ob-makefile.el (96%) rename elpa/{org-20150629 => org-20160215}/ob-matlab.el (95%) rename elpa/{org-20150629 => org-20160215}/ob-maxima.el (91%) rename elpa/{org-20150629 => org-20160215}/ob-mscgen.el (97%) rename elpa/{org-20150629 => org-20160215}/ob-ocaml.el (78%) rename elpa/{org-20150629 => org-20160215}/ob-octave.el (93%) rename elpa/{org-20150629 => org-20160215}/ob-org.el (97%) rename elpa/{org-20150629 => org-20160215}/ob-perl.el (96%) rename elpa/{org-20150629 => org-20160215}/ob-picolisp.el (99%) rename elpa/{org-20150629 => org-20160215}/ob-plantuml.el (98%) create mode 100644 elpa/org-20160215/ob-processing.el rename elpa/{org-20150629 => org-20160215}/ob-python.el (95%) rename elpa/{org-20150629 => org-20160215}/ob-ref.el (57%) rename elpa/{org-20150629 => org-20160215}/ob-ruby.el (86%) rename elpa/{org-20150629 => org-20160215}/ob-sass.el (97%) rename elpa/{org-20150629 => org-20160215}/ob-scala.el (88%) rename elpa/{org-20150629 => org-20160215}/ob-scheme.el (88%) rename elpa/{org-20150629 => org-20160215}/ob-screen.el (98%) create mode 100644 elpa/org-20160215/ob-sed.el rename elpa/{org-20150629/ob-sh.el => org-20160215/ob-shell.el} (64%) rename elpa/{org-20150629 => org-20160215}/ob-shen.el (97%) rename elpa/{org-20150629 => org-20160215}/ob-sql.el (88%) rename elpa/{org-20150629 => org-20160215}/ob-sqlite.el (97%) create mode 100644 elpa/org-20160215/ob-stan.el rename elpa/{org-20150629 => org-20160215}/ob-table.el (84%) rename elpa/{org-20150629 => org-20160215}/ob-tangle.el (78%) rename elpa/{org-20150629 => org-20160215}/ob.el (95%) rename elpa/{org-20150629 => org-20160215}/org (87%) rename elpa/{org-20150629 => org-20160215}/org-agenda.el (93%) rename elpa/{org-20150629 => org-20160215}/org-archive.el (86%) rename elpa/{org-20150629 => org-20160215}/org-attach.el (94%) rename elpa/{org-20150629 => org-20160215}/org-autoloads.el (85%) rename elpa/{org-20150629 => org-20160215}/org-bbdb.el (99%) rename elpa/{org-20150629 => org-20160215}/org-bibtex.el (95%) rename elpa/{org-20150629 => org-20160215}/org-capture.el (96%) rename elpa/{org-20150629 => org-20160215}/org-clock.el (84%) rename elpa/{org-20150629 => org-20160215}/org-colview.el (79%) rename elpa/{org-20150629 => org-20160215}/org-compat.el (93%) rename elpa/{org-20150629 => org-20160215}/org-crypt.el (94%) rename elpa/{org-20150629 => org-20160215}/org-ctags.el (97%) rename elpa/{org-20150629 => org-20160215}/org-datetree.el (82%) rename elpa/{org-20150629 => org-20160215}/org-docview.el (84%) create mode 100644 elpa/org-20160215/org-element.el create mode 100644 elpa/org-20160215/org-entities.el rename elpa/{org-20150629 => org-20160215}/org-eshell.el (97%) rename elpa/{org-20150629 => org-20160215}/org-faces.el (93%) rename elpa/{org-20150629 => org-20160215}/org-feed.el (97%) rename elpa/{org-20150629 => org-20160215}/org-footnote.el (59%) rename elpa/{org-20150629 => org-20160215}/org-gnus.el (96%) rename elpa/{org-20150629 => org-20160215}/org-habit.el (87%) rename elpa/{org-20150629 => org-20160215}/org-id.el (99%) rename elpa/{org-20150629 => org-20160215}/org-indent.el (71%) rename elpa/{org-20150629 => org-20160215}/org-info.el (68%) rename elpa/{org-20150629 => org-20160215}/org-inlinetask.el (93%) rename elpa/{org-20150629 => org-20160215}/org-install.el (100%) rename elpa/{org-20150629 => org-20160215}/org-irc.el (98%) create mode 100644 elpa/org-20160215/org-lint.el rename elpa/{org-20150629 => org-20160215}/org-list.el (91%) rename elpa/{org-20150629 => org-20160215}/org-loaddefs.el (86%) rename elpa/{org-20150629 => org-20160215}/org-macro.el (60%) rename elpa/{org-20150629 => org-20160215}/org-macs.el (95%) rename elpa/{org-20150629 => org-20160215}/org-mhe.el (99%) rename elpa/{org-20150629 => org-20160215}/org-mobile.el (99%) rename elpa/{org-20150629 => org-20160215}/org-mouse.el (98%) rename elpa/{org-20150629 => org-20160215}/org-pcomplete.el (94%) create mode 100644 elpa/org-20160215/org-pkg.el rename elpa/{org-20150629 => org-20160215}/org-plot.el (77%) rename elpa/{org-20150629 => org-20160215}/org-protocol.el (96%) rename elpa/{org-20150629 => org-20160215}/org-rmail.el (96%) create mode 100644 elpa/org-20160215/org-src.el rename elpa/{org-20150629 => org-20160215}/org-table.el (58%) rename elpa/{org-20150629 => org-20160215}/org-timer.el (63%) rename elpa/{org-20150629 => org-20160215}/org-version.el (87%) rename elpa/{org-20150629 => org-20160215}/org-w3m.el (99%) rename elpa/{org-20150629 => org-20160215}/org.el (78%) rename elpa/{org-20150629 => org-20160215}/orgcard.pdf (99%) rename elpa/{org-20150629 => org-20160215}/ox-ascii.el (74%) rename elpa/{org-20150629 => org-20160215}/ox-beamer.el (86%) rename elpa/{org-20150629 => org-20160215}/ox-html.el (74%) rename elpa/{org-20150629 => org-20160215}/ox-icalendar.el (78%) rename elpa/{org-20150629 => org-20160215}/ox-latex.el (61%) rename elpa/{org-20150629 => org-20160215}/ox-man.el (92%) rename elpa/{org-20150629 => org-20160215}/ox-md.el (75%) rename elpa/{org-20150629 => org-20160215}/ox-odt.el (90%) rename elpa/{org-20150629 => org-20160215}/ox-org.el (75%) rename elpa/{org-20150629 => org-20160215}/ox-publish.el (88%) rename elpa/{org-20150629 => org-20160215}/ox-texinfo.el (80%) rename elpa/{org-20150629 => org-20160215}/ox.el (74%) diff --git a/elpa/org-20150629/ob-C.el b/elpa/org-20150629/ob-C.el deleted file mode 100644 index c460be32..00000000 --- a/elpa/org-20150629/ob-C.el +++ /dev/null @@ -1,243 +0,0 @@ -;;; ob-C.el --- org-babel functions for C and similar languages - -;; Copyright (C) 2010-2014 Free Software Foundation, Inc. - -;; Author: Eric Schulte -;; Keywords: literate programming, reproducible research -;; Homepage: http://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 . - -;;; Commentary: - -;; Org-Babel support for evaluating C code. -;; -;; very limited implementation: -;; - currently only support :results output -;; - not much in the way of error feedback - -;;; Code: -(require 'ob) -(require 'cc-mode) - -(declare-function org-entry-get "org" - (pom property &optional inherit literal-nil)) - - -(defvar org-babel-tangle-lang-exts) -(add-to-list 'org-babel-tangle-lang-exts '("C++" . "cpp")) - -(defvar org-babel-default-header-args:C '()) - -(defvar org-babel-C-compiler "gcc" - "Command used to compile a C source code file into an -executable.") - -(defvar org-babel-C++-compiler "g++" - "Command used to compile a C++ source code file into an -executable.") - -(defvar org-babel-c-variant nil - "Internal variable used to hold which type of C (e.g. C or C++) -is currently being evaluated.") - -(defun org-babel-execute:cpp (body params) - "Execute BODY according to PARAMS. -This function calls `org-babel-execute:C++'." - (org-babel-execute:C++ body params)) - -(defun org-babel-execute:C++ (body params) - "Execute a block of C++ code with org-babel. -This function is called by `org-babel-execute-src-block'." - (let ((org-babel-c-variant 'cpp)) (org-babel-C-execute body params))) - -(defun org-babel-expand-body:C++ (body params) - "Expand a block of C++ code with org-babel according to it's -header arguments (calls `org-babel-C-expand')." - (let ((org-babel-c-variant 'cpp)) (org-babel-C-expand body params))) - -(defun org-babel-execute:C (body params) - "Execute a block of C code with org-babel. -This function is called by `org-babel-execute-src-block'." - (let ((org-babel-c-variant 'c)) (org-babel-C-execute body params))) - -(defun org-babel-expand-body:c (body params) - "Expand a block of C code with org-babel according to it's -header arguments (calls `org-babel-C-expand')." - (let ((org-babel-c-variant 'c)) (org-babel-C-expand body params))) - -(defun org-babel-C-execute (body params) - "This function should only be called by `org-babel-execute:C' -or `org-babel-execute:C++'." - (let* ((tmp-src-file (org-babel-temp-file - "C-src-" - (cond - ((equal org-babel-c-variant 'c) ".c") - ((equal org-babel-c-variant 'cpp) ".cpp")))) - (tmp-bin-file (org-babel-temp-file "C-bin-" org-babel-exeext)) - (cmdline (cdr (assoc :cmdline params))) - (flags (cdr (assoc :flags params))) - (full-body (org-babel-C-expand body params)) - (compile - (progn - (with-temp-file tmp-src-file (insert full-body)) - (org-babel-eval - (format "%s -o %s %s %s" - (cond - ((equal org-babel-c-variant 'c) org-babel-C-compiler) - ((equal org-babel-c-variant 'cpp) org-babel-C++-compiler)) - (org-babel-process-file-name tmp-bin-file) - (mapconcat 'identity - (if (listp flags) flags (list flags)) " ") - (org-babel-process-file-name tmp-src-file)) "")))) - (let ((results - (org-babel-trim - (org-babel-eval - (concat tmp-bin-file (if cmdline (concat " " cmdline) "")) "")))) - (org-babel-reassemble-table - (org-babel-result-cond (cdr (assoc :result-params params)) - (org-babel-read results) - (let ((tmp-file (org-babel-temp-file "c-"))) - (with-temp-file tmp-file (insert results)) - (org-babel-import-elisp-from-file tmp-file))) - (org-babel-pick-name - (cdr (assoc :colname-names params)) (cdr (assoc :colnames params))) - (org-babel-pick-name - (cdr (assoc :rowname-names params)) (cdr (assoc :rownames params))))) - )) - -(defun org-babel-C-expand (body params) - "Expand a block of C or C++ code with org-babel according to -it's header arguments." - (let ((vars (mapcar #'cdr (org-babel-get-header params :var))) - (main-p (not (string= (cdr (assoc :main params)) "no"))) - (includes (or (cdr (assoc :includes params)) - (org-babel-read (org-entry-get nil "includes" t)))) - (defines (org-babel-read - (or (cdr (assoc :defines params)) - (org-babel-read (org-entry-get nil "defines" t)))))) - (mapconcat 'identity - (list - ;; includes - (mapconcat - (lambda (inc) (format "#include %s" inc)) - (if (listp includes) includes (list includes)) "\n") - ;; defines - (mapconcat - (lambda (inc) (format "#define %s" inc)) - (if (listp defines) defines (list defines)) "\n") - ;; variables - (mapconcat 'org-babel-C-var-to-C vars "\n") - ;; body - (if main-p - (org-babel-C-ensure-main-wrap body) - body) "\n") "\n"))) - -(defun org-babel-C-ensure-main-wrap (body) - "Wrap BODY in a \"main\" function call if none exists." - (if (string-match "^[ \t]*[intvod]+[ \t\n\r]*main[ \t]*(.*)" body) - body - (format "int main() {\n%s\nreturn 0;\n}\n" body))) - -(defun org-babel-prep-session:C (session params) - "This function does nothing as C is a compiled language with no -support for sessions" - (error "C is a compiled languages -- 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" - (error "C is a compiled languages -- no support for sessions")) - -;; helper functions - -(defun org-babel-C-format-val (type val) - "Handle the FORMAT part of TYPE with the data from VAL." - (let ((format-data (cadr type))) - (if (stringp format-data) - (cons "" (format format-data val)) - (funcall format-data val)))) - -(defun org-babel-C-val-to-C-type (val) - "Determine the type of VAL. -Return a list (TYPE-NAME FORMAT). TYPE-NAME should be the name of the type. -FORMAT can be either a format string or a function which is called with VAL." - (cond - ((integerp val) '("int" "%d")) - ((floatp val) '("double" "%f")) - ((or (listp val) (vectorp val)) - (lexical-let ((type (org-babel-C-val-to-C-list-type val))) - (list (car type) - (lambda (val) - (cons - (format "[%d]%s" - (length val) - (car (org-babel-C-format-val type (elt val 0)))) - (concat "{ " - (mapconcat (lambda (v) - (cdr (org-babel-C-format-val type v))) - val - ", ") - " }")))))) - (t ;; treat unknown types as string - '("char" (lambda (val) - (let ((s (format "%s" val))) ;; convert to string for unknown types - (cons (format "[%d]" (1+ (length s))) - (concat "\"" s "\"")))))))) - -(defun org-babel-C-val-to-C-list-type (val) - "Determine the C array type of a VAL." - (let (type) - (mapc - #'(lambda (i) - (let* ((tmp-type (org-babel-C-val-to-C-type i)) - (type-name (car type)) - (tmp-type-name (car tmp-type))) - (when (and type (not (string= type-name tmp-type-name))) - (if (and (member type-name '("int" "double" "int32_t")) - (member tmp-type-name '("int" "double" "int32_t"))) - (setq tmp-type '("double" "" "%f")) - (error "Only homogeneous lists are supported by C. You can not mix %s and %s" - type-name - tmp-type-name))) - (setq type tmp-type))) - val) - type)) - -(defun org-babel-C-var-to-C (pair) - "Convert an elisp val into a string of C code specifying a var -of the same value." - ;; TODO list support - (let ((var (car pair)) - (val (cdr pair))) - (when (symbolp val) - (setq val (symbol-name val)) - (when (= (length val) 1) - (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))) - (format "%s %s%s = %s;" - type - var - suffix - data)))) - -(provide 'ob-C) - -;;; ob-C.el ends here diff --git a/elpa/org-20150629/org-element.el b/elpa/org-20150629/org-element.el deleted file mode 100644 index 0ec86cfa..00000000 --- a/elpa/org-20150629/org-element.el +++ /dev/null @@ -1,5024 +0,0 @@ -;;; org-element.el --- Parser And Applications for Org syntax - -;; Copyright (C) 2012-2014 Free Software Foundation, Inc. - -;; Author: Nicolas Goaziou -;; Keywords: outlines, hypermedia, calendar, wp - -;; 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 . - -;;; Commentary: -;; -;; Org syntax can be divided into three categories: "Greater -;; elements", "Elements" and "Objects". -;; -;; Elements are related to the structure of the document. Indeed, all -;; elements are a cover for the document: each position within belongs -;; to at least one element. -;; -;; An element always starts and ends at the beginning of a line. With -;; a few exceptions (`clock', `headline', `inlinetask', `item', -;; `planning', `node-property', `quote-section' `section' and -;; `table-row' types), it can also accept a fixed set of keywords as -;; attributes. Those are called "affiliated keywords" to distinguish -;; them from other keywords, which are full-fledged elements. Almost -;; all affiliated keywords are referenced in -;; `org-element-affiliated-keywords'; the others are export attributes -;; and start with "ATTR_" prefix. -;; -;; Element containing other elements (and only elements) are called -;; greater elements. Concerned types are: `center-block', `drawer', -;; `dynamic-block', `footnote-definition', `headline', `inlinetask', -;; `item', `plain-list', `property-drawer', `quote-block', `section' -;; and `special-block'. -;; -;; Other element types are: `babel-call', `clock', `comment', -;; `comment-block', `diary-sexp', `example-block', `export-block', -;; `fixed-width', `horizontal-rule', `keyword', `latex-environment', -;; `node-property', `paragraph', `planning', `quote-section', -;; `src-block', `table', `table-row' and `verse-block'. Among them, -;; `paragraph' and `verse-block' types can contain Org objects and -;; plain text. -;; -;; Objects are related to document's contents. Some of them are -;; recursive. Associated types are of the following: `bold', `code', -;; `entity', `export-snippet', `footnote-reference', -;; `inline-babel-call', `inline-src-block', `italic', -;; `latex-fragment', `line-break', `link', `macro', `radio-target', -;; `statistics-cookie', `strike-through', `subscript', `superscript', -;; `table-cell', `target', `timestamp', `underline' and `verbatim'. -;; -;; Some elements also have special properties whose value can hold -;; objects themselves (e.g. an item tag or a headline name). Such -;; values are called "secondary strings". Any object belongs to -;; either an element or a secondary string. -;; -;; Notwithstanding affiliated keywords, each greater element, element -;; and object has a fixed set of properties attached to it. Among -;; them, four are shared by all types: `:begin' and `:end', which -;; refer to the beginning and ending buffer positions of the -;; considered element or object, `:post-blank', which holds the number -;; of blank lines, or white spaces, at its end and `:parent' which -;; refers to the element or object containing it. Greater elements, -;; elements and objects containing objects will also have -;; `:contents-begin' and `:contents-end' properties to delimit -;; contents. Eventually, greater elements and elements accepting -;; affiliated keywords will have a `:post-affiliated' property, -;; referring to the buffer position after all such keywords. -;; -;; At the lowest level, a `:parent' property is also attached to any -;; string, as a text property. -;; -;; Lisp-wise, an element or an object can be represented as a list. -;; It follows the pattern (TYPE PROPERTIES CONTENTS), where: -;; TYPE is a symbol describing the Org element or object. -;; PROPERTIES is the property list attached to it. See docstring of -;; appropriate parsing function to get an exhaustive -;; list. -;; CONTENTS is a list of elements, objects or raw strings contained -;; in the current element or object, when applicable. -;; -;; An Org buffer is a nested list of such elements and objects, whose -;; type is `org-data' and properties is nil. -;; -;; The first part of this file defines Org syntax, while the second -;; one provide accessors and setters functions. -;; -;; The next part implements a parser and an interpreter for each -;; element and object type in Org syntax. -;; -;; The following part creates a fully recursive buffer parser. It -;; also provides a tool to map a function to elements or objects -;; matching some criteria in the parse tree. Functions of interest -;; are `org-element-parse-buffer', `org-element-map' and, to a lesser -;; extent, `org-element-parse-secondary-string'. -;; -;; The penultimate part is the cradle of an interpreter for the -;; obtained parse tree: `org-element-interpret-data'. -;; -;; The library ends by furnishing `org-element-at-point' function, and -;; a way to give information about document structure around point -;; with `org-element-context'. - - -;;; Code: - -(eval-when-compile (require 'cl)) -(require 'org) - - - -;;; Definitions And Rules -;; -;; Define elements, greater elements and specify recursive objects, -;; along with the affiliated keywords recognized. Also set up -;; restrictions on recursive objects combinations. -;; -;; These variables really act as a control center for the parsing -;; process. - -(defconst org-element-paragraph-separate - (concat "^\\(?:" - ;; Headlines, inlinetasks. - org-outline-regexp "\\|" - ;; Footnote definitions. - "\\[\\(?:[0-9]+\\|fn:[-_[:word:]]+\\)\\]" "\\|" - ;; Diary sexps. - "%%(" "\\|" - "[ \t]*\\(?:" - ;; Empty lines. - "$" "\\|" - ;; Tables (any type). - "\\(?:|\\|\\+-[-+]\\)" "\\|" - ;; Blocks (any type), Babel calls and keywords. Note: this - ;; is only an indication and need some thorough check. - "#\\(?:[+ ]\\|$\\)" "\\|" - ;; Drawers (any type) and fixed-width areas. This is also - ;; only an indication. - ":" "\\|" - ;; Horizontal rules. - "-\\{5,\\}[ \t]*$" "\\|" - ;; LaTeX environments. - "\\\\begin{\\([A-Za-z0-9]+\\*?\\)}" "\\|" - ;; Planning and Clock lines. - (regexp-opt (list org-scheduled-string - org-deadline-string - org-closed-string - org-clock-string)) - "\\|" - ;; Lists. - (let ((term (case org-plain-list-ordered-item-terminator - (?\) ")") (?. "\\.") (otherwise "[.)]"))) - (alpha (and org-list-allow-alphabetical "\\|[A-Za-z]"))) - (concat "\\(?:[-+*]\\|\\(?:[0-9]+" alpha "\\)" term "\\)" - "\\(?:[ \t]\\|$\\)")) - "\\)\\)") - "Regexp to separate paragraphs in an Org buffer. -In the case of lines starting with \"#\" and \":\", this regexp -is not sufficient to know if point is at a paragraph ending. See -`org-element-paragraph-parser' for more information.") - -(defconst org-element-all-elements - '(babel-call center-block clock comment comment-block diary-sexp drawer - dynamic-block example-block export-block fixed-width - footnote-definition headline horizontal-rule inlinetask item - keyword latex-environment node-property paragraph plain-list - planning property-drawer quote-block quote-section section - special-block src-block table table-row verse-block) - "Complete list of element types.") - -(defconst org-element-greater-elements - '(center-block drawer dynamic-block footnote-definition headline inlinetask - item plain-list property-drawer quote-block section - special-block table) - "List of recursive element types aka Greater Elements.") - -(defconst org-element-all-successors - '(link export-snippet footnote-reference inline-babel-call - inline-src-block latex-or-entity line-break macro plain-link - radio-target statistics-cookie sub/superscript table-cell target - text-markup timestamp) - "Complete list of successors.") - -(defconst org-element-object-successor-alist - '((subscript . sub/superscript) (superscript . sub/superscript) - (bold . text-markup) (code . text-markup) (italic . text-markup) - (strike-through . text-markup) (underline . text-markup) - (verbatim . text-markup) (entity . latex-or-entity) - (latex-fragment . latex-or-entity)) - "Alist of translations between object type and successor name. -Sharing the same successor comes handy when, for example, the -regexp matching one object can also match the other object.") - -(defconst org-element-all-objects - '(bold code entity export-snippet footnote-reference inline-babel-call - inline-src-block italic line-break latex-fragment link macro - radio-target statistics-cookie strike-through subscript superscript - table-cell target timestamp underline verbatim) - "Complete list of object types.") - -(defconst org-element-recursive-objects - '(bold italic link subscript radio-target strike-through superscript - table-cell underline) - "List of recursive object types.") - -(defvar org-element-block-name-alist - '(("CENTER" . org-element-center-block-parser) - ("COMMENT" . org-element-comment-block-parser) - ("EXAMPLE" . org-element-example-block-parser) - ("QUOTE" . org-element-quote-block-parser) - ("SRC" . org-element-src-block-parser) - ("VERSE" . org-element-verse-block-parser)) - "Alist between block names and the associated parsing function. -Names must be uppercase. Any block whose name has no association -is parsed with `org-element-special-block-parser'.") - -(defconst org-element-link-type-is-file - '("file" "file+emacs" "file+sys" "docview") - "List of link types equivalent to \"file\". -Only these types can accept search options and an explicit -application to open them.") - -(defconst org-element-affiliated-keywords - '("CAPTION" "DATA" "HEADER" "HEADERS" "LABEL" "NAME" "PLOT" "RESNAME" "RESULT" - "RESULTS" "SOURCE" "SRCNAME" "TBLNAME") - "List of affiliated keywords as strings. -By default, all keywords setting attributes (e.g., \"ATTR_LATEX\") -are affiliated keywords and need not to be in this list.") - -(defconst org-element-keyword-translation-alist - '(("DATA" . "NAME") ("LABEL" . "NAME") ("RESNAME" . "NAME") - ("SOURCE" . "NAME") ("SRCNAME" . "NAME") ("TBLNAME" . "NAME") - ("RESULT" . "RESULTS") ("HEADERS" . "HEADER")) - "Alist of usual translations for keywords. -The key is the old name and the value the new one. The property -holding their value will be named after the translated name.") - -(defconst org-element-multiple-keywords '("CAPTION" "HEADER") - "List of affiliated keywords that can occur more than once in an element. - -Their value will be consed into a list of strings, which will be -returned as the value of the property. - -This list is checked after translations have been applied. See -`org-element-keyword-translation-alist'. - -By default, all keywords setting attributes (e.g., \"ATTR_LATEX\") -allow multiple occurrences and need not to be in this list.") - -(defconst org-element-parsed-keywords '("CAPTION") - "List of affiliated keywords whose value can be parsed. - -Their value will be stored as a secondary string: a list of -strings and objects. - -This list is checked after translations have been applied. See -`org-element-keyword-translation-alist'.") - -(defconst org-element-dual-keywords '("CAPTION" "RESULTS") - "List of affiliated keywords which can have a secondary value. - -In Org syntax, they can be written with optional square brackets -before the colons. For example, RESULTS keyword can be -associated to a hash value with the following: - - #+RESULTS[hash-string]: some-source - -This list is checked after translations have been applied. See -`org-element-keyword-translation-alist'.") - -(defconst org-element-document-properties '("AUTHOR" "DATE" "TITLE") - "List of properties associated to the whole document. -Any keyword in this list will have its value parsed and stored as -a secondary string.") - -(defconst org-element--affiliated-re - (format "[ \t]*#\\+\\(?:%s\\):\\(?: \\|$\\)" - (concat - ;; Dual affiliated keywords. - (format "\\(?1:%s\\)\\(?:\\[\\(.*\\)\\]\\)?" - (regexp-opt org-element-dual-keywords)) - "\\|" - ;; Regular affiliated keywords. - (format "\\(?1:%s\\)" - (regexp-opt - (org-remove-if - #'(lambda (keyword) - (member keyword org-element-dual-keywords)) - org-element-affiliated-keywords))) - "\\|" - ;; Export attributes. - "\\(?1:ATTR_[-_A-Za-z0-9]+\\)")) - "Regexp matching any affiliated keyword. - -Keyword name is put in match group 1. Moreover, if keyword -belongs to `org-element-dual-keywords', put the dual value in -match group 2. - -Don't modify it, set `org-element-affiliated-keywords' instead.") - -(defconst org-element-object-restrictions - (let* ((standard-set - (remq 'plain-link (remq 'table-cell org-element-all-successors))) - (standard-set-no-line-break (remq 'line-break standard-set))) - `((bold ,@standard-set) - (footnote-reference ,@standard-set) - (headline ,@standard-set-no-line-break) - (inlinetask ,@standard-set-no-line-break) - (italic ,@standard-set) - (item ,@standard-set-no-line-break) - (keyword ,@standard-set) - ;; Ignore all links excepted plain links in a link description. - ;; Also ignore radio-targets and line breaks. - (link export-snippet inline-babel-call inline-src-block latex-or-entity - macro plain-link statistics-cookie sub/superscript text-markup) - (paragraph ,@standard-set) - ;; Remove any variable object from radio target as it would - ;; prevent it from being properly recognized. - (radio-target latex-or-entity sub/superscript text-markup) - (strike-through ,@standard-set) - (subscript ,@standard-set) - (superscript ,@standard-set) - ;; Ignore inline babel call and inline src block as formulas are - ;; possible. Also ignore line breaks and statistics cookies. - (table-cell link export-snippet footnote-reference latex-or-entity macro - radio-target sub/superscript target text-markup timestamp) - (table-row table-cell) - (underline ,@standard-set) - (verse-block ,@standard-set))) - "Alist of objects restrictions. - -CAR is an element or object type containing objects and CDR is -a list of successors that will be called within an element or -object of such type. - -For example, in a `radio-target' object, one can only find -entities, latex-fragments, subscript, superscript and text -markup. - -This alist also applies to secondary string. For example, an -`headline' type element doesn't directly contain objects, but -still has an entry since one of its properties (`:title') does.") - -(defconst org-element-secondary-value-alist - '((headline . :title) - (inlinetask . :title) - (item . :tag) - (footnote-reference . :inline-definition)) - "Alist between element types and location of secondary value.") - - - -;;; Accessors and Setters -;; -;; Provide four accessors: `org-element-type', `org-element-property' -;; `org-element-contents' and `org-element-restriction'. -;; -;; Setter functions allow to modify elements by side effect. There is -;; `org-element-put-property', `org-element-set-contents', -;; `org-element-set-element' and `org-element-adopt-element'. Note -;; that `org-element-set-element' and `org-element-adopt-elements' are -;; higher level functions since also update `:parent' property. - -(defsubst org-element-type (element) - "Return type of ELEMENT. - -The function returns the type of the element or object provided. -It can also return the following special value: - `plain-text' for a string - `org-data' for a complete document - nil in any other case." - (cond - ((not (consp element)) (and (stringp element) 'plain-text)) - ((symbolp (car element)) (car element)))) - -(defsubst org-element-property (property element) - "Extract the value from the PROPERTY of an ELEMENT." - (if (stringp element) (get-text-property 0 property element) - (plist-get (nth 1 element) property))) - -(defsubst org-element-contents (element) - "Extract contents from an ELEMENT." - (cond ((not (consp element)) nil) - ((symbolp (car element)) (nthcdr 2 element)) - (t element))) - -(defsubst org-element-restriction (element) - "Return restriction associated to ELEMENT. -ELEMENT can be an element, an object or a symbol representing an -element or object type." - (cdr (assq (if (symbolp element) element (org-element-type element)) - org-element-object-restrictions))) - -(defsubst org-element-put-property (element property value) - "In ELEMENT set PROPERTY to VALUE. -Return modified element." - (if (stringp element) (org-add-props element nil property value) - (setcar (cdr element) (plist-put (nth 1 element) property value)) - element)) - -(defsubst org-element-set-contents (element &rest contents) - "Set ELEMENT contents to CONTENTS. -Return modified element." - (cond ((not element) (list contents)) - ((not (symbolp (car element))) contents) - ((cdr element) (setcdr (cdr element) contents)) - (t (nconc element contents)))) - -(defsubst org-element-set-element (old new) - "Replace element or object OLD with element or object NEW. -The function takes care of setting `:parent' property for NEW." - ;; Since OLD is going to be changed into NEW by side-effect, first - ;; make sure that every element or object within NEW has OLD as - ;; parent. - (mapc (lambda (blob) (org-element-put-property blob :parent old)) - (org-element-contents new)) - ;; Transfer contents. - (apply 'org-element-set-contents old (org-element-contents new)) - ;; Ensure NEW has same parent as OLD, then overwrite OLD properties - ;; with NEW's. - (org-element-put-property new :parent (org-element-property :parent old)) - (setcar (cdr old) (nth 1 new)) - ;; Transfer type. - (setcar old (car new))) - -(defsubst org-element-adopt-elements (parent &rest children) - "Append elements to the contents of another element. - -PARENT is an element or object. CHILDREN can be elements, -objects, or a strings. - -The function takes care of setting `:parent' property for CHILD. -Return parent element." - ;; Link every child to PARENT. If PARENT is nil, it is a secondary - ;; string: parent is the list itself. - (mapc (lambda (child) - (org-element-put-property child :parent (or parent children))) - children) - ;; Add CHILDREN at the end of PARENT contents. - (when parent - (apply 'org-element-set-contents - parent - (nconc (org-element-contents parent) children))) - ;; Return modified PARENT element. - (or parent children)) - - - -;;; Greater elements -;; -;; For each greater element type, we define a parser and an -;; interpreter. -;; -;; A parser returns the element or object as the list described above. -;; Most of them accepts no argument. Though, exceptions exist. Hence -;; every element containing a secondary string (see -;; `org-element-secondary-value-alist') will accept an optional -;; argument to toggle parsing of that secondary string. Moreover, -;; `item' parser requires current list's structure as its first -;; element. -;; -;; An interpreter accepts two arguments: the list representation of -;; the element or object, and its contents. The latter may be nil, -;; depending on the element or object considered. It returns the -;; appropriate Org syntax, as a string. -;; -;; Parsing functions must follow the naming convention: -;; org-element-TYPE-parser, where TYPE is greater element's type, as -;; defined in `org-element-greater-elements'. -;; -;; Similarly, interpreting functions must follow the naming -;; convention: org-element-TYPE-interpreter. -;; -;; With the exception of `headline' and `item' types, greater elements -;; cannot contain other greater elements of their own type. -;; -;; Beside implementing a parser and an interpreter, adding a new -;; greater element requires to tweak `org-element--current-element'. -;; Moreover, the newly defined type must be added to both -;; `org-element-all-elements' and `org-element-greater-elements'. - - -;;;; Center Block - -(defun org-element-center-block-parser (limit affiliated) - "Parse a center block. - -LIMIT bounds the search. AFFILIATED is a list of which CAR is -the buffer position at the beginning of the first affiliated -keyword and CDR is a plist of affiliated keywords along with -their value. - -Return a list whose CAR is `center-block' and CDR is a plist -containing `:begin', `:end', `:hiddenp', `:contents-begin', -`:contents-end', `:post-blank' and `:post-affiliated' keywords. - -Assume point is at the beginning of the block." - (let ((case-fold-search t)) - (if (not (save-excursion - (re-search-forward "^[ \t]*#\\+END_CENTER[ \t]*$" limit t))) - ;; Incomplete block: parse it as a paragraph. - (org-element-paragraph-parser limit affiliated) - (let ((block-end-line (match-beginning 0))) - (let* ((begin (car affiliated)) - (post-affiliated (point)) - ;; Empty blocks have no contents. - (contents-begin (progn (forward-line) - (and (< (point) block-end-line) - (point)))) - (contents-end (and contents-begin block-end-line)) - (hidden (org-invisible-p2)) - (pos-before-blank (progn (goto-char block-end-line) - (forward-line) - (point))) - (end (save-excursion - (skip-chars-forward " \r\t\n" limit) - (if (eobp) (point) (line-beginning-position))))) - (list 'center-block - (nconc - (list :begin begin - :end end - :hiddenp hidden - :contents-begin contents-begin - :contents-end contents-end - :post-blank (count-lines pos-before-blank end) - :post-affiliated post-affiliated) - (cdr affiliated)))))))) - -(defun org-element-center-block-interpreter (center-block contents) - "Interpret CENTER-BLOCK element as Org syntax. -CONTENTS is the contents of the element." - (format "#+BEGIN_CENTER\n%s#+END_CENTER" contents)) - - -;;;; Drawer - -(defun org-element-drawer-parser (limit affiliated) - "Parse a drawer. - -LIMIT bounds the search. AFFILIATED is a list of which CAR is -the buffer position at the beginning of the first affiliated -keyword and CDR is a plist of affiliated keywords along with -their value. - -Return a list whose CAR is `drawer' and CDR is a plist containing -`:drawer-name', `:begin', `:end', `:hiddenp', `:contents-begin', -`:contents-end', `:post-blank' and `:post-affiliated' keywords. - -Assume point is at beginning of drawer." - (let ((case-fold-search t)) - (if (not (save-excursion (re-search-forward "^[ \t]*:END:[ \t]*$" limit t))) - ;; Incomplete drawer: parse it as a paragraph. - (org-element-paragraph-parser limit affiliated) - (save-excursion - (let* ((drawer-end-line (match-beginning 0)) - (name (progn (looking-at org-drawer-regexp) - (org-match-string-no-properties 1))) - (begin (car affiliated)) - (post-affiliated (point)) - ;; Empty drawers have no contents. - (contents-begin (progn (forward-line) - (and (< (point) drawer-end-line) - (point)))) - (contents-end (and contents-begin drawer-end-line)) - (hidden (org-invisible-p2)) - (pos-before-blank (progn (goto-char drawer-end-line) - (forward-line) - (point))) - (end (progn (skip-chars-forward " \r\t\n" limit) - (if (eobp) (point) (line-beginning-position))))) - (list 'drawer - (nconc - (list :begin begin - :end end - :drawer-name name - :hiddenp hidden - :contents-begin contents-begin - :contents-end contents-end - :post-blank (count-lines pos-before-blank end) - :post-affiliated post-affiliated) - (cdr affiliated)))))))) - -(defun org-element-drawer-interpreter (drawer contents) - "Interpret DRAWER element as Org syntax. -CONTENTS is the contents of the element." - (format ":%s:\n%s:END:" - (org-element-property :drawer-name drawer) - contents)) - - -;;;; Dynamic Block - -(defun org-element-dynamic-block-parser (limit affiliated) - "Parse a dynamic block. - -LIMIT bounds the search. AFFILIATED is a list of which CAR is -the buffer position at the beginning of the first affiliated -keyword and CDR is a plist of affiliated keywords along with -their value. - -Return a list whose CAR is `dynamic-block' and CDR is a plist -containing `:block-name', `:begin', `:end', `:hiddenp', -`:contents-begin', `:contents-end', `:arguments', `:post-blank' -and `:post-affiliated' keywords. - -Assume point is at beginning of dynamic block." - (let ((case-fold-search t)) - (if (not (save-excursion - (re-search-forward "^[ \t]*#\\+END:?[ \t]*$" limit t))) - ;; Incomplete block: parse it as a paragraph. - (org-element-paragraph-parser limit affiliated) - (let ((block-end-line (match-beginning 0))) - (save-excursion - (let* ((name (progn (looking-at org-dblock-start-re) - (org-match-string-no-properties 1))) - (arguments (org-match-string-no-properties 3)) - (begin (car affiliated)) - (post-affiliated (point)) - ;; Empty blocks have no contents. - (contents-begin (progn (forward-line) - (and (< (point) block-end-line) - (point)))) - (contents-end (and contents-begin block-end-line)) - (hidden (org-invisible-p2)) - (pos-before-blank (progn (goto-char block-end-line) - (forward-line) - (point))) - (end (progn (skip-chars-forward " \r\t\n" limit) - (if (eobp) (point) (line-beginning-position))))) - (list 'dynamic-block - (nconc - (list :begin begin - :end end - :block-name name - :arguments arguments - :hiddenp hidden - :contents-begin contents-begin - :contents-end contents-end - :post-blank (count-lines pos-before-blank end) - :post-affiliated post-affiliated) - (cdr affiliated))))))))) - -(defun org-element-dynamic-block-interpreter (dynamic-block contents) - "Interpret DYNAMIC-BLOCK element as Org syntax. -CONTENTS is the contents of the element." - (format "#+BEGIN: %s%s\n%s#+END:" - (org-element-property :block-name dynamic-block) - (let ((args (org-element-property :arguments dynamic-block))) - (and args (concat " " args))) - contents)) - - -;;;; Footnote Definition - -(defun org-element-footnote-definition-parser (limit affiliated) - "Parse a footnote definition. - -LIMIT bounds the search. AFFILIATED is a list of which CAR is -the buffer position at the beginning of the first affiliated -keyword and CDR is a plist of affiliated keywords along with -their value. - -Return a list whose CAR is `footnote-definition' and CDR is -a plist containing `:label', `:begin' `:end', `:contents-begin', -`:contents-end', `:post-blank' and `:post-affiliated' keywords. - -Assume point is at the beginning of the footnote definition." - (save-excursion - (let* ((label (progn (looking-at org-footnote-definition-re) - (org-match-string-no-properties 1))) - (begin (car affiliated)) - (post-affiliated (point)) - (ending (save-excursion - (if (progn - (end-of-line) - (re-search-forward - (concat org-outline-regexp-bol "\\|" - org-footnote-definition-re "\\|" - "^\\([ \t]*\n\\)\\{2,\\}") limit 'move)) - (match-beginning 0) - (point)))) - (contents-begin (progn - (search-forward "]") - (skip-chars-forward " \r\t\n" ending) - (cond ((= (point) ending) nil) - ((= (line-beginning-position) begin) (point)) - (t (line-beginning-position))))) - (contents-end (and contents-begin ending)) - (end (progn (goto-char ending) - (skip-chars-forward " \r\t\n" limit) - (if (eobp) (point) (line-beginning-position))))) - (list 'footnote-definition - (nconc - (list :label label - :begin begin - :end end - :contents-begin contents-begin - :contents-end contents-end - :post-blank (count-lines ending end) - :post-affiliated post-affiliated) - (cdr affiliated)))))) - -(defun org-element-footnote-definition-interpreter (footnote-definition contents) - "Interpret FOOTNOTE-DEFINITION element as Org syntax. -CONTENTS is the contents of the footnote-definition." - (concat (format "[%s]" (org-element-property :label footnote-definition)) - " " - contents)) - - -;;;; Headline - -(defun org-element-headline-parser (limit &optional raw-secondary-p) - "Parse a headline. - -Return a list whose CAR is `headline' and CDR is a plist -containing `:raw-value', `:title', `:alt-title', `:begin', -`:end', `:pre-blank', `:hiddenp', `:contents-begin', -`:contents-end', `:level', `:priority', `:tags', -`:todo-keyword',`:todo-type', `:scheduled', `:deadline', -`:closed', `:quotedp', `:archivedp', `:commentedp', -`:footnote-section-p' and `:post-blank' keywords. - -The plist also contains any property set in the property drawer, -with its name in upper cases and colons added at the -beginning (e.g., `:CUSTOM_ID'). - -LIMIT is a buffer position bounding the search. - -When RAW-SECONDARY-P is non-nil, headline's title will not be -parsed as a secondary string, but as a plain string instead. - -Assume point is at beginning of the headline." - (save-excursion - (let* ((components (org-heading-components)) - (level (nth 1 components)) - (todo (nth 2 components)) - (todo-type - (and todo (if (member todo org-done-keywords) 'done 'todo))) - (tags (let ((raw-tags (nth 5 components))) - (and raw-tags (org-split-string raw-tags ":")))) - (raw-value (or (nth 4 components) "")) - (quotedp - (let ((case-fold-search nil)) - (string-match (format "^%s\\( \\|$\\)" org-quote-string) - raw-value))) - (commentedp - (let ((case-fold-search nil)) - (string-match (format "^%s\\( \\|$\\)" org-comment-string) - raw-value))) - (archivedp (member org-archive-tag tags)) - (footnote-section-p (and org-footnote-section - (string= org-footnote-section raw-value))) - ;; Upcase property names. It avoids confusion between - ;; properties obtained through property drawer and default - ;; properties from the parser (e.g. `:end' and :END:) - (standard-props - (let (plist) - (mapc - (lambda (p) - (setq plist - (plist-put plist - (intern (concat ":" (upcase (car p)))) - (cdr p)))) - (org-entry-properties nil 'standard)) - plist)) - (time-props - ;; Read time properties on the line below the headline. - (save-excursion - (when (progn (forward-line) - (looking-at org-planning-or-clock-line-re)) - (let ((end (line-end-position)) plist) - (while (re-search-forward - org-keyword-time-not-clock-regexp end t) - (goto-char (match-end 1)) - (skip-chars-forward " \t") - (let ((keyword (match-string 1)) - (time (org-element-timestamp-parser))) - (cond ((equal keyword org-scheduled-string) - (setq plist (plist-put plist :scheduled time))) - ((equal keyword org-deadline-string) - (setq plist (plist-put plist :deadline time))) - (t (setq plist (plist-put plist :closed time)))))) - plist)))) - (begin (point)) - (end (min (save-excursion (org-end-of-subtree t t)) limit)) - (pos-after-head (progn (forward-line) (point))) - (contents-begin (save-excursion - (skip-chars-forward " \r\t\n" end) - (and (/= (point) end) (line-beginning-position)))) - (hidden (org-invisible-p2)) - (contents-end (and contents-begin - (progn (goto-char end) - (skip-chars-backward " \r\t\n") - (forward-line) - (point))))) - ;; Clean RAW-VALUE from any quote or comment string. - (when (or quotedp commentedp) - (let ((case-fold-search nil)) - (setq raw-value - (replace-regexp-in-string - (concat - (regexp-opt (list org-quote-string org-comment-string)) - "\\(?: \\|$\\)") - "" - raw-value)))) - ;; Clean TAGS from archive tag, if any. - (when archivedp (setq tags (delete org-archive-tag tags))) - (let ((headline - (list 'headline - (nconc - (list :raw-value raw-value - :begin begin - :end end - :pre-blank - (if (not contents-begin) 0 - (count-lines pos-after-head contents-begin)) - :hiddenp hidden - :contents-begin contents-begin - :contents-end contents-end - :level level - :priority (nth 3 components) - :tags tags - :todo-keyword todo - :todo-type todo-type - :post-blank (count-lines - (or contents-end pos-after-head) - end) - :footnote-section-p footnote-section-p - :archivedp archivedp - :commentedp commentedp - :quotedp quotedp) - time-props - standard-props)))) - (let ((alt-title (org-element-property :ALT_TITLE headline))) - (when alt-title - (org-element-put-property - headline :alt-title - (if raw-secondary-p alt-title - (org-element-parse-secondary-string - alt-title (org-element-restriction 'headline) headline))))) - (org-element-put-property - headline :title - (if raw-secondary-p raw-value - (org-element-parse-secondary-string - raw-value (org-element-restriction 'headline) headline))))))) - -(defun org-element-headline-interpreter (headline contents) - "Interpret HEADLINE element as Org syntax. -CONTENTS is the contents of the element." - (let* ((level (org-element-property :level headline)) - (todo (org-element-property :todo-keyword headline)) - (priority (org-element-property :priority headline)) - (title (org-element-interpret-data - (org-element-property :title headline))) - (tags (let ((tag-list (if (org-element-property :archivedp headline) - (cons org-archive-tag - (org-element-property :tags headline)) - (org-element-property :tags headline)))) - (and tag-list - (format ":%s:" (mapconcat #'identity tag-list ":"))))) - (commentedp (org-element-property :commentedp headline)) - (quotedp (org-element-property :quotedp headline)) - (pre-blank (or (org-element-property :pre-blank headline) 0)) - (heading - (concat (make-string (if org-odd-levels-only (1- (* level 2)) level) - ?*) - (and todo (concat " " todo)) - (and quotedp (concat " " org-quote-string)) - (and commentedp (concat " " org-comment-string)) - (and priority (format " [#%s]" (char-to-string priority))) - " " - (if (and org-footnote-section - (org-element-property :footnote-section-p headline)) - org-footnote-section - title)))) - (concat - heading - ;; Align tags. - (when tags - (cond - ((zerop org-tags-column) (format " %s" tags)) - ((< org-tags-column 0) - (concat - (make-string - (max (- (+ org-tags-column (length heading) (length tags))) 1) - ?\s) - tags)) - (t - (concat - (make-string (max (- org-tags-column (length heading)) 1) ?\s) - tags)))) - (make-string (1+ pre-blank) ?\n) - contents))) - - -;;;; Inlinetask - -(defun org-element-inlinetask-parser (limit &optional raw-secondary-p) - "Parse an inline task. - -Return a list whose CAR is `inlinetask' and CDR is a plist -containing `:title', `:begin', `:end', `:hiddenp', -`:contents-begin' and `:contents-end', `:level', `:priority', -`:raw-value', `:tags', `:todo-keyword', `:todo-type', -`:scheduled', `:deadline', `:closed' and `:post-blank' keywords. - -The plist also contains any property set in the property drawer, -with its name in upper cases and colons added at the -beginning (e.g., `:CUSTOM_ID'). - -When optional argument RAW-SECONDARY-P is non-nil, inline-task's -title will not be parsed as a secondary string, but as a plain -string instead. - -Assume point is at beginning of the inline task." - (save-excursion - (let* ((begin (point)) - (components (org-heading-components)) - (todo (nth 2 components)) - (todo-type (and todo - (if (member todo org-done-keywords) 'done 'todo))) - (tags (let ((raw-tags (nth 5 components))) - (and raw-tags (org-split-string raw-tags ":")))) - (raw-value (or (nth 4 components) "")) - ;; Upcase property names. It avoids confusion between - ;; properties obtained through property drawer and default - ;; properties from the parser (e.g. `:end' and :END:) - (standard-props - (let (plist) - (mapc - (lambda (p) - (setq plist - (plist-put plist - (intern (concat ":" (upcase (car p)))) - (cdr p)))) - (org-entry-properties nil 'standard)) - plist)) - (time-props - ;; Read time properties on the line below the inlinetask - ;; opening string. - (save-excursion - (when (progn (forward-line) - (looking-at org-planning-or-clock-line-re)) - (let ((end (line-end-position)) plist) - (while (re-search-forward - org-keyword-time-not-clock-regexp end t) - (goto-char (match-end 1)) - (skip-chars-forward " \t") - (let ((keyword (match-string 1)) - (time (org-element-timestamp-parser))) - (cond ((equal keyword org-scheduled-string) - (setq plist (plist-put plist :scheduled time))) - ((equal keyword org-deadline-string) - (setq plist (plist-put plist :deadline time))) - (t (setq plist (plist-put plist :closed time)))))) - plist)))) - (task-end (save-excursion - (end-of-line) - (and (re-search-forward org-outline-regexp-bol limit t) - (org-looking-at-p "END[ \t]*$") - (line-beginning-position)))) - (contents-begin (progn (forward-line) - (and task-end (< (point) task-end) (point)))) - (hidden (and contents-begin (org-invisible-p2))) - (contents-end (and contents-begin task-end)) - (before-blank (if (not task-end) (point) - (goto-char task-end) - (forward-line) - (point))) - (end (progn (skip-chars-forward " \r\t\n" limit) - (if (eobp) (point) (line-beginning-position)))) - (inlinetask - (list 'inlinetask - (nconc - (list :raw-value raw-value - :begin begin - :end end - :hiddenp hidden - :contents-begin contents-begin - :contents-end contents-end - :level (nth 1 components) - :priority (nth 3 components) - :tags tags - :todo-keyword todo - :todo-type todo-type - :post-blank (count-lines before-blank end)) - time-props - standard-props)))) - (org-element-put-property - inlinetask :title - (if raw-secondary-p raw-value - (org-element-parse-secondary-string - raw-value - (org-element-restriction 'inlinetask) - inlinetask)))))) - -(defun org-element-inlinetask-interpreter (inlinetask contents) - "Interpret INLINETASK element as Org syntax. -CONTENTS is the contents of inlinetask." - (let* ((level (org-element-property :level inlinetask)) - (todo (org-element-property :todo-keyword inlinetask)) - (priority (org-element-property :priority inlinetask)) - (title (org-element-interpret-data - (org-element-property :title inlinetask))) - (tags (let ((tag-list (org-element-property :tags inlinetask))) - (and tag-list - (format ":%s:" (mapconcat 'identity tag-list ":"))))) - (task (concat (make-string level ?*) - (and todo (concat " " todo)) - (and priority - (format " [#%s]" (char-to-string priority))) - (and title (concat " " title))))) - (concat task - ;; Align tags. - (when tags - (cond - ((zerop org-tags-column) (format " %s" tags)) - ((< org-tags-column 0) - (concat - (make-string - (max (- (+ org-tags-column (length task) (length tags))) 1) - ? ) - tags)) - (t - (concat - (make-string (max (- org-tags-column (length task)) 1) ? ) - tags)))) - ;; Prefer degenerate inlinetasks when there are no - ;; contents. - (when contents - (concat "\n" - contents - (make-string level ?*) " END"))))) - - -;;;; Item - -(defun org-element-item-parser (limit struct &optional raw-secondary-p) - "Parse an item. - -STRUCT is the structure of the plain list. - -Return a list whose CAR is `item' and CDR is a plist containing -`:bullet', `:begin', `:end', `:contents-begin', `:contents-end', -`:checkbox', `:counter', `:tag', `:structure', `:hiddenp' and -`:post-blank' keywords. - -When optional argument RAW-SECONDARY-P is non-nil, item's tag, if -any, will not be parsed as a secondary string, but as a plain -string instead. - -Assume point is at the beginning of the item." - (save-excursion - (beginning-of-line) - (looking-at org-list-full-item-re) - (let* ((begin (point)) - (bullet (org-match-string-no-properties 1)) - (checkbox (let ((box (org-match-string-no-properties 3))) - (cond ((equal "[ ]" box) 'off) - ((equal "[X]" box) 'on) - ((equal "[-]" box) 'trans)))) - (counter (let ((c (org-match-string-no-properties 2))) - (save-match-data - (cond - ((not c) nil) - ((string-match "[A-Za-z]" c) - (- (string-to-char (upcase (match-string 0 c))) - 64)) - ((string-match "[0-9]+" c) - (string-to-number (match-string 0 c))))))) - (end (save-excursion (goto-char (org-list-get-item-end begin struct)) - (unless (bolp) (forward-line)) - (point))) - (contents-begin - (progn (goto-char - ;; Ignore tags in un-ordered lists: they are just - ;; a part of item's body. - (if (and (match-beginning 4) - (save-match-data (string-match "[.)]" bullet))) - (match-beginning 4) - (match-end 0))) - (skip-chars-forward " \r\t\n" limit) - ;; If first line isn't empty, contents really start - ;; at the text after item's meta-data. - (if (= (point-at-bol) begin) (point) (point-at-bol)))) - (hidden (progn (forward-line) - (and (not (= (point) end)) (org-invisible-p2)))) - (contents-end (progn (goto-char end) - (skip-chars-backward " \r\t\n") - (forward-line) - (point))) - (item - (list 'item - (list :bullet bullet - :begin begin - :end end - ;; CONTENTS-BEGIN and CONTENTS-END may be - ;; mixed up in the case of an empty item - ;; separated from the next by a blank line. - ;; Thus ensure the former is always the - ;; smallest. - :contents-begin (min contents-begin contents-end) - :contents-end (max contents-begin contents-end) - :checkbox checkbox - :counter counter - :hiddenp hidden - :structure struct - :post-blank (count-lines contents-end end))))) - (org-element-put-property - item :tag - (let ((raw-tag (org-list-get-tag begin struct))) - (and raw-tag - (if raw-secondary-p raw-tag - (org-element-parse-secondary-string - raw-tag (org-element-restriction 'item) item)))))))) - -(defun org-element-item-interpreter (item contents) - "Interpret ITEM element as Org syntax. -CONTENTS is the contents of the element." - (let* ((bullet (let ((bullet (org-element-property :bullet item))) - (org-list-bullet-string - (cond ((not (string-match "[0-9a-zA-Z]" bullet)) "- ") - ((eq org-plain-list-ordered-item-terminator ?\)) "1)") - (t "1."))))) - (checkbox (org-element-property :checkbox item)) - (counter (org-element-property :counter item)) - (tag (let ((tag (org-element-property :tag item))) - (and tag (org-element-interpret-data tag)))) - ;; Compute indentation. - (ind (make-string (length bullet) 32)) - (item-starts-with-par-p - (eq (org-element-type (car (org-element-contents item))) - 'paragraph))) - ;; Indent contents. - (concat - bullet - (and counter (format "[@%d] " counter)) - (case checkbox - (on "[X] ") - (off "[ ] ") - (trans "[-] ")) - (and tag (format "%s :: " tag)) - (when contents - (let ((contents (replace-regexp-in-string - "\\(^\\)[ \t]*\\S-" ind contents nil nil 1))) - (if item-starts-with-par-p (org-trim contents) - (concat "\n" contents))))))) - - -;;;; Plain List - -(defun org-element--list-struct (limit) - ;; Return structure of list at point. Internal function. See - ;; `org-list-struct' for details. - (let ((case-fold-search t) - (top-ind limit) - (item-re (org-item-re)) - (drawers-re (concat ":\\(" - (mapconcat 'regexp-quote org-drawers "\\|") - "\\):[ \t]*$")) - (inlinetask-re (and (featurep 'org-inlinetask) "^\\*+ ")) - items struct) - (save-excursion - (catch 'exit - (while t - (cond - ;; At limit: end all items. - ((>= (point) limit) - (throw 'exit - (let ((end (progn (skip-chars-backward " \r\t\n") - (forward-line) - (point)))) - (dolist (item items (sort (nconc items struct) - 'car-less-than-car)) - (setcar (nthcdr 6 item) end))))) - ;; At list end: end all items. - ((looking-at org-list-end-re) - (throw 'exit (dolist (item items (sort (nconc items struct) - 'car-less-than-car)) - (setcar (nthcdr 6 item) (point))))) - ;; At a new item: end previous sibling. - ((looking-at item-re) - (let ((ind (save-excursion (skip-chars-forward " \t") - (current-column)))) - (setq top-ind (min top-ind ind)) - (while (and items (<= ind (nth 1 (car items)))) - (let ((item (pop items))) - (setcar (nthcdr 6 item) (point)) - (push item struct))) - (push (progn (looking-at org-list-full-item-re) - (let ((bullet (match-string-no-properties 1))) - (list (point) - ind - bullet - (match-string-no-properties 2) ; counter - (match-string-no-properties 3) ; checkbox - ;; Description tag. - (and (save-match-data - (string-match "[-+*]" bullet)) - (match-string-no-properties 4)) - ;; Ending position, unknown so far. - nil))) - items)) - (forward-line 1)) - ;; Skip empty lines. - ((looking-at "^[ \t]*$") (forward-line)) - ;; Skip inline tasks and blank lines along the way. - ((and inlinetask-re (looking-at inlinetask-re)) - (forward-line) - (let ((origin (point))) - (when (re-search-forward inlinetask-re limit t) - (if (org-looking-at-p "END[ \t]*$") (forward-line) - (goto-char origin))))) - ;; At some text line. Check if it ends any previous item. - (t - (let ((ind (progn (skip-chars-forward " \t") (current-column)))) - (when (<= ind top-ind) - (skip-chars-backward " \r\t\n") - (forward-line)) - (while (<= ind (nth 1 (car items))) - (let ((item (pop items))) - (setcar (nthcdr 6 item) (line-beginning-position)) - (push item struct) - (unless items - (throw 'exit (sort struct 'car-less-than-car)))))) - ;; Skip blocks (any type) and drawers contents. - (cond - ((and (looking-at "#\\+BEGIN\\(:\\|_\\S-+\\)") - (re-search-forward - (format "^[ \t]*#\\+END%s[ \t]*$" - (org-match-string-no-properties 1)) - limit t))) - ((and (looking-at drawers-re) - (re-search-forward "^[ \t]*:END:[ \t]*$" limit t)))) - (forward-line)))))))) - -(defun org-element-plain-list-parser (limit affiliated structure) - "Parse a plain list. - -LIMIT bounds the search. AFFILIATED is a list of which CAR is -the buffer position at the beginning of the first affiliated -keyword and CDR is a plist of affiliated keywords along with -their value. STRUCTURE is the structure of the plain list being -parsed. - -Return a list whose CAR is `plain-list' and CDR is a plist -containing `:type', `:begin', `:end', `:contents-begin' and -`:contents-end', `:structure', `:post-blank' and -`:post-affiliated' keywords. - -Assume point is at the beginning of the list." - (save-excursion - (let* ((struct (or structure (org-element--list-struct limit))) - (prevs (org-list-prevs-alist struct)) - (type (org-list-get-list-type (point) struct prevs)) - (contents-begin (point)) - (begin (car affiliated)) - (contents-end - (progn (goto-char (org-list-get-list-end (point) struct prevs)) - (unless (bolp) (forward-line)) - (point))) - (end (progn (skip-chars-forward " \r\t\n" limit) - (if (= (point) limit) limit (line-beginning-position))))) - ;; Return value. - (list 'plain-list - (nconc - (list :type type - :begin begin - :end end - :contents-begin contents-begin - :contents-end contents-end - :structure struct - :post-blank (count-lines contents-end end) - :post-affiliated contents-begin) - (cdr affiliated)))))) - -(defun org-element-plain-list-interpreter (plain-list contents) - "Interpret PLAIN-LIST element as Org syntax. -CONTENTS is the contents of the element." - (with-temp-buffer - (insert contents) - (goto-char (point-min)) - (org-list-repair) - (buffer-string))) - - -;;;; Property Drawer - -(defun org-element-property-drawer-parser (limit affiliated) - "Parse a property drawer. - -LIMIT bounds the search. AFFILIATED is a list of which CAR is -the buffer position at the beginning of the first affiliated -keyword and CDR is a plist of affiliated keywords along with -their value. - -Return a list whose CAR is `property-drawer' and CDR is a plist -containing `:begin', `:end', `:hiddenp', `:contents-begin', -`:contents-end', `:post-blank' and `:post-affiliated' keywords. - -Assume point is at the beginning of the property drawer." - (let ((case-fold-search t)) - (if (not (save-excursion (re-search-forward "^[ \t]*:END:[ \t]*$" limit t))) - ;; Incomplete drawer: parse it as a paragraph. - (org-element-paragraph-parser limit affiliated) - (save-excursion - (let* ((drawer-end-line (match-beginning 0)) - (begin (car affiliated)) - (post-affiliated (point)) - (contents-begin - (progn - (forward-line) - (and (re-search-forward org-property-re drawer-end-line t) - (line-beginning-position)))) - (contents-end (and contents-begin drawer-end-line)) - (hidden (org-invisible-p2)) - (pos-before-blank (progn (goto-char drawer-end-line) - (forward-line) - (point))) - (end (progn (skip-chars-forward " \r\t\n" limit) - (if (eobp) (point) (line-beginning-position))))) - (list 'property-drawer - (nconc - (list :begin begin - :end end - :hiddenp hidden - :contents-begin contents-begin - :contents-end contents-end - :post-blank (count-lines pos-before-blank end) - :post-affiliated post-affiliated) - (cdr affiliated)))))))) - -(defun org-element-property-drawer-interpreter (property-drawer contents) - "Interpret PROPERTY-DRAWER element as Org syntax. -CONTENTS is the properties within the drawer." - (format ":PROPERTIES:\n%s:END:" contents)) - - -;;;; Quote Block - -(defun org-element-quote-block-parser (limit affiliated) - "Parse a quote block. - -LIMIT bounds the search. AFFILIATED is a list of which CAR is -the buffer position at the beginning of the first affiliated -keyword and CDR is a plist of affiliated keywords along with -their value. - -Return a list whose CAR is `quote-block' and CDR is a plist -containing `:begin', `:end', `:hiddenp', `:contents-begin', -`:contents-end', `:post-blank' and `:post-affiliated' keywords. - -Assume point is at the beginning of the block." - (let ((case-fold-search t)) - (if (not (save-excursion - (re-search-forward "^[ \t]*#\\+END_QUOTE[ \t]*$" limit t))) - ;; Incomplete block: parse it as a paragraph. - (org-element-paragraph-parser limit affiliated) - (let ((block-end-line (match-beginning 0))) - (save-excursion - (let* ((begin (car affiliated)) - (post-affiliated (point)) - ;; Empty blocks have no contents. - (contents-begin (progn (forward-line) - (and (< (point) block-end-line) - (point)))) - (contents-end (and contents-begin block-end-line)) - (hidden (org-invisible-p2)) - (pos-before-blank (progn (goto-char block-end-line) - (forward-line) - (point))) - (end (progn (skip-chars-forward " \r\t\n" limit) - (if (eobp) (point) (line-beginning-position))))) - (list 'quote-block - (nconc - (list :begin begin - :end end - :hiddenp hidden - :contents-begin contents-begin - :contents-end contents-end - :post-blank (count-lines pos-before-blank end) - :post-affiliated post-affiliated) - (cdr affiliated))))))))) - -(defun org-element-quote-block-interpreter (quote-block contents) - "Interpret QUOTE-BLOCK element as Org syntax. -CONTENTS is the contents of the element." - (format "#+BEGIN_QUOTE\n%s#+END_QUOTE" contents)) - - -;;;; Section - -(defun org-element-section-parser (limit) - "Parse a section. - -LIMIT bounds the search. - -Return a list whose CAR is `section' and CDR is a plist -containing `:begin', `:end', `:contents-begin', `contents-end' -and `:post-blank' keywords." - (save-excursion - ;; Beginning of section is the beginning of the first non-blank - ;; line after previous headline. - (let ((begin (point)) - (end (progn (org-with-limited-levels (outline-next-heading)) - (point))) - (pos-before-blank (progn (skip-chars-backward " \r\t\n") - (forward-line) - (point)))) - (list 'section - (list :begin begin - :end end - :contents-begin begin - :contents-end pos-before-blank - :post-blank (count-lines pos-before-blank end)))))) - -(defun org-element-section-interpreter (section contents) - "Interpret SECTION element as Org syntax. -CONTENTS is the contents of the element." - contents) - - -;;;; Special Block - -(defun org-element-special-block-parser (limit affiliated) - "Parse a special block. - -LIMIT bounds the search. AFFILIATED is a list of which CAR is -the buffer position at the beginning of the first affiliated -keyword and CDR is a plist of affiliated keywords along with -their value. - -Return a list whose CAR is `special-block' and CDR is a plist -containing `:type', `:begin', `:end', `:hiddenp', -`:contents-begin', `:contents-end', `:post-blank' and -`:post-affiliated' keywords. - -Assume point is at the beginning of the block." - (let* ((case-fold-search t) - (type (progn (looking-at "[ \t]*#\\+BEGIN_\\(\\S-+\\)") - (upcase (match-string-no-properties 1))))) - (if (not (save-excursion - (re-search-forward - (format "^[ \t]*#\\+END_%s[ \t]*$" (regexp-quote type)) - limit t))) - ;; Incomplete block: parse it as a paragraph. - (org-element-paragraph-parser limit affiliated) - (let ((block-end-line (match-beginning 0))) - (save-excursion - (let* ((begin (car affiliated)) - (post-affiliated (point)) - ;; Empty blocks have no contents. - (contents-begin (progn (forward-line) - (and (< (point) block-end-line) - (point)))) - (contents-end (and contents-begin block-end-line)) - (hidden (org-invisible-p2)) - (pos-before-blank (progn (goto-char block-end-line) - (forward-line) - (point))) - (end (progn (skip-chars-forward " \r\t\n" limit) - (if (eobp) (point) (line-beginning-position))))) - (list 'special-block - (nconc - (list :type type - :begin begin - :end end - :hiddenp hidden - :contents-begin contents-begin - :contents-end contents-end - :post-blank (count-lines pos-before-blank end) - :post-affiliated post-affiliated) - (cdr affiliated))))))))) - -(defun org-element-special-block-interpreter (special-block contents) - "Interpret SPECIAL-BLOCK element as Org syntax. -CONTENTS is the contents of the element." - (let ((block-type (org-element-property :type special-block))) - (format "#+BEGIN_%s\n%s#+END_%s" block-type contents block-type))) - - - -;;; Elements -;; -;; For each element, a parser and an interpreter are also defined. -;; Both follow the same naming convention used for greater elements. -;; -;; Also, as for greater elements, adding a new element type is done -;; through the following steps: implement a parser and an interpreter, -;; tweak `org-element--current-element' so that it recognizes the new -;; type and add that new type to `org-element-all-elements'. -;; -;; As a special case, when the newly defined type is a block type, -;; `org-element-block-name-alist' has to be modified accordingly. - - -;;;; Babel Call - -(defun org-element-babel-call-parser (limit affiliated) - "Parse a babel call. - -LIMIT bounds the search. AFFILIATED is a list of which CAR is -the buffer position at the beginning of the first affiliated -keyword and CDR is a plist of affiliated keywords along with -their value. - -Return a list whose CAR is `babel-call' and CDR is a plist -containing `:begin', `:end', `:info', `:post-blank' and -`:post-affiliated' as keywords." - (save-excursion - (let ((case-fold-search t) - (info (progn (looking-at org-babel-block-lob-one-liner-regexp) - (org-babel-lob-get-info))) - (begin (car affiliated)) - (post-affiliated (point)) - (pos-before-blank (progn (forward-line) (point))) - (end (progn (skip-chars-forward " \r\t\n" limit) - (if (eobp) (point) (line-beginning-position))))) - (list 'babel-call - (nconc - (list :begin begin - :end end - :info info - :post-blank (count-lines pos-before-blank end) - :post-affiliated post-affiliated) - (cdr affiliated)))))) - -(defun org-element-babel-call-interpreter (babel-call contents) - "Interpret BABEL-CALL element as Org syntax. -CONTENTS is nil." - (let* ((babel-info (org-element-property :info babel-call)) - (main (car babel-info)) - (post-options (nth 1 babel-info))) - (concat "#+CALL: " - (if (not (string-match "\\[\\(\\[.*?\\]\\)\\]" main)) main - ;; Remove redundant square brackets. - (replace-match (match-string 1 main) nil nil main)) - (and post-options (format "[%s]" post-options))))) - - -;;;; Clock - -(defun org-element-clock-parser (limit) - "Parse a clock. - -LIMIT bounds the search. - -Return a list whose CAR is `clock' and CDR is a plist containing -`:status', `:value', `:time', `:begin', `:end' and `:post-blank' -as keywords." - (save-excursion - (let* ((case-fold-search nil) - (begin (point)) - (value (progn (search-forward org-clock-string (line-end-position) t) - (skip-chars-forward " \t") - (org-element-timestamp-parser))) - (duration (and (search-forward " => " (line-end-position) t) - (progn (skip-chars-forward " \t") - (looking-at "\\(\\S-+\\)[ \t]*$")) - (org-match-string-no-properties 1))) - (status (if duration 'closed 'running)) - (post-blank (let ((before-blank (progn (forward-line) (point)))) - (skip-chars-forward " \r\t\n" limit) - (skip-chars-backward " \t") - (unless (bolp) (end-of-line)) - (count-lines before-blank (point)))) - (end (point))) - (list 'clock - (list :status status - :value value - :duration duration - :begin begin - :end end - :post-blank post-blank))))) - -(defun org-element-clock-interpreter (clock contents) - "Interpret CLOCK element as Org syntax. -CONTENTS is nil." - (concat org-clock-string " " - (org-element-timestamp-interpreter - (org-element-property :value clock) nil) - (let ((duration (org-element-property :duration clock))) - (and duration - (concat " => " - (apply 'format - "%2s:%02s" - (org-split-string duration ":"))))))) - - -;;;; Comment - -(defun org-element-comment-parser (limit affiliated) - "Parse a comment. - -LIMIT bounds the search. AFFILIATED is a list of which CAR is -the buffer position at the beginning of the first affiliated -keyword and CDR is a plist of affiliated keywords along with -their value. - -Return a list whose CAR is `comment' and CDR is a plist -containing `:begin', `:end', `:value', `:post-blank', -`:post-affiliated' keywords. - -Assume point is at comment beginning." - (save-excursion - (let* ((begin (car affiliated)) - (post-affiliated (point)) - (value (prog2 (looking-at "[ \t]*# ?") - (buffer-substring-no-properties - (match-end 0) (line-end-position)) - (forward-line))) - (com-end - ;; Get comments ending. - (progn - (while (and (< (point) limit) (looking-at "[ \t]*#\\( \\|$\\)")) - ;; Accumulate lines without leading hash and first - ;; whitespace. - (setq value - (concat value - "\n" - (buffer-substring-no-properties - (match-end 0) (line-end-position)))) - (forward-line)) - (point))) - (end (progn (goto-char com-end) - (skip-chars-forward " \r\t\n" limit) - (if (eobp) (point) (line-beginning-position))))) - (list 'comment - (nconc - (list :begin begin - :end end - :value value - :post-blank (count-lines com-end end) - :post-affiliated post-affiliated) - (cdr affiliated)))))) - -(defun org-element-comment-interpreter (comment contents) - "Interpret COMMENT element as Org syntax. -CONTENTS is nil." - (replace-regexp-in-string "^" "# " (org-element-property :value comment))) - - -;;;; Comment Block - -(defun org-element-comment-block-parser (limit affiliated) - "Parse an export block. - -LIMIT bounds the search. AFFILIATED is a list of which CAR is -the buffer position at the beginning of the first affiliated -keyword and CDR is a plist of affiliated keywords along with -their value. - -Return a list whose CAR is `comment-block' and CDR is a plist -containing `:begin', `:end', `:hiddenp', `:value', `:post-blank' -and `:post-affiliated' keywords. - -Assume point is at comment block beginning." - (let ((case-fold-search t)) - (if (not (save-excursion - (re-search-forward "^[ \t]*#\\+END_COMMENT[ \t]*$" limit t))) - ;; Incomplete block: parse it as a paragraph. - (org-element-paragraph-parser limit affiliated) - (let ((contents-end (match-beginning 0))) - (save-excursion - (let* ((begin (car affiliated)) - (post-affiliated (point)) - (contents-begin (progn (forward-line) (point))) - (hidden (org-invisible-p2)) - (pos-before-blank (progn (goto-char contents-end) - (forward-line) - (point))) - (end (progn (skip-chars-forward " \r\t\n" limit) - (if (eobp) (point) (line-beginning-position)))) - (value (buffer-substring-no-properties - contents-begin contents-end))) - (list 'comment-block - (nconc - (list :begin begin - :end end - :value value - :hiddenp hidden - :post-blank (count-lines pos-before-blank end) - :post-affiliated post-affiliated) - (cdr affiliated))))))))) - -(defun org-element-comment-block-interpreter (comment-block contents) - "Interpret COMMENT-BLOCK element as Org syntax. -CONTENTS is nil." - (format "#+BEGIN_COMMENT\n%s#+END_COMMENT" - (org-remove-indentation (org-element-property :value comment-block)))) - - -;;;; Diary Sexp - -(defun org-element-diary-sexp-parser (limit affiliated) - "Parse a diary sexp. - -LIMIT bounds the search. AFFILIATED is a list of which CAR is -the buffer position at the beginning of the first affiliated -keyword and CDR is a plist of affiliated keywords along with -their value. - -Return a list whose CAR is `diary-sexp' and CDR is a plist -containing `:begin', `:end', `:value', `:post-blank' and -`:post-affiliated' keywords." - (save-excursion - (let ((begin (car affiliated)) - (post-affiliated (point)) - (value (progn (looking-at "\\(%%(.*\\)[ \t]*$") - (org-match-string-no-properties 1))) - (pos-before-blank (progn (forward-line) (point))) - (end (progn (skip-chars-forward " \r\t\n" limit) - (if (eobp) (point) (line-beginning-position))))) - (list 'diary-sexp - (nconc - (list :value value - :begin begin - :end end - :post-blank (count-lines pos-before-blank end) - :post-affiliated post-affiliated) - (cdr affiliated)))))) - -(defun org-element-diary-sexp-interpreter (diary-sexp contents) - "Interpret DIARY-SEXP as Org syntax. -CONTENTS is nil." - (org-element-property :value diary-sexp)) - - -;;;; Example Block - -(defun org-element--remove-indentation (s &optional n) - "Remove maximum common indentation in string S and return it. -When optional argument N is a positive integer, remove exactly -that much characters from indentation, if possible, or return -S as-is otherwise. Unlike to `org-remove-indentation', this -function doesn't call `untabify' on S." - (catch 'exit - (with-temp-buffer - (insert s) - (goto-char (point-min)) - ;; Find maximum common indentation, if not specified. - (setq n (or n - (let ((min-ind (point-max))) - (save-excursion - (while (re-search-forward "^[ \t]*\\S-" nil t) - (let ((ind (1- (current-column)))) - (if (zerop ind) (throw 'exit s) - (setq min-ind (min min-ind ind)))))) - min-ind))) - (if (zerop n) s - ;; Remove exactly N indentation, but give up if not possible. - (while (not (eobp)) - (let ((ind (progn (skip-chars-forward " \t") (current-column)))) - (cond ((eolp) (delete-region (line-beginning-position) (point))) - ((< ind n) (throw 'exit s)) - (t (org-indent-line-to (- ind n)))) - (forward-line))) - (buffer-string))))) - -(defun org-element-example-block-parser (limit affiliated) - "Parse an example block. - -LIMIT bounds the search. AFFILIATED is a list of which CAR is -the buffer position at the beginning of the first affiliated -keyword and CDR is a plist of affiliated keywords along with -their value. - -Return a list whose CAR is `example-block' and CDR is a plist -containing `:begin', `:end', `:number-lines', `:preserve-indent', -`:retain-labels', `:use-labels', `:label-fmt', `:hiddenp', -`:switches', `:value', `:post-blank' and `:post-affiliated' -keywords." - (let ((case-fold-search t)) - (if (not (save-excursion - (re-search-forward "^[ \t]*#\\+END_EXAMPLE[ \t]*$" limit t))) - ;; Incomplete block: parse it as a paragraph. - (org-element-paragraph-parser limit affiliated) - (let ((contents-end (match-beginning 0))) - (save-excursion - (let* ((switches - (progn - (looking-at "^[ \t]*#\\+BEGIN_EXAMPLE\\(?: +\\(.*\\)\\)?") - (org-match-string-no-properties 1))) - ;; Switches analysis - (number-lines - (cond ((not switches) nil) - ((string-match "-n\\>" switches) 'new) - ((string-match "+n\\>" switches) 'continued))) - (preserve-indent - (or org-src-preserve-indentation - (and switches (string-match "-i\\>" switches)))) - ;; Should labels be retained in (or stripped from) example - ;; blocks? - (retain-labels - (or (not switches) - (not (string-match "-r\\>" switches)) - (and number-lines (string-match "-k\\>" switches)))) - ;; What should code-references use - labels or - ;; line-numbers? - (use-labels - (or (not switches) - (and retain-labels - (not (string-match "-k\\>" switches))))) - (label-fmt - (and switches - (string-match "-l +\"\\([^\"\n]+\\)\"" switches) - (match-string 1 switches))) - ;; Standard block parsing. - (begin (car affiliated)) - (post-affiliated (point)) - (block-ind (progn (skip-chars-forward " \t") (current-column))) - (contents-begin (progn (forward-line) (point))) - (hidden (org-invisible-p2)) - (value (org-element--remove-indentation - (org-unescape-code-in-string - (buffer-substring-no-properties - contents-begin contents-end)) - (and preserve-indent block-ind))) - (pos-before-blank (progn (goto-char contents-end) - (forward-line) - (point))) - (end (progn (skip-chars-forward " \r\t\n" limit) - (if (eobp) (point) (line-beginning-position))))) - (list 'example-block - (nconc - (list :begin begin - :end end - :value value - :switches switches - :number-lines number-lines - :preserve-indent preserve-indent - :retain-labels retain-labels - :use-labels use-labels - :label-fmt label-fmt - :hiddenp hidden - :post-blank (count-lines pos-before-blank end) - :post-affiliated post-affiliated) - (cdr affiliated))))))))) - -(defun org-element-example-block-interpreter (example-block contents) - "Interpret EXAMPLE-BLOCK element as Org syntax. -CONTENTS is nil." - (let ((switches (org-element-property :switches example-block))) - (concat "#+BEGIN_EXAMPLE" (and switches (concat " " switches)) "\n" - (org-escape-code-in-string - (org-element-property :value example-block)) - "#+END_EXAMPLE"))) - - -;;;; Export Block - -(defun org-element-export-block-parser (limit affiliated) - "Parse an export block. - -LIMIT bounds the search. AFFILIATED is a list of which CAR is -the buffer position at the beginning of the first affiliated -keyword and CDR is a plist of affiliated keywords along with -their value. - -Return a list whose CAR is `export-block' and CDR is a plist -containing `:begin', `:end', `:type', `:hiddenp', `:value', -`:post-blank' and `:post-affiliated' keywords. - -Assume point is at export-block beginning." - (let* ((case-fold-search t) - (type (progn (looking-at "[ \t]*#\\+BEGIN_\\(\\S-+\\)") - (upcase (org-match-string-no-properties 1))))) - (if (not (save-excursion - (re-search-forward - (format "^[ \t]*#\\+END_%s[ \t]*$" type) limit t))) - ;; Incomplete block: parse it as a paragraph. - (org-element-paragraph-parser limit affiliated) - (let ((contents-end (match-beginning 0))) - (save-excursion - (let* ((begin (car affiliated)) - (post-affiliated (point)) - (contents-begin (progn (forward-line) (point))) - (hidden (org-invisible-p2)) - (pos-before-blank (progn (goto-char contents-end) - (forward-line) - (point))) - (end (progn (skip-chars-forward " \r\t\n" limit) - (if (eobp) (point) (line-beginning-position)))) - (value (buffer-substring-no-properties contents-begin - contents-end))) - (list 'export-block - (nconc - (list :begin begin - :end end - :type type - :value value - :hiddenp hidden - :post-blank (count-lines pos-before-blank end) - :post-affiliated post-affiliated) - (cdr affiliated))))))))) - -(defun org-element-export-block-interpreter (export-block contents) - "Interpret EXPORT-BLOCK element as Org syntax. -CONTENTS is nil." - (let ((type (org-element-property :type export-block))) - (concat (format "#+BEGIN_%s\n" type) - (org-element-property :value export-block) - (format "#+END_%s" type)))) - - -;;;; Fixed-width - -(defun org-element-fixed-width-parser (limit affiliated) - "Parse a fixed-width section. - -LIMIT bounds the search. AFFILIATED is a list of which CAR is -the buffer position at the beginning of the first affiliated -keyword and CDR is a plist of affiliated keywords along with -their value. - -Return a list whose CAR is `fixed-width' and CDR is a plist -containing `:begin', `:end', `:value', `:post-blank' and -`:post-affiliated' keywords. - -Assume point is at the beginning of the fixed-width area." - (save-excursion - (let* ((begin (car affiliated)) - (post-affiliated (point)) - value - (end-area - (progn - (while (and (< (point) limit) - (looking-at "[ \t]*:\\( \\|$\\)")) - ;; Accumulate text without starting colons. - (setq value - (concat value - (buffer-substring-no-properties - (match-end 0) (point-at-eol)) - "\n")) - (forward-line)) - (point))) - (end (progn (skip-chars-forward " \r\t\n" limit) - (if (eobp) (point) (line-beginning-position))))) - (list 'fixed-width - (nconc - (list :begin begin - :end end - :value value - :post-blank (count-lines end-area end) - :post-affiliated post-affiliated) - (cdr affiliated)))))) - -(defun org-element-fixed-width-interpreter (fixed-width contents) - "Interpret FIXED-WIDTH element as Org syntax. -CONTENTS is nil." - (let ((value (org-element-property :value fixed-width))) - (and value - (replace-regexp-in-string - "^" ": " - (if (string-match "\n\\'" value) (substring value 0 -1) value))))) - - -;;;; Horizontal Rule - -(defun org-element-horizontal-rule-parser (limit affiliated) - "Parse an horizontal rule. - -LIMIT bounds the search. AFFILIATED is a list of which CAR is -the buffer position at the beginning of the first affiliated -keyword and CDR is a plist of affiliated keywords along with -their value. - -Return a list whose CAR is `horizontal-rule' and CDR is a plist -containing `:begin', `:end', `:post-blank' and `:post-affiliated' -keywords." - (save-excursion - (let ((begin (car affiliated)) - (post-affiliated (point)) - (post-hr (progn (forward-line) (point))) - (end (progn (skip-chars-forward " \r\t\n" limit) - (if (eobp) (point) (line-beginning-position))))) - (list 'horizontal-rule - (nconc - (list :begin begin - :end end - :post-blank (count-lines post-hr end) - :post-affiliated post-affiliated) - (cdr affiliated)))))) - -(defun org-element-horizontal-rule-interpreter (horizontal-rule contents) - "Interpret HORIZONTAL-RULE element as Org syntax. -CONTENTS is nil." - "-----") - - -;;;; Keyword - -(defun org-element-keyword-parser (limit affiliated) - "Parse a keyword at point. - -LIMIT bounds the search. AFFILIATED is a list of which CAR is -the buffer position at the beginning of the first affiliated -keyword and CDR is a plist of affiliated keywords along with -their value. - -Return a list whose CAR is `keyword' and CDR is a plist -containing `:key', `:value', `:begin', `:end', `:post-blank' and -`:post-affiliated' keywords." - (save-excursion - (let ((begin (car affiliated)) - (post-affiliated (point)) - (key (progn (looking-at "[ \t]*#\\+\\(\\S-+*\\):") - (upcase (org-match-string-no-properties 1)))) - (value (org-trim (buffer-substring-no-properties - (match-end 0) (point-at-eol)))) - (pos-before-blank (progn (forward-line) (point))) - (end (progn (skip-chars-forward " \r\t\n" limit) - (if (eobp) (point) (line-beginning-position))))) - (list 'keyword - (nconc - (list :key key - :value value - :begin begin - :end end - :post-blank (count-lines pos-before-blank end) - :post-affiliated post-affiliated) - (cdr affiliated)))))) - -(defun org-element-keyword-interpreter (keyword contents) - "Interpret KEYWORD element as Org syntax. -CONTENTS is nil." - (format "#+%s: %s" - (org-element-property :key keyword) - (org-element-property :value keyword))) - - -;;;; Latex Environment - -(defun org-element-latex-environment-parser (limit affiliated) - "Parse a LaTeX environment. - -LIMIT bounds the search. AFFILIATED is a list of which CAR is -the buffer position at the beginning of the first affiliated -keyword and CDR is a plist of affiliated keywords along with -their value. - -Return a list whose CAR is `latex-environment' and CDR is a plist -containing `:begin', `:end', `:value', `:post-blank' and -`:post-affiliated' keywords. - -Assume point is at the beginning of the latex environment." - (save-excursion - (let ((case-fold-search t) - (code-begin (point))) - (looking-at "[ \t]*\\\\begin{\\([A-Za-z0-9]+\\*?\\)}") - (if (not (re-search-forward (format "^[ \t]*\\\\end{%s}[ \t]*$" - (regexp-quote (match-string 1))) - limit t)) - ;; Incomplete latex environment: parse it as a paragraph. - (org-element-paragraph-parser limit affiliated) - (let* ((code-end (progn (forward-line) (point))) - (begin (car affiliated)) - (value (buffer-substring-no-properties code-begin code-end)) - (end (progn (skip-chars-forward " \r\t\n" limit) - (if (eobp) (point) (line-beginning-position))))) - (list 'latex-environment - (nconc - (list :begin begin - :end end - :value value - :post-blank (count-lines code-end end) - :post-affiliated code-begin) - (cdr affiliated)))))))) - -(defun org-element-latex-environment-interpreter (latex-environment contents) - "Interpret LATEX-ENVIRONMENT element as Org syntax. -CONTENTS is nil." - (org-element-property :value latex-environment)) - - -;;;; Node Property - -(defun org-element-node-property-parser (limit) - "Parse a node-property at point. - -LIMIT bounds the search. - -Return a list whose CAR is `node-property' and CDR is a plist -containing `:key', `:value', `:begin', `:end' and `:post-blank' -keywords." - (looking-at org-property-re) - (let ((begin (point)) - (key (org-match-string-no-properties 2)) - (value (org-match-string-no-properties 3)) - (end (save-excursion - (end-of-line) - (if (re-search-forward org-property-re limit t) - (line-beginning-position) - limit)))) - (list 'node-property - (list :key key - :value value - :begin begin - :end end - :post-blank 0)))) - -(defun org-element-node-property-interpreter (node-property contents) - "Interpret NODE-PROPERTY element as Org syntax. -CONTENTS is nil." - (format org-property-format - (format ":%s:" (org-element-property :key node-property)) - (or (org-element-property :value node-property) ""))) - - -;;;; Paragraph - -(defun org-element-paragraph-parser (limit affiliated) - "Parse a paragraph. - -LIMIT bounds the search. AFFILIATED is a list of which CAR is -the buffer position at the beginning of the first affiliated -keyword and CDR is a plist of affiliated keywords along with -their value. - -Return a list whose CAR is `paragraph' and CDR is a plist -containing `:begin', `:end', `:contents-begin' and -`:contents-end', `:post-blank' and `:post-affiliated' keywords. - -Assume point is at the beginning of the paragraph." - (save-excursion - (let* ((begin (car affiliated)) - (contents-begin (point)) - (before-blank - (let ((case-fold-search t)) - (end-of-line) - (if (not (re-search-forward - org-element-paragraph-separate limit 'm)) - limit - ;; A matching `org-element-paragraph-separate' is not - ;; necessarily the end of the paragraph. In - ;; particular, lines starting with # or : as a first - ;; non-space character are ambiguous. We have to - ;; check if they are valid Org syntax (e.g., not an - ;; incomplete keyword). - (beginning-of-line) - (while (not - (or - ;; There's no ambiguity for other symbols or - ;; empty lines: stop here. - (looking-at "[ \t]*\\(?:[^:#]\\|$\\)") - ;; Stop at valid fixed-width areas. - (looking-at "[ \t]*:\\(?: \\|$\\)") - ;; Stop at drawers. - (and (looking-at org-drawer-regexp) - (save-excursion - (re-search-forward - "^[ \t]*:END:[ \t]*$" limit t))) - ;; Stop at valid comments. - (looking-at "[ \t]*#\\(?: \\|$\\)") - ;; Stop at valid dynamic blocks. - (and (looking-at org-dblock-start-re) - (save-excursion - (re-search-forward - "^[ \t]*#\\+END:?[ \t]*$" limit t))) - ;; Stop at valid blocks. - (and (looking-at "[ \t]*#\\+BEGIN_\\(\\S-+\\)") - (save-excursion - (re-search-forward - (format "^[ \t]*#\\+END_%s[ \t]*$" - (regexp-quote - (org-match-string-no-properties 1))) - limit t))) - ;; Stop at valid latex environments. - (and (looking-at - "[ \t]*\\\\begin{\\([A-Za-z0-9]+\\*?\\)}") - (save-excursion - (re-search-forward - (format "^[ \t]*\\\\end{%s}[ \t]*$" - (regexp-quote - (org-match-string-no-properties 1))) - limit t))) - ;; Stop at valid keywords. - (looking-at "[ \t]*#\\+\\S-+:") - ;; Skip everything else. - (not - (progn - (end-of-line) - (re-search-forward org-element-paragraph-separate - limit 'm))))) - (beginning-of-line))) - (if (= (point) limit) limit - (goto-char (line-beginning-position))))) - (contents-end (progn (skip-chars-backward " \r\t\n" contents-begin) - (forward-line) - (point))) - (end (progn (skip-chars-forward " \r\t\n" limit) - (if (eobp) (point) (line-beginning-position))))) - (list 'paragraph - (nconc - (list :begin begin - :end end - :contents-begin contents-begin - :contents-end contents-end - :post-blank (count-lines before-blank end) - :post-affiliated contents-begin) - (cdr affiliated)))))) - -(defun org-element-paragraph-interpreter (paragraph contents) - "Interpret PARAGRAPH element as Org syntax. -CONTENTS is the contents of the element." - contents) - - -;;;; Planning - -(defun org-element-planning-parser (limit) - "Parse a planning. - -LIMIT bounds the search. - -Return a list whose CAR is `planning' and CDR is a plist -containing `:closed', `:deadline', `:scheduled', `:begin', `:end' -and `:post-blank' keywords." - (save-excursion - (let* ((case-fold-search nil) - (begin (point)) - (post-blank (let ((before-blank (progn (forward-line) (point)))) - (skip-chars-forward " \r\t\n" limit) - (skip-chars-backward " \t") - (unless (bolp) (end-of-line)) - (count-lines before-blank (point)))) - (end (point)) - closed deadline scheduled) - (goto-char begin) - (while (re-search-forward org-keyword-time-not-clock-regexp end t) - (goto-char (match-end 1)) - (skip-chars-forward " \t" end) - (let ((keyword (match-string 1)) - (time (org-element-timestamp-parser))) - (cond ((equal keyword org-closed-string) (setq closed time)) - ((equal keyword org-deadline-string) (setq deadline time)) - (t (setq scheduled time))))) - (list 'planning - (list :closed closed - :deadline deadline - :scheduled scheduled - :begin begin - :end end - :post-blank post-blank))))) - -(defun org-element-planning-interpreter (planning contents) - "Interpret PLANNING element as Org syntax. -CONTENTS is nil." - (mapconcat - 'identity - (delq nil - (list (let ((deadline (org-element-property :deadline planning))) - (when deadline - (concat org-deadline-string " " - (org-element-timestamp-interpreter deadline nil)))) - (let ((scheduled (org-element-property :scheduled planning))) - (when scheduled - (concat org-scheduled-string " " - (org-element-timestamp-interpreter scheduled nil)))) - (let ((closed (org-element-property :closed planning))) - (when closed - (concat org-closed-string " " - (org-element-timestamp-interpreter closed nil)))))) - " ")) - - -;;;; Quote Section - -(defun org-element-quote-section-parser (limit) - "Parse a quote section. - -LIMIT bounds the search. - -Return a list whose CAR is `quote-section' and CDR is a plist -containing `:begin', `:end', `:value' and `:post-blank' keywords. - -Assume point is at beginning of the section." - (save-excursion - (let* ((begin (point)) - (end (progn (org-with-limited-levels (outline-next-heading)) - (point))) - (pos-before-blank (progn (skip-chars-backward " \r\t\n") - (forward-line) - (point))) - (value (buffer-substring-no-properties begin pos-before-blank))) - (list 'quote-section - (list :begin begin - :end end - :value value - :post-blank (count-lines pos-before-blank end)))))) - -(defun org-element-quote-section-interpreter (quote-section contents) - "Interpret QUOTE-SECTION element as Org syntax. -CONTENTS is nil." - (org-element-property :value quote-section)) - - -;;;; Src Block - -(defun org-element-src-block-parser (limit affiliated) - "Parse a src block. - -LIMIT bounds the search. AFFILIATED is a list of which CAR is -the buffer position at the beginning of the first affiliated -keyword and CDR is a plist of affiliated keywords along with -their value. - -Return a list whose CAR is `src-block' and CDR is a plist -containing `:language', `:switches', `:parameters', `:begin', -`:end', `:hiddenp', `:number-lines', `:retain-labels', -`:use-labels', `:label-fmt', `:preserve-indent', `:value', -`:post-blank' and `:post-affiliated' keywords. - -Assume point is at the beginning of the block." - (let ((case-fold-search t)) - (if (not (save-excursion (re-search-forward "^[ \t]*#\\+END_SRC[ \t]*$" - limit t))) - ;; Incomplete block: parse it as a paragraph. - (org-element-paragraph-parser limit affiliated) - (let ((contents-end (match-beginning 0))) - (save-excursion - (let* ((begin (car affiliated)) - (post-affiliated (point)) - ;; Get language as a string. - (language - (progn - (looking-at - (concat "^[ \t]*#\\+BEGIN_SRC" - "\\(?: +\\(\\S-+\\)\\)?" - "\\(\\(?: +\\(?:-l \".*?\"\\|[-+][A-Za-z]\\)\\)+\\)?" - "\\(.*\\)[ \t]*$")) - (org-match-string-no-properties 1))) - ;; Get switches. - (switches (org-match-string-no-properties 2)) - ;; Get parameters. - (parameters (org-match-string-no-properties 3)) - ;; Switches analysis - (number-lines - (cond ((not switches) nil) - ((string-match "-n\\>" switches) 'new) - ((string-match "+n\\>" switches) 'continued))) - (preserve-indent (or org-src-preserve-indentation - (and switches - (string-match "-i\\>" switches)))) - (label-fmt - (and switches - (string-match "-l +\"\\([^\"\n]+\\)\"" switches) - (match-string 1 switches))) - ;; Should labels be retained in (or stripped from) - ;; src blocks? - (retain-labels - (or (not switches) - (not (string-match "-r\\>" switches)) - (and number-lines (string-match "-k\\>" switches)))) - ;; What should code-references use - labels or - ;; line-numbers? - (use-labels - (or (not switches) - (and retain-labels - (not (string-match "-k\\>" switches))))) - ;; Indentation. - (block-ind (progn (skip-chars-forward " \t") (current-column))) - ;; Get visibility status. - (hidden (progn (forward-line) (org-invisible-p2))) - ;; Retrieve code. - (value (org-element--remove-indentation - (org-unescape-code-in-string - (buffer-substring-no-properties - (point) contents-end)) - (and preserve-indent block-ind))) - (pos-before-blank (progn (goto-char contents-end) - (forward-line) - (point))) - ;; Get position after ending blank lines. - (end (progn (skip-chars-forward " \r\t\n" limit) - (if (eobp) (point) (line-beginning-position))))) - (list 'src-block - (nconc - (list :language language - :switches (and (org-string-nw-p switches) - (org-trim switches)) - :parameters (and (org-string-nw-p parameters) - (org-trim parameters)) - :begin begin - :end end - :number-lines number-lines - :preserve-indent preserve-indent - :retain-labels retain-labels - :use-labels use-labels - :label-fmt label-fmt - :hiddenp hidden - :value value - :post-blank (count-lines pos-before-blank end) - :post-affiliated post-affiliated) - (cdr affiliated))))))))) - -(defun org-element-src-block-interpreter (src-block contents) - "Interpret SRC-BLOCK element as Org syntax. -CONTENTS is nil." - (let ((lang (org-element-property :language src-block)) - (switches (org-element-property :switches src-block)) - (params (org-element-property :parameters src-block)) - (value (let ((val (org-element-property :value src-block))) - (cond - ((org-element-property :preserve-indent src-block) val) - ((zerop org-edit-src-content-indentation) val) - (t - (let ((ind (make-string - org-edit-src-content-indentation 32))) - (replace-regexp-in-string - "\\(^\\)[ \t]*\\S-" ind val nil nil 1))))))) - (concat (format "#+BEGIN_SRC%s\n" - (concat (and lang (concat " " lang)) - (and switches (concat " " switches)) - (and params (concat " " params)))) - (org-escape-code-in-string value) - "#+END_SRC"))) - - -;;;; Table - -(defun org-element-table-parser (limit affiliated) - "Parse a table at point. - -LIMIT bounds the search. AFFILIATED is a list of which CAR is -the buffer position at the beginning of the first affiliated -keyword and CDR is a plist of affiliated keywords along with -their value. - -Return a list whose CAR is `table' and CDR is a plist containing -`:begin', `:end', `:tblfm', `:type', `:contents-begin', -`:contents-end', `:value', `:post-blank' and `:post-affiliated' -keywords. - -Assume point is at the beginning of the table." - (save-excursion - (let* ((case-fold-search t) - (table-begin (point)) - (type (if (org-at-table.el-p) 'table.el 'org)) - (begin (car affiliated)) - (table-end - (if (re-search-forward org-table-any-border-regexp limit 'm) - (goto-char (match-beginning 0)) - (point))) - (tblfm (let (acc) - (while (looking-at "[ \t]*#\\+TBLFM: +\\(.*\\)[ \t]*$") - (push (org-match-string-no-properties 1) acc) - (forward-line)) - acc)) - (pos-before-blank (point)) - (end (progn (skip-chars-forward " \r\t\n" limit) - (if (eobp) (point) (line-beginning-position))))) - (list 'table - (nconc - (list :begin begin - :end end - :type type - :tblfm tblfm - ;; Only `org' tables have contents. `table.el' tables - ;; use a `:value' property to store raw table as - ;; a string. - :contents-begin (and (eq type 'org) table-begin) - :contents-end (and (eq type 'org) table-end) - :value (and (eq type 'table.el) - (buffer-substring-no-properties - table-begin table-end)) - :post-blank (count-lines pos-before-blank end) - :post-affiliated table-begin) - (cdr affiliated)))))) - -(defun org-element-table-interpreter (table contents) - "Interpret TABLE element as Org syntax. -CONTENTS is a string, if table's type is `org', or nil." - (if (eq (org-element-property :type table) 'table.el) - (org-remove-indentation (org-element-property :value table)) - (concat (with-temp-buffer (insert contents) - (org-table-align) - (buffer-string)) - (mapconcat (lambda (fm) (concat "#+TBLFM: " fm)) - (reverse (org-element-property :tblfm table)) - "\n")))) - - -;;;; Table Row - -(defun org-element-table-row-parser (limit) - "Parse table row at point. - -LIMIT bounds the search. - -Return a list whose CAR is `table-row' and CDR is a plist -containing `:begin', `:end', `:contents-begin', `:contents-end', -`:type' and `:post-blank' keywords." - (save-excursion - (let* ((type (if (looking-at "^[ \t]*|-") 'rule 'standard)) - (begin (point)) - ;; A table rule has no contents. In that case, ensure - ;; CONTENTS-BEGIN matches CONTENTS-END. - (contents-begin (and (eq type 'standard) - (search-forward "|") - (point))) - (contents-end (and (eq type 'standard) - (progn - (end-of-line) - (skip-chars-backward " \t") - (point)))) - (end (progn (forward-line) (point)))) - (list 'table-row - (list :type type - :begin begin - :end end - :contents-begin contents-begin - :contents-end contents-end - :post-blank 0))))) - -(defun org-element-table-row-interpreter (table-row contents) - "Interpret TABLE-ROW element as Org syntax. -CONTENTS is the contents of the table row." - (if (eq (org-element-property :type table-row) 'rule) "|-" - (concat "| " contents))) - - -;;;; Verse Block - -(defun org-element-verse-block-parser (limit affiliated) - "Parse a verse block. - -LIMIT bounds the search. AFFILIATED is a list of which CAR is -the buffer position at the beginning of the first affiliated -keyword and CDR is a plist of affiliated keywords along with -their value. - -Return a list whose CAR is `verse-block' and CDR is a plist -containing `:begin', `:end', `:contents-begin', `:contents-end', -`:hiddenp', `:post-blank' and `:post-affiliated' keywords. - -Assume point is at beginning of the block." - (let ((case-fold-search t)) - (if (not (save-excursion - (re-search-forward "^[ \t]*#\\+END_VERSE[ \t]*$" limit t))) - ;; Incomplete block: parse it as a paragraph. - (org-element-paragraph-parser limit affiliated) - (let ((contents-end (match-beginning 0))) - (save-excursion - (let* ((begin (car affiliated)) - (post-affiliated (point)) - (hidden (progn (forward-line) (org-invisible-p2))) - (contents-begin (point)) - (pos-before-blank (progn (goto-char contents-end) - (forward-line) - (point))) - (end (progn (skip-chars-forward " \r\t\n" limit) - (if (eobp) (point) (line-beginning-position))))) - (list 'verse-block - (nconc - (list :begin begin - :end end - :contents-begin contents-begin - :contents-end contents-end - :hiddenp hidden - :post-blank (count-lines pos-before-blank end) - :post-affiliated post-affiliated) - (cdr affiliated))))))))) - -(defun org-element-verse-block-interpreter (verse-block contents) - "Interpret VERSE-BLOCK element as Org syntax. -CONTENTS is verse block contents." - (format "#+BEGIN_VERSE\n%s#+END_VERSE" contents)) - - - -;;; Objects -;; -;; Unlike to elements, interstices can be found between objects. -;; That's why, along with the parser, successor functions are provided -;; for each object. Some objects share the same successor (e.g., -;; `code' and `verbatim' objects). -;; -;; A successor must accept a single argument bounding the search. It -;; will return either a cons cell whose CAR is the object's type, as -;; a symbol, and CDR the position of its next occurrence, or nil. -;; -;; Successors follow the naming convention: -;; org-element-NAME-successor, where NAME is the name of the -;; successor, as defined in `org-element-all-successors'. -;; -;; Some object types (e.g., `italic') are recursive. Restrictions on -;; object types they can contain will be specified in -;; `org-element-object-restrictions'. -;; -;; Adding a new type of object is simple. Implement a successor, -;; a parser, and an interpreter for it, all following the naming -;; convention. Register type in `org-element-all-objects' and -;; successor in `org-element-all-successors'. Maybe tweak -;; restrictions about it, and that's it. - - -;;;; Bold - -(defun org-element-bold-parser () - "Parse bold object at point. - -Return a list whose CAR is `bold' and CDR is a plist with -`:begin', `:end', `:contents-begin' and `:contents-end' and -`:post-blank' keywords. - -Assume point is at the first star marker." - (save-excursion - (unless (bolp) (backward-char 1)) - (looking-at org-emph-re) - (let ((begin (match-beginning 2)) - (contents-begin (match-beginning 4)) - (contents-end (match-end 4)) - (post-blank (progn (goto-char (match-end 2)) - (skip-chars-forward " \t"))) - (end (point))) - (list 'bold - (list :begin begin - :end end - :contents-begin contents-begin - :contents-end contents-end - :post-blank post-blank))))) - -(defun org-element-bold-interpreter (bold contents) - "Interpret BOLD object as Org syntax. -CONTENTS is the contents of the object." - (format "*%s*" contents)) - -(defun org-element-text-markup-successor () - "Search for the next text-markup object. - -Return value is a cons cell whose CAR is a symbol among `bold', -`italic', `underline', `strike-through', `code' and `verbatim' -and CDR is beginning position." - (save-excursion - (unless (bolp) (backward-char)) - (when (re-search-forward org-emph-re nil t) - (let ((marker (match-string 3))) - (cons (cond - ((equal marker "*") 'bold) - ((equal marker "/") 'italic) - ((equal marker "_") 'underline) - ((equal marker "+") 'strike-through) - ((equal marker "~") 'code) - ((equal marker "=") 'verbatim) - (t (error "Unknown marker at %d" (match-beginning 3)))) - (match-beginning 2)))))) - - -;;;; Code - -(defun org-element-code-parser () - "Parse code object at point. - -Return a list whose CAR is `code' and CDR is a plist with -`:value', `:begin', `:end' and `:post-blank' keywords. - -Assume point is at the first tilde marker." - (save-excursion - (unless (bolp) (backward-char 1)) - (looking-at org-emph-re) - (let ((begin (match-beginning 2)) - (value (org-match-string-no-properties 4)) - (post-blank (progn (goto-char (match-end 2)) - (skip-chars-forward " \t"))) - (end (point))) - (list 'code - (list :value value - :begin begin - :end end - :post-blank post-blank))))) - -(defun org-element-code-interpreter (code contents) - "Interpret CODE object as Org syntax. -CONTENTS is nil." - (format "~%s~" (org-element-property :value code))) - - -;;;; Entity - -(defun org-element-entity-parser () - "Parse entity at point. - -Return a list whose CAR is `entity' and CDR a plist with -`:begin', `:end', `:latex', `:latex-math-p', `:html', `:latin1', -`:utf-8', `:ascii', `:use-brackets-p' and `:post-blank' as -keywords. - -Assume point is at the beginning of the entity." - (save-excursion - (looking-at "\\\\\\(there4\\|sup[123]\\|frac[13][24]\\|[a-zA-Z]+\\)\\($\\|{}\\|[^[:alpha:]]\\)") - (let* ((value (org-entity-get (match-string 1))) - (begin (match-beginning 0)) - (bracketsp (string= (match-string 2) "{}")) - (post-blank (progn (goto-char (match-end 1)) - (when bracketsp (forward-char 2)) - (skip-chars-forward " \t"))) - (end (point))) - (list 'entity - (list :name (car value) - :latex (nth 1 value) - :latex-math-p (nth 2 value) - :html (nth 3 value) - :ascii (nth 4 value) - :latin1 (nth 5 value) - :utf-8 (nth 6 value) - :begin begin - :end end - :use-brackets-p bracketsp - :post-blank post-blank))))) - -(defun org-element-entity-interpreter (entity contents) - "Interpret ENTITY object as Org syntax. -CONTENTS is nil." - (concat "\\" - (org-element-property :name entity) - (when (org-element-property :use-brackets-p entity) "{}"))) - -(defun org-element-latex-or-entity-successor () - "Search for the next latex-fragment or entity object. - -Return value is a cons cell whose CAR is `entity' or -`latex-fragment' and CDR is beginning position." - (save-excursion - (unless (bolp) (backward-char)) - (let ((matchers (cdr org-latex-regexps)) - ;; ENTITY-RE matches both LaTeX commands and Org entities. - (entity-re - "\\\\\\(there4\\|sup[123]\\|frac[13][24]\\|[a-zA-Z]+\\)\\($\\|{}\\|[^[:alpha:]]\\)")) - (when (re-search-forward - (concat (mapconcat #'cadr matchers "\\|") "\\|" entity-re) nil t) - (goto-char (match-beginning 0)) - (if (looking-at entity-re) - ;; Determine if it's a real entity or a LaTeX command. - (cons (if (org-entity-get (match-string 1)) 'entity 'latex-fragment) - (match-beginning 0)) - ;; No entity nor command: point is at a LaTeX fragment. - ;; Determine its type to get the correct beginning position. - (cons 'latex-fragment - (catch 'return - (dolist (e matchers) - (when (looking-at (nth 1 e)) - (throw 'return (match-beginning (nth 2 e))))) - (point)))))))) - - -;;;; Export Snippet - -(defun org-element-export-snippet-parser () - "Parse export snippet at point. - -Return a list whose CAR is `export-snippet' and CDR a plist with -`:begin', `:end', `:back-end', `:value' and `:post-blank' as -keywords. - -Assume point is at the beginning of the snippet." - (save-excursion - (re-search-forward "@@\\([-A-Za-z0-9]+\\):" nil t) - (let* ((begin (match-beginning 0)) - (back-end (org-match-string-no-properties 1)) - (value (buffer-substring-no-properties - (point) - (progn (re-search-forward "@@" nil t) (match-beginning 0)))) - (post-blank (skip-chars-forward " \t")) - (end (point))) - (list 'export-snippet - (list :back-end back-end - :value value - :begin begin - :end end - :post-blank post-blank))))) - -(defun org-element-export-snippet-interpreter (export-snippet contents) - "Interpret EXPORT-SNIPPET object as Org syntax. -CONTENTS is nil." - (format "@@%s:%s@@" - (org-element-property :back-end export-snippet) - (org-element-property :value export-snippet))) - -(defun org-element-export-snippet-successor () - "Search for the next export-snippet object. - -Return value is a cons cell whose CAR is `export-snippet' and CDR -its beginning position." - (save-excursion - (let (beg) - (when (and (re-search-forward "@@[-A-Za-z0-9]+:" nil t) - (setq beg (match-beginning 0)) - (search-forward "@@" nil t)) - (cons 'export-snippet beg))))) - - -;;;; Footnote Reference - -(defun org-element-footnote-reference-parser () - "Parse footnote reference at point. - -Return a list whose CAR is `footnote-reference' and CDR a plist -with `:label', `:type', `:inline-definition', `:begin', `:end' -and `:post-blank' as keywords." - (save-excursion - (looking-at org-footnote-re) - (let* ((begin (point)) - (label (or (org-match-string-no-properties 2) - (org-match-string-no-properties 3) - (and (match-string 1) - (concat "fn:" (org-match-string-no-properties 1))))) - (type (if (or (not label) (match-string 1)) 'inline 'standard)) - (inner-begin (match-end 0)) - (inner-end - (let ((count 1)) - (forward-char) - (while (and (> count 0) (re-search-forward "[][]" nil t)) - (if (equal (match-string 0) "[") (incf count) (decf count))) - (1- (point)))) - (post-blank (progn (goto-char (1+ inner-end)) - (skip-chars-forward " \t"))) - (end (point)) - (footnote-reference - (list 'footnote-reference - (list :label label - :type type - :begin begin - :end end - :post-blank post-blank)))) - (org-element-put-property - footnote-reference :inline-definition - (and (eq type 'inline) - (org-element-parse-secondary-string - (buffer-substring inner-begin inner-end) - (org-element-restriction 'footnote-reference) - footnote-reference)))))) - -(defun org-element-footnote-reference-interpreter (footnote-reference contents) - "Interpret FOOTNOTE-REFERENCE object as Org syntax. -CONTENTS is nil." - (let ((label (or (org-element-property :label footnote-reference) "fn:")) - (def - (let ((inline-def - (org-element-property :inline-definition footnote-reference))) - (if (not inline-def) "" - (concat ":" (org-element-interpret-data inline-def)))))) - (format "[%s]" (concat label def)))) - -(defun org-element-footnote-reference-successor () - "Search for the next footnote-reference object. - -Return value is a cons cell whose CAR is `footnote-reference' and -CDR is beginning position." - (save-excursion - (catch 'exit - (while (re-search-forward org-footnote-re nil t) - (save-excursion - (let ((beg (match-beginning 0)) - (count 1)) - (backward-char) - (while (re-search-forward "[][]" nil t) - (if (equal (match-string 0) "[") (incf count) (decf count)) - (when (zerop count) - (throw 'exit (cons 'footnote-reference beg)))))))))) - - -;;;; Inline Babel Call - -(defun org-element-inline-babel-call-parser () - "Parse inline babel call at point. - -Return a list whose CAR is `inline-babel-call' and CDR a plist -with `:begin', `:end', `:info' and `:post-blank' as keywords. - -Assume point is at the beginning of the babel call." - (save-excursion - (unless (bolp) (backward-char)) - (looking-at org-babel-inline-lob-one-liner-regexp) - (let ((info (save-match-data (org-babel-lob-get-info))) - (begin (match-end 1)) - (post-blank (progn (goto-char (match-end 0)) - (skip-chars-forward " \t"))) - (end (point))) - (list 'inline-babel-call - (list :begin begin - :end end - :info info - :post-blank post-blank))))) - -(defun org-element-inline-babel-call-interpreter (inline-babel-call contents) - "Interpret INLINE-BABEL-CALL object as Org syntax. -CONTENTS is nil." - (let* ((babel-info (org-element-property :info inline-babel-call)) - (main-source (car babel-info)) - (post-options (nth 1 babel-info))) - (concat "call_" - (if (string-match "\\[\\(\\[.*?\\]\\)\\]" main-source) - ;; Remove redundant square brackets. - (replace-match - (match-string 1 main-source) nil nil main-source) - main-source) - (and post-options (format "[%s]" post-options))))) - -(defun org-element-inline-babel-call-successor () - "Search for the next inline-babel-call object. - -Return value is a cons cell whose CAR is `inline-babel-call' and -CDR is beginning position." - (save-excursion - (when (re-search-forward org-babel-inline-lob-one-liner-regexp nil t) - (cons 'inline-babel-call (match-end 1))))) - - -;;;; Inline Src Block - -(defun org-element-inline-src-block-parser () - "Parse inline source block at point. - -Return a list whose CAR is `inline-src-block' and CDR a plist -with `:begin', `:end', `:language', `:value', `:parameters' and -`:post-blank' as keywords. - -Assume point is at the beginning of the inline src block." - (save-excursion - (unless (bolp) (backward-char)) - (looking-at org-babel-inline-src-block-regexp) - (let ((begin (match-beginning 1)) - (language (org-match-string-no-properties 2)) - (parameters (org-match-string-no-properties 4)) - (value (org-match-string-no-properties 5)) - (post-blank (progn (goto-char (match-end 0)) - (skip-chars-forward " \t"))) - (end (point))) - (list 'inline-src-block - (list :language language - :value value - :parameters parameters - :begin begin - :end end - :post-blank post-blank))))) - -(defun org-element-inline-src-block-interpreter (inline-src-block contents) - "Interpret INLINE-SRC-BLOCK object as Org syntax. -CONTENTS is nil." - (let ((language (org-element-property :language inline-src-block)) - (arguments (org-element-property :parameters inline-src-block)) - (body (org-element-property :value inline-src-block))) - (format "src_%s%s{%s}" - language - (if arguments (format "[%s]" arguments) "") - body))) - -(defun org-element-inline-src-block-successor () - "Search for the next inline-babel-call element. - -Return value is a cons cell whose CAR is `inline-babel-call' and -CDR is beginning position." - (save-excursion - (unless (bolp) (backward-char)) - (when (re-search-forward org-babel-inline-src-block-regexp nil t) - (cons 'inline-src-block (match-beginning 1))))) - -;;;; Italic - -(defun org-element-italic-parser () - "Parse italic object at point. - -Return a list whose CAR is `italic' and CDR is a plist with -`:begin', `:end', `:contents-begin' and `:contents-end' and -`:post-blank' keywords. - -Assume point is at the first slash marker." - (save-excursion - (unless (bolp) (backward-char 1)) - (looking-at org-emph-re) - (let ((begin (match-beginning 2)) - (contents-begin (match-beginning 4)) - (contents-end (match-end 4)) - (post-blank (progn (goto-char (match-end 2)) - (skip-chars-forward " \t"))) - (end (point))) - (list 'italic - (list :begin begin - :end end - :contents-begin contents-begin - :contents-end contents-end - :post-blank post-blank))))) - -(defun org-element-italic-interpreter (italic contents) - "Interpret ITALIC object as Org syntax. -CONTENTS is the contents of the object." - (format "/%s/" contents)) - - -;;;; Latex Fragment - -(defun org-element-latex-fragment-parser () - "Parse LaTeX fragment at point. - -Return a list whose CAR is `latex-fragment' and CDR a plist with -`:value', `:begin', `:end', and `:post-blank' as keywords. - -Assume point is at the beginning of the LaTeX fragment." - (save-excursion - (let* ((begin (point)) - (substring-match - (catch 'exit - (dolist (e (cdr org-latex-regexps)) - (let ((latex-regexp (nth 1 e))) - (when (or (looking-at latex-regexp) - (and (not (bobp)) - (save-excursion - (backward-char) - (looking-at latex-regexp)))) - (throw 'exit (nth 2 e))))) - ;; None found: it's a macro. - (looking-at "\\\\[a-zA-Z]+\\*?\\(\\(\\[[^][\n{}]*\\]\\)\\|\\({[^{}\n]*}\\)\\)*") - 0)) - (value (org-match-string-no-properties substring-match)) - (post-blank (progn (goto-char (match-end substring-match)) - (skip-chars-forward " \t"))) - (end (point))) - (list 'latex-fragment - (list :value value - :begin begin - :end end - :post-blank post-blank))))) - -(defun org-element-latex-fragment-interpreter (latex-fragment contents) - "Interpret LATEX-FRAGMENT object as Org syntax. -CONTENTS is nil." - (org-element-property :value latex-fragment)) - -;;;; Line Break - -(defun org-element-line-break-parser () - "Parse line break at point. - -Return a list whose CAR is `line-break', and CDR a plist with -`:begin', `:end' and `:post-blank' keywords. - -Assume point is at the beginning of the line break." - (list 'line-break - (list :begin (point) - :end (progn (forward-line) (point)) - :post-blank 0))) - -(defun org-element-line-break-interpreter (line-break contents) - "Interpret LINE-BREAK object as Org syntax. -CONTENTS is nil." - "\\\\\n") - -(defun org-element-line-break-successor () - "Search for the next line-break object. - -Return value is a cons cell whose CAR is `line-break' and CDR is -beginning position." - (save-excursion - (let ((beg (and (re-search-forward "[^\\\\]\\(\\\\\\\\\\)[ \t]*$" nil t) - (goto-char (match-beginning 1))))) - ;; A line break can only happen on a non-empty line. - (when (and beg (re-search-backward "\\S-" (point-at-bol) t)) - (cons 'line-break beg))))) - - -;;;; Link - -(defun org-element-link-parser () - "Parse link at point. - -Return a list whose CAR is `link' and CDR a plist with `:type', -`:path', `:raw-link', `:application', `:search-option', `:begin', -`:end', `:contents-begin', `:contents-end' and `:post-blank' as -keywords. - -Assume point is at the beginning of the link." - (save-excursion - (let ((begin (point)) - end contents-begin contents-end link-end post-blank path type - raw-link link search-option application) - (cond - ;; Type 1: Text targeted from a radio target. - ((and org-target-link-regexp (looking-at org-target-link-regexp)) - (setq type "radio" - link-end (match-end 0) - path (org-match-string-no-properties 0) - contents-begin (match-beginning 0) - contents-end (match-end 0))) - ;; Type 2: Standard link, i.e. [[http://orgmode.org][homepage]] - ((looking-at org-bracket-link-regexp) - (setq contents-begin (match-beginning 3) - contents-end (match-end 3) - link-end (match-end 0) - ;; RAW-LINK is the original link. Expand any - ;; abbreviation in it. - raw-link (org-translate-link - (org-link-expand-abbrev - (org-match-string-no-properties 1)))) - ;; Determine TYPE of link and set PATH accordingly. - (cond - ;; File type. - ((or (file-name-absolute-p raw-link) - (string-match "\\`\\.\\.?/" raw-link)) - (setq type "file" path raw-link)) - ;; Explicit type (http, irc, bbdb...). See `org-link-types'. - ((string-match org-link-types-re raw-link) - (setq type (match-string 1 raw-link) - ;; According to RFC 3986, extra whitespace should be - ;; ignored when a URI is extracted. - path (replace-regexp-in-string - "[ \t]*\n[ \t]*" "" (substring raw-link (match-end 0))))) - ;; Id type: PATH is the id. - ((string-match "\\`id:\\([-a-f0-9]+\\)" raw-link) - (setq type "id" path (match-string 1 raw-link))) - ;; Code-ref type: PATH is the name of the reference. - ((string-match "\\`(\\(.*\\))\\'" raw-link) - (setq type "coderef" path (match-string 1 raw-link))) - ;; Custom-id type: PATH is the name of the custom id. - ((= (aref raw-link 0) ?#) - (setq type "custom-id" path (substring raw-link 1))) - ;; Fuzzy type: Internal link either matches a target, an - ;; headline name or nothing. PATH is the target or - ;; headline's name. - (t (setq type "fuzzy" path raw-link)))) - ;; Type 3: Plain link, e.g., http://orgmode.org - ((looking-at org-plain-link-re) - (setq raw-link (org-match-string-no-properties 0) - type (org-match-string-no-properties 1) - link-end (match-end 0) - path (org-match-string-no-properties 2))) - ;; Type 4: Angular link, e.g., - ((looking-at org-angle-link-re) - (setq raw-link (buffer-substring-no-properties - (match-beginning 1) (match-end 2)) - type (org-match-string-no-properties 1) - link-end (match-end 0) - path (org-match-string-no-properties 2)))) - ;; In any case, deduce end point after trailing white space from - ;; LINK-END variable. - (setq post-blank (progn (goto-char link-end) (skip-chars-forward " \t")) - end (point)) - ;; Special "file" type link processing. - (when (member type org-element-link-type-is-file) - ;; Extract opening application and search option. - (cond ((string-match "^file\\+\\(.*\\)$" type) - (setq application (match-string 1 type))) - ((not (string-match "^file" type)) - (setq application type))) - (when (string-match "::\\(.*\\)\\'" path) - (setq search-option (match-string 1 path) - path (replace-match "" nil nil path))) - ;; Normalize URI. - (when (and (not (org-string-match-p "\\`//" path)) - (file-name-absolute-p path)) - (setq path (concat "//" (expand-file-name path)))) - ;; Make sure TYPE always reports "file". - (setq type "file")) - (list 'link - (list :type type - :path path - :raw-link (or raw-link path) - :application application - :search-option search-option - :begin begin - :end end - :contents-begin contents-begin - :contents-end contents-end - :post-blank post-blank))))) - -(defun org-element-link-interpreter (link contents) - "Interpret LINK object as Org syntax. -CONTENTS is the contents of the object, or nil." - (let ((type (org-element-property :type link)) - (raw-link (org-element-property :raw-link link))) - (if (string= type "radio") raw-link - (format "[[%s]%s]" - raw-link - (if contents (format "[%s]" contents) ""))))) - -(defun org-element-link-successor () - "Search for the next link object. - -Return value is a cons cell whose CAR is `link' and CDR is -beginning position." - (save-excursion - (let ((link-regexp - (if (not org-target-link-regexp) org-any-link-re - (concat org-any-link-re "\\|" org-target-link-regexp)))) - (when (re-search-forward link-regexp nil t) - (cons 'link (match-beginning 0)))))) - -(defun org-element-plain-link-successor () - "Search for the next plain link object. - -Return value is a cons cell whose CAR is `link' and CDR is -beginning position." - (and (save-excursion (re-search-forward org-plain-link-re nil t)) - (cons 'link (match-beginning 0)))) - - -;;;; Macro - -(defun org-element-macro-parser () - "Parse macro at point. - -Return a list whose CAR is `macro' and CDR a plist with `:key', -`:args', `:begin', `:end', `:value' and `:post-blank' as -keywords. - -Assume point is at the macro." - (save-excursion - (looking-at "{{{\\([a-zA-Z][-a-zA-Z0-9_]*\\)\\(([ \t\n]*\\([^\000]*?\\))\\)?}}}") - (let ((begin (point)) - (key (downcase (org-match-string-no-properties 1))) - (value (org-match-string-no-properties 0)) - (post-blank (progn (goto-char (match-end 0)) - (skip-chars-forward " \t"))) - (end (point)) - (args (let ((args (org-match-string-no-properties 3))) - (when args - ;; Do not use `org-split-string' since empty - ;; strings are meaningful here. - (split-string - (replace-regexp-in-string - "\\(\\\\*\\)\\(,\\)" - (lambda (str) - (let ((len (length (match-string 1 str)))) - (concat (make-string (/ len 2) ?\\) - (if (zerop (mod len 2)) "\000" ",")))) - args nil t) - "\000"))))) - (list 'macro - (list :key key - :value value - :args args - :begin begin - :end end - :post-blank post-blank))))) - -(defun org-element-macro-interpreter (macro contents) - "Interpret MACRO object as Org syntax. -CONTENTS is nil." - (org-element-property :value macro)) - -(defun org-element-macro-successor () - "Search for the next macro object. - -Return value is cons cell whose CAR is `macro' and CDR is -beginning position." - (save-excursion - (when (re-search-forward - "{{{\\([a-zA-Z][-a-zA-Z0-9_]*\\)\\(([ \t\n]*\\([^\000]*?\\))\\)?}}}" - nil t) - (cons 'macro (match-beginning 0))))) - - -;;;; Radio-target - -(defun org-element-radio-target-parser () - "Parse radio target at point. - -Return a list whose CAR is `radio-target' and CDR a plist with -`:begin', `:end', `:contents-begin', `:contents-end', `:value' -and `:post-blank' as keywords. - -Assume point is at the radio target." - (save-excursion - (looking-at org-radio-target-regexp) - (let ((begin (point)) - (contents-begin (match-beginning 1)) - (contents-end (match-end 1)) - (value (org-match-string-no-properties 1)) - (post-blank (progn (goto-char (match-end 0)) - (skip-chars-forward " \t"))) - (end (point))) - (list 'radio-target - (list :begin begin - :end end - :contents-begin contents-begin - :contents-end contents-end - :post-blank post-blank - :value value))))) - -(defun org-element-radio-target-interpreter (target contents) - "Interpret TARGET object as Org syntax. -CONTENTS is the contents of the object." - (concat "<<<" contents ">>>")) - -(defun org-element-radio-target-successor () - "Search for the next radio-target object. - -Return value is a cons cell whose CAR is `radio-target' and CDR -is beginning position." - (save-excursion - (when (re-search-forward org-radio-target-regexp nil t) - (cons 'radio-target (match-beginning 0))))) - - -;;;; Statistics Cookie - -(defun org-element-statistics-cookie-parser () - "Parse statistics cookie at point. - -Return a list whose CAR is `statistics-cookie', and CDR a plist -with `:begin', `:end', `:value' and `:post-blank' keywords. - -Assume point is at the beginning of the statistics-cookie." - (save-excursion - (looking-at "\\[[0-9]*\\(%\\|/[0-9]*\\)\\]") - (let* ((begin (point)) - (value (buffer-substring-no-properties - (match-beginning 0) (match-end 0))) - (post-blank (progn (goto-char (match-end 0)) - (skip-chars-forward " \t"))) - (end (point))) - (list 'statistics-cookie - (list :begin begin - :end end - :value value - :post-blank post-blank))))) - -(defun org-element-statistics-cookie-interpreter (statistics-cookie contents) - "Interpret STATISTICS-COOKIE object as Org syntax. -CONTENTS is nil." - (org-element-property :value statistics-cookie)) - -(defun org-element-statistics-cookie-successor () - "Search for the next statistics cookie object. - -Return value is a cons cell whose CAR is `statistics-cookie' and -CDR is beginning position." - (save-excursion - (when (re-search-forward "\\[[0-9]*\\(%\\|/[0-9]*\\)\\]" nil t) - (cons 'statistics-cookie (match-beginning 0))))) - - -;;;; Strike-Through - -(defun org-element-strike-through-parser () - "Parse strike-through object at point. - -Return a list whose CAR is `strike-through' and CDR is a plist -with `:begin', `:end', `:contents-begin' and `:contents-end' and -`:post-blank' keywords. - -Assume point is at the first plus sign marker." - (save-excursion - (unless (bolp) (backward-char 1)) - (looking-at org-emph-re) - (let ((begin (match-beginning 2)) - (contents-begin (match-beginning 4)) - (contents-end (match-end 4)) - (post-blank (progn (goto-char (match-end 2)) - (skip-chars-forward " \t"))) - (end (point))) - (list 'strike-through - (list :begin begin - :end end - :contents-begin contents-begin - :contents-end contents-end - :post-blank post-blank))))) - -(defun org-element-strike-through-interpreter (strike-through contents) - "Interpret STRIKE-THROUGH object as Org syntax. -CONTENTS is the contents of the object." - (format "+%s+" contents)) - - -;;;; Subscript - -(defun org-element-subscript-parser () - "Parse subscript at point. - -Return a list whose CAR is `subscript' and CDR a plist with -`:begin', `:end', `:contents-begin', `:contents-end', -`:use-brackets-p' and `:post-blank' as keywords. - -Assume point is at the underscore." - (save-excursion - (unless (bolp) (backward-char)) - (let ((bracketsp (if (looking-at org-match-substring-with-braces-regexp) - t - (not (looking-at org-match-substring-regexp)))) - (begin (match-beginning 2)) - (contents-begin (or (match-beginning 5) - (match-beginning 3))) - (contents-end (or (match-end 5) (match-end 3))) - (post-blank (progn (goto-char (match-end 0)) - (skip-chars-forward " \t"))) - (end (point))) - (list 'subscript - (list :begin begin - :end end - :use-brackets-p bracketsp - :contents-begin contents-begin - :contents-end contents-end - :post-blank post-blank))))) - -(defun org-element-subscript-interpreter (subscript contents) - "Interpret SUBSCRIPT object as Org syntax. -CONTENTS is the contents of the object." - (format - (if (org-element-property :use-brackets-p subscript) "_{%s}" "_%s") - contents)) - -(defun org-element-sub/superscript-successor () - "Search for the next sub/superscript object. - -Return value is a cons cell whose CAR is either `subscript' or -`superscript' and CDR is beginning position." - (save-excursion - (unless (bolp) (backward-char)) - (when (re-search-forward org-match-substring-regexp nil t) - (cons (if (string= (match-string 2) "_") 'subscript 'superscript) - (match-beginning 2))))) - - -;;;; Superscript - -(defun org-element-superscript-parser () - "Parse superscript at point. - -Return a list whose CAR is `superscript' and CDR a plist with -`:begin', `:end', `:contents-begin', `:contents-end', -`:use-brackets-p' and `:post-blank' as keywords. - -Assume point is at the caret." - (save-excursion - (unless (bolp) (backward-char)) - (let ((bracketsp (if (looking-at org-match-substring-with-braces-regexp) t - (not (looking-at org-match-substring-regexp)))) - (begin (match-beginning 2)) - (contents-begin (or (match-beginning 5) - (match-beginning 3))) - (contents-end (or (match-end 5) (match-end 3))) - (post-blank (progn (goto-char (match-end 0)) - (skip-chars-forward " \t"))) - (end (point))) - (list 'superscript - (list :begin begin - :end end - :use-brackets-p bracketsp - :contents-begin contents-begin - :contents-end contents-end - :post-blank post-blank))))) - -(defun org-element-superscript-interpreter (superscript contents) - "Interpret SUPERSCRIPT object as Org syntax. -CONTENTS is the contents of the object." - (format - (if (org-element-property :use-brackets-p superscript) "^{%s}" "^%s") - contents)) - - -;;;; Table Cell - -(defun org-element-table-cell-parser () - "Parse table cell at point. - -Return a list whose CAR is `table-cell' and CDR is a plist -containing `:begin', `:end', `:contents-begin', `:contents-end' -and `:post-blank' keywords." - (looking-at "[ \t]*\\(.*?\\)[ \t]*\\(?:|\\|$\\)") - (let* ((begin (match-beginning 0)) - (end (match-end 0)) - (contents-begin (match-beginning 1)) - (contents-end (match-end 1))) - (list 'table-cell - (list :begin begin - :end end - :contents-begin contents-begin - :contents-end contents-end - :post-blank 0)))) - -(defun org-element-table-cell-interpreter (table-cell contents) - "Interpret TABLE-CELL element as Org syntax. -CONTENTS is the contents of the cell, or nil." - (concat " " contents " |")) - -(defun org-element-table-cell-successor () - "Search for the next table-cell object. - -Return value is a cons cell whose CAR is `table-cell' and CDR is -beginning position." - (when (looking-at "[ \t]*.*?[ \t]*\\(|\\|$\\)") (cons 'table-cell (point)))) - - -;;;; Target - -(defun org-element-target-parser () - "Parse target at point. - -Return a list whose CAR is `target' and CDR a plist with -`:begin', `:end', `:value' and `:post-blank' as keywords. - -Assume point is at the target." - (save-excursion - (looking-at org-target-regexp) - (let ((begin (point)) - (value (org-match-string-no-properties 1)) - (post-blank (progn (goto-char (match-end 0)) - (skip-chars-forward " \t"))) - (end (point))) - (list 'target - (list :begin begin - :end end - :value value - :post-blank post-blank))))) - -(defun org-element-target-interpreter (target contents) - "Interpret TARGET object as Org syntax. -CONTENTS is nil." - (format "<<%s>>" (org-element-property :value target))) - -(defun org-element-target-successor () - "Search for the next target object. - -Return value is a cons cell whose CAR is `target' and CDR is -beginning position." - (save-excursion - (when (re-search-forward org-target-regexp nil t) - (cons 'target (match-beginning 0))))) - - -;;;; Timestamp - -(defun org-element-timestamp-parser () - "Parse time stamp at point. - -Return a list whose CAR is `timestamp', and CDR a plist with -`:type', `:raw-value', `:year-start', `:month-start', -`:day-start', `:hour-start', `:minute-start', `:year-end', -`:month-end', `:day-end', `:hour-end', `:minute-end', -`:repeater-type', `:repeater-value', `:repeater-unit', -`:warning-type', `:warning-value', `:warning-unit', `:begin', -`:end' and `:post-blank' keywords. - -Assume point is at the beginning of the timestamp." - (save-excursion - (let* ((begin (point)) - (activep (eq (char-after) ?<)) - (raw-value - (progn - (looking-at "\\([<[]\\(%%\\)?.*?\\)[]>]\\(?:--\\([<[].*?[]>]\\)\\)?") - (match-string-no-properties 0))) - (date-start (match-string-no-properties 1)) - (date-end (match-string 3)) - (diaryp (match-beginning 2)) - (post-blank (progn (goto-char (match-end 0)) - (skip-chars-forward " \t"))) - (end (point)) - (time-range - (and (not diaryp) - (string-match - "[012]?[0-9]:[0-5][0-9]\\(-\\([012]?[0-9]\\):\\([0-5][0-9]\\)\\)" - date-start) - (cons (string-to-number (match-string 2 date-start)) - (string-to-number (match-string 3 date-start))))) - (type (cond (diaryp 'diary) - ((and activep (or date-end time-range)) 'active-range) - (activep 'active) - ((or date-end time-range) 'inactive-range) - (t 'inactive))) - (repeater-props - (and (not diaryp) - (string-match "\\([.+]?\\+\\)\\([0-9]+\\)\\([hdwmy]\\)" - raw-value) - (list - :repeater-type - (let ((type (match-string 1 raw-value))) - (cond ((equal "++" type) 'catch-up) - ((equal ".+" type) 'restart) - (t 'cumulate))) - :repeater-value (string-to-number (match-string 2 raw-value)) - :repeater-unit - (case (string-to-char (match-string 3 raw-value)) - (?h 'hour) (?d 'day) (?w 'week) (?m 'month) (t 'year))))) - (warning-props - (and (not diaryp) - (string-match "\\(-\\)?-\\([0-9]+\\)\\([hdwmy]\\)" raw-value) - (list - :warning-type (if (match-string 1 raw-value) 'first 'all) - :warning-value (string-to-number (match-string 2 raw-value)) - :warning-unit - (case (string-to-char (match-string 3 raw-value)) - (?h 'hour) (?d 'day) (?w 'week) (?m 'month) (t 'year))))) - year-start month-start day-start hour-start minute-start year-end - month-end day-end hour-end minute-end) - ;; Parse date-start. - (unless diaryp - (let ((date (org-parse-time-string date-start t))) - (setq year-start (nth 5 date) - month-start (nth 4 date) - day-start (nth 3 date) - hour-start (nth 2 date) - minute-start (nth 1 date)))) - ;; Compute date-end. It can be provided directly in time-stamp, - ;; or extracted from time range. Otherwise, it defaults to the - ;; same values as date-start. - (unless diaryp - (let ((date (and date-end (org-parse-time-string date-end t)))) - (setq year-end (or (nth 5 date) year-start) - month-end (or (nth 4 date) month-start) - day-end (or (nth 3 date) day-start) - hour-end (or (nth 2 date) (car time-range) hour-start) - minute-end (or (nth 1 date) (cdr time-range) minute-start)))) - (list 'timestamp - (nconc (list :type type - :raw-value raw-value - :year-start year-start - :month-start month-start - :day-start day-start - :hour-start hour-start - :minute-start minute-start - :year-end year-end - :month-end month-end - :day-end day-end - :hour-end hour-end - :minute-end minute-end - :begin begin - :end end - :post-blank post-blank) - repeater-props - warning-props))))) - -(defun org-element-timestamp-interpreter (timestamp contents) - "Interpret TIMESTAMP object as Org syntax. -CONTENTS is nil." - ;; Use `:raw-value' if specified. - (or (org-element-property :raw-value timestamp) - ;; Otherwise, build timestamp string. - (let* ((repeat-string - (concat - (case (org-element-property :repeater-type timestamp) - (cumulate "+") (catch-up "++") (restart ".+")) - (let ((val (org-element-property :repeater-value timestamp))) - (and val (number-to-string val))) - (case (org-element-property :repeater-unit timestamp) - (hour "h") (day "d") (week "w") (month "m") (year "y")))) - (warning-string - (concat - (case (org-element-property :warning-type timestamp) - (first "--") - (all "-")) - (let ((val (org-element-property :warning-value timestamp))) - (and val (number-to-string val))) - (case (org-element-property :warning-unit timestamp) - (hour "h") (day "d") (week "w") (month "m") (year "y")))) - (build-ts-string - ;; Build an Org timestamp string from TIME. ACTIVEP is - ;; non-nil when time stamp is active. If WITH-TIME-P is - ;; non-nil, add a time part. HOUR-END and MINUTE-END - ;; specify a time range in the timestamp. REPEAT-STRING - ;; is the repeater string, if any. - (lambda (time activep &optional with-time-p hour-end minute-end) - (let ((ts (format-time-string - (funcall (if with-time-p 'cdr 'car) - org-time-stamp-formats) - time))) - (when (and hour-end minute-end) - (string-match "[012]?[0-9]:[0-5][0-9]" ts) - (setq ts - (replace-match - (format "\\&-%02d:%02d" hour-end minute-end) - nil nil ts))) - (unless activep (setq ts (format "[%s]" (substring ts 1 -1)))) - (dolist (s (list repeat-string warning-string)) - (when (org-string-nw-p s) - (setq ts (concat (substring ts 0 -1) - " " - s - (substring ts -1))))) - ;; Return value. - ts))) - (type (org-element-property :type timestamp))) - (case type - ((active inactive) - (let* ((minute-start (org-element-property :minute-start timestamp)) - (minute-end (org-element-property :minute-end timestamp)) - (hour-start (org-element-property :hour-start timestamp)) - (hour-end (org-element-property :hour-end timestamp)) - (time-range-p (and hour-start hour-end minute-start minute-end - (or (/= hour-start hour-end) - (/= minute-start minute-end))))) - (funcall - build-ts-string - (encode-time 0 - (or minute-start 0) - (or hour-start 0) - (org-element-property :day-start timestamp) - (org-element-property :month-start timestamp) - (org-element-property :year-start timestamp)) - (eq type 'active) - (and hour-start minute-start) - (and time-range-p hour-end) - (and time-range-p minute-end)))) - ((active-range inactive-range) - (let ((minute-start (org-element-property :minute-start timestamp)) - (minute-end (org-element-property :minute-end timestamp)) - (hour-start (org-element-property :hour-start timestamp)) - (hour-end (org-element-property :hour-end timestamp))) - (concat - (funcall - build-ts-string (encode-time - 0 - (or minute-start 0) - (or hour-start 0) - (org-element-property :day-start timestamp) - (org-element-property :month-start timestamp) - (org-element-property :year-start timestamp)) - (eq type 'active-range) - (and hour-start minute-start)) - "--" - (funcall build-ts-string - (encode-time 0 - (or minute-end 0) - (or hour-end 0) - (org-element-property :day-end timestamp) - (org-element-property :month-end timestamp) - (org-element-property :year-end timestamp)) - (eq type 'active-range) - (and hour-end minute-end))))))))) - -(defun org-element-timestamp-successor () - "Search for the next timestamp object. - -Return value is a cons cell whose CAR is `timestamp' and CDR is -beginning position." - (save-excursion - (when (re-search-forward - (concat org-ts-regexp-both - "\\|" - "\\(?:<[0-9]+-[0-9]+-[0-9]+[^>\n]+?\\+[0-9]+[dwmy]>\\)" - "\\|" - "\\(?:<%%\\(?:([^>\n]+)\\)>\\)") - nil t) - (cons 'timestamp (match-beginning 0))))) - - -;;;; Underline - -(defun org-element-underline-parser () - "Parse underline object at point. - -Return a list whose CAR is `underline' and CDR is a plist with -`:begin', `:end', `:contents-begin' and `:contents-end' and -`:post-blank' keywords. - -Assume point is at the first underscore marker." - (save-excursion - (unless (bolp) (backward-char 1)) - (looking-at org-emph-re) - (let ((begin (match-beginning 2)) - (contents-begin (match-beginning 4)) - (contents-end (match-end 4)) - (post-blank (progn (goto-char (match-end 2)) - (skip-chars-forward " \t"))) - (end (point))) - (list 'underline - (list :begin begin - :end end - :contents-begin contents-begin - :contents-end contents-end - :post-blank post-blank))))) - -(defun org-element-underline-interpreter (underline contents) - "Interpret UNDERLINE object as Org syntax. -CONTENTS is the contents of the object." - (format "_%s_" contents)) - - -;;;; Verbatim - -(defun org-element-verbatim-parser () - "Parse verbatim object at point. - -Return a list whose CAR is `verbatim' and CDR is a plist with -`:value', `:begin', `:end' and `:post-blank' keywords. - -Assume point is at the first equal sign marker." - (save-excursion - (unless (bolp) (backward-char 1)) - (looking-at org-emph-re) - (let ((begin (match-beginning 2)) - (value (org-match-string-no-properties 4)) - (post-blank (progn (goto-char (match-end 2)) - (skip-chars-forward " \t"))) - (end (point))) - (list 'verbatim - (list :value value - :begin begin - :end end - :post-blank post-blank))))) - -(defun org-element-verbatim-interpreter (verbatim contents) - "Interpret VERBATIM object as Org syntax. -CONTENTS is nil." - (format "=%s=" (org-element-property :value verbatim))) - - - -;;; Parsing Element Starting At Point -;; -;; `org-element--current-element' is the core function of this section. -;; It returns the Lisp representation of the element starting at -;; point. -;; -;; `org-element--current-element' makes use of special modes. They -;; are activated for fixed element chaining (e.g., `plain-list' > -;; `item') or fixed conditional element chaining (e.g., `headline' > -;; `section'). Special modes are: `first-section', `item', -;; `node-property', `quote-section', `section' and `table-row'. - -(defun org-element--current-element - (limit &optional granularity special structure) - "Parse the element starting at point. - -Return value is a list like (TYPE PROPS) where TYPE is the type -of the element and PROPS a plist of properties associated to the -element. - -Possible types are defined in `org-element-all-elements'. - -LIMIT bounds the search. - -Optional argument GRANULARITY determines the depth of the -recursion. Allowed values are `headline', `greater-element', -`element', `object' or nil. When it is broader than `object' (or -nil), secondary values will not be parsed, since they only -contain objects. - -Optional argument SPECIAL, when non-nil, can be either -`first-section', `item', `node-property', `quote-section', -`section', and `table-row'. - -If STRUCTURE isn't provided but SPECIAL is set to `item', it will -be computed. - -This function assumes point is always at the beginning of the -element it has to parse." - (save-excursion - (let ((case-fold-search t) - ;; Determine if parsing depth allows for secondary strings - ;; parsing. It only applies to elements referenced in - ;; `org-element-secondary-value-alist'. - (raw-secondary-p (and granularity (not (eq granularity 'object))))) - (cond - ;; Item. - ((eq special 'item) - (org-element-item-parser limit structure raw-secondary-p)) - ;; Table Row. - ((eq special 'table-row) (org-element-table-row-parser limit)) - ;; Node Property. - ((eq special 'node-property) (org-element-node-property-parser limit)) - ;; Headline. - ((org-with-limited-levels (org-at-heading-p)) - (org-element-headline-parser limit raw-secondary-p)) - ;; Sections (must be checked after headline). - ((eq special 'section) (org-element-section-parser limit)) - ((eq special 'quote-section) (org-element-quote-section-parser limit)) - ((eq special 'first-section) - (org-element-section-parser - (or (save-excursion (org-with-limited-levels (outline-next-heading))) - limit))) - ;; When not at bol, point is at the beginning of an item or - ;; a footnote definition: next item is always a paragraph. - ((not (bolp)) (org-element-paragraph-parser limit (list (point)))) - ;; Planning and Clock. - ((looking-at org-planning-or-clock-line-re) - (if (equal (match-string 1) org-clock-string) - (org-element-clock-parser limit) - (org-element-planning-parser limit))) - ;; Inlinetask. - ((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))) - (cond - ;; Jumping over affiliated keywords put point off-limits. - ;; Parse them as regular keywords. - ((and (cdr affiliated) (>= (point) limit)) - (goto-char (car affiliated)) - (org-element-keyword-parser limit nil)) - ;; LaTeX Environment. - ((looking-at "[ \t]*\\\\begin{\\([A-Za-z0-9]+\\*?\\)}\\(\\[.*?\\]\\|{.*?}\\)*[ \t]*$") - (org-element-latex-environment-parser limit affiliated)) - ;; Drawer and Property Drawer. - ((looking-at org-drawer-regexp) - (if (equal (match-string 1) "PROPERTIES") - (org-element-property-drawer-parser limit affiliated) - (org-element-drawer-parser limit affiliated))) - ;; Fixed Width - ((looking-at "[ \t]*:\\( \\|$\\)") - (org-element-fixed-width-parser limit affiliated)) - ;; Inline Comments, Blocks, Babel Calls, Dynamic Blocks and - ;; Keywords. - ((looking-at "[ \t]*#") - (goto-char (match-end 0)) - (cond ((looking-at "\\(?: \\|$\\)") - (beginning-of-line) - (org-element-comment-parser limit affiliated)) - ((looking-at "\\+BEGIN_\\(\\S-+\\)") - (beginning-of-line) - (let ((parser (assoc (upcase (match-string 1)) - org-element-block-name-alist))) - (if parser (funcall (cdr parser) limit affiliated) - (org-element-special-block-parser limit affiliated)))) - ((looking-at "\\+CALL:") - (beginning-of-line) - (org-element-babel-call-parser limit affiliated)) - ((looking-at "\\+BEGIN:? ") - (beginning-of-line) - (org-element-dynamic-block-parser limit affiliated)) - ((looking-at "\\+\\S-+:") - (beginning-of-line) - (org-element-keyword-parser limit affiliated)) - (t - (beginning-of-line) - (org-element-paragraph-parser limit affiliated)))) - ;; Footnote Definition. - ((looking-at org-footnote-definition-re) - (org-element-footnote-definition-parser limit affiliated)) - ;; Horizontal Rule. - ((looking-at "[ \t]*-\\{5,\\}[ \t]*$") - (org-element-horizontal-rule-parser limit affiliated)) - ;; Diary Sexp. - ((looking-at "%%(") - (org-element-diary-sexp-parser limit affiliated)) - ;; Table. - ((org-at-table-p t) (org-element-table-parser limit affiliated)) - ;; List. - ((looking-at (org-item-re)) - (org-element-plain-list-parser - limit affiliated - (or structure (org-element--list-struct limit)))) - ;; Default element: Paragraph. - (t (org-element-paragraph-parser limit affiliated))))))))) - - -;; Most elements can have affiliated keywords. When looking for an -;; element beginning, we want to move before them, as they belong to -;; that element, and, in the meantime, collect information they give -;; into appropriate properties. Hence the following function. - -(defun org-element--collect-affiliated-keywords (limit) - "Collect affiliated keywords from point down to LIMIT. - -Return a list whose CAR is the position at the first of them and -CDR a plist of keywords and values and move point to the -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." - (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)) - output) - (while (and (< (point) limit) (looking-at org-element--affiliated-re)) - (let* ((raw-kwd (upcase (match-string 1))) - ;; Apply translation to RAW-KWD. From there, KWD is - ;; the official keyword. - (kwd (or (cdr (assoc raw-kwd - org-element-keyword-translation-alist)) - raw-kwd)) - ;; Find main value for any keyword. - (value - (save-match-data - (org-trim - (buffer-substring-no-properties - (match-end 0) (point-at-eol))))) - ;; 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)) - (dual-value - (and dualp - (let ((sec (org-match-string-no-properties 2))) - (if (or (not sec) (not parsedp)) sec - (org-element-parse-secondary-string sec restrict))))) - ;; 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-secondary-string value restrict))) - (when dualp - (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. - (string-match "^ATTR_" kwd)) - (setq value (cons value (plist-get output kwd-sym)))) - ;; Eventually store the new value in OUTPUT. - (setq output (plist-put output kwd-sym value)) - ;; Move to next keyword. - (forward-line))) - ;; If affiliated keywords are orphaned: move back to first one. - ;; They will be parsed as a paragraph. - (when (looking-at "[ \t]*$") (goto-char origin) (setq output nil)) - ;; Return value. - (cons origin output)))) - - - -;;; The Org Parser -;; -;; The two major functions here are `org-element-parse-buffer', which -;; parses Org syntax inside the current buffer, taking into account -;; region, narrowing, or even visibility if specified, and -;; `org-element-parse-secondary-string', which parses objects within -;; a given string. -;; -;; The (almost) almighty `org-element-map' allows to apply a function -;; on elements or objects matching some type, and accumulate the -;; resulting values. In an export situation, it also skips unneeded -;; parts of the parse tree. - -(defun org-element-parse-buffer (&optional granularity visible-only) - "Recursively parse the buffer and return structure. -If narrowing is in effect, only parse the visible part of the -buffer. - -Optional argument GRANULARITY determines the depth of the -recursion. It can be set to the following symbols: - -`headline' Only parse headlines. -`greater-element' Don't recurse into greater elements excepted - headlines and sections. Thus, elements - parsed are the top-level ones. -`element' Parse everything but objects and plain text. -`object' Parse the complete buffer (default). - -When VISIBLE-ONLY is non-nil, don't parse contents of hidden -elements. - -An element or an objects is represented as a list with the -pattern (TYPE PROPERTIES CONTENTS), where : - - TYPE is a symbol describing the element or object. See - `org-element-all-elements' and `org-element-all-objects' for an - exhaustive list of such symbols. One can retrieve it with - `org-element-type' function. - - PROPERTIES is the list of attributes attached to the element or - object, as a plist. Although most of them are specific to the - element or object type, all types share `:begin', `:end', - `:post-blank' and `:parent' properties, which respectively - refer to buffer position where the element or object starts, - ends, the number of white spaces or blank lines after it, and - the element or object containing it. Properties values can be - obtained by using `org-element-property' function. - - CONTENTS is a list of elements, objects or raw strings - contained in the current element or object, when applicable. - One can access them with `org-element-contents' function. - -The Org buffer has `org-data' as type and nil as properties. -`org-element-map' function can be used to find specific elements -or objects within the parse tree. - -This function assumes that current major mode is `org-mode'." - (save-excursion - (goto-char (point-min)) - (org-skip-whitespace) - (org-element--parse-elements - (point-at-bol) (point-max) - ;; Start in `first-section' mode so text before the first - ;; headline belongs to a section. - 'first-section nil granularity visible-only (list 'org-data nil)))) - -(defun org-element-parse-secondary-string (string restriction &optional parent) - "Recursively parse objects in STRING and return structure. - -RESTRICTION is a symbol limiting the object types that will be -looked after. - -Optional argument PARENT, when non-nil, is the element or object -containing the secondary string. It is used to set correctly -`:parent' property within the string." - (let ((local-variables (buffer-local-variables))) - (with-temp-buffer - (dolist (v local-variables) - (ignore-errors - (if (symbolp v) (makunbound v) - (org-set-local (car v) (cdr v))))) - (insert string) - (restore-buffer-modified-p nil) - (let ((secondary (org-element--parse-objects - (point-min) (point-max) nil restriction))) - (when parent - (dolist (o secondary) (org-element-put-property o :parent parent))) - secondary)))) - -(defun org-element-map - (data types fun &optional info first-match no-recursion with-affiliated) - "Map a function on selected elements or objects. - -DATA is a parse tree, an element, an object, a string, or a list -of such constructs. TYPES is a symbol or list of symbols of -elements or objects types (see `org-element-all-elements' and -`org-element-all-objects' for a complete list of types). FUN is -the function called on the matching element or object. It has to -accept one argument: the element or object itself. - -When optional argument INFO is non-nil, it should be a plist -holding export options. In that case, parts of the parse tree -not exportable according to that property list will be skipped. - -When optional argument FIRST-MATCH is non-nil, stop at the first -match for which FUN doesn't return nil, and return that value. - -Optional argument NO-RECURSION is a symbol or a list of symbols -representing elements or objects types. `org-element-map' won't -enter any recursive element or object whose type belongs to that -list. Though, FUN can still be applied on them. - -When optional argument WITH-AFFILIATED is non-nil, FUN will also -apply to matching objects within parsed affiliated keywords (see -`org-element-parsed-keywords'). - -Nil values returned from FUN do not appear in the results. - - -Examples: ---------- - -Assuming TREE is a variable containing an Org buffer parse tree, -the following example will return a flat list of all `src-block' -and `example-block' elements in it: - - \(org-element-map tree '(example-block src-block) 'identity) - -The following snippet will find the first headline with a level -of 1 and a \"phone\" tag, and will return its beginning position: - - \(org-element-map tree 'headline - \(lambda (hl) - \(and (= (org-element-property :level hl) 1) - \(member \"phone\" (org-element-property :tags hl)) - \(org-element-property :begin hl))) - nil t) - -The next example will return a flat list of all `plain-list' type -elements in TREE that are not a sub-list themselves: - - \(org-element-map tree 'plain-list 'identity nil nil 'plain-list) - -Eventually, this example will return a flat list of all `bold' -type objects containing a `latex-snippet' type object, even -looking into captions: - - \(org-element-map tree 'bold - \(lambda (b) - \(and (org-element-map b 'latex-snippet 'identity nil t) b)) - nil nil nil t)" - ;; Ensure TYPES and NO-RECURSION are a list, even of one element. - (unless (listp types) (setq types (list types))) - (unless (listp no-recursion) (setq no-recursion (list no-recursion))) - ;; Recursion depth is determined by --CATEGORY. - (let* ((--category - (catch 'found - (let ((category 'greater-elements)) - (mapc (lambda (type) - (cond ((or (memq type org-element-all-objects) - (eq type 'plain-text)) - ;; If one object is found, the function - ;; has to recurse into every object. - (throw 'found 'objects)) - ((not (memq type org-element-greater-elements)) - ;; If one regular element is found, the - ;; function has to recurse, at least, - ;; into every element it encounters. - (and (not (eq category 'elements)) - (setq category 'elements))))) - types) - category))) - ;; Compute properties for affiliated keywords if necessary. - (--affiliated-alist - (and with-affiliated - (mapcar (lambda (kwd) - (cons kwd (intern (concat ":" (downcase kwd))))) - org-element-affiliated-keywords))) - --acc - --walk-tree - (--walk-tree - (function - (lambda (--data) - ;; Recursively walk DATA. INFO, if non-nil, is a plist - ;; holding contextual information. - (let ((--type (org-element-type --data))) - (cond - ((not --data)) - ;; Ignored element in an export context. - ((and info (memq --data (plist-get info :ignore-list)))) - ;; List of elements or objects. - ((not --type) (mapc --walk-tree --data)) - ;; Unconditionally enter parse trees. - ((eq --type 'org-data) - (mapc --walk-tree (org-element-contents --data))) - (t - ;; Check if TYPE is matching among TYPES. If so, - ;; apply FUN to --DATA and accumulate return value - ;; into --ACC (or exit if FIRST-MATCH is non-nil). - (when (memq --type types) - (let ((result (funcall fun --data))) - (cond ((not result)) - (first-match (throw '--map-first-match result)) - (t (push result --acc))))) - ;; If --DATA has a secondary string that can contain - ;; objects with their type among TYPES, look into it. - (when (and (eq --category 'objects) (not (stringp --data))) - (let ((sec-prop - (assq --type org-element-secondary-value-alist))) - (when sec-prop - (funcall --walk-tree - (org-element-property (cdr sec-prop) --data))))) - ;; If --DATA has any affiliated keywords and - ;; WITH-AFFILIATED is non-nil, look for objects in - ;; them. - (when (and with-affiliated - (eq --category 'objects) - (memq --type org-element-all-elements)) - (mapc (lambda (kwd-pair) - (let ((kwd (car kwd-pair)) - (value (org-element-property - (cdr kwd-pair) --data))) - ;; Pay attention to the type of value. - ;; Preserve order for multiple keywords. - (cond - ((not value)) - ((and (member kwd org-element-multiple-keywords) - (member kwd org-element-dual-keywords)) - (mapc (lambda (line) - (funcall --walk-tree (cdr line)) - (funcall --walk-tree (car line))) - (reverse value))) - ((member kwd org-element-multiple-keywords) - (mapc (lambda (line) (funcall --walk-tree line)) - (reverse value))) - ((member kwd org-element-dual-keywords) - (funcall --walk-tree (cdr value)) - (funcall --walk-tree (car value))) - (t (funcall --walk-tree value))))) - --affiliated-alist)) - ;; Determine if a recursion into --DATA is possible. - (cond - ;; --TYPE is explicitly removed from recursion. - ((memq --type no-recursion)) - ;; --DATA has no contents. - ((not (org-element-contents --data))) - ;; Looking for greater elements but --DATA is simply - ;; an element or an object. - ((and (eq --category 'greater-elements) - (not (memq --type org-element-greater-elements)))) - ;; Looking for elements but --DATA is an object. - ((and (eq --category 'elements) - (memq --type org-element-all-objects))) - ;; In any other case, map contents. - (t (mapc --walk-tree (org-element-contents --data))))))))))) - (catch '--map-first-match - (funcall --walk-tree data) - ;; Return value in a proper order. - (nreverse --acc)))) -(put 'org-element-map 'lisp-indent-function 2) - -;; The following functions are internal parts of the parser. -;; -;; The first one, `org-element--parse-elements' acts at the element's -;; level. -;; -;; The second one, `org-element--parse-objects' applies on all objects -;; of a paragraph or a secondary string. It uses -;; `org-element--get-next-object-candidates' to optimize the search of -;; the next object in the buffer. -;; -;; More precisely, that function looks for every allowed object type -;; first. Then, it discards failed searches, keeps further matches, -;; and searches again types matched behind point, for subsequent -;; calls. Thus, searching for a given type fails only once, and every -;; object is searched only once at top level (but sometimes more for -;; nested types). - -(defun org-element--parse-elements - (beg end special structure granularity visible-only acc) - "Parse elements between BEG and END positions. - -SPECIAL prioritize some elements over the others. It can be set -to `first-section', `quote-section', `section' `item' or -`table-row'. - -When value is `item', STRUCTURE will be used as the current list -structure. - -GRANULARITY determines the depth of the recursion. See -`org-element-parse-buffer' for more information. - -When VISIBLE-ONLY is non-nil, don't parse contents of hidden -elements. - -Elements are accumulated into ACC." - (save-excursion - (goto-char beg) - ;; Visible only: skip invisible parts at the beginning of the - ;; element. - (when (and visible-only (org-invisible-p2)) - (goto-char (min (1+ (org-find-visible)) end))) - ;; When parsing only headlines, skip any text before first one. - (when (and (eq granularity 'headline) (not (org-at-heading-p))) - (org-with-limited-levels (outline-next-heading))) - ;; Main loop start. - (while (< (point) end) - ;; Find current element's type and parse it accordingly to - ;; its category. - (let* ((element (org-element--current-element - end granularity special structure)) - (type (org-element-type element)) - (cbeg (org-element-property :contents-begin element))) - (goto-char (org-element-property :end element)) - ;; Visible only: skip invisible parts between siblings. - (when (and visible-only (org-invisible-p2)) - (goto-char (min (1+ (org-find-visible)) end))) - ;; Fill ELEMENT contents by side-effect. - (cond - ;; If element has no contents, don't modify it. - ((not cbeg)) - ;; Greater element: parse it between `contents-begin' and - ;; `contents-end'. Make sure GRANULARITY allows the - ;; recursion, or ELEMENT is a headline, in which case going - ;; inside is mandatory, in order to get sub-level headings. - ((and (memq type org-element-greater-elements) - (or (memq granularity '(element object nil)) - (and (eq granularity 'greater-element) - (eq type 'section)) - (eq type 'headline))) - (org-element--parse-elements - cbeg (org-element-property :contents-end element) - ;; Possibly switch to a special mode. - (case type - (headline - (if (org-element-property :quotedp element) 'quote-section - 'section)) - (plain-list 'item) - (property-drawer 'node-property) - (table 'table-row)) - (and (memq type '(item plain-list)) - (org-element-property :structure element)) - granularity visible-only element)) - ;; ELEMENT has contents. Parse objects inside, if - ;; GRANULARITY allows it. - ((memq granularity '(object nil)) - (org-element--parse-objects - cbeg (org-element-property :contents-end element) element - (org-element-restriction type)))) - (org-element-adopt-elements acc element))) - ;; Return result. - acc)) - -(defun org-element--parse-objects (beg end acc restriction) - "Parse objects between BEG and END and return recursive structure. - -Objects are accumulated in ACC. - -RESTRICTION is a list of object successors which are allowed in -the current object." - (let ((candidates 'initial)) - (save-excursion - (save-restriction - (narrow-to-region beg end) - (goto-char (point-min)) - (while (and (not (eobp)) - (setq candidates - (org-element--get-next-object-candidates - restriction candidates))) - (let ((next-object - (let ((pos (apply 'min (mapcar 'cdr candidates)))) - (save-excursion - (goto-char pos) - (funcall (intern (format "org-element-%s-parser" - (car (rassq pos candidates))))))))) - ;; 1. Text before any object. Untabify it. - (let ((obj-beg (org-element-property :begin next-object))) - (unless (= (point) obj-beg) - (setq acc - (org-element-adopt-elements - acc - (replace-regexp-in-string - "\t" (make-string tab-width ? ) - (buffer-substring-no-properties (point) obj-beg)))))) - ;; 2. Object... - (let ((obj-end (org-element-property :end next-object)) - (cont-beg (org-element-property :contents-begin next-object))) - ;; Fill contents of NEXT-OBJECT by side-effect, if it has - ;; a recursive type. - (when (and cont-beg - (memq (car next-object) org-element-recursive-objects)) - (org-element--parse-objects - cont-beg (org-element-property :contents-end next-object) - next-object (org-element-restriction next-object))) - (setq acc (org-element-adopt-elements acc next-object)) - (goto-char obj-end)))) - ;; 3. Text after last object. Untabify it. - (unless (eobp) - (setq acc - (org-element-adopt-elements - acc - (replace-regexp-in-string - "\t" (make-string tab-width ? ) - (buffer-substring-no-properties (point) end))))) - ;; Result. - acc)))) - -(defun org-element--get-next-object-candidates (restriction objects) - "Return an alist of candidates for the next object. - -RESTRICTION is a list of object types, as symbols. Only -candidates with such types are looked after. - -OBJECTS is the previous candidates alist. If it is set to -`initial', no search has been done before, and all symbols in -RESTRICTION should be looked after. - -Return value is an alist whose CAR is the object type and CDR its -beginning position." - (delq - nil - (if (eq objects 'initial) - ;; When searching for the first time, look for every successor - ;; allowed in RESTRICTION. - (mapcar - (lambda (res) - (funcall (intern (format "org-element-%s-successor" res)))) - restriction) - ;; Focus on objects returned during last search. Keep those - ;; still after point. Search again objects before it. - (mapcar - (lambda (obj) - (if (>= (cdr obj) (point)) obj - (let* ((type (car obj)) - (succ (or (cdr (assq type org-element-object-successor-alist)) - type))) - (and succ - (funcall (intern (format "org-element-%s-successor" succ))))))) - objects)))) - - - -;;; Towards A Bijective Process -;; -;; The parse tree obtained with `org-element-parse-buffer' is really -;; a snapshot of the corresponding Org buffer. Therefore, it can be -;; interpreted and expanded into a string with canonical Org syntax. -;; Hence `org-element-interpret-data'. -;; -;; The function relies internally on -;; `org-element--interpret-affiliated-keywords'. - -;;;###autoload -(defun org-element-interpret-data (data &optional parent) - "Interpret DATA as Org syntax. - -DATA is a parse tree, an element, an object or a secondary string -to interpret. - -Optional argument PARENT is used for recursive calls. It contains -the element or object containing data, or nil. - -Return Org syntax as a string." - (let* ((type (org-element-type data)) - (results - (cond - ;; Secondary string. - ((not type) - (mapconcat - (lambda (obj) (org-element-interpret-data obj parent)) - data "")) - ;; Full Org document. - ((eq type 'org-data) - (mapconcat - (lambda (obj) (org-element-interpret-data obj parent)) - (org-element-contents data) "")) - ;; Plain text: return it. - ((stringp data) data) - ;; Element/Object without contents. - ((not (org-element-contents data)) - (funcall (intern (format "org-element-%s-interpreter" type)) - data nil)) - ;; Element/Object with contents. - (t - (let* ((greaterp (memq type org-element-greater-elements)) - (objectp (and (not greaterp) - (memq type org-element-recursive-objects))) - (contents - (mapconcat - (lambda (obj) (org-element-interpret-data obj data)) - (org-element-contents - (if (or greaterp objectp) data - ;; Elements directly containing objects must - ;; have their indentation normalized first. - (org-element-normalize-contents - data - ;; When normalizing first paragraph of an - ;; item or a footnote-definition, ignore - ;; first line's indentation. - (and (eq type 'paragraph) - (equal data (car (org-element-contents parent))) - (memq (org-element-type parent) - '(footnote-definition item)))))) - ""))) - (funcall (intern (format "org-element-%s-interpreter" type)) - data - (if greaterp (org-element-normalize-contents contents) - contents))))))) - (if (memq type '(org-data plain-text nil)) results - ;; Build white spaces. If no `:post-blank' property is - ;; specified, assume its value is 0. - (let ((post-blank (or (org-element-property :post-blank data) 0))) - (if (memq type org-element-all-objects) - (concat results (make-string post-blank 32)) - (concat - (org-element--interpret-affiliated-keywords data) - (org-element-normalize-string results) - (make-string post-blank 10))))))) - -(defun org-element--interpret-affiliated-keywords (element) - "Return ELEMENT's affiliated keywords as Org syntax. -If there is no affiliated keyword, return the empty string." - (let ((keyword-to-org - (function - (lambda (key value) - (let (dual) - (when (member key org-element-dual-keywords) - (setq dual (cdr value) value (car value))) - (concat "#+" key - (and dual - (format "[%s]" (org-element-interpret-data dual))) - ": " - (if (member key org-element-parsed-keywords) - (org-element-interpret-data value) - value) - "\n")))))) - (mapconcat - (lambda (prop) - (let ((value (org-element-property prop element)) - (keyword (upcase (substring (symbol-name prop) 1)))) - (when value - (if (or (member keyword org-element-multiple-keywords) - ;; All attribute keywords can have multiple lines. - (string-match "^ATTR_" keyword)) - (mapconcat (lambda (line) (funcall keyword-to-org keyword line)) - (reverse value) - "") - (funcall keyword-to-org keyword value))))) - ;; List all ELEMENT's properties matching an attribute line or an - ;; affiliated keyword, but ignore translated keywords since they - ;; cannot belong to the property list. - (loop for prop in (nth 1 element) by 'cddr - when (let ((keyword (upcase (substring (symbol-name prop) 1)))) - (or (string-match "^ATTR_" keyword) - (and - (member keyword org-element-affiliated-keywords) - (not (assoc keyword - org-element-keyword-translation-alist))))) - collect prop) - ""))) - -;; Because interpretation of the parse tree must return the same -;; number of blank lines between elements and the same number of white -;; space after objects, some special care must be given to white -;; spaces. -;; -;; The first function, `org-element-normalize-string', ensures any -;; string different from the empty string will end with a single -;; newline character. -;; -;; The second function, `org-element-normalize-contents', removes -;; global indentation from the contents of the current element. - -(defun org-element-normalize-string (s) - "Ensure string S ends with a single newline character. - -If S isn't a string return it unchanged. If S is the empty -string, return it. Otherwise, return a new string with a single -newline character at its end." - (cond - ((not (stringp s)) s) - ((string= "" s) "") - (t (and (string-match "\\(\n[ \t]*\\)*\\'" s) - (replace-match "\n" nil nil s))))) - -(defun org-element-normalize-contents (element &optional ignore-first) - "Normalize plain text in ELEMENT's contents. - -ELEMENT must only contain plain text and objects. - -If optional argument IGNORE-FIRST is non-nil, ignore first line's -indentation to compute maximal common indentation. - -Return the normalized element that is element with global -indentation removed from its contents. The function assumes that -indentation is not done with TAB characters." - (let* ((min-ind most-positive-fixnum) - find-min-ind ; For byte-compiler. - (find-min-ind - ;; Return minimal common indentation within BLOB. This is - ;; done by walking recursively BLOB and updating MIN-IND - ;; along the way. FIRST-FLAG is non-nil when the first - ;; string hasn't been seen yet. It is required as this - ;; string is the only one whose indentation doesn't happen - ;; after a newline character. - (lambda (blob first-flag) - (dolist (object (org-element-contents blob)) - (when (and first-flag (stringp object)) - (setq first-flag nil) - (string-match "\\` *" object) - (let ((len (match-end 0))) - ;; An indentation of zero means no string will be - ;; modified. Quit the process. - (if (zerop len) (throw 'zero (setq min-ind 0)) - (setq min-ind (min len min-ind))))) - (cond - ((stringp object) - (dolist (line (cdr (org-split-string object " *\n"))) - (unless (string= line "") - (setq min-ind (min (org-get-indentation line) min-ind))))) - ((memq (org-element-type object) org-element-recursive-objects) - (funcall find-min-ind object first-flag))))))) - ;; Find minimal indentation in ELEMENT. - (catch 'zero (funcall find-min-ind element (not ignore-first))) - (if (or (zerop min-ind) (= min-ind most-positive-fixnum)) element - ;; Build ELEMENT back, replacing each string with the same - ;; string minus common indentation. - (let* (build ; For byte compiler. - (build - (function - (lambda (blob first-flag) - ;; Return BLOB with all its strings indentation - ;; shortened from MIN-IND white spaces. FIRST-FLAG - ;; is non-nil when the first string hasn't been seen - ;; yet. - (setcdr (cdr blob) - (mapcar - #'(lambda (object) - (when (and first-flag (stringp object)) - (setq first-flag nil) - (setq object - (replace-regexp-in-string - (format "\\` \\{%d\\}" min-ind) - "" object))) - (cond - ((stringp object) - (replace-regexp-in-string - (format "\n \\{%d\\}" min-ind) "\n" object)) - ((memq (org-element-type object) - org-element-recursive-objects) - (funcall build object first-flag)) - (t object))) - (org-element-contents blob))) - blob)))) - (funcall build element (not ignore-first)))))) - - - -;;; The Toolbox -;; -;; The first move is to implement a way to obtain the smallest element -;; containing point. This is the job of `org-element-at-point'. It -;; basically jumps back to the beginning of section containing point -;; and moves, element after element, with -;; `org-element--current-element' until the container is found. Note: -;; When using `org-element-at-point', secondary values are never -;; parsed since the function focuses on elements, not on objects. -;; -;; At a deeper level, `org-element-context' lists all elements and -;; objects containing point. -;; -;; `org-element-nested-p' and `org-element-swap-A-B' may be used -;; internally by navigation and manipulation tools. - -;;;###autoload -(defun org-element-at-point (&optional keep-trail) - "Determine closest element around point. - -Return value is a list like (TYPE PROPS) where TYPE is the type -of the element and PROPS a plist of properties associated to the -element. - -Possible types are defined in `org-element-all-elements'. -Properties depend on element or object type, but always include -`:begin', `:end', `:parent' and `:post-blank' properties. - -As a special case, if point is at the very beginning of a list or -sub-list, returned element will be that list instead of the first -item. In the same way, if point is at the beginning of the first -row of a table, returned element will be the table instead of the -first row. - -If optional argument KEEP-TRAIL is non-nil, the function returns -a list of elements leading to element at point. The list's CAR -is always the element at point. The following positions contain -element's siblings, then parents, siblings of parents, until the -first element of current section." - (org-with-wide-buffer - ;; If at a headline, parse it. It is the sole element that - ;; doesn't require to know about context. Be sure to disallow - ;; secondary string parsing, though. - (if (org-with-limited-levels (org-at-heading-p)) - (progn - (beginning-of-line) - (if (not keep-trail) (org-element-headline-parser (point-max) t) - (list (org-element-headline-parser (point-max) t)))) - ;; Otherwise move at the beginning of the section containing - ;; point. - (catch 'exit - (let ((origin (point)) - (end (save-excursion - (org-with-limited-levels (outline-next-heading)) (point))) - element type special-flag trail struct prevs parent) - (org-with-limited-levels - (if (org-before-first-heading-p) - ;; In empty lines at buffer's beginning, return nil. - (progn (goto-char (point-min)) - (org-skip-whitespace) - (when (or (eobp) (> (line-beginning-position) origin)) - (throw 'exit nil))) - (org-back-to-heading) - (forward-line) - (org-skip-whitespace) - (when (or (eobp) (> (line-beginning-position) origin)) - ;; In blank lines just after the headline, point still - ;; belongs to the headline. - (throw 'exit - (progn (skip-chars-backward " \r\t\n") - (beginning-of-line) - (if (not keep-trail) - (org-element-headline-parser (point-max) t) - (list (org-element-headline-parser - (point-max) t)))))))) - (beginning-of-line) - ;; Parse successively each element, skipping those ending - ;; before original position. - (while t - (setq element - (org-element--current-element end 'element special-flag struct) - type (car element)) - (org-element-put-property element :parent parent) - (when keep-trail (push element trail)) - (cond - ;; 1. Skip any element ending before point. Also skip - ;; element ending at point when we're sure that another - ;; element has started. - ((let ((elem-end (org-element-property :end element))) - (when (or (< elem-end origin) - (and (= elem-end origin) (/= elem-end end))) - (goto-char elem-end)))) - ;; 2. An element containing point is always the element at - ;; point. - ((not (memq type org-element-greater-elements)) - (throw 'exit (if keep-trail trail element))) - ;; 3. At any other greater element type, if point is - ;; within contents, move into it. - (t - (let ((cbeg (org-element-property :contents-begin element)) - (cend (org-element-property :contents-end element))) - (if (or (not cbeg) (not cend) (> cbeg origin) (< cend origin) - ;; Create an anchor for tables and plain lists: - ;; when point is at the very beginning of these - ;; elements, ignoring affiliated keywords, - ;; target them instead of their contents. - (and (= cbeg origin) (memq type '(plain-list table))) - ;; When point is at contents end, do not move - ;; into elements with an explicit ending, but - ;; return that element instead. - (and (= cend origin) - (or (memq type - '(center-block - drawer dynamic-block inlinetask - property-drawer quote-block - special-block)) - ;; Corner case: if a list ends at the - ;; end of a buffer without a final new - ;; line, return last element in last - ;; item instead. - (and (memq type '(item plain-list)) - (progn (goto-char cend) - (or (bolp) (not (eobp)))))))) - (throw 'exit (if keep-trail trail element)) - (setq parent element) - (case type - (plain-list - (setq special-flag 'item - struct (org-element-property :structure element))) - (item (setq special-flag nil)) - (property-drawer - (setq special-flag 'node-property struct nil)) - (table (setq special-flag 'table-row struct nil)) - (otherwise (setq special-flag nil struct nil))) - (setq end cend) - (goto-char cbeg))))))))))) - -;;;###autoload -(defun org-element-context (&optional element) - "Return closest element or object around point. - -Return value is a list like (TYPE PROPS) where TYPE is the type -of the element or object and PROPS a plist of properties -associated to it. - -Possible types are defined in `org-element-all-elements' and -`org-element-all-objects'. Properties depend on element or -object type, but always include `:begin', `:end', `:parent' and -`:post-blank'. - -Optional argument ELEMENT, when non-nil, is the closest element -containing point, as returned by `org-element-at-point'. -Providing it allows for quicker computation." - (catch 'objects-forbidden - (org-with-wide-buffer - (let* ((origin (point)) - (element (or element (org-element-at-point))) - (type (org-element-type element)) - context) - ;; Check if point is inside an element containing objects or at - ;; a secondary string. In that case, narrow buffer to the - ;; containing area. Otherwise, return ELEMENT. - (cond - ;; At a parsed affiliated keyword, check if we're inside main - ;; or dual value. - ((let ((post (org-element-property :post-affiliated element))) - (and post (< origin post))) - (beginning-of-line) - (let ((case-fold-search t)) (looking-at org-element--affiliated-re)) - (cond - ((not (member-ignore-case (match-string 1) - org-element-parsed-keywords)) - (throw 'objects-forbidden element)) - ((< (match-end 0) origin) - (narrow-to-region (match-end 0) (line-end-position))) - ((and (match-beginning 2) - (>= origin (match-beginning 2)) - (< origin (match-end 2))) - (narrow-to-region (match-beginning 2) (match-end 2))) - (t (throw 'objects-forbidden element))) - ;; Also change type to retrieve correct restrictions. - (setq type 'keyword)) - ;; At an item, objects can only be located within tag, if any. - ((eq type 'item) - (let ((tag (org-element-property :tag element))) - (if (not tag) (throw 'objects-forbidden element) - (beginning-of-line) - (search-forward tag (line-end-position)) - (goto-char (match-beginning 0)) - (if (and (>= origin (point)) (< origin (match-end 0))) - (narrow-to-region (point) (match-end 0)) - (throw 'objects-forbidden element))))) - ;; At an headline or inlinetask, objects are located within - ;; their title. - ((memq type '(headline inlinetask)) - (goto-char (org-element-property :begin element)) - (skip-chars-forward "*") - (if (and (> origin (point)) (< origin (line-end-position))) - (narrow-to-region (point) (line-end-position)) - (throw 'objects-forbidden element))) - ;; At a paragraph, a table-row or a verse block, objects are - ;; located within their contents. - ((memq type '(paragraph table-row verse-block)) - (let ((cbeg (org-element-property :contents-begin element)) - (cend (org-element-property :contents-end element))) - ;; CBEG is nil for table rules. - (if (and cbeg cend (>= origin cbeg) (< origin cend)) - (narrow-to-region cbeg cend) - (throw 'objects-forbidden element)))) - ;; At a parsed keyword, objects are located within value. - ((eq type 'keyword) - (if (not (member (org-element-property :key element) - org-element-document-properties)) - (throw 'objects-forbidden element) - (goto-char (org-element-property :begin element)) - (search-forward ":") - (if (and (>= origin (point)) (< origin (line-end-position))) - (narrow-to-region (point) (line-end-position)) - (throw 'objects-forbidden element)))) - ;; At a planning line, if point is at a timestamp, return it, - ;; otherwise, return element. - ((eq type 'planning) - (dolist (p '(:closed :deadline :scheduled)) - (let ((timestamp (org-element-property p element))) - (when (and timestamp - (<= (org-element-property :begin timestamp) origin) - (> (org-element-property :end timestamp) origin)) - (throw 'objects-forbidden timestamp)))) - (throw 'objects-forbidden element)) - (t (throw 'objects-forbidden element))) - (goto-char (point-min)) - (let ((restriction (org-element-restriction type)) - (parent element) - (candidates 'initial)) - (catch 'exit - (while (setq candidates - (org-element--get-next-object-candidates - restriction candidates)) - (let ((closest-cand (rassq (apply 'min (mapcar 'cdr candidates)) - candidates))) - ;; If ORIGIN is before next object in element, there's - ;; no point in looking further. - (if (> (cdr closest-cand) origin) (throw 'exit parent) - (let* ((object - (progn (goto-char (cdr closest-cand)) - (funcall (intern (format "org-element-%s-parser" - (car closest-cand)))))) - (cbeg (org-element-property :contents-begin object)) - (cend (org-element-property :contents-end object)) - (obj-end (org-element-property :end object))) - (cond - ;; ORIGIN is after OBJECT, so skip it. - ((<= obj-end origin) (goto-char obj-end)) - ;; ORIGIN is within a non-recursive object or at - ;; an object boundaries: Return that object. - ((or (not cbeg) (< origin cbeg) (>= origin cend)) - (throw 'exit - (org-element-put-property object :parent parent))) - ;; Otherwise, move within current object and - ;; restrict search to the end of its contents. - (t (goto-char cbeg) - (narrow-to-region (point) cend) - (org-element-put-property object :parent parent) - (setq parent object - restriction (org-element-restriction object) - candidates 'initial))))))) - parent)))))) - -(defun org-element-nested-p (elem-A elem-B) - "Non-nil when elements ELEM-A and ELEM-B are nested." - (let ((beg-A (org-element-property :begin elem-A)) - (beg-B (org-element-property :begin elem-B)) - (end-A (org-element-property :end elem-A)) - (end-B (org-element-property :end elem-B))) - (or (and (>= beg-A beg-B) (<= end-A end-B)) - (and (>= beg-B beg-A) (<= end-B end-A))))) - -(defun org-element-swap-A-B (elem-A elem-B) - "Swap elements ELEM-A and ELEM-B. -Assume ELEM-B is after ELEM-A in the buffer. Leave point at the -end of ELEM-A." - (goto-char (org-element-property :begin elem-A)) - ;; There are two special cases when an element doesn't start at bol: - ;; the first paragraph in an item or in a footnote definition. - (let ((specialp (not (bolp)))) - ;; Only a paragraph without any affiliated keyword can be moved at - ;; ELEM-A position in such a situation. Note that the case of - ;; a footnote definition is impossible: it cannot contain two - ;; paragraphs in a row because it cannot contain a blank line. - (if (and specialp - (or (not (eq (org-element-type elem-B) 'paragraph)) - (/= (org-element-property :begin elem-B) - (org-element-property :contents-begin elem-B)))) - (error "Cannot swap elements")) - ;; In a special situation, ELEM-A will have no indentation. We'll - ;; give it ELEM-B's (which will in, in turn, have no indentation). - (let* ((ind-B (when specialp - (goto-char (org-element-property :begin elem-B)) - (org-get-indentation))) - (beg-A (org-element-property :begin elem-A)) - (end-A (save-excursion - (goto-char (org-element-property :end elem-A)) - (skip-chars-backward " \r\t\n") - (point-at-eol))) - (beg-B (org-element-property :begin elem-B)) - (end-B (save-excursion - (goto-char (org-element-property :end elem-B)) - (skip-chars-backward " \r\t\n") - (point-at-eol))) - ;; Store overlays responsible for visibility status. We - ;; also need to store their boundaries as they will be - ;; removed from buffer. - (overlays - (cons - (mapcar (lambda (ov) (list ov (overlay-start ov) (overlay-end ov))) - (overlays-in beg-A end-A)) - (mapcar (lambda (ov) (list ov (overlay-start ov) (overlay-end ov))) - (overlays-in beg-B end-B)))) - ;; Get contents. - (body-A (buffer-substring beg-A end-A)) - (body-B (delete-and-extract-region beg-B end-B))) - (goto-char beg-B) - (when specialp - (setq body-B (replace-regexp-in-string "\\`[ \t]*" "" body-B)) - (org-indent-to-column ind-B)) - (insert body-A) - ;; Restore ex ELEM-A overlays. - (let ((offset (- beg-B beg-A))) - (mapc (lambda (ov) - (move-overlay - (car ov) (+ (nth 1 ov) offset) (+ (nth 2 ov) offset))) - (car overlays)) - (goto-char beg-A) - (delete-region beg-A end-A) - (insert body-B) - ;; Restore ex ELEM-B overlays. - (mapc (lambda (ov) - (move-overlay - (car ov) (- (nth 1 ov) offset) (- (nth 2 ov) offset))) - (cdr overlays))) - (goto-char (org-element-property :end elem-B))))) - -(provide 'org-element) - -;; Local variables: -;; generated-autoload-file: "org-loaddefs.el" -;; End: - -;;; org-element.el ends here diff --git a/elpa/org-20150629/org-entities.el b/elpa/org-20150629/org-entities.el deleted file mode 100644 index 6324a625..00000000 --- a/elpa/org-20150629/org-entities.el +++ /dev/null @@ -1,619 +0,0 @@ -;;; org-entities.el --- Support for special entities in Org-mode - -;; Copyright (C) 2010-2014 Free Software Foundation, Inc. - -;; Author: Carsten Dominik , -;; Ulf Stegemann -;; Keywords: outlines, calendar, wp -;; Homepage: http://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 . -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;;; Commentary: - -;;; Code: - -(declare-function org-toggle-pretty-entities "org" ()) -(declare-function org-table-align "org-table" ()) - -(eval-when-compile - (require 'cl)) - -(defgroup org-entities nil - "Options concerning entities in Org-mode." - :tag "Org Entities" - :group 'org) - -(defcustom org-entities-ascii-explanatory nil - "Non-nil means replace special entities in ASCII. -For example, this will replace \"\\nsup\" with \"[not a superset of]\" -in backends where the corresponding character is not available." - :group 'org-entities - :version "24.1" - :type 'boolean) - -(defcustom org-entities-user nil - "User-defined entities used in Org-mode to produce special characters. -Each entry in this list is a list of strings. It associates the name -of the entity that can be inserted into an Org file as \\name with the -appropriate replacements for the different export backends. The order -of the fields is the following - -name As a string, without the leading backslash -LaTeX replacement In ready LaTeX, no further processing will take place -LaTeX mathp A Boolean, either t or nil. t if this entity needs - to be in math mode. -HTML replacement In ready HTML, no further processing will take place. - Usually this will be an &...; entity. -ASCII replacement Plain ASCII, no extensions. Symbols that cannot be - represented will be left as they are, but see the. - variable `org-entities-ascii-explanatory'. -Latin1 replacement Use the special characters available in latin1. -utf-8 replacement Use the special characters available in utf-8. - -If you define new entities here that require specific LaTeX -packages to be loaded, add these packages to `org-latex-packages-alist'." - :group 'org-entities - :version "24.1" - :type '(repeat - (list - (string :tag "name ") - (string :tag "LaTeX ") - (boolean :tag "Require LaTeX math?") - (string :tag "HTML ") - (string :tag "ASCII ") - (string :tag "Latin1") - (string :tag "utf-8 ")))) - -(defconst org-entities - '( - "* Letters" - "** Latin" - ("Agrave" "\\`{A}" nil "À" "A" "À" "À") - ("agrave" "\\`{a}" nil "à" "a" "à" "à") - ("Aacute" "\\'{A}" nil "Á" "A" "Á" "Á") - ("aacute" "\\'{a}" nil "á" "a" "á" "á") - ("Acirc" "\\^{A}" nil "Â" "A" "Â" "Â") - ("acirc" "\\^{a}" nil "â" "a" "â" "â") - ("Atilde" "\\~{A}" nil "Ã" "A" "Ã" "Ã") - ("atilde" "\\~{a}" nil "ã" "a" "ã" "ã") - ("Auml" "\\\"{A}" nil "Ä" "Ae" "Ä" "Ä") - ("auml" "\\\"{a}" nil "ä" "ae" "ä" "ä") - ("Aring" "\\AA{}" nil "Å" "A" "Å" "Å") - ("AA" "\\AA{}" nil "Å" "A" "Å" "Å") - ("aring" "\\aa{}" nil "å" "a" "Ã¥" "Ã¥") - ("AElig" "\\AE{}" nil "Æ" "AE" "Æ" "Æ") - ("aelig" "\\ae{}" nil "æ" "ae" "æ" "æ") - ("Ccedil" "\\c{C}" nil "Ç" "C" "Ç" "Ç") - ("ccedil" "\\c{c}" nil "ç" "c" "ç" "ç") - ("Egrave" "\\`{E}" nil "È" "E" "È" "È") - ("egrave" "\\`{e}" nil "è" "e" "è" "è") - ("Eacute" "\\'{E}" nil "É" "E" "É" "É") - ("eacute" "\\'{e}" nil "é" "e" "é" "é") - ("Ecirc" "\\^{E}" nil "Ê" "E" "Ê" "Ê") - ("ecirc" "\\^{e}" nil "ê" "e" "ê" "ê") - ("Euml" "\\\"{E}" nil "Ë" "E" "Ë" "Ë") - ("euml" "\\\"{e}" nil "ë" "e" "ë" "ë") - ("Igrave" "\\`{I}" nil "Ì" "I" "Ì" "Ì") - ("igrave" "\\`{i}" nil "ì" "i" "ì" "ì") - ("Iacute" "\\'{I}" nil "Í" "I" "Í" "Í") - ("iacute" "\\'{i}" nil "í" "i" "í" "í") - ("Icirc" "\\^{I}" nil "Î" "I" "Î" "Î") - ("icirc" "\\^{i}" nil "î" "i" "î" "î") - ("Iuml" "\\\"{I}" nil "Ï" "I" "Ï" "Ï") - ("iuml" "\\\"{i}" nil "ï" "i" "ï" "ï") - ("Ntilde" "\\~{N}" nil "Ñ" "N" "Ñ" "Ñ") - ("ntilde" "\\~{n}" nil "ñ" "n" "ñ" "ñ") - ("Ograve" "\\`{O}" nil "Ò" "O" "Ò" "Ò") - ("ograve" "\\`{o}" nil "ò" "o" "ò" "ò") - ("Oacute" "\\'{O}" nil "Ó" "O" "Ó" "Ó") - ("oacute" "\\'{o}" nil "ó" "o" "ó" "ó") - ("Ocirc" "\\^{O}" nil "Ô" "O" "Ô" "Ô") - ("ocirc" "\\^{o}" nil "ô" "o" "ô" "ô") - ("Otilde" "\\~{O}" nil "Õ" "O" "Õ" "Õ") - ("otilde" "\\~{o}" nil "õ" "o" "õ" "õ") - ("Ouml" "\\\"{O}" nil "Ö" "Oe" "Ö" "Ö") - ("ouml" "\\\"{o}" nil "ö" "oe" "ö" "ö") - ("Oslash" "\\O" nil "Ø" "O" "Ø" "Ø") - ("oslash" "\\o{}" nil "ø" "o" "ø" "ø") - ("OElig" "\\OE{}" nil "Œ" "OE" "OE" "Œ") - ("oelig" "\\oe{}" nil "œ" "oe" "oe" "œ") - ("Scaron" "\\v{S}" nil "Š" "S" "S" "Å ") - ("scaron" "\\v{s}" nil "š" "s" "s" "Å¡") - ("szlig" "\\ss{}" nil "ß" "ss" "ß" "ß") - ("Ugrave" "\\`{U}" nil "Ù" "U" "Ù" "Ù") - ("ugrave" "\\`{u}" nil "ù" "u" "ù" "ù") - ("Uacute" "\\'{U}" nil "Ú" "U" "Ú" "Ú") - ("uacute" "\\'{u}" nil "ú" "u" "ú" "ú") - ("Ucirc" "\\^{U}" nil "Û" "U" "Û" "Û") - ("ucirc" "\\^{u}" nil "û" "u" "û" "û") - ("Uuml" "\\\"{U}" nil "Ü" "Ue" "Ü" "Ü") - ("uuml" "\\\"{u}" nil "ü" "ue" "ü" "ü") - ("Yacute" "\\'{Y}" nil "Ý" "Y" "Ý" "Ý") - ("yacute" "\\'{y}" nil "ý" "y" "ý" "ý") - ("Yuml" "\\\"{Y}" nil "Ÿ" "Y" "Y" "Ÿ") - ("yuml" "\\\"{y}" nil "ÿ" "y" "ÿ" "ÿ") - - "** Latin (special face)" - ("fnof" "\\textit{f}" nil "ƒ" "f" "f" "ƒ") - ("real" "\\Re" t "ℜ" "R" "R" "ℜ") - ("image" "\\Im" t "ℑ" "I" "I" "ℑ") - ("weierp" "\\wp" t "℘" "P" "P" "℘") - ("ell" "\\ell" t "ℓ" "ell" "ell" "ℓ") - ("imath" "\\imath" t "ı" "[dotless i]" "dotless i" "ı") - ("jmath" "\\jmath" t "ȷ" "[dotless j]" "dotless j" "È·") - - "** Greek" - ("Alpha" "A" nil "Α" "Alpha" "Alpha" "Α") - ("alpha" "\\alpha" t "α" "alpha" "alpha" "α") - ("Beta" "B" nil "Β" "Beta" "Beta" "Β") - ("beta" "\\beta" t "β" "beta" "beta" "β") - ("Gamma" "\\Gamma" t "Γ" "Gamma" "Gamma" "Γ") - ("gamma" "\\gamma" t "γ" "gamma" "gamma" "γ") - ("Delta" "\\Delta" t "Δ" "Delta" "Gamma" "Δ") - ("delta" "\\delta" t "δ" "delta" "delta" "δ") - ("Epsilon" "E" nil "Ε" "Epsilon" "Epsilon" "Ε") - ("epsilon" "\\epsilon" t "ε" "epsilon" "epsilon" "ε") - ("varepsilon" "\\varepsilon" t "ε" "varepsilon" "varepsilon" "ε") - ("Zeta" "Z" nil "Ζ" "Zeta" "Zeta" "Ζ") - ("zeta" "\\zeta" t "ζ" "zeta" "zeta" "ζ") - ("Eta" "H" nil "Η" "Eta" "Eta" "Η") - ("eta" "\\eta" t "η" "eta" "eta" "η") - ("Theta" "\\Theta" t "Θ" "Theta" "Theta" "Θ") - ("theta" "\\theta" t "θ" "theta" "theta" "θ") - ("thetasym" "\\vartheta" t "ϑ" "theta" "theta" "ϑ") - ("vartheta" "\\vartheta" t "ϑ" "theta" "theta" "ϑ") - ("Iota" "I" nil "Ι" "Iota" "Iota" "Ι") - ("iota" "\\iota" t "ι" "iota" "iota" "ι") - ("Kappa" "K" nil "Κ" "Kappa" "Kappa" "Κ") - ("kappa" "\\kappa" t "κ" "kappa" "kappa" "κ") - ("Lambda" "\\Lambda" t "Λ" "Lambda" "Lambda" "Λ") - ("lambda" "\\lambda" t "λ" "lambda" "lambda" "λ") - ("Mu" "M" nil "Μ" "Mu" "Mu" "Μ") - ("mu" "\\mu" t "μ" "mu" "mu" "μ") - ("nu" "\\nu" t "ν" "nu" "nu" "ν") - ("Nu" "N" nil "Ν" "Nu" "Nu" "Ν") - ("Xi" "\\Xi" t "Ξ" "Xi" "Xi" "Ξ") - ("xi" "\\xi" t "ξ" "xi" "xi" "ξ") - ("Omicron" "O" nil "Ο" "Omicron" "Omicron" "Ο") - ("omicron" "\\textit{o}" nil "ο" "omicron" "omicron" "ο") - ("Pi" "\\Pi" t "Π" "Pi" "Pi" "Π") - ("pi" "\\pi" t "π" "pi" "pi" "π") - ("Rho" "P" nil "Ρ" "Rho" "Rho" "Ρ") - ("rho" "\\rho" t "ρ" "rho" "rho" "ρ") - ("Sigma" "\\Sigma" t "Σ" "Sigma" "Sigma" "Σ") - ("sigma" "\\sigma" t "σ" "sigma" "sigma" "σ") - ("sigmaf" "\\varsigma" t "ς" "sigmaf" "sigmaf" "ς") - ("varsigma" "\\varsigma" t "ς" "varsigma" "varsigma" "ς") - ("Tau" "T" nil "Τ" "Tau" "Tau" "Τ") - ("Upsilon" "\\Upsilon" t "Υ" "Upsilon" "Upsilon" "Î¥") - ("upsih" "\\Upsilon" t "ϒ" "upsilon" "upsilon" "ϒ") - ("upsilon" "\\upsilon" t "υ" "upsilon" "upsilon" "υ") - ("Phi" "\\Phi" t "Φ" "Phi" "Phi" "Φ") - ("phi" "\\phi" t "φ" "phi" "phi" "φ") - ("varphi" "\\varphi" t "ϕ" "varphi" "varphi" "ɸ") - ("Chi" "X" nil "Χ" "Chi" "Chi" "Χ") - ("chi" "\\chi" t "χ" "chi" "chi" "χ") - ("acutex" "\\acute x" t "´x" "'x" "'x" "𝑥́") - ("Psi" "\\Psi" t "Ψ" "Psi" "Psi" "Ψ") - ("psi" "\\psi" t "ψ" "psi" "psi" "ψ") - ("tau" "\\tau" t "τ" "tau" "tau" "τ") - ("Omega" "\\Omega" t "Ω" "Omega" "Omega" "Ω") - ("omega" "\\omega" t "ω" "omega" "omega" "ω") - ("piv" "\\varpi" t "ϖ" "omega-pi" "omega-pi" "ϖ") - ("varpi" "\\varpi" t "ϖ" "omega-pi" "omega-pi" "ϖ") - ("partial" "\\partial" t "∂" "[partial differential]" "[partial differential]" "∂") - - "** Hebrew" - ("alefsym" "\\aleph" t "ℵ" "aleph" "aleph" "ℵ") - ("aleph" "\\aleph" t "ℵ" "aleph" "aleph" "ℵ") - ("gimel" "\\gimel" t "ℷ" "gimel" "gimel" "ℷ") - ("beth" "\\beth" t "ℶ" "beth" "beth" "ב") - ("dalet" "\\daleth" t "ℸ" "dalet" "dalet" "ד") - - "** Dead languages" - ("ETH" "\\DH{}" nil "Ð" "D" "Ð" "Ð") - ("eth" "\\dh{}" nil "ð" "dh" "ð" "ð") - ("THORN" "\\TH{}" nil "Þ" "TH" "Þ" "Þ") - ("thorn" "\\th{}" nil "þ" "th" "þ" "þ") - - "* Punctuation" - "** Dots and Marks" - ("dots" "\\dots{}" nil "…" "..." "..." "…") - ("cdots" "\\cdots{}" t "⋯" "..." "..." "⋯") - ("hellip" "\\dots{}" nil "…" "..." "..." "…") - ("middot" "\\textperiodcentered{}" nil "·" "." "·" "·") - ("iexcl" "!`" nil "¡" "!" "¡" "¡") - ("iquest" "?`" nil "¿" "?" "¿" "¿") - - "** Dash-like" - ("shy" "\\-" nil "­" "" "" "") - ("ndash" "--" nil "–" "-" "-" "–") - ("mdash" "---" nil "—" "--" "--" "—") - - "** Quotations" - ("quot" "\\textquotedbl{}" nil """ "\"" "\"" "\"") - ("acute" "\\textasciiacute{}" nil "´" "'" "´" "´") - ("ldquo" "\\textquotedblleft{}" nil "“" "\"" "\"" "“") - ("rdquo" "\\textquotedblright{}" nil "”" "\"" "\"" "”") - ("bdquo" "\\quotedblbase{}" nil "„" "\"" "\"" "„") - ("lsquo" "\\textquoteleft{}" nil "‘" "`" "`" "‘") - ("rsquo" "\\textquoteright{}" nil "’" "'" "'" "’") - ("sbquo" "\\quotesinglbase{}" nil "‚" "," "," "‚") - ("laquo" "\\guillemotleft{}" nil "«" "<<" "«" "«") - ("raquo" "\\guillemotright{}" nil "»" ">>" "»" "»") - ("lsaquo" "\\guilsinglleft{}" nil "‹" "<" "<" "‹") - ("rsaquo" "\\guilsinglright{}" nil "›" ">" ">" "›") - - "* Other" - "** Misc. (often used)" - ("circ" "\\^{}" nil "ˆ" "^" "^" "ˆ") - ("vert" "\\vert{}" t "|" "|" "|" "|") - ("brvbar" "\\textbrokenbar{}" nil "¦" "|" "¦" "¦") - ("S" "\\S" nil "§" "paragraph" "§" "§") - ("sect" "\\S" nil "§" "paragraph" "§" "§") - ("amp" "\\&" nil "&" "&" "&" "&") - ("lt" "\\textless{}" nil "<" "<" "<" "<") - ("gt" "\\textgreater{}" nil ">" ">" ">" ">") - ("tilde" "\\textasciitilde{}" nil "~" "~" "~" "~") - ("slash" "/" nil "/" "/" "/" "/") - ("plus" "+" nil "+" "+" "+" "+") - ("under" "\\_" nil "_" "_" "_" "_") - ("equal" "=" nil "=" "=" "=" "=") - ("asciicirc" "\\textasciicircum{}" nil "^" "^" "^" "^") - ("dagger" "\\textdagger{}" nil "†" "[dagger]" "[dagger]" "†") - ("dag" "\\dag{}" nil "†" "[dagger]" "[dagger]" "†") - ("Dagger" "\\textdaggerdbl{}" nil "‡" "[doubledagger]" "[doubledagger]" "‡") - ("ddag" "\\ddag{}" nil "‡" "[doubledagger]" "[doubledagger]" "‡") - - "** Whitespace" - ("nbsp" "~" nil " " " " " " " ") - ("ensp" "\\hspace*{.5em}" nil " " " " " " " ") - ("emsp" "\\hspace*{1em}" nil " " " " " " " ") - ("thinsp" "\\hspace*{.2em}" nil " " " " " " " ") - - "** Currency" - ("curren" "\\textcurrency{}" nil "¤" "curr." "¤" "¤") - ("cent" "\\textcent{}" nil "¢" "cent" "¢" "¢") - ("pound" "\\pounds{}" nil "£" "pound" "£" "£") - ("yen" "\\textyen{}" nil "¥" "yen" "Â¥" "Â¥") - ("euro" "\\texteuro{}" nil "€" "EUR" "EUR" "€") - ("EUR" "\\EUR{}" nil "€" "EUR" "EUR" "€") - ("EURdig" "\\EURdig{}" nil "€" "EUR" "EUR" "€") - ("EURhv" "\\EURhv{}" nil "€" "EUR" "EUR" "€") - ("EURcr" "\\EURcr{}" nil "€" "EUR" "EUR" "€") - ("EURtm" "\\EURtm{}" nil "€" "EUR" "EUR" "€") - - "** Property Marks" - ("copy" "\\textcopyright{}" nil "©" "(c)" "©" "©") - ("reg" "\\textregistered{}" nil "®" "(r)" "®" "®") - ("trade" "\\texttrademark{}" nil "™" "TM" "TM" "™") - - "** Science et al." - ("minus" "\\minus" t "−" "-" "-" "−") - ("pm" "\\textpm{}" nil "±" "+-" "±" "±") - ("plusmn" "\\textpm{}" nil "±" "+-" "±" "±") - ("times" "\\texttimes{}" nil "×" "*" "×" "×") - ("frasl" "/" nil "⁄" "/" "/" "⁄") - ("colon" "\\colon" t ":" ":" ":" ":") - ("div" "\\textdiv{}" nil "÷" "/" "÷" "÷") - ("frac12" "\\textonehalf{}" nil "½" "1/2" "½" "½") - ("frac14" "\\textonequarter{}" nil "¼" "1/4" "¼" "¼") - ("frac34" "\\textthreequarters{}" nil "¾" "3/4" "¾" "¾") - ("permil" "\\textperthousand{}" nil "‰" "per thousand" "per thousand" "‰") - ("sup1" "\\textonesuperior{}" nil "¹" "^1" "¹" "¹") - ("sup2" "\\texttwosuperior{}" nil "²" "^2" "²" "²") - ("sup3" "\\textthreesuperior{}" nil "³" "^3" "³" "³") - ("radic" "\\sqrt{\\,}" t "√" "[square root]" "[square root]" "√") - ("sum" "\\sum" t "∑" "[sum]" "[sum]" "∑") - ("prod" "\\prod" t "∏" "[product]" "[n-ary product]" "∏") - ("micro" "\\textmu{}" nil "µ" "micro" "µ" "µ") - ("macr" "\\textasciimacron{}" nil "¯" "[macron]" "¯" "¯") - ("deg" "\\textdegree{}" nil "°" "degree" "°" "°") - ("prime" "\\prime" t "′" "'" "'" "′") - ("Prime" "\\prime{}\\prime" t "″" "''" "''" "″") - ("infin" "\\propto" t "∞" "[infinity]" "[infinity]" "∞") - ("infty" "\\infty" t "∞" "[infinity]" "[infinity]" "∞") - ("prop" "\\propto" t "∝" "[proportional to]" "[proportional to]" "∝") - ("propto" "\\propto" t "∝" "[proportional to]" "[proportional to]" "∝") - ("not" "\\textlnot{}" nil "¬" "[angled dash]" "¬" "¬") - ("neg" "\\neg{}" t "¬" "[angled dash]" "¬" "¬") - ("land" "\\land" t "∧" "[logical and]" "[logical and]" "∧") - ("wedge" "\\wedge" t "∧" "[logical and]" "[logical and]" "∧") - ("lor" "\\lor" t "∨" "[logical or]" "[logical or]" "∨") - ("vee" "\\vee" t "∨" "[logical or]" "[logical or]" "∨") - ("cap" "\\cap" t "∩" "[intersection]" "[intersection]" "∩") - ("cup" "\\cup" t "∪" "[union]" "[union]" "∪") - ("int" "\\int" t "∫" "[integral]" "[integral]" "∫") - ("therefore" "\\therefore" t "∴" "[therefore]" "[therefore]" "∴") - ("there4" "\\therefore" t "∴" "[therefore]" "[therefore]" "∴") - ("because" "\\because" t "∵" "[because]" "[because]" "∵") - ("sim" "\\sim" t "∼" "~" "~" "∼") - ("cong" "\\cong" t "≅" "[approx. equal to]" "[approx. equal to]" "≅") - ("simeq" "\\simeq" t "≅" "[approx. equal to]" "[approx. equal to]" "≅") - ("asymp" "\\asymp" t "≈" "[almost equal to]" "[almost equal to]" "≈") - ("approx" "\\approx" t "≈" "[almost equal to]" "[almost equal to]" "≈") - ("ne" "\\ne" t "≠" "[not equal to]" "[not equal to]" "≠") - ("neq" "\\neq" t "≠" "[not equal to]" "[not equal to]" "≠") - ("equiv" "\\equiv" t "≡" "[identical to]" "[identical to]" "≡") - - ("triangleq" "\\triangleq" t "≜" "[defined to]" "[defined to]" "≜") - ("le" "\\le" t "≤" "<=" "<=" "≤") - ("leq" "\\le" t "≤" "<=" "<=" "≤") - ("ge" "\\ge" t "≥" ">=" ">=" "≥") - ("geq" "\\ge" t "≥" ">=" ">=" "≥") - ("lessgtr" "\\lessgtr" t "≶" "[less than or greater than]" "[less than or greater than]" "≶") - ("lesseqgtr" "\\lesseqgtr" t "⋚" "[less than or equal or greater than or equal]" "[less than or equal or greater than or equal]" "⋚") - ("ll" "\\ll" t "≪" "<<" "<<" "≪") - ("Ll" "\lll" t "⋘" "<<<" "<<<" "⋘") - ("lll" "\lll" t "⋘" "<<<" "<<<" "⋘") - ("gg" "\\gg" t "≫" ">>" ">>" "≫") - ("Gg" "\\ggg" t "⋙" ">>>" ">>>" "⋙") - ("ggg" "\\ggg" t "⋙" ">>>" ">>>" "⋙") - ("prec" "\\prec" t "≺" "[precedes]" "[precedes]" "≺") - ("preceq" "\\preceq" t "≼" "[precedes or equal]" "[precedes or equal]" "≼") - ("preccurlyeq" "\\preccurlyeq" t "≼" "[precedes or equal]" "[precedes or equal]" "≼") - ("succ" "\\succ" t "≻" "[succeeds]" "[succeeds]" "≻") - ("succeq" "\\succeq" t "≽" "[succeeds or equal]" "[succeeds or equal]" "≽") - ("succcurlyeq" "\\succcurlyeq" t "≽" "[succeeds or equal]" "[succeeds or equal]" "≽") - ("sub" "\\subset" t "⊂" "[subset of]" "[subset of]" "⊂") - ("subset" "\\subset" t "⊂" "[subset of]" "[subset of]" "⊂") - ("sup" "\\supset" t "⊃" "[superset of]" "[superset of]" "⊃") - ("supset" "\\supset" t "⊃" "[superset of]" "[superset of]" "⊃") - ("nsub" "\\not\\subset" t "⊄" "[not a subset of]" "[not a subset of" "⊄") - ("sube" "\\subseteq" t "⊆" "[subset of or equal to]" "[subset of or equal to]" "⊆") - ("nsup" "\\not\\supset" t "⊅" "[not a superset of]" "[not a superset of]" "⊅") - ("supe" "\\supseteq" t "⊇" "[superset of or equal to]" "[superset of or equal to]" "⊇") - ("setminus" "\\setminus" t "∖" "\" "\" "â§µ") - ("forall" "\\forall" t "∀" "[for all]" "[for all]" "∀") - ("exist" "\\exists" t "∃" "[there exists]" "[there exists]" "∃") - ("exists" "\\exists" t "∃" "[there exists]" "[there exists]" "∃") - ("nexist" "\\nexists" t "∃" "[there does not exists]" "[there does not exists]" "∄") - ("nexists" "\\nexists" t "∃" "[there does not exists]" "[there does not exists]" "∄") - ("empty" "\\empty" t "∅" "[empty set]" "[empty set]" "∅") - ("emptyset" "\\emptyset" t "∅" "[empty set]" "[empty set]" "∅") - ("isin" "\\in" t "∈" "[element of]" "[element of]" "∈") - ("in" "\\in" t "∈" "[element of]" "[element of]" "∈") - ("notin" "\\notin" t "∉" "[not an element of]" "[not an element of]" "∉") - ("ni" "\\ni" t "∋" "[contains as member]" "[contains as member]" "∋") - ("nabla" "\\nabla" t "∇" "[nabla]" "[nabla]" "∇") - ("ang" "\\angle" t "∠" "[angle]" "[angle]" "∠") - ("angle" "\\angle" t "∠" "[angle]" "[angle]" "∠") - ("perp" "\\perp" t "⊥" "[up tack]" "[up tack]" "⊥") - ("sdot" "\\cdot" t "⋅" "[dot]" "[dot]" "⋅") - ("cdot" "\\cdot" t "⋅" "[dot]" "[dot]" "⋅") - ("lceil" "\\lceil" t "⌈" "[left ceiling]" "[left ceiling]" "⌈") - ("rceil" "\\rceil" t "⌉" "[right ceiling]" "[right ceiling]" "⌉") - ("lfloor" "\\lfloor" t "⌊" "[left floor]" "[left floor]" "⌊") - ("rfloor" "\\rfloor" t "⌋" "[right floor]" "[right floor]" "⌋") - ("lang" "\\langle" t "⟨" "<" "<" "⟨") - ("rang" "\\rangle" t "⟩" ">" ">" "⟩") - ("hbar" "\\hbar" t "ℏ" "hbar" "hbar" "ℏ") - ("mho" "\\mho" t "℧" "mho" "mho" "℧") - - "** Arrows" - ("larr" "\\leftarrow" t "←" "<-" "<-" "←") - ("leftarrow" "\\leftarrow" t "←" "<-" "<-" "←") - ("gets" "\\gets" t "←" "<-" "<-" "←") - ("lArr" "\\Leftarrow" t "⇐" "<=" "<=" "⇐") - ("Leftarrow" "\\Leftarrow" t "⇐" "<=" "<=" "⇐") - ("uarr" "\\uparrow" t "↑" "[uparrow]" "[uparrow]" "↑") - ("uparrow" "\\uparrow" t "↑" "[uparrow]" "[uparrow]" "↑") - ("uArr" "\\Uparrow" t "⇑" "[dbluparrow]" "[dbluparrow]" "⇑") - ("Uparrow" "\\Uparrow" t "⇑" "[dbluparrow]" "[dbluparrow]" "⇑") - ("rarr" "\\rightarrow" t "→" "->" "->" "→") - ("to" "\\to" t "→" "->" "->" "→") - ("rightarrow" "\\rightarrow" t "→" "->" "->" "→") - ("rArr" "\\Rightarrow" t "⇒" "=>" "=>" "⇒") - ("Rightarrow" "\\Rightarrow" t "⇒" "=>" "=>" "⇒") - ("darr" "\\downarrow" t "↓" "[downarrow]" "[downarrow]" "↓") - ("downarrow" "\\downarrow" t "↓" "[downarrow]" "[downarrow]" "↓") - ("dArr" "\\Downarrow" t "⇓" "[dbldownarrow]" "[dbldownarrow]" "⇓") - ("Downarrow" "\\Downarrow" t "⇓" "[dbldownarrow]" "[dbldownarrow]" "⇓") - ("harr" "\\leftrightarrow" t "↔" "<->" "<->" "↔") - ("leftrightarrow" "\\leftrightarrow" t "↔" "<->" "<->" "↔") - ("hArr" "\\Leftrightarrow" t "⇔" "<=>" "<=>" "⇔") - ("Leftrightarrow" "\\Leftrightarrow" t "⇔" "<=>" "<=>" "⇔") - ("crarr" "\\hookleftarrow" t "↵" "<-'" "<-'" "↵") - ("hookleftarrow" "\\hookleftarrow" t "↵" "<-'" "<-'" "↵") - - "** Function names" - ("arccos" "\\arccos" t "arccos" "arccos" "arccos" "arccos") - ("arcsin" "\\arcsin" t "arcsin" "arcsin" "arcsin" "arcsin") - ("arctan" "\\arctan" t "arctan" "arctan" "arctan" "arctan") - ("arg" "\\arg" t "arg" "arg" "arg" "arg") - ("cos" "\\cos" t "cos" "cos" "cos" "cos") - ("cosh" "\\cosh" t "cosh" "cosh" "cosh" "cosh") - ("cot" "\\cot" t "cot" "cot" "cot" "cot") - ("coth" "\\coth" t "coth" "coth" "coth" "coth") - ("csc" "\\csc" t "csc" "csc" "csc" "csc") - ("deg" "\\deg" t "°" "deg" "deg" "deg") - ("det" "\\det" t "det" "det" "det" "det") - ("dim" "\\dim" t "dim" "dim" "dim" "dim") - ("exp" "\\exp" t "exp" "exp" "exp" "exp") - ("gcd" "\\gcd" t "gcd" "gcd" "gcd" "gcd") - ("hom" "\\hom" t "hom" "hom" "hom" "hom") - ("inf" "\\inf" t "inf" "inf" "inf" "inf") - ("ker" "\\ker" t "ker" "ker" "ker" "ker") - ("lg" "\\lg" t "lg" "lg" "lg" "lg") - ("lim" "\\lim" t "lim" "lim" "lim" "lim") - ("liminf" "\\liminf" t "liminf" "liminf" "liminf" "liminf") - ("limsup" "\\limsup" t "limsup" "limsup" "limsup" "limsup") - ("ln" "\\ln" t "ln" "ln" "ln" "ln") - ("log" "\\log" t "log" "log" "log" "log") - ("max" "\\max" t "max" "max" "max" "max") - ("min" "\\min" t "min" "min" "min" "min") - ("Pr" "\\Pr" t "Pr" "Pr" "Pr" "Pr") - ("sec" "\\sec" t "sec" "sec" "sec" "sec") - ("sin" "\\sin" t "sin" "sin" "sin" "sin") - ("sinh" "\\sinh" t "sinh" "sinh" "sinh" "sinh") - ("sup" "\\sup" t "⊃" "sup" "sup" "sup") - ("tan" "\\tan" t "tan" "tan" "tan" "tan") - ("tanh" "\\tanh" t "tanh" "tanh" "tanh" "tanh") - - "** Signs & Symbols" - ("bull" "\\textbullet{}" nil "•" "*" "*" "•") - ("bullet" "\\textbullet{}" nil "•" "*" "*" "•") - ("star" "\\star" t "*" "*" "*" "⋆") - ("lowast" "\\ast" t "∗" "*" "*" "∗") - ("ast" "\\ast" t "∗" "*" "*" "*") - ("odot" "\\odot" t "o" "[circled dot]" "[circled dot]" "ʘ") - ("oplus" "\\oplus" t "⊕" "[circled plus]" "[circled plus]" "⊕") - ("otimes" "\\otimes" t "⊗" "[circled times]" "[circled times]" "⊗") - ("check" "\\checkmark" t "✓" "[checkmark]" "[checkmark]" "✓") - ("checkmark" "\\checkmark" t "✓" "[checkmark]" "[checkmark]" "✓") - - "** Miscellaneous (seldom used)" - ("para" "\\P{}" nil "¶" "[pilcrow]" "¶" "¶") - ("ordf" "\\textordfeminine{}" nil "ª" "_a_" "ª" "ª") - ("ordm" "\\textordmasculine{}" nil "º" "_o_" "º" "º") - ("cedil" "\\c{}" nil "¸" "[cedilla]" "¸" "¸") - ("oline" "\\overline{~}" t "‾" "[overline]" "¯" "‾") - ("uml" "\\textasciidieresis{}" nil "¨" "[diaeresis]" "¨" "¨") - ("zwnj" "\\/{}" nil "‌" "" "" "‌") - ("zwj" "" nil "‍" "" "" "‍") - ("lrm" "" nil "‎" "" "" "‎") - ("rlm" "" nil "‏" "" "" "‏") - - "** Smilies" - ("smile" "\\smile" t "⌣" ":-)" ":-)" "⌣") - ("frown" "\\frown" t "⌢" ":-(" ":-(" "⌢") - ("smiley" "\\smiley{}" nil "☺" ":-)" ":-)" "☺") - ("blacksmile" "\\blacksmiley{}" nil "☻" ":-)" ":-)" "☻") - ("sad" "\\frownie{}" nil "☹" ":-(" ":-(" "☹") - - "** Suits" - ("clubs" "\\clubsuit" t "♣" "[clubs]" "[clubs]" "♣") - ("clubsuit" "\\clubsuit" t "♣" "[clubs]" "[clubs]" "♣") - ("spades" "\\spadesuit" t "♠" "[spades]" "[spades]" "♠") - ("spadesuit" "\\spadesuit" t "♠" "[spades]" "[spades]" "♠") - ("hearts" "\\heartsuit" t "♥" "[hearts]" "[hearts]" "♥") - ("heartsuit" "\\heartsuit" t "♥" "[hearts]" "[hearts]" "♥") - ("diams" "\\diamondsuit" t "♦" "[diamonds]" "[diamonds]" "◆") - ("diamondsuit" "\\diamondsuit" t "♦" "[diamonds]" "[diamonds]" "◆") - ("diamond" "\\diamondsuit" t "⋄" "[diamond]" "[diamond]" "◆") - ("Diamond" "\\diamondsuit" t "⋄" "[diamond]" "[diamond]" "◆") - ("loz" "\\lozenge" t "◊" "[lozenge]" "[lozenge]" "â§«") - ) - "Default entities used in Org-mode to produce special characters. -For details see `org-entities-user'.") - -(defsubst org-entity-get (name) - "Get the proper association for NAME from the entity lists. -This first checks the user list, then the built-in list." - (or (assoc name org-entities-user) - (assoc name org-entities))) - -(defun org-entity-get-representation (name kind) - "Get the correct representation of entity NAME for export type KIND. -Kind can be any of `latex', `html', `ascii', `latin1', or `utf8'." - (let* ((e (org-entity-get name)) - (n (cdr (assq kind '((latex . 1) (html . 3) (ascii . 4) - (latin1 . 5) (utf8 . 6))))) - (r (and e n (nth n e)))) - (if (and e r - (not org-entities-ascii-explanatory) - (memq kind '(ascii latin1 utf8)) - (= (string-to-char r) ?\[)) - (concat "\\" name) - r))) - -(defsubst org-entity-latex-math-p (name) - "Does entity NAME require math mode in LaTeX?" - (nth 2 (org-entity-get name))) - -;; Helpfunctions to create a table for orgmode.org/worg/org-symbols.org - -(defun org-entities-create-table () - "Create an Org mode table with all entities." - (interactive) - (let ((pos (point)) e latex mathp html latin utf8 name ascii) - (insert "|Name|LaTeX code|LaTeX|HTML code |HTML|ASCII|Latin1|UTF-8\n|-\n") - (mapc (lambda (e) (when (listp e) - (setq name (car e) - latex (nth 1 e) - mathp (nth 2 e) - html (nth 3 e) - ascii (nth 4 e) - latin (nth 5 e) - utf8 (nth 6 e)) - (if (equal ascii "|") (setq ascii "\\vert")) - (if (equal latin "|") (setq latin "\\vert")) - (if (equal utf8 "|") (setq utf8 "\\vert")) - (if (equal ascii "=>") (setq ascii "= >")) - (if (equal latin "=>") (setq latin "= >")) - (insert "|" name - "|" (format "=%s=" latex) - "|" (format (if mathp "$%s$" "$\\mbox{%s}$") - latex) - "|" (format "=%s=" html) "|" html - "|" ascii "|" latin "|" utf8 - "|\n"))) - org-entities) - (goto-char pos) - (org-table-align))) - -(defvar org-pretty-entities) ;; declare defcustom from org -(defun org-entities-help () - "Create a Help buffer with all available entities." - (interactive) - (with-output-to-temp-buffer "*Org Entity Help*" - (princ "Org-mode entities\n=================\n\n") - (let ((ll (append '("* User-defined additions (variable org-entities-user)") - org-entities-user - org-entities)) - e latex mathp html latin utf8 name ascii - (lastwasstring t) - (head (concat - "\n" - " Symbol Org entity LaTeX code HTML code\n" - " -----------------------------------------------------------\n"))) - (while ll - (setq e (pop ll)) - (if (stringp e) - (progn - (princ e) - (princ "\n") - (setq lastwasstring t)) - (if lastwasstring (princ head)) - (setq lastwasstring nil) - (setq name (car e) - latex (nth 1 e) - html (nth 3 e) - utf8 (nth 6 e)) - (princ (format " %-8s \\%-16s %-22s %-13s\n" - utf8 name latex html)))))) - (with-current-buffer "*Org Entity Help*" - (org-mode) - (when org-pretty-entities - (org-toggle-pretty-entities))) - (select-window (get-buffer-window "*Org Entity Help*"))) - - -(defun replace-amp () - "Postprocess HTML file to unescape the ampersand." - (interactive) - (while (re-search-forward "&\\([^<;]+;\\)" nil t) - (replace-match (concat "&" (match-string 1)) t t))) - -(provide 'org-entities) - -;; Local variables: -;; coding: utf-8 -;; End: - -;;; org-entities.el ends here diff --git a/elpa/org-20150629/org-pkg.el b/elpa/org-20150629/org-pkg.el deleted file mode 100644 index 201e081a..00000000 --- a/elpa/org-20150629/org-pkg.el +++ /dev/null @@ -1,3 +0,0 @@ -(define-package "org" - "20150629" "Outline-based notes management and organizer" ( )) -;; no-byte-compile: t diff --git a/elpa/org-20150629/org-src.el b/elpa/org-20150629/org-src.el deleted file mode 100644 index 618ed9fb..00000000 --- a/elpa/org-20150629/org-src.el +++ /dev/null @@ -1,961 +0,0 @@ -;;; org-src.el --- Source code examples in Org -;; -;; Copyright (C) 2004-2014 Free Software Foundation, Inc. -;; -;; Author: Carsten Dominik -;; Bastien Guerry -;; Dan Davison -;; Keywords: outlines, hypermedia, calendar, wp -;; Homepage: http://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 . -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;;; Commentary: - -;; This file contains the code dealing with source code examples in Org-mode. - -;;; Code: - -(require 'org-macs) -(require 'org-compat) -(require 'ob-keys) -(require 'ob-comint) -(eval-when-compile - (require 'cl)) - -(declare-function org-do-remove-indentation "org" (&optional n)) -(declare-function org-at-table.el-p "org" ()) -(declare-function org-in-src-block-p "org" (&optional inside)) -(declare-function org-in-block-p "org" (names)) -(declare-function org-get-indentation "org" (&optional line)) -(declare-function org-switch-to-buffer-other-window "org" (&rest args)) -(declare-function org-pop-to-buffer-same-window - "org-compat" (&optional buffer-or-name norecord label)) -(declare-function org-base-buffer "org" (buffer)) - -(defcustom org-edit-src-region-extra nil - "Additional regexps to identify regions for editing with `org-edit-src-code'. -For examples see the function `org-edit-src-find-region-and-lang'. -The regular expression identifying the begin marker should end with a newline, -and the regexp marking the end line should start with a newline, to make sure -there are kept outside the narrowed region." - :group 'org-edit-structure - :type '(repeat - (list - (regexp :tag "begin regexp") - (regexp :tag "end regexp") - (choice :tag "language" - (string :tag "specify") - (integer :tag "from match group") - (const :tag "from `lang' element") - (const :tag "from `style' element"))))) - -(defcustom org-edit-src-turn-on-auto-save nil - "Non-nil means turn `auto-save-mode' on when editing a source block. -This will save the content of the source code editing buffer into -a newly created file, not the base buffer for this source block. - -If you want to regularly save the base buffer instead of the source -code editing buffer, see `org-edit-src-auto-save-idle-delay' instead." - :group 'org-edit-structure - :version "24.4" - :package-version '(Org . "8.0") - :type 'boolean) - -(defcustom org-edit-src-auto-save-idle-delay 0 - "Delay before saving a source code buffer back into its base buffer. -When a positive integer N, save after N seconds of idle time. -When 0 (the default), don't auto-save. - -If you want to save the source code buffer itself, don't use this. -Check `org-edit-src-turn-on-auto-save' instead." - :group 'org-edit-structure - :version "24.4" - :package-version '(Org . "8.0") - :type 'integer) - -(defcustom org-coderef-label-format "(ref:%s)" - "The default coderef format. -This format string will be used to search for coderef labels in literal -examples (EXAMPLE and SRC blocks). The format can be overwritten in -an individual literal example with the -l option, like - -#+BEGIN_SRC pascal +n -r -l \"((%s))\" -... -#+END_SRC - -If you want to use this for HTML export, make sure that the format does -not introduce special font-locking, and avoid the HTML special -characters `<', `>', and `&'. The reason for this restriction is that -the labels are searched for only after htmlize has done its job." - :group 'org-edit-structure ; FIXME this is not in the right group - :type 'string) - -(defcustom org-edit-fixed-width-region-mode 'artist-mode - "The mode that should be used to edit fixed-width regions. -These are the regions where each line starts with a colon." - :group 'org-edit-structure - :type '(choice - (const artist-mode) - (const picture-mode) - (const fundamental-mode) - (function :tag "Other (specify)"))) - -(defcustom org-src-preserve-indentation nil - "If non-nil preserve leading whitespace characters on export. -If non-nil leading whitespace characters in source code blocks -are preserved on export, and when switching between the org -buffer and the language mode edit buffer. If this variable is nil -then, after editing with \\[org-edit-src-code], the -minimum (across-lines) number of leading whitespace characters -are removed from all lines, and the code block is uniformly -indented according to the value of `org-edit-src-content-indentation'." - :group 'org-edit-structure - :type 'boolean) - -(defcustom org-edit-src-content-indentation 2 - "Indentation for the content of a source code block. -This should be the number of spaces added to the indentation of the #+begin -line in order to compute the indentation of the block content after -editing it with \\[org-edit-src-code]. Has no effect if -`org-src-preserve-indentation' is non-nil." - :group 'org-edit-structure - :type 'integer) - -(defvar org-src-strip-leading-and-trailing-blank-lines nil - "If non-nil, blank lines are removed when exiting the code edit buffer.") - -(defcustom org-edit-src-persistent-message t - "Non-nil means show persistent exit help message while editing src examples. -The message is shown in the header-line, which will be created in the -first line of the window showing the editing buffer." - :group 'org-edit-structure - :type 'boolean) - -(defcustom org-src-window-setup 'reorganize-frame - "How the source code edit buffer should be displayed. -Possible values for this option are: - -current-window Show edit buffer in 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, - return to one window. -other-frame Use `switch-to-buffer-other-frame' to display edit buffer. - Also, when exiting the edit buffer, kill that frame." - :group 'org-edit-structure - :type '(choice - (const current-window) - (const other-frame) - (const other-window) - (const reorganize-frame))) - -(defvar org-src-mode-hook nil - "Hook run after Org switched a source code snippet to its Emacs mode. -This hook will run - -- when editing a source code snippet with \"C-c '\". -- When formatting a source code snippet for export with htmlize. - -You may want to use this hook for example to turn off `outline-minor-mode' -or similar things which you want to have when editing a source code file, -but which mess up the display of a snippet in Org exported files.") - -(defcustom org-src-lang-modes - '(("ocaml" . tuareg) ("elisp" . emacs-lisp) ("ditaa" . artist) - ("asymptote" . asy) ("dot" . fundamental) ("sqlite" . sql) - ("calc" . fundamental) ("C" . c) ("cpp" . c++) ("C++" . c++) - ("screen" . shell-script)) - "Alist mapping languages to their major mode. -The key is the language name, the value is the string that should -be inserted as the name of the major mode. For many languages this is -simple, but for language where this is not the case, this variable -provides a way to simplify things on the user side. -For example, there is no ocaml-mode in Emacs, but the mode to use is -`tuareg-mode'." - :group 'org-edit-structure - :type '(repeat - (cons - (string "Language name") - (symbol "Major mode")))) - -;;; Editing source examples - -(defvar org-src-mode-map (make-sparse-keymap)) -(define-key org-src-mode-map "\C-c'" 'org-edit-src-exit) -(define-key org-src-mode-map "\C-c\C-k" 'org-edit-src-abort) -(define-key org-src-mode-map "\C-x\C-s" 'org-edit-src-save) - -(defvar org-edit-src-force-single-line nil) -(defvar org-edit-src-from-org-mode nil) -(defvar org-edit-src-allow-write-back-p t) -(defvar org-edit-src-picture nil) -(defvar org-edit-src-beg-marker nil) -(defvar org-edit-src-end-marker nil) -(defvar org-edit-src-overlay nil) -(defvar org-edit-src-block-indentation nil) -(defvar org-edit-src-saved-temp-window-config nil) - -(defcustom org-src-ask-before-returning-to-edit-buffer t - "If nil, when org-edit-src code is used on a block that already -has an active edit buffer, it will switch to that edit buffer -immediately; otherwise it will ask whether you want to return to -the existing edit buffer." - :group 'org-edit-structure - :version "24.4" - :package-version '(Org . "8.0") - :type 'boolean) - -(defvar org-src-babel-info nil) - -(define-minor-mode org-src-mode - "Minor mode for language major mode buffers generated by org. -This minor mode is turned on in two situations: -- when editing a source code snippet with \"C-c '\". -- When formatting a source code snippet for export with htmlize. -There is a mode hook, and keybindings for `org-edit-src-exit' and -`org-edit-src-save'") - -(defvar org-edit-src-code-timer nil) -(defun org-edit-src-code (&optional context code edit-buffer-name) - "Edit the source CODE block at point. -The code is copied to a separate buffer and the appropriate mode -is turned on. When done, exit with \\[org-edit-src-exit]. This will -remove the original code in the Org buffer, and replace it with the -edited version. An optional argument CONTEXT is used by \\[org-edit-src-save] -when calling this function. See `org-src-window-setup' to configure -the display of windows containing the Org buffer and the code buffer." - (interactive) - (if (not (or (org-in-block-p '("src" "example" "latex" "html")) - (org-at-table.el-p))) - (user-error "Not in a source code or example block") - (unless (eq context 'save) - (setq org-edit-src-saved-temp-window-config (current-window-configuration))) - (let* ((mark (and (org-region-active-p) (mark))) - (case-fold-search t) - (info - ;; If the src region consists in no lines, we insert a blank - ;; line. - (let* ((temp (org-edit-src-find-region-and-lang)) - (beg (nth 0 temp)) - (end (nth 1 temp))) - (if (>= end beg) temp - (goto-char beg) - (insert "\n") - (org-edit-src-find-region-and-lang)))) - (full-info (org-babel-get-src-block-info 'light)) - (org-mode-p (derived-mode-p 'org-mode)) ;; derived-mode-p is reflexive - (beg (make-marker)) - ;; Move marker with inserted text for case when src block is - ;; just one empty line, i.e. beg == end. - (end (copy-marker (make-marker) t)) - (allow-write-back-p (null code)) - block-nindent total-nindent ovl lang lang-f single lfmt buffer msg - begline markline markcol line col transmitted-variables) - (setq beg (move-marker beg (nth 0 info)) - end (move-marker end (nth 1 info)) - msg (if allow-write-back-p - (substitute-command-keys - "Edit, then exit with C-c ' (C-c and single quote) -- C-c C-k to abort") - "Exit with C-c ' (C-c and single quote) -- C-c C-k to abort") - code (or code (buffer-substring-no-properties beg end)) - lang (or (cdr (assoc (nth 2 info) org-src-lang-modes)) - (nth 2 info)) - lang (if (symbolp lang) (symbol-name lang) lang) - single (nth 3 info) - block-nindent (nth 5 info) - lang-f (intern (concat lang "-mode")) - begline (save-excursion (goto-char beg) (org-current-line)) - transmitted-variables - `((org-edit-src-content-indentation - ,org-edit-src-content-indentation) - (org-edit-src-force-single-line ,single) - (org-edit-src-from-org-mode ,org-mode-p) - (org-edit-src-allow-write-back-p ,allow-write-back-p) - (org-src-preserve-indentation ,org-src-preserve-indentation) - (org-src-babel-info ,(org-babel-get-src-block-info 'light)) - (org-coderef-label-format - ,(or (nth 4 info) org-coderef-label-format)) - (org-edit-src-beg-marker ,beg) - (org-edit-src-end-marker ,end) - (org-edit-src-block-indentation ,block-nindent))) - (if (and mark (>= mark beg) (<= mark (1+ end))) - (save-excursion (goto-char (min mark end)) - (setq markline (org-current-line) - markcol (current-column)))) - (if (equal lang-f 'table.el-mode) - (setq lang-f (lambda () - (text-mode) - (if (org-bound-and-true-p flyspell-mode) - (flyspell-mode -1)) - (table-recognize) - (org-set-local 'org-edit-src-content-indentation 0)))) - (unless (functionp lang-f) - (error "No such language mode: %s" lang-f)) - (save-excursion - (if (> (point) end) (goto-char end)) - (setq line (org-current-line) - col (current-column))) - (if (and (setq buffer (org-edit-src-find-buffer beg end)) - (or (eq context 'save) - (if org-src-ask-before-returning-to-edit-buffer - (y-or-n-p "Return to existing edit buffer ([n] will revert changes)? ") t))) - (org-src-switch-to-buffer buffer 'return) - (when buffer - (with-current-buffer buffer - (if (boundp 'org-edit-src-overlay) - (delete-overlay org-edit-src-overlay))) - (kill-buffer buffer)) - (setq buffer (generate-new-buffer - (or edit-buffer-name - (org-src-construct-edit-buffer-name (buffer-name) lang)))) - (setq ovl (make-overlay beg end)) - (overlay-put ovl 'edit-buffer buffer) - (overlay-put ovl 'help-echo "Click with mouse-1 to switch to buffer editing this segment") - (overlay-put ovl 'face 'secondary-selection) - (overlay-put ovl - 'keymap - (let ((map (make-sparse-keymap))) - (define-key map [mouse-1] 'org-edit-src-continue) - map)) - (overlay-put ovl :read-only "Leave me alone") - (setq transmitted-variables - (append transmitted-variables `((org-edit-src-overlay ,ovl)))) - (org-src-switch-to-buffer buffer 'edit) - (if (eq single 'macro-definition) - (setq code (replace-regexp-in-string "\\\\n" "\n" code t t))) - (insert code) - (remove-text-properties (point-min) (point-max) - '(display nil invisible nil intangible nil)) - (unless (cadr (assq 'org-src-preserve-indentation transmitted-variables)) - (setq total-nindent (or (org-do-remove-indentation) 0))) - (let ((org-inhibit-startup t)) - (condition-case e - (funcall lang-f) - (error - (message "Language mode `%s' fails with: %S" lang-f (nth 1 e))))) - (dolist (pair transmitted-variables) - (org-set-local (car pair) (cadr pair))) - ;; Remove protecting commas from visible part of buffer. - (org-unescape-code-in-region (point-min) (point-max)) - (when markline - (org-goto-line (1+ (- markline begline))) - (org-move-to-column - (if org-src-preserve-indentation markcol - (max 0 (- markcol total-nindent)))) - (push-mark (point) 'no-message t) - (setq deactivate-mark nil)) - (org-goto-line (1+ (- line begline))) - (org-move-to-column - (if org-src-preserve-indentation col (max 0 (- col total-nindent)))) - (org-src-mode) - (set-buffer-modified-p nil) - (setq buffer-file-name nil) - (when org-edit-src-turn-on-auto-save - (setq buffer-auto-save-file-name - (concat (make-temp-name "org-src-") - (format-time-string "-%Y-%d-%m") ".txt"))) - (and org-edit-src-persistent-message - (org-set-local 'header-line-format msg)) - (let ((edit-prep-func (intern (concat "org-babel-edit-prep:" lang)))) - (when (fboundp edit-prep-func) - (funcall edit-prep-func full-info))) - (or org-edit-src-code-timer - (zerop org-edit-src-auto-save-idle-delay) - (setq org-edit-src-code-timer - (run-with-idle-timer - org-edit-src-auto-save-idle-delay t - (lambda () - (cond - ((org-string-match-p "\\`\\*Org Src" (buffer-name)) - (when (buffer-modified-p) (org-edit-src-save))) - ((not (org-some (lambda (b) - (org-string-match-p "\\`\\*Org Src" - (buffer-name b))) - (buffer-list))) - (cancel-timer org-edit-src-code-timer) - (setq org-edit-src-code-timer nil)))))))) - t))) - -(defun org-edit-src-continue (e) - "Continue editing source blocks." ;; Fixme: be more accurate - (interactive "e") - (mouse-set-point e) - (let ((buf (get-char-property (point) 'edit-buffer))) - (if buf (org-src-switch-to-buffer buf 'continue) - (error "Something is wrong here")))) - -(defun org-src-switch-to-buffer (buffer context) - (case org-src-window-setup - ('current-window - (org-pop-to-buffer-same-window buffer)) - ('other-window - (switch-to-buffer-other-window buffer)) - ('other-frame - (case context - ('exit - (let ((frame (selected-frame))) - (switch-to-buffer-other-frame buffer) - (delete-frame frame))) - ('save - (kill-buffer (current-buffer)) - (org-pop-to-buffer-same-window buffer)) - (t - (switch-to-buffer-other-frame buffer)))) - ('reorganize-frame - (if (eq context 'edit) (delete-other-windows)) - (org-switch-to-buffer-other-window buffer) - (if (eq context 'exit) (delete-other-windows))) - ('switch-invisibly - (set-buffer buffer)) - (t - (message "Invalid value %s for org-src-window-setup" - (symbol-name org-src-window-setup)) - (org-pop-to-buffer-same-window buffer)))) - -(defun org-src-construct-edit-buffer-name (org-buffer-name lang) - "Construct the buffer name for a source editing buffer." - (concat "*Org Src " org-buffer-name "[ " lang " ]*")) - -(defun org-src-edit-buffer-p (&optional buffer) - "Test whether BUFFER (or the current buffer if BUFFER is nil) -is a source block editing buffer." - (let ((buffer (org-base-buffer (or buffer (current-buffer))))) - (and (buffer-name buffer) - (string-match "\\`*Org Src " (buffer-name buffer)) - (local-variable-p 'org-edit-src-beg-marker buffer) - (local-variable-p 'org-edit-src-end-marker buffer)))) - -(defun org-edit-src-find-buffer (beg end) - "Find a source editing buffer that is already editing the region BEG to END." - (catch 'exit - (mapc - (lambda (b) - (with-current-buffer b - (if (and (string-match "\\`*Org Src " (buffer-name)) - (local-variable-p 'org-edit-src-beg-marker (current-buffer)) - (local-variable-p 'org-edit-src-end-marker (current-buffer)) - (equal beg org-edit-src-beg-marker) - (equal end org-edit-src-end-marker)) - (throw 'exit (current-buffer))))) - (buffer-list)) - nil)) - -(defun org-edit-fixed-width-region () - "Edit the fixed-width ascii drawing at point. -This must be a region where each line starts with a colon followed by -a space character. -An new buffer is created and the fixed-width region is copied into it, -and the buffer is switched into `artist-mode' for editing. When done, -exit with \\[org-edit-src-exit]. The edited text will then replace -the fragment in the Org-mode buffer." - (interactive) - (let ((line (org-current-line)) - (col (current-column)) - (case-fold-search t) - (msg (substitute-command-keys - "Edit, then exit with C-c ' (C-c and single quote) -- C-c C-k to abort")) - (org-mode-p (derived-mode-p 'org-mode)) - (beg (make-marker)) - (end (make-marker)) - (preserve-indentation org-src-preserve-indentation) - block-nindent ovl beg1 end1 code begline buffer) - (beginning-of-line 1) - (if (looking-at "[ \t]*[^:\n \t]") - nil - (if (looking-at "[ \t]*\\(\n\\|\\'\\)") - (setq beg1 (point) end1 beg1) - (save-excursion - (if (re-search-backward "^[ \t]*[^: \t]" nil 'move) - (setq beg1 (point-at-bol 2)) - (setq beg1 (point)))) - (save-excursion - (if (re-search-forward "^[ \t]*[^: \t]" nil 'move) - (setq end1 (1- (match-beginning 0))) - (setq end1 (point)))) - (org-goto-line line)) - (setq beg (move-marker beg beg1) - end (move-marker end end1) - code (buffer-substring-no-properties beg end) - begline (save-excursion (goto-char beg) (org-current-line))) - (if (and (setq buffer (org-edit-src-find-buffer beg end)) - (y-or-n-p "Return to existing edit buffer ([n] will revert changes)? ")) - (org-pop-to-buffer-same-window buffer) - (when buffer - (with-current-buffer buffer - (if (boundp 'org-edit-src-overlay) - (delete-overlay org-edit-src-overlay))) - (kill-buffer buffer)) - (setq buffer (generate-new-buffer - (org-src-construct-edit-buffer-name - (buffer-name) "Fixed Width"))) - (setq ovl (make-overlay beg end)) - (overlay-put ovl 'face 'secondary-selection) - (overlay-put ovl 'edit-buffer buffer) - (overlay-put ovl 'help-echo "Click with mouse-1 to switch to buffer editing this segment") - (overlay-put ovl 'face 'secondary-selection) - (overlay-put ovl - 'keymap - (let ((map (make-sparse-keymap))) - (define-key map [mouse-1] 'org-edit-src-continue) - map)) - (overlay-put ovl :read-only "Leave me alone") - (org-pop-to-buffer-same-window buffer) - (insert code) - (remove-text-properties (point-min) (point-max) - '(display nil invisible nil intangible nil)) - (setq block-nindent (or (org-do-remove-indentation) 0)) - (cond - ((eq org-edit-fixed-width-region-mode 'artist-mode) - (fundamental-mode) - (artist-mode 1)) - (t (funcall org-edit-fixed-width-region-mode))) - (set (make-local-variable 'org-edit-src-force-single-line) nil) - (set (make-local-variable 'org-edit-src-from-org-mode) org-mode-p) - (set (make-local-variable 'org-edit-src-picture) t) - (goto-char (point-min)) - (while (re-search-forward "^[ \t]*: ?" nil t) - (replace-match "")) - (org-goto-line (1+ (- line begline))) - (org-move-to-column (max 0 (- col block-nindent 2))) - (org-set-local 'org-edit-src-beg-marker beg) - (org-set-local 'org-edit-src-end-marker end) - (org-set-local 'org-edit-src-overlay ovl) - (org-set-local 'org-edit-src-block-indentation block-nindent) - (org-set-local 'org-edit-src-content-indentation 0) - (org-set-local 'org-src-preserve-indentation nil) - (org-src-mode) - (set-buffer-modified-p nil) - (and org-edit-src-persistent-message - (org-set-local 'header-line-format msg))) - (message "%s" msg) - t))) - -(defun org-edit-src-find-region-and-lang () - "Find the region and language for a local edit. -Return a list with beginning and end of the region, a string representing -the language, a switch telling if the content should be in a single line." - (let ((re-list - (append - org-edit-src-region-extra - '( - ("[^<]*>[ \t]*\n?" "\n?[ \t]*" lang) - ("[^<]*>[ \t]*\n?" "\n?[ \t]*" style) - ("[ \t]*\n?" "\n?[ \t]*" "fundamental") - ("[ \t]*\n?" "\n?[ \t]*" "emacs-lisp") - ("[ \t]*\n?" "\n?[ \t]*" "perl") - ("[ \t]*\n?" "\n?[ \t]*" "python") - ("[ \t]*\n?" "\n?[ \t]*" "ruby") - ("^[ \t]*#\\+begin_src\\( \\([^ \t\n]+\\)\\)?.*\n" "\n[ \t]*#\\+end_src" 2) - ("^[ \t]*#\\+begin_example.*\n" "\n[ \t]*#\\+end_example" "fundamental") - ("^[ \t]*#\\+html:" "\n" "html" single-line) - ("^[ \t]*#\\+begin_html.*\n" "\n[ \t]*#\\+end_html" "html") - ("^[ \t]*#\\+latex:" "\n" "latex" single-line) - ("^[ \t]*#\\+begin_latex.*\n" "\n[ \t]*#\\+end_latex" "latex") - ("^[ \t]*#\\+ascii:" "\n" "fundamental" single-line) - ("^[ \t]*#\\+begin_ascii.*\n" "\n[ \t]*#\\+end_ascii" "fundamental") - ("^[ \t]*#\\+macro:[ \t]+\\S-+\\( \\|$\\)" - "\n" "fundamental" macro-definition) - ))) - (pos (point)) - re1 re2 single beg end lang lfmt match-re1 ind entry) - (catch 'exit - (while (setq entry (pop re-list)) - (setq re1 (car entry) re2 (nth 1 entry) lang (nth 2 entry) - single (nth 3 entry)) - (save-excursion - (if (or (looking-at re1) - (re-search-backward re1 nil t)) - (progn - (setq match-re1 (match-string 0)) - (setq beg (match-end 0) - lang (org-edit-src-get-lang lang) - lfmt (org-edit-src-get-label-format match-re1) - ind (org-edit-src-get-indentation (match-beginning 0))) - (if (and (re-search-forward re2 nil t) - (>= (match-end 0) pos)) - (throw 'exit (list beg (match-beginning 0) - lang single lfmt ind)))) - (if (or (looking-at re2) - (re-search-forward re2 nil t)) - (progn - (setq end (match-beginning 0)) - (if (and (re-search-backward re1 nil t) - (<= (match-beginning 0) pos)) - (progn - (setq lfmt (org-edit-src-get-label-format - (match-string 0)) - ind (org-edit-src-get-indentation - (match-beginning 0))) - (throw 'exit - (list (match-end 0) end - (org-edit-src-get-lang lang) - single lfmt ind))))))))) - (when (org-at-table.el-p) - (re-search-backward "^[\t]*[^ \t|\\+]" nil t) - (setq beg (1+ (point-at-eol))) - (goto-char beg) - (or (re-search-forward "^[\t]*[^ \t|\\+]" nil t) - (progn (goto-char (point-max)) (newline))) - (setq end (1- (point-at-bol))) - (throw 'exit (list beg end 'table.el nil nil 0)))))) - -(defun org-edit-src-get-lang (lang) - "Extract the src language." - (let ((m (match-string 0))) - (cond - ((stringp lang) lang) - ((integerp lang) (match-string lang)) - ((and (eq lang 'lang) - (string-match "\\ cnt 0)) - (goto-char (point-max)) (insert "\\n"))) - (goto-char (point-min)) - (if (looking-at "\\s-*") (replace-match " "))) - (when (and (org-bound-and-true-p org-edit-src-from-org-mode) - (not fixed-width-p)) - (org-escape-code-in-region (point-min) (point-max)) - (setq delta (+ delta - (save-excursion - (org-goto-line line) - (if (looking-at "[ \t]*\\(,,\\)?\\(\\*\\|#+\\)") 1 - 0))))) - (when (org-bound-and-true-p org-edit-src-picture) - (setq preserve-indentation nil) - (untabify (point-min) (point-max)) - (goto-char (point-min)) - (while (re-search-forward "^" nil t) - (replace-match ": "))) - (unless (or single preserve-indentation (= total-nindent 0)) - (setq indent (make-string total-nindent ?\ )) - (goto-char (point-min)) - (while (re-search-forward "\\(^\\).+" nil t) - (replace-match indent nil nil nil 1))) - (if (org-bound-and-true-p org-edit-src-picture) - (setq total-nindent (+ total-nindent 2))) - (setq code (buffer-string)) - (when (eq context 'save) - (erase-buffer) - (insert bufstr)) - (set-buffer-modified-p nil)) - (org-src-switch-to-buffer (marker-buffer beg) (or context 'exit)) - (if (eq context 'save) (save-buffer) - (with-current-buffer buffer - (set-buffer-modified-p nil)) - (kill-buffer buffer)) - (goto-char beg) - (when allow-write-back-p - (undo-boundary) - (delete-region beg (max beg end)) - (unless (string-match "\\`[ \t]*\\'" code) - (insert code)) - ;; Make sure the overlay stays in place - (when (eq context 'save) (move-overlay ovl beg (point))) - (goto-char beg) - (if single (just-one-space))) - (if (memq t (mapcar (lambda (overlay) - (eq (overlay-get overlay 'invisible) - 'org-hide-block)) - (overlays-at (point)))) - ;; Block is hidden; put point at start of block - (beginning-of-line 0) - ;; Block is visible, put point where it was in the code buffer - (when allow-write-back-p - (org-goto-line (1- (+ (org-current-line) line))) - (org-move-to-column (if preserve-indentation col (+ col total-nindent delta))))) - (unless (eq context 'save) - (move-marker beg nil) - (move-marker end nil))) - (unless (eq context 'save) - (when org-edit-src-saved-temp-window-config - (set-window-configuration org-edit-src-saved-temp-window-config) - (setq org-edit-src-saved-temp-window-config nil)))) - -(defun org-edit-src-abort () - "Abort editing of the src code and return to the Org buffer." - (interactive) - (let (org-edit-src-allow-write-back-p) - (org-edit-src-exit 'exit))) - -(defmacro org-src-in-org-buffer (&rest body) - `(let ((p (point)) (m (mark)) (ul buffer-undo-list) msg) - (save-window-excursion - (org-edit-src-exit 'save) - ,@body - (setq msg (current-message)) - (if (eq org-src-window-setup 'other-frame) - (let ((org-src-window-setup 'current-window)) - (org-edit-src-code 'save)) - (org-edit-src-code 'save))) - (setq buffer-undo-list ul) - (push-mark m 'nomessage) - (goto-char (min p (point-max))) - (message (or msg "")))) -(def-edebug-spec org-src-in-org-buffer (body)) - -(defun org-edit-src-save () - "Save parent buffer with current state source-code buffer." - (interactive) - (if (string-match "Fixed Width" (buffer-name)) - (user-error "Use C-c ' to save and exit, C-c C-k to abort editing") - (org-src-in-org-buffer (save-buffer)))) - -(declare-function org-babel-tangle "ob-tangle" (&optional arg target-file lang)) - -(defun org-src-tangle (arg) - "Tangle the parent buffer." - (interactive) - (org-src-in-org-buffer (org-babel-tangle arg))) - -(defun org-src-mode-configure-edit-buffer () - (when (org-bound-and-true-p org-edit-src-from-org-mode) - (org-add-hook 'kill-buffer-hook - (lambda () - (when (overlayp org-edit-src-overlay) - (delete-overlay org-edit-src-overlay))) - nil 'local) - (if (org-bound-and-true-p org-edit-src-allow-write-back-p) - (progn - (setq buffer-offer-save t) - (setq buffer-file-name - (concat (buffer-file-name (marker-buffer org-edit-src-beg-marker)) - "[" (buffer-name) "]")) - (if (featurep 'xemacs) - (progn - (make-variable-buffer-local 'write-contents-hooks) ; needed only for 21.4 - (setq write-contents-hooks '(org-edit-src-save))) - (setq write-contents-functions '(org-edit-src-save)))) - (setq buffer-read-only t)))) - -(org-add-hook 'org-src-mode-hook 'org-src-mode-configure-edit-buffer) - - -(defun org-src-associate-babel-session (info) - "Associate edit buffer with comint session." - (interactive) - (let ((session (cdr (assoc :session (nth 2 info))))) - (and session (not (string= session "none")) - (org-babel-comint-buffer-livep session) - (let ((f (intern (format "org-babel-%s-associate-session" - (nth 0 info))))) - (and (fboundp f) (funcall f session)))))) - -(defun org-src-babel-configure-edit-buffer () - (when org-src-babel-info - (org-src-associate-babel-session org-src-babel-info))) - -(org-add-hook 'org-src-mode-hook 'org-src-babel-configure-edit-buffer) -(defmacro org-src-do-at-code-block (&rest body) - "Execute a command from an edit buffer in the Org-mode buffer." - `(let ((beg-marker org-edit-src-beg-marker)) - (if beg-marker - (with-current-buffer (marker-buffer beg-marker) - (goto-char (marker-position beg-marker)) - ,@body)))) -(def-edebug-spec org-src-do-at-code-block (body)) - -(defun org-src-do-key-sequence-at-code-block (&optional key) - "Execute key sequence at code block in the source Org buffer. -The command bound to KEY in the Org-babel key map is executed -remotely with point temporarily at the start of the code block in -the Org buffer. - -This command is not bound to a key by default, to avoid conflicts -with language major mode bindings. To bind it to C-c @ in all -language major modes, you could use - - (add-hook 'org-src-mode-hook - (lambda () (define-key org-src-mode-map \"\\C-c@\" - 'org-src-do-key-sequence-at-code-block))) - -In that case, for example, C-c @ t issued in code edit buffers -would tangle the current Org code block, C-c @ e would execute -the block and C-c @ h would display the other available -Org-babel commands." - (interactive "kOrg-babel key: ") - (if (equal key (kbd "C-g")) (keyboard-quit) - (org-edit-src-save) - (org-src-do-at-code-block - (call-interactively - (lookup-key org-babel-map key))))) - -(defcustom org-src-tab-acts-natively nil - "If non-nil, the effect of TAB in a code block is as if it were -issued in the language major mode buffer." - :type 'boolean - :version "24.1" - :group 'org-babel) - -(defun org-src-native-tab-command-maybe () - "Perform language-specific TAB action. -Alter code block according to what TAB does in the language major mode." - (and org-src-tab-acts-natively - (org-in-src-block-p) - (not (equal this-command 'org-shifttab)) - (let ((org-src-strip-leading-and-trailing-blank-lines nil)) - (org-babel-do-key-sequence-in-edit-buffer (kbd "TAB"))))) - -(add-hook 'org-tab-first-hook 'org-src-native-tab-command-maybe) - -(defun org-src-font-lock-fontify-block (lang start end) - "Fontify code block. -This function is called by emacs automatic fontification, as long -as `org-src-fontify-natively' is non-nil. For manual -fontification of code blocks see `org-src-fontify-block' and -`org-src-fontify-buffer'" - (let ((lang-mode (org-src-get-lang-mode lang))) - (if (fboundp lang-mode) - (let ((string (buffer-substring-no-properties start end)) - (modified (buffer-modified-p)) - (org-buffer (current-buffer)) pos next) - (remove-text-properties start end '(face nil)) - (with-current-buffer - (get-buffer-create - (concat " org-src-fontification:" (symbol-name lang-mode))) - (delete-region (point-min) (point-max)) - (insert string " ") ;; so there's a final property change - (unless (eq major-mode lang-mode) (funcall lang-mode)) - (font-lock-fontify-buffer) - (setq pos (point-min)) - (while (setq next (next-single-property-change pos 'face)) - (put-text-property - (+ start (1- pos)) (1- (+ start next)) 'face - (get-text-property pos 'face) org-buffer) - (setq pos next))) - (add-text-properties - start end - '(font-lock-fontified t fontified t font-lock-multiline t)) - (set-buffer-modified-p modified))))) - -(defun org-src-fontify-block () - "Fontify code block at point." - (interactive) - (save-excursion - (let ((org-src-fontify-natively t) - (info (org-edit-src-find-region-and-lang))) - (font-lock-fontify-region (nth 0 info) (nth 1 info))))) - -(defun org-src-fontify-buffer () - "Fontify all code blocks in the current buffer." - (interactive) - (org-babel-map-src-blocks nil - (org-src-fontify-block))) - -(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"))) - -(provide 'org-src) - -;;; org-src.el ends here diff --git a/elpa/org-20160215.signed b/elpa/org-20160215.signed new file mode 100644 index 00000000..2728875c --- /dev/null +++ b/elpa/org-20160215.signed @@ -0,0 +1 @@ +Good signature from 474F05837FBDEF9B GNU ELPA Signing Agent (trust undefined) created at 2016-02-15T11:10:06+0100 using DSA \ No newline at end of file diff --git a/elpa/org-20150629/COPYING b/elpa/org-20160215/COPYING similarity index 100% rename from elpa/org-20150629/COPYING rename to elpa/org-20160215/COPYING diff --git a/elpa/org-20150629/README_ELPA b/elpa/org-20160215/README_ELPA similarity index 100% rename from elpa/org-20150629/README_ELPA rename to elpa/org-20160215/README_ELPA diff --git a/elpa/org-20150629/dir b/elpa/org-20160215/dir similarity index 100% rename from elpa/org-20150629/dir rename to elpa/org-20160215/dir diff --git a/elpa/org-20160215/etc/ORG-NEWS b/elpa/org-20160215/etc/ORG-NEWS new file mode 100644 index 00000000..37911c66 --- /dev/null +++ b/elpa/org-20160215/etc/ORG-NEWS @@ -0,0 +1,3119 @@ +ORG NEWS -- history of user-visible changes. -*- org -*- + +#+LINK: doc http://orgmode.org/worg/doc.html#%s +#+LINK: git http://orgmode.org/cgit.cgi/org-mode.git/commit/?id=%s + +Copyright (C) 2012-2016 Free Software Foundation, Inc. +See the end of the file for license conditions. + +Please send Org bug reports to emacs-orgmode@gnu.org. + +* Version 8.3 + +** Incompatible changes + +*** Properties drawers syntax changes + +Properties drawers are now required to be located right after a +headline and its planning line, when applicable. + +It will break some documents as TODO states changes were sometimes +logged before the property drawer. + +The following function will repair them: + +#+BEGIN_SRC emacs-lisp +(defun org-repair-property-drawers () + "Fix properties drawers in current buffer. +Ignore non Org buffers." + (when (eq major-mode 'org-mode) + (org-with-wide-buffer + (goto-char (point-min)) + (let ((case-fold-search t) + (inline-re (and (featurep 'org-inlinetask) + (concat (org-inlinetask-outline-regexp) + "END[ \t]*$")))) + (org-map-entries + (lambda () + (unless (and inline-re (org-looking-at-p inline-re)) + (save-excursion + (let ((end (save-excursion (outline-next-heading) (point)))) + (forward-line) + (when (org-looking-at-p org-planning-line-re) (forward-line)) + (when (and (< (point) end) + (not (org-looking-at-p org-property-drawer-re)) + (save-excursion + (and (re-search-forward org-property-drawer-re end t) + (eq (org-element-type + (save-match-data (org-element-at-point))) + 'drawer)))) + (insert (delete-and-extract-region + (match-beginning 0) + (min (1+ (match-end 0)) end))) + (unless (bolp) (insert "\n")))))))))))) +#+END_SRC + +*** Using "COMMENT" is now equivalent to commenting with "#" + +If you used "COMMENT" in headlines to prevent a subtree from being +exported, you can still do it but all information within the subtree +is now commented out, i.e. no #+OPTIONS line will be parsed or taken +into account when exporting. + +If you want to exclude a headline from export while using its contents +for setting options, use =:noexport:= (see =org-export-exclude-tags=.) + +*** =#+CATEGORY= keywords no longer apply partially to document + +It was possible to use several such keywords and have them apply to +the text below until the next one, but strongly deprecated since Org +5.14 (2008). + +=#+CATEGORY= keywords are now global to the document. You can use node +properties to set category for a subtree, e.g., + +#+BEGIN_SRC org +,* Headline + :PROPERTIES: + :CATEGORY: some category + :END: +#+END_SRC + +*** New variable to control visibility when revealing a location + +~org-show-following-heading~, ~org-show-siblings~, ~org-show-entry-below~ +and ~org-show-hierarchy-above~ no longer exist. Instead, visibility is +controlled through a single variable: ~org-show-context-detail~, which +see. + +*** Replace disputed keys again when reading a date + +~org-replace-disputed-keys~ has been ignored when reading date since +version 8.1, but the former behavior is restored again. + +Keybinding for reading date can be customized with a new variable +~org-read-date-minibuffer-local-map~. + +*** No default title is provided when =TITLE= keyword is missing + +Skipping =TITLE= keyword no longer provides the current file name, or +buffer name, as the title. Instead, simply ignore the title. + +*** Default bindings of =C-c C-n= and =C-c C-p= changed + +The key sequences =C-c C-n= and =C-c C-p= are now bound to +~org-next-visible-heading~ and ~org-next-visible-heading~ respectively, +rather than the =outline-mode= versions of these functions. The Org +version of these functions skips over inline tasks (and even-level +headlines when ~org-odd-levels-only~ is set). + +*** ~org-element-context~ no longer return objects in keywords + +~org-element-context~ used to return objects on some keywords, i.e., +=TITLE=, =DATE= and =AUTHOR=. It now returns only the keyword. + +*** ~org-timer-default-timer~ type changed from number to string + +If you have, in your configuration, something like =(setq +org-timer-default-timer 10)= replace it with =(setq +org-timer-default-timer "10")=. + +*** Functions signature changes + +The following functions require an additional argument. See their +docstring for more information. + +- ~org-export-collect-footnote-definitions~ +- ~org-html-format-headline-function~ +- ~org-html-format-inlinetask-function~ +- ~org-latex-format-headline-function~ +- ~org-latex-format-inlinetask-function~ +- ~org-link-search~ +** New features + +*** Behavior of ~org-return~ changed + +If point is before or after the headline title, insert a new line +without changing the headline. + +*** Hierarchies of tags +The functionality of nesting tags in hierarchies is added to org-mode. +This is the generalization of what was previously called "Tag groups" +in the manual. That term is now changed to "Tag hierarchy". + +The following in-buffer definition: +#+BEGIN_SRC org + ,#+TAGS: [ Group : SubOne SubTwo ] + ,#+TAGS: [ SubOne : SubOne1 SubOne2 ] + ,#+TAGS: [ SubTwo : SubTwo1 SubTwo2 ] +#+END_SRC + +Should be seen as the following tree of tags: +- Group + - SubOne + - SubOne1 + - SubOne2 + - SubTwo + - SubTwo1 + - SubTwo2 + +Searching for "Group" should return all tags defined above. Filtering +on SubOne filters also it's sub-tags. Etc. + +There is no limit on the depth for the tag hierarchy. + +*** Additional syntax for non-unique grouptags +Additional syntax is defined for grouptags if the tags in the group +don't have to be distinct on a heading. + +Grouptags had to previously be defined with { }. This syntax is +already used for exclusive tags and Grouptags need their own, +non-exclusive syntax. This behaviour is achieved with [ ]. Note: { +} can still be used also for Grouptags but then only one of the +given tags can be used on the headline at the same time. Example: + +[ group : sub1 sub2 ] + +#+BEGIN_SRC org + ,* Test :sub1:sub2: +#+END_SRC + +This is a more general case than the already existing syntax for +grouptags; { }. + +*** Define regular expression patterns as tags +Tags can be defined as grouptags with regular expressions as +"sub-tags". + +The regular expressions in the group must be marked up within { }. +Example use: + +: #+TAGS: [ Project : {P@.+} ] + +Searching for the tag Project will now list all tags also including +regular expression matches for P@.+. Good for example if tags for a +certain project is tagged with a common project-identifier, +i.e. P@2014_OrgTags. + +*** Filtering in the agenda on grouptags (Tag hierarchies) +Filtering in the agenda on grouptags filter all of the related tags. +Exception if filter is applied with a (double) prefix-argument. + +Filtering in the agenda on subcategories does not filter the "above" +levels anymore. + +If a grouptag contains a regular expression the regular expression +is also used as a filter. + +*** Minor refactoring of ~org-agenda-filter-by-tag~ +Now uses the argument arg and optional argument exclude instead of +strip and narrow. ARG because the argument has multiple purposes and +makes more sense than strip now. The term narrowing is changed to +exclude. + +The main purpose is for the function to make more logical sense when +filtering on tags now when tags can be structured in hierarchies. + +*** Babel: support for sed scripts + +Thanks to Bjarte Johansen for this feature. + +*** Babel: support for Processing language + +New ob-processing.el library. + +This library implements necessary functions for implementing editing +of Processing code blocks, viewing the resulting sketches in an +external viewer, and HTML export of the sketches. + +Check the documentation for more. + +Thanks to Jarmo Hurri for this feature. + +*** New behaviour for `org-toggle-latex-fragment' +The new behaviour is the following: + +- With a double prefix argument or with a single prefix argument + when point is before the first headline, toggle overlays in the + whole buffer; + +- With a single prefix argument, toggle overlays in the current + subtree; + +- On latex code, toggle overlay at point; + +- Otherwise, toggle overlays in the current section. + +*** Additional markup with =#+INCLUDE= keyword + +The content of the included file can now be optionally marked up, for +instance as HTML. See the documentation for details. + +*** File links with =#+INCLUDE= keyword + +Objects can be extracted via =#+INCLUDE= using file links. It is +possible to include only the contents of the object. See manual for +more information. + +*** Drawers do not need anymore to be referenced in =#+DRAWERS= + +One can use a drawer without listing it in the =#+DRAWERS= keyword, +which is now obsolete. As a consequence, this change also deprecates +~org-drawers~ variable. + +*** ~org-edit-special~ can edit export blocks + +Using C-c ' on an export block now opens a sub-editing buffer. Major +mode in that buffer is determined by export backend name (e.g., +"latex" \to "latex-mode"). You can define exceptions to this rule by +configuring ~org-src-lang-modes~, which see. + +*** Additional =:hline= processing to ob-shell + +If the argument =:hlines yes= is present in a babel call, an optional +argument =:hlines-string= can be used to define a string to use as a +representation for the lisp symbol ='hline= in the shell program. The +default is =hline=. + +*** Markdown export supports switches in source blocks + +For example, it is now possible to number lines using the =-n= switch +in a source block. + +*** New option in ASCII export + +Plain lists can have an extra margin by setting +~org-ascii-list-margin~ variable to an appopriate integer. + +*** New blocks in ASCII export + +ASCII export now supports =#+BEGIN_JUSTIFYRIGHT= and +=#+BEGIN_JUSTIFYLEFT= blocks. See documentation for details. + +*** More back-end specific publishing options + +The number of publishing options specific to each back-end has been +increased. See manual for details. + +*** Export inline source blocks + +Inline source code was used to be removed upon exporting. They are +now handled as standard code blocks, i.e., the source code can appear +in the output, depending on the parameters. + +*** Extend ~org-export-first-sibling-p~ and ~org-export-last-sibling-p~ + +These functions now support any element or object, not only headlines. + +*** New function: ~org-export-table-row-in-header-p~ + +*** New function: ~org-export-get-reference~ + +*** New function: ~org-element-lineage~ + +This function deprecates ~org-export-get-genealogy~. It also provides +more features. See docstring for details. + +*** New function: ~org-element-copy~ + +*** New filter: ~org-export-filter-body-functions~ + +Functions in this filter are applied on the body of the exported +document, befor wrapping it within the template. + +*** New :environment parameter when exporting example blocks to LaTeX + +: #+ATTR_LATEX: :environment myverbatim +: #+BEGIN_EXAMPLE +: This sentence is false. +: #+END_EXAMPLE + +will be exported using =@samp(myverbatim)= instead of =@samp(verbatim)=. + +*** Various improvements on radio tables + +Radio tables feature now relies on Org's export framework ("ox.el"). +~:no-escape~ parameter no longer exists, but additional global +parameters are now supported: ~:raw~, ~:backend~. Moreover, there are +new parameters specific to some pre-defined translators, e.g., +~:environment~ and ~:booktabs~ for ~orgtbl-to-latex~. See translators +docstrings (including ~orgtbl-to-generic~) for details. + +*** Non-floating minted listings in Latex export + +It is not possible to specify =#+attr_latex: :float nil= in conjunction with +source blocks exported by the minted package. + +*** Field formulas can now create columns as needed + +Previously, evaluating formulas that referenced out-of-bounds columns +would throw an error. A new variable +~org-table-formula-create-columns~ was added to adjust this +behavior. It is now possible to silently add new columns, to do so +with a warning or to explicitly ask the user each time. + +*** ASCII plot + +Ability to plot values in a column through ASCII-art bars. See manual +for details. + +*** New hook: ~org-archive-hook~ + +This hook is called after successfully archiving a subtree, with point +on the original subtree, not yet deleted. + +*** New option: ~org-attach-archive-delete~ + +When non-nil, attachments from archived subtrees are removed. + +*** New option: ~org-latex-caption-above~ + +This variable generalizes ~org-latex-table-caption-above~, which is +now deprecated. In addition to tables, it applies to source blocks, +special blocks and images. See docstring for more information. + +*** New option: ~org-latex-prefer-user-labels~ + +See docstring for more information. + +*** Export unnumbered headlines + +Headlines, for which the property ~UNNUMBERED~ is non-nil, are now +exported without section numbers irrespective of their levels. The +property is inherited by children. + +*** Tables can be sorted with an arbitrary function + +It is now possible to specify a function, both programatically, +through a new optional argument, and interactively with ~f~ or ~F~ +keys, to sort a table. + +*** Table of contents can be local to a section + +The ~TOC~ keywords now accepts an optional ~local~ parameter. See +manual for details. + +*** Countdown timers can now be paused + +~org-timer-pause-time~ now pauses and restarts both relative and +countdown timers. + +*** New option ~only-window~ for ~org-agenda-window-setup~ + +When ~org-agenda-window-setup~ is set to ~only-window~, the agenda is +displayed as the sole window of the current frame. + +*** ~{{{date}}}~ macro supports optional formatting argument + +It is now possible to supply and optional formatting argument to +~{{{date}}}~. See manual for details. + +*** ~{{{property}}}~ macro supports optional search argument + +It is now possible to supply an optional search option to +~{{{property}}}~ in order to retrieve remote properties optional. See +manual for details. + +*** New option ~org-export-with-title~ + +It is possible to suppress the title insertion with ~#+OPTIONS: +title:nil~ or globally using the variable ~org-export-with-title~. + +*** New entities family: "\_ " + +"\_ " are used to insert up to 20 contiguous spaces in various +back-ends. In particular, this family can be used to introduce +leading spaces within table cells. + +*** New MathJax configuration options + +Org uses the MathJax CDN by default. See the manual and the docstring +of ~org-html-mathjax-options~ for details. + +*** New behaviour in `org-export-options-alist' + +When defining a back-end, it is now possible to specify to give +`parse' behaviour on a keyword. It is equivalent to call +`org-element-parse-secondary-string' on the value. + +However, parsed =KEYWORD= is automatically associated to an +=:EXPORT_KEYWORD:= property, which can be used to override the keyword +value during a subtree export. Moreover, macros are expanded in such +keywords and properties. + +*** Viewport support in html export + +Viewport for mobile-optimized website is now automatically inserted +when exporting to html. See ~org-html-viewport~ for details. + +*** New ~#+SUBTITLE~ export keyword + +Org can typeset a subtitle in some export backends. See the manual +for details. + +*** Remotely edit a footnote definition + +Calling ~org-edit-footnote-reference~ (C-c ') on a footnote reference +allows to edit its definition, as long as it is not anonymous, in +a dedicated buffer. It works even if buffer is currently narrowed. + +*** New function ~org-delete-indentation~ bound to ~M-^~ + +Work as ~delete-indentation~ unless at heading, in which case text is +added to headline text. + +*** Support for images in Texinfo export + +~Texinfo~ back-end now handles images. See manual for details. + +*** Support for captions in Texinfo export + +Tables and source blocks can now have captions. Additionally, lists +of tables and lists of listings can be inserted in the document with +=#+TOC= keyword. + +*** Countdown timer support hh:mm:ss format + +In addition to setting countdown timers in minutes, they can also be +set using the hh:mm:ss format. + +*** Extend ~org-clone-subtree-with-time-shift~ + +~org-clone-subtree-with-time-shift~ now accepts 0 as an argument for +the number of clones, which removes the repeater from the original +subtree and creates one shifted, repeating clone. + +*** New time block for clock tables: ~untilnow~ + +It encompasses all past closed clocks. + +*** Support for the ~polyglossia~ LaTeX package + +See the docstring of ~org-latex-classes~ and +~org-latex-guess-polyglossia-language~ for details. + +*** None-floating tables, graphics and blocks can have captions + +*** `org-insert-heading' can be forced to insert top-level headline + +** Removed functions + +*** Removed function ~org-translate-time~ + +Use ~org-timestamp-translate~ instead. + +*** Removed function ~org-beamer-insert-options-template~ + +This function inserted a Beamer specific template at point or in +current subtree. Use ~org-export-insert-default-template~ instead, as +it provides more features and covers all export back-ends. It is also +accessible from the export dispatcher. + +*** Removed function ~org-timer-cancel-timer~ + +~org-timer-stop~ now stops both relative and countdown timers. + +*** Removed function ~org-export-solidify-link-text~ + +This function, being non-bijective, introduced bug in internal +references. Use ~org-export-get-reference~ instead. + +*** Removed function ~org-end-of-meta-data-and-drawers~ + +The function is superseded by ~org-end-of-meta-data~, called with an +optional argument. + +*** Removed functions ~org-table-colgroup-line-p~, ~org-table-cookie-line-p~ + +These functions were left-over from pre 8.0 era. They are not correct +anymore. Since they are not needed, they have no replacement. +** Removed options + +*** ~org-list-empty-line-terminates-plain-lists~ is deprecated + +It will be kept in code base until next release, for backward +compatibility. + +If you need to separate consecutive lists with blank lines, always use +two of them, as if this option was nil (default value). + +*** ~org-export-with-creator~ is a boolean + +Special ~comment~ value is no longer allowed. It is possible to use a +body filter to add comments about the creator at the end of the +document instead. + +*** Removed option =org-html-use-unicode-chars= + +Setting this to non-nil was problematic as it converted characters +everywhere in the buffer, possibly corrupting URLs. + +*** Removed option =org-babel-sh-command= + +This undocumented option defaulted to the value of =shell-file-name= +at the time of loading =ob-shell=. The new behaviour is to use the +value of =shell-file-name= directly when the shell langage is =shell=. +To chose a different shell, either customize =shell-file-name= or bind +this variable locally. + +*** Removed option =org-babel-sh-var-quote-fmt= + +This undocumented option was supposed to provide different quoting +styles when changing the shell type. Changing the shell type can now +be done directly from the source block and the quoting style has to be +compatible across all shells, so a customization doesn't make sense +anymore. The chosen hard coded quoting style conforms to POSIX. + +*** Removed option ~org-insert-labeled-timestamps-at-point~ + +Setting this option to anything else that the default value (nil) +would create invalid planning info. This dangerous option is now +removed. + +*** Removed option ~org-koma-letter-use-title~ + +Use org-export-with-title instead. See also below. + +*** Removed option ~org-entities-ascii-explanatory~ + +This variable has no effect since Org 8.0. + +*** Removed option ~org-table-error-on-row-ref-crossing-hline~ + +This variable has no effect since August 2009. + +*** Removed MathML-related options from ~org-html-mathjax-options~ + +MathJax automatically chooses the best display technology based on the +end-users browser. You may force initial usage of MathML via +~org-html-mathjax-template~ or by setting the ~path~ property of +~org-html-mathjax-options~. + +*** Removed comment-related filters + +~org-export-filter-comment-functions~ and +~org-export-filter-comment-block-functions~ variables do not exist +anymore. +** Miscellaneous + +*** Strip all meta data from ITEM special property + +ITEM special property does not contain TODO, priority or tags anymore. + +*** File names in links accept are now compatible with URI syntax + +Absolute file names can now start with =///= in addition to =/=. E.g., +=[[file:///home/me/unicorn.jpg]]=. + +*** Footnotes in included files are now local to the file + +As a consequence, it is possible to include multiple Org files with +footnotes in a master document without being concerned about footnote +labels colliding. + +*** Mailto links now use regular URI syntax + +This change deprecates old Org syntax for mailto links: +=mailto:user@domain::Subject=. + +*** =QUOTE= keywords do not exist anymore + +=QUOTE= keywords have been deprecated since Org 8.2. + +*** Select tests to perform with the build system + +The build system has been enhanced to allow test selection with a +regular expression by defining =BTEST_RE= during the test invocation. +This is especially useful during bisection to find just when a +particular test failure was introduced. + +*** Exact heading search for external links ignore spaces and cookies + +Exact heading search for links now ignore spaces and cookies. This is +the case for links of the form ~file:projects.org::*task title~, as +well as links of the form ~file:projects.org::some words~ +when ~org-link-search-must-match-exact-headline~ is not nil. + +*** ~org-latex-hyperref-template~, ~org-latex-title-command~ formatting + +New formatting keys are supported. See the respective docstrings. +Note, ~org-latex-hyperref-template~ has a new default value. + +*** ~float, wasysym, marvosym~ are removed from ~org-latex-default-packages-alist~ + +If you require any of these package add them to your preamble via +~org-latex-packages-alist~. Org also uses default LaTeX ~\tolerance~ +now. + +*** When exporting, throw an error on unresolved id/fuzzy links and code refs + +This helps spotting wrong links. +* Version 8.2 + +** Incompatible changes +*** =ob-sh.el= renamed to =ob-shell= +This may require two changes in user config. + +1. In =org-babel-do-load-languages=, change =(sh . t)= to =(shell . t)=. +2. Edit =local.mk= files to change the value of =BTEST_OB_LANGUAGES= + to remove "sh" and include "shell". + +*** Combine org-mac-message.el and org-mac-link-grabber into org-mac-link.el + +Please remove calls to =(require 'org-mac-message)= and =(require +'org-mac-link-grabber)= in your =.emacs= initialization file. All you +need now is =(require 'org-mac-link)=. + +Additionally, replace any calls to =ogml-grab-link= to +=org-mac-grab-link=. For example, replace this line: + +: (define-key org-mode-map (kbd "C-c g") 'omgl-grab-link) + +with this: + +: (define-key org-mode-map (kbd "C-c g") 'org-mac-grab-link) + +*** HTML export: Replace =HTML_HTML5_FANCY= by =:html-html5-fancy= (...) + +Some of the HTML specific export options in Org <8.1 are either nil or +t, like =#+HTML_INCLUDE_STYLE=. We replaced these binary options with +option keywords like :html-include-style. + +So you need to replace + +: #+HTML_INCLUDE_STYLE: t + +by + +: #+OPTIONS: :html-include-style t + +Options affected by this change: =HTML5_FANCY=, =HTML_INCLUDE_SCRIPTS= +and =HTML_INCLUDE_STYLE=. + +*** Add an argument to ~org-export-to-file~ and ~org-export-to-buffer~ + +~org-export-to-file~ and ~org-export-to-file~ can run in a different +process when provided a non-nil =ASYNC= optional argument, without +relying on ~org-export-async-start~ macro. + +Since =ASYNC= is the first of optional arguments, you have to shift +the other optional arguments accordingly. + +*** Export back-ends are now structures + +Export back-ends are now structures, and stored as such in the +communication channel during an export process. In other words, from +now on, ~(plist-get info :back-end)~ will return a structure instead +of a symbol. + +Arguments in hooks and in filters are still symbols, though. + +** Important bugfixes + +*** [[doc:org-insert-heading][org-insert-heading]] has been rewritten and bugs are now fixed +*** The replacement of disputed keys is now turned of when reading a date + +*** Match string for sparse trees can now contain a slash in a property value + + You can now have searches like SOMEPROP="aaa/bbb". Until now, + this would break because the slash would be interpreted as the + separator starting a TOTO match string. +** New features + +*** =C-c ^ x= will now sort checklist items by their checked status + +See [[doc:org-sort-list][org-sort-list]]: hitting =C-c ^ x= will put checked items at the end +of the list. +*** Various LaTeX export enhancements + +- Support SVG images +- Support for .pgf files +- LaTeX Babel blocks can now be exported as =.tikz= files +- Allow =latexmk= as an option for [[doc:org-latex-pdf-process][org-latex-pdf-process]] +- When using =\usepackage[AUTO]{babel}=, AUTO will automatically be + replaced with a value compatible with ~org-export-default-language~ + or ~LANGUAGE~ keyword. +- The dependency on the =latexsym= LaTeX package has been removed, we + now use =amssymb= symbols by default instead. + +*** New functions for paragraph motion + + The commands =C-down= and =C-up= now invoke special commands + that use knowledge from the org-elements parser to move the cursor + in a paragraph-like way. + +*** New entities in =org-entities.el= + +Add support for ell, imath, jmath, varphi, varpi, aleph, gimel, beth, +dalet, cdots, S (§), dag, ddag, colon, therefore, because, triangleq, +leq, geq, lessgtr, lesseqgtr, ll, lll, gg, ggg, prec, preceq, +preccurlyeq, succ, succeq, succurlyeq, setminus, nexist(s), mho, +check, frown, diamond. Changes loz, vert, checkmark, smile and tilde. + +*** Anonymous export back-ends + +~org-export-create-backend~ can create anonymous export back-ends, +which can then be passed to export functions like +~org-export-to-file~, ~org-export-to-buffer~ or ~org-export-as~. + +It allows for quick translation of Org syntax without the overhead of +registering a new back-end. + +*** New agenda fortnight view + + The agenda has not, in addition to day, week, month, and year + views, also a fortnight view covering 14 days. +** New options + +*** New option [[doc:org-bookmark-names-plist][org-bookmark-names-plist]] + +This allows to specify the names of automatic bookmarks. +*** New option [[doc:org-agenda-ignore-drawer-properties][org-agenda-ignore-drawer-properties]] + +This allows more flexibility when optimizing the agenda generation. +See http://orgmode.org/worg/agenda-optimization.html for details. +*** New option: [[doc:org-html-link-use-abs-url][org-html-link-use-abs-url]] to force using absolute URLs + +This is an export/publishing option, and should be used either within +the =#+OPTIONS= line(s) or within a [[doc:org-publish-project-alist][org-publish-project-alist]]. + +Setting this option to =t= is needed when the HTML output does not +allow relative URLs. For example, the =contrib/lisp/ox-rss.el= +library produces a RSS feed, and RSS feeds need to use absolute URLs, +so a combination of =:html-link-home "..." and :html-link-use-abs-url +t= is required---see the configuration example in the comment section +of =ox-rss.el=. + +*** New option [[doc:org-babel-ditaa-java-cmd][org-babel-ditaa-java-cmd]] + +This makes java executable configurable for ditaa blocks. + +*** New options [[doc:org-babel-latex-htlatex][org-babel-latex-htlatex]] and [[doc:org-babel-latex-htlatex-packages][org-babel-latex-htlatex-packages]] + +This enables SVG generation from latex code blocks. + +*** New option: [[doc:org-habit-show-done-always-green][org-habit-show-done-always-green]] + +See [[http://lists.gnu.org/archive/html/emacs-orgmode/2013-05/msg00214.html][this message]] from Max Mikhanosha. + +*** New option: [[doc:org-babel-inline-result-wrap][org-babel-inline-result-wrap]] + +If you set this to the following + +: (setq org-babel-inline-result-wrap "$%s$") + +then inline code snippets will be wrapped into the formatting string. + +*** New option: [[doc:org-special-ctrl-o][org-special-ctrl-o]] + + This variable can be used to turn off the special behavior of + =C-o= in tables. +** New contributed packages + +- =ox-bibtex.el= by Nicolas Goaziou :: an utility to handle BibTeX + export to both LaTeX and HTML exports. It uses the [[http://www.lri.fr/~filliatr/bibtex2html/][bibtex2html]] + software. + +- =org-screenshot.el= by Max Mikhanosha :: an utility to handle + screenshots easily from Org, using the external tool [[http://freecode.com/projects/scrot][scrot]]. + +** Miscellaneous + +*** "QUOTE" keywords in headlines are deprecated + +"QUOTE" keywords are an undocumented feature in Org. When a headline +starts with the keyword "QUOTE", its contents are parsed as +a ~quote-section~ and treated as an example block. You can achieve +the same with example blocks. + +This feature is deprecated and will be removed in the next Org +release. + +* Version 8.0.1 + +** Installation + +Installation instructions have been updated and simplified. + +If you have troubles installing or updating Org, focus on these +instructions: + +- when updating via a =.zip/.tar.gz= file, you only need to set the + =load-path= in your =.emacs=. Set it before any other Org + customization that would call autoloaded Org functions. + +- when updating by pulling Org's Git repository, make sure to create the + correct autoloads. You can do this by running =~$ make autoloads= (to + only create the autoloads) or by running =~$ make= (to also compile + the Emacs lisp files.) =~$ make help= and =~$ make helpall= gives you + detailed explanations. + +- when updating through ELPA (either from GNU ELPA or from Org ELPA), + you have to install Org's ELPA package in a session where no Org + function has been called already. + +When in doubt, run =M-x org-version RET= and see if you have a mixed-up +installation. + +See http://orgmode.org/org.html#Installation for details. + +** Incompatible changes + +Org 8.0 is the most disruptive major version of Org. + +If you configured export options, you will have to update some of them. + +If you used =#+ATTR_*= keywords, the syntax of the attributes changed and +you will have to update them. + +Below is a list of changes for which you need to take action. + +See http://orgmode.org/worg/org-8.0.html for the most recent version of +this list and for detailed instructions on how to migrate. + +**** New export engine + +Org 8.0 comes with a new export engine written by Nicolas Goaziou. This +export engine relies on ~org-element.el~ (Org's syntax parser), which was +already in Org's core. This new export engine triggered the rewriting of +/all/ export back-ends. + +The most visible change is the export dispatcher, accessible through the +keybinding =C-c C-e=. By default, this menu only shows some of the +built-in export formats, but you can add more formats by loading them +directly (e.g., =(require 'ox-texinfo)= or by configuring the option +[[doc:org-export-backends][org-export-backends]]. + +More contributed back-ends are available from the =contrib/= directory, the +corresponding files start with the =ox-= prefix. + +If you customized an export back-end (like HTML or LaTeX), you will need to +rename some options so that your customization is not lost. Typically, an +option starting with =org-export-html-= is now named =org-html-=. See the +manual for details and check [[http://orgmode.org/worg/org-8.0.html][this Worg page]] for directions. + +**** New syntax for #+ATTR_HTML/LaTeX/... options + + : #+ATTR_HTML width="200px" + + should now be written + + : #+ATTR_HTML :width 200px + + Keywords like =#+ATTR_HTML= and =#+ATTR_LaTeX= are defined in their + respective back-ends, and the list of supported parameters depends on + each backend. See Org's manual for details. + +**** ~org-remember.el~ has been removed + + You cannot use =remember.el= anymore to capture notes. + + Support for remember templates has been obsoleted since long, it is + now fully removed. + + Use =M-x org-capture-import-remember-templates RET= to import your + remember templates into capture templates. + +**** ~org-jsinfo.el~ has been merged into ~ox-html.el~ + + If you were requiring ~ox-jsinfo.el~ in your ~.emacs.el~ file, you + will have to remove this requirement from your initialization file. + +**** Note for third-party developers + + The name of the files for export back-end have changed: we now use the + prefix =ox-= for those files (like we use the =ob-= prefix for Babel + files.) For example ~org-html.el~ is now ~ox-html.el~. + + If your code relies on these files, please update the names in your + code. + +**** Packages moved from core to contrib + + Since packages in Org's core are meant to be part of GNU Emacs, we try + to be minimalist when it comes to adding files into core. For 8.0, we + moved some contributions into the =contrib/= directory. + + The rationale for deciding that these files should live in =contrib/= + is either because they rely on third-party software that is not + included in Emacs, or because they are not targeting a significant + user-base. + + - org-colview-xemacs.el + - org-mac-message.el + - org-mew.el + - org-wl.el + - ox-freedmind.el + - ox-taskjuggler.el + + Note that ~ox-freedmind.el~ has been rewritten by Jambunathan, + ~org-mew.el~ has been enhanced by Tokuya Kameshima and + ~ox-taskjuggler.el~ by Nicolas Goaziou and others. + + Also, the Taskjuggler exporter now uses TJ3 by default. John Hendy + wrote [[http://orgmode.org/worg/org-tutorials/org-taskjuggler3.html][a tutorial on Worg]] for the TJ3 export. + +** New packages in core + +*** ~ob-makefile.el~ by Eric Schulte and Thomas S. Dye + + =ob-makefile.el= implements Org Babel support for Makefile tangling. + +*** ~ox-man.el~ by Luis Anaya + + =ox-man.el= allows you to export Org files to =man= pages. + +*** ~ox-md.el~ by Nicolas Goaziou + + =ox-md.el= allows you to export Org files to Markdown files, using the + vanilla [[http://daringfireball.net/projects/markdown/][Markdown syntax]]. + +*** ~ox-texinfo.el~ by Jonathan Leech-Pepin + + =ox-texinfo.el= allows you to export Org files to [[http://www.gnu.org/software/texinfo/][Texinfo]] files. + +** New packages in contrib + +*** ~ob-julia.el~ by G. Jay Kerns + + [[http://julialang.org/][Julia]] is a new programming language. + + =ob-julia.el= provides Org Babel support for evaluating Julia source + code. + +*** ~ob-mathomatic.el~ by Luis Anaya + + [[http://www.mathomatic.org/][mathomatic]] a portable, command-line, educational CAS and calculator + software, written entirely in the C programming language. + + ~ob-mathomatic.el~ provides Org Babel support for evaluating mathomatic + entries. + +*** ~ob-tcl.el~ by Luis Anaya + + ~ob-tcl.el~ provides Org Babel support for evaluating [[http://www.tcl.tk/][Tcl]] source code. + +*** ~org-bullets.el~ by Evgeni Sabof + + Display bullets instead of stars for headlines. + + Also see [[http://orgmode.org/worg/org-faq.html#sec-8-12][this updated FAQ]] on how to display another character than "*" + for starting headlines. + +*** ~org-favtable.el~ by Marc-Oliver Ihm + + ~org-favtable.el~ helps you to create and update a table of favorite + locations in org, keeping the most frequently visited lines right at + the top. This table is called "favtable". See the documentation on + [[http://orgmode.org/worg/org-contrib/org-favtable.html][Worg]]. + +*** ~ox-confluence.el~ by Sébastien Delafond + + ~ox-confluence.el~ lets you convert Org files to [[https://confluence.atlassian.com/display/DOC/Confluence%2BWiki%2BMarkup][Confluence Wiki]] files. + +*** ~ox-deck.el~ and ~ox-s5.el~ by Rick Frankel + + [[http://imakewebthings.com/deck.js/][deck.js]] is a javascript library for displaying HTML ages as + presentations. ~ox-deck.el~ exports Org files to HTML presentations + using =deck.js=. + + [[http://meyerweb.com/eric/tools/s5/][s5]] is a set of scripts which also allows to display HTML pages as + presentations. ~ox-s5.el~ exports Org files to HTML presentations + using =s5=. + +*** ~ox-groff.el~ by Luis Anaya and Nicolas Goaziou + + The [[http://www.gnu.org/software/groff/][groff]] (GNU troff) software is a typesetting package which reads + plain text mixed with formatting commands and produces formatted + output. + + Luis Anaya and Nicolas Goaziou implemented ~ox-groff.el~ to allow + conversion from Org files to groff. + +*** ~ox-koma-letter.el~ by Nicolas Goaziou and Alan Schmitt + + This back-end allow to export Org pages to the =KOMA Scrlttr2= format. + +*** ~ox-rss.el~ by Bastien + + This back-end lets you export Org pages to RSS 2.0 feeds. Combined + with the HTML publishing feature, this allows you to build a blog + entirely with Org. + +** New features + +*** Export + +**** New export generic options + +If you use Org exporter, we advise you to re-read [[http://orgmode.org/org.html#Exporting][the manual section about +it]]. It has been updated and includes new options. + +Among the new/updated export options, three are of particular importance: + +- [[doc:org-export-allow-bind-keywords][org-export-allow-bind-keywords]] :: This option replaces the old option + =org-export-allow-BIND= and the default value is =nil=, not =confirm=. + You will need to explicitly set this to =t= in your initialization + file if you want to allow =#+BIND= keywords. + +- [[doc:org-export-with-planning][org-export-with-planning]] :: This new option controls the export of + =SCHEDULED:, DEADLINE:, CLOSED:= lines, and planning information is + now skipped by default during export. This use to be the job of + [[doc:org-export-with-timestamps][org-export-with-timestamps]], but this latter option has been given a + new role: it controls the export of /standalone time-stamps/. When + set to =nil=, Org will not export active and inactive time-stamps + standing on a line by themselves or within a paragraph that only + contains time-stamps. + +To check if an option has been introduced or its default value changed in +Org 8.0, do =C-h v [option] RET= and check if the documentation says that +the variable has been introduced (or changed) in version 24.4 of Emacs. + +**** Enhanced default stylesheet for the HTML exporter + +See the new default value of [[doc:org-html-style-default][org-html-style-default]]. + +**** New tags, classes and ids for the HTML exporter + +See the new default value of [[doc:org-html-divs][org-html-divs]]. + +**** Support for tikz pictures in LaTeX export +**** ~org-man.el~: New export function for "man" links +**** ~org-docview.el~: New export function for docview links +*** Structure editing + +**** =C-u C-u M-RET= inserts a heading at the end of the parent subtree +**** Cycling to the =CONTENTS= view keeps inline tasks folded + +[[doc:org-cycle-hook][org-cycle-hook]] as a new function [[doc:org-cycle-hide-inline-tasks][org-cycle-hide-inline-tasks]] which +prevents the display of inline tasks when showing the content of a subtree. + +**** =C-c -= in a region makes a list item for each line + +This is the opposite of the previous behavior, where =C-c -= on a region +would create one item for the whole region, and where =C-u C-c -= would +create an item for each line. Now =C-c -= on the selected region creates +an item per line, and =C-u C-c -= creates a single item for the whole +region. + +**** When transposing words, markup characters are now part of the words + +In Emacs, you can transpose words with =M-t=. Transposing =*these* +_words__= will preserve markup. + +**** New command [[doc:org-set-property-and-value][org-set-property-and-value]] bound to =C-c C-x P= + +This command allows you to quickly add both the property and its value. It +is useful in buffers where there are many properties and where =C-c C-x p= +can slow down the flow of editing too much. + +**** New commands [[doc:org-next-block][org-next-block]] and [[doc:org-previous-block][org-previous-block]] + +These commands allow you to go to the previous block (=C-c M-b= or the +speedy key =B=) or to the next block (=C-c M-f= or the speedy key =F=.) + +**** New commands [[doc:org-drag-line-forward][org-drag-line-forward]] and [[doc:org-drag-line-backward][org-drag-line-backward]] + +These commands emulate the old behavior of =M-= and =M-= but are +now bound to =S-M-= and =S-M-= respectively, since =M-= and +=M-= now drag the whole element at point (a paragraph, a table, etc.) +forward and backward. + +**** When a list item has a checkbox, inserting a new item uses a checkbox too +**** When sorting entries/items, only the description of links is considered + +Now Org will sort this list + +: - [[http://abc.org][B]] +: - [[http://def.org][A]] + +like this: + +: - [[http://def.org][A]] +: - [[http://abc.org][B]] + +by comparing the descriptions, not the links. +Same when sorting headlines instead of list items. +**** New option =orgstruct-heading-prefix-regexp= + +For example, setting this option to "^;;; " in Emacs lisp files and using +=orgstruct-mode= in those files will allow you to cycle through visibility +states as if lines starting with ";;; *..." where headlines. + +In general, you want to set =orgstruct-heading-prefix-regexp= as a file +local variable. + +**** New behavior of [[doc:org-clone-subtree-with-time-shift][org-clone-subtree-with-time-shift]] + +The default is now to ask for a time-shift only when there is a time-stamp. +When called with a universal prefix argument =C-u=, it will not ask for a +time-shift even if there is a time-stamp. + +**** New option [[doc:org-agenda-restriction-lock-highlight-subtree][org-agenda-restriction-lock-highlight-subtree]] + +This defaults to =t= so that the whole subtree is highlighted when you +restrict the agenda view to it with =C-c C-x <= (or the speed command =<=). +The default setting helps ensuring that you are not adding tasks after the +restricted region. If you find this highlighting too intrusive, set this +option to =nil=. +**** New option [[doc:org-closed-keep-when-no-todo][org-closed-keep-when-no-todo]] + +When switching back from a =DONE= keyword to a =TODO= keyword, Org now +removes the =CLOSED= planning information, if any. It also removes this +information when going back to a non-TODO state (e.g., with =C-c C-t SPC=). +If you want to keep the =CLOSED= planning information when removing the +TODO keyword, set [[doc:org-closed-keep-when-no-todo][org-closed-keep-when-no-todo]] to =t=. + +**** New option [[doc:org-image-actual-width][org-image-actual-width]] + +This option allows you to change the width of in-buffer displayed images. +The default is to use the actual width of the image, but you can use a +fixed value for all images, or fall back on an attribute like + +: #+attr_html: :width 300px +*** Scheduled/deadline + +**** Implement "delay" cookies for scheduled items + +If you want to delay the display of a scheduled task in the agenda, you can +now use a delay cookie like this: =SCHEDULED: <2004-12-25 Sat -2d>=. The +task is still scheduled on the 25th but will appear in your agenda starting +from two days later (i.e. from March 27th.) + +Imagine for example that your co-workers are not done in due time and tell +you "we need two more days". In that case, you may want to delay the +display of the task in your agenda by two days, but you still want the task +to appear as scheduled on March 25th. + +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 [[doc:org-scheduled-delay-days][org-scheduled-delay-days]] +and [[doc:org-agenda-skip-scheduled-delay-if-deadline][org-agenda-skip-scheduled-delay-if-deadline]] for details on how to +control this globally or per agenda. + +**** Use =C-u C-u C-c C-s= will insert a delay cookie for scheduled tasks + +See the previous section for why delay cookies may be useful. + +**** Use =C-u C-u C-c C-d= will insert a warning delay for deadline tasks + +=C-u C-u C-c C-d= now inserts a warning delay to deadlines. +*** Calendar, diary and appts + +**** New variable [[doc:org-read-date-minibuffer-local-map][org-read-date-minibuffer-local-map]] + +By default, this new local map uses "." to go to today's date, like in the +normal =M-x calendar RET=. If you want to deactivate this and to reassign +the "@" key to =calendar-goto-today=, use this: + +#+BEGIN_SRC emacs-lisp + ;; Unbind "." in Org's calendar: + (define-key org-read-date-minibuffer-local-map (kbd ".") nil) + + ;; Bind "@" to `calendar-goto-today': + (define-key org-read-date-minibuffer-local-map + (kbd "@") + (lambda () (interactive) (org-eval-in-calendar '(calendar-goto-today)))) +#+END_SRC + +**** In Org's calendar, =!= displays diary entries of the date at point + +This is useful when you want to check if you don't already have an +appointment when setting new ones with =C-c .= or =C-c s=. =!= will +call =diary-view-entries= and display the diary in a separate buffer. + +**** [[doc:org-diary][org-diary]]: only keep the descriptions of links + +[[doc:org-diary][org-diary]] returns diary information from Org files, but it returns it +in a diary buffer, not in an Org mode buffer. When links are displayed, +only show their description, not the full links. +*** Agenda + +**** New agenda type =agenda*= and entry types =:scheduled* :deadline*= + +When defining agenda custom commands, you can now use =agenda*=: this will +list entries that have both a date and a time. This is useful when you +want to build a list of appointments. + +You can also set [[doc:org-agenda-entry-types][org-agenda-entry-types]] either globally or locally in +each agenda custom command and use =:timestamp*= and/or =:deadline*= there. + +Another place where this is useful is your =.diary= file: + +: %%(org-diary :scheduled*) ~/org/rdv.org + +This will list only entries from =~/org/rdv.org= that are scheduled with a +time value (i.e. appointments). + +**** New agenda sorting strategies + +[[doc:org-agenda-sorting-strategy][org-agenda-sorting-strategy]] allows these new sorting strategies: + +| Strategy | Explanations | +|----------------+------------------------------------------| +| 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 | + +**** New options to limit the number of agenda entries + +You can now limit the number of entries in an agenda view. This is +different from filters: filters only /hide/ the entries in the agenda, +while limits are set while generating the list of agenda entries. + +These new options are available: + +- [[doc:org-agenda-max-entries][org-agenda-max-entries]] :: limit by number of entries. +- [[doc:org-agenda-max-todos][org-agenda-max-todos]] :: limit by number of TODOs. +- [[doc:org-agenda-max-tags][org-agenda-max-tags]] :: limit by number of tagged entries. +- [[doc:org-agenda-max-effort][org-agenda-max-effort]] :: limit by effort (minutes). + +For example, if you locally set [[doc:org-agenda-max-todos][org-agenda-max-todos]] to 3 in an agenda +view, the agenda will be limited to the first three todos. Other entries +without a TODO keyword or beyond the third TODO headline will be ignored. + +When setting a limit (e.g. about an effort's sum), the default behavior is +to exclude entries that cannot be checked against (e.g. entries that have +no effort property.) To include other entries too, you can set the limit +to a negative number. For example =(setq org-agenda-max-tags -3)= will not +show the fourth tagged headline (and beyond), but it will also show +non-tagged headlines. + +**** =~= in agenda view sets temporary limits + +You can hit =~= in the agenda to temporarily set limits: this will +regenerate the agenda as if the limits were set. This is useful for +example when you want to only see a list of =N= tasks, or a list of tasks +that take only =N= minutes. + +**** "=" in agenda view filters by regular expressions + +You can now filter agenda entries by regular expressions using ~=~. =C-u +== will filter entries out. Regexp filters are cumulative. You can set +[[doc:org-agenda-regexp-filter-preset][org-agenda-regexp-filter-preset]] to suit your needs in each agenda view. + +**** =|= in agenda view resets all filters + +Since it's common to combine tag filters, category filters, and now regexp +filters, there is a new command =|= to reset all filters at once. + +**** Allow writing an agenda to an =.org= file + +You can now write an agenda view to an =.org= file. It copies the +headlines and their content (but not subheadings) into the new file. + +This is useful when you want to quickly share an agenda containing the full +list of notes. + +**** New commands to drag an agenda line forward (=M-=) or backward (=M-=) + +It sometimes handy to move agenda lines around, just to quickly reorganize +your tasks, or maybe before saving the agenda to a file. Now you can use +=M-= and =M-= to move the line forward or backward. + +This does not persist after a refresh of the agenda, and this does not +change the =.org= files who contribute to the agenda. + +**** Use =%b= for displaying "breadcrumbs" in the agenda view + +[[doc:org-agenda-prefix-format][org-agenda-prefix-format]] now allows to use a =%b= formatter to tell Org +to display "breadcrumbs" in the agenda view. + +This is useful when you want to display the task hierarchy in your agenda. + +**** Use =%l= for displaying the headline's level in the agenda view + +[[doc:org-agenda-prefix-format][org-agenda-prefix-format]] allows to use a =%l= formatter to tell Org to +display entries with additional spaces corresponding to their level in the +outline tree. + +**** [[doc:org-agenda-write][org-agenda-write]] will ask before overwriting an existing file + +=M-x org-agenda-write RET= (or =C-c C-w= from an agenda buffer) used to +overwrite preexisting file with the same name without confirmation. It now +asks for a confirmation. + +**** New commands =M-m= and =M-*= to toggle (all) mark(s) for bulk action + +- [[doc:org-agenda-bulk-toggle][org-agenda-bulk-toggle]] :: this command is bound to =M-m= and toggles + the mark of the entry at point. + +- [[doc:org-agenda-bulk-toggle-all][org-agenda-bulk-toggle-all]] :: this command is bound to =M-*= and + toggles all the marks in the current agenda. + +**** New option [[doc:org-agenda-search-view-max-outline-level][org-agenda-search-view-max-outline-level]] + +This option sets the maximum outline level to display in search view. +E.g. when this is set to 1, the search view will only show headlines of +level 1. + +**** New option [[doc:org-agenda-todo-ignore-time-comparison-use-seconds][org-agenda-todo-ignore-time-comparison-use-seconds]] + +This allows to compare times using seconds instead of days when honoring +options like =org-agenda-todo-ignore-*= in the agenda display. + +**** New option [[doc:org-agenda-entry-text-leaders][org-agenda-entry-text-leaders]] + +This allows you to get rid of the ">" character that gets added in front of +entries excerpts when hitting =E= in the agenda view. + +**** New formatting string for past deadlines in [[doc:org-agenda-deadline-leaders][org-agenda-deadline-leaders]] + +The default formatting for past deadlines is ="%2d d. ago: "=, which makes +it explicit that the deadline is in the past. You can configure this via +[[doc:org-agenda-deadline-leaders][org-agenda-deadline-leaders]]. Note that the width of the formatting +string is important to keep the agenda alignment clean. + +**** New allowed value =repeated-after-deadline= for [[doc:org-agenda-skip-scheduled-if-deadline-is-shown][org-agenda-skip-scheduled-if-deadline-is-shown]] + +When [[doc:org-agenda-skip-scheduled-if-deadline-is-shown][org-agenda-skip-scheduled-if-deadline-is-shown]] is set to +=repeated-after-deadline=, the agenda will skip scheduled items if they are +repeated beyond the current deadline. + +**** New option for [[doc:org-agenda-skip-deadline-prewarning-if-scheduled][org-agenda-skip-deadline-prewarning-if-scheduled]] + +This variable may be set to nil, t, the symbol `pre-scheduled', or a number +which will then give the number of days before the actual deadline when the +prewarnings should resume. The symbol `pre-scheduled' eliminates the +deadline prewarning only prior to the scheduled date. + +Read the full docstring for details. + +**** [[doc:org-class][org-class]] now supports holiday strings in the skip-weeks parameter + +For example, this task will now be skipped only on new year's day: + + : * Task + : <%%(org-class 2012 1 1 2013 12 12 2 "New Year's Day")> +*** Capture + +**** Allow =C-1= as a prefix for [[doc:org-agenda-capture][org-agenda-capture]] and [[doc:org-capture][org-capture]] + +With a =C-1= prefix, the capture mechanism will use the =HH:MM= value at +point (if any) or the current =HH:MM= time as the default time for the +capture template. + +**** Expand keywords within %(sexp) placeholder in capture templates + +If you use a =%:keyword= construct within a =%(sexp)= construct, Org will +expand the keywords before expanding the =%(sexp)=. + +**** Allow to contextualize capture (and agenda) commands by checking the name of the buffer + +[[doc:org-capture-templates-contexts][org-capture-templates-contexts]] and [[doc:org-agenda-custom-commands-contexts][org-agenda-custom-commands-contexts]] +allow you to define what capture templates and what agenda commands should +be available in various contexts. It is now possible for the context to +check against the name of the buffer. +*** Tag groups + +Using =#+TAGS: { Tag1 : Tag2 Tag3 }= will define =Tag1= as a /group tag/ +(note the colon after =Tag1=). If you search for =Tag1=, it will return +headlines containing either =Tag1=, =Tag2= or =Tag3= (or any combination +of those tags.) + +You can use group tags for sparse tree in an Org buffer, for creating +agenda views, and for filtering. + +See http://orgmode.org/org.html#Tag-groups for details. + +*** Links + +**** =C-u C-u M-x org-store-link RET= will ignore non-core link functions + +Org knows how to store links from Org buffers, from info files and from +other Emacs buffers. Org can be taught how to store links from any buffer +through new link protocols (see [[http://orgmode.org/org.html#Adding-hyperlink-types]["Adding hyperlink types"]] in the manual.) + +Sometimes you want Org to ignore added link protocols and store the link +as if the protocol was not known. + +You can now do this with =C-u C-u M-x org-store-link RET=. + +**** =C-u C-u C-u M-x org-store-link RET= on an active region will store links for each lines + +Imagine for example that you want to store a link for every message in a +Gnus summary buffer. In that case =C-x h C-u C-u C-u M-x org-store-link +RET= will store a link for every line (i.e. message) if the region is +active. + +**** =C-c C-M-l= will add a default description for links which don't have one + +=C-c C-M-l= inserts all stored links. If a link does not have a +description, this command now adds a default one, so that we are not mixing +with-description and without-description links when inserting them. + +**** No curly braces to bracket links within internal links + +When storing a link to a headline like + +: * See [[http://orgmode.org][Org website]] + +[[doc:org-store-link][org-store-link]] used to convert the square brackets into curly brackets. +It does not anymore, taking the link description or the link path, when +there is no description. +*** Table + +**** Switching between #+TBLFM lines + +If you have several =#+TBLFM= lines below a table, =C-c C-c= on a line will +apply the formulas from this line, and =C-c C-c= on another line will apply +those other formulas. + +**** You now use "nan" for empty fields in Calc formulas + +If empty fields are of interest, it is recommended to reread the section +[[http://orgmode.org/org.html#Formula-syntax-for-Calc][3.5.2 Formula syntax for Calc]] of the manual because the description for the +mode strings has been clarified and new examples have been added towards +the end. + +**** Handle localized time-stamps in formulas evaluation + +If your =LOCALE= is set so that Org time-stamps use another language than +english, and if you make time computations in Org's table, it now works by +internally converting the time-stamps with a temporary =LOCALE=C= before +doing computation. + +**** New lookup functions + +There are now three lookup functions: + +- [[doc:org-loopup-first][org-loopup-first]] +- [[doc:org-loopup-last][org-loopup-last]] +- [[doc:org-loopup-all][org-loopup-all]] + +See [[http://orgmode.org/org.html#Lookup-functions][the manual]] for details. +*** Startup keywords + +These new startup keywords are now available: + +| Startup keyword | Option | +|----------------------------------+---------------------------------------------| +| =#+STARTUP: logdrawer= | =(setq org-log-into-drawer t)= | +| =#+STARTUP: nologdrawer= | =(setq org-log-into-drawer nil)= | +|----------------------------------+---------------------------------------------| +| =#+STARTUP: logstatesreversed= | =(setq org-log-states-order-reversed t)= | +| =#+STARTUP: nologstatesreversed= | =(setq org-log-states-order-reversed nil)= | +|----------------------------------+---------------------------------------------| +| =#+STARTUP: latexpreview= | =(setq org-startup-with-latex-preview t)= | +| =#+STARTUP: nolatexpreview= | =(setq org-startup-with-latex-preview nil)= | + +*** Clocking + +**** New option [[doc:org-clock-rounding-minutes][org-clock-rounding-minutes]] + +E.g. if [[doc:org-clock-rounding-minutes][org-clock-rounding-minutes]] is set to 5, time is 14:47 and you +clock in: then the clock starts at 14:45. If you clock out within the next +5 minutes, the clock line will be removed; if you clock out 8 minutes after +your clocked in, the clock out time will be 14:50. + +**** New option [[doc:org-time-clocksum-use-effort-durations][org-time-clocksum-use-effort-durations]] + +When non-nil, =C-c C-x C-d= uses effort durations. E.g., by default, one +day is considered to be a 8 hours effort, so a task that has been clocked +for 16 hours will be displayed as during 2 days in the clock display or in +the clocktable. + +See [[doc:org-effort-durations][org-effort-durations]] on how to set effort durations and +[[doc:org-time-clocksum-format][org-time-clocksum-format]] for more on time clock formats. + +**** New option [[doc:org-clock-x11idle-program-name][org-clock-x11idle-program-name]] + +This allows to set the name of the program which prints X11 idle time in +milliseconds. The default is to use =x11idle=. + +**** New option [[doc:org-use-last-clock-out-time-as-effective-time][org-use-last-clock-out-time-as-effective-time]] + +When non-nil, use the last clock out time for [[doc:org-todo][org-todo]]. Note that this +option has precedence over the combined use of [[doc:org-use-effective-time][org-use-effective-time]] and +[[doc:org-extend-today-until][org-extend-today-until]]. + +**** =S-= on a clocksum column will update the sum by updating the last clock +**** =C-u 3 C-S-= will update clock timestamps synchronously by 3 units +**** New parameter =:wstart= for clocktables to define the week start day +**** New parameter =:mstart= to state the starting day of the month +**** Allow relative times in clocktable tstart and tend options +**** The clocktable summary is now a caption +**** =:tstart= and =:tend= and friends allow relative times like "<-1w>" or "" +*** Babel + +**** You can now use =C-c C-k= for [[doc:org-edit-src-abort][org-edit-src-abort]] + +This allows you to quickly cancel editing a source block. + +**** =C-u C-u M-x org-babel-tangle RET= tangles by the target file of the block at point + +This is handy if you want to tangle all source code blocks that have the +same target than the block at point. + +**** New options for auto-saving the base buffer or the source block editing buffer + +When [[doc:org-edit-src-turn-on-auto-save][org-edit-src-turn-on-auto-save]] is set to =t=, editing a source block +in a new window will turn on =auto-save-mode= and save the code in a new +file under the same directory than the base Org file. + +When [[doc:org-edit-src-auto-save-idle-delay][org-edit-src-auto-save-idle-delay]] is set to a number of minutes =N=, +the base Org buffer will be saved after this number of minutes of idle +time. + +**** New =:post= header argument post-processes results + + This header argument may be used to pass the results of the current + code block through another code block for post-processing. See the + manual for a usage example. + +**** Commented out heading are ignored when collecting blocks for tangling + +If you comment out a heading (with =C-c ;= anywhere on the heading or in +the subtree), code blocks from within this heading are now ignored when +collecting blocks for tangling. + +**** New option [[doc:org-babel-hash-show-time][org-babel-hash-show-time]] to show a time-stamp in the result hash +**** Do not ask for confirmation if cached value is current + +Do not run [[doc:org-babel-confirm-evaluate][org-babel-confirm-evaluate]] if source block has a cache and the +cache value is current as there is no evaluation involved in this case. +**** =ob-sql.el= and =ob-python.el= have been improved. +**** New Babel files only need to =(require 'ob)= + +When writing a new Babel file, you now only need to use =(require 'ob)= +instead of requiring each Babel library one by one. +*** Faces + +- Org now fontifies radio link targets by default +- In the agenda, use [[doc:org-todo-keyword-faces][org-todo-keyword-faces]] to highlight selected TODO keywords +- New face [[doc:org-priority][org-priority]], enhanced fontification of priority cookies in agenda +- New face [[doc:org-tag-group][org-tag-group]] for group tags + +** Miscellaneous + +- New speedy key =s= pour [[doc:org-narrow-to-subtree][org-narrow-to-subtree]] +- Handling of [[doc:org-html-table-row][org-html-table-row]] has been updated (incompatible change) +- [[doc:org-export-html-table-tag][org-export-html-table-tag]] is replaced by [[doc:org-html-table-default-attributes][org-html-table-default-attributes]] +- Support using =git-annex= with Org attachments +- org-protocol: Pass optional value using query in url to capture from protocol +- When the refile history is empty, use the current filename as default +- When you cannot change the TODO state of a task, Org displays the blocking task +- New option [[doc:org-mobile-allpriorities][org-mobile-allpriorities]] +- org-bibtex.el now use =visual-line-mode= instead of the deprecated =longlines-mode= +- [[doc:org-format-latex-options][org-format-latex-options]] allows to set the foreground/background colors automatically +- New option [[doc:org-archive-file-header-format][org-archive-file-header-format]] +- New "neg" entity in [[doc:org-entities][org-entities]] +- New function [[doc:org-docview-export][org-docview-export]] to export docview links +- New =:eps= header argument for ditaa code blocks +- New option [[doc:org-gnus-no-server][org-gnus-no-server]] to start Gnus with =gnus-no-server= +- Org is now distributed with =htmlize.el= version 1.43 +- ~org-drill.el~ has been updated to version 2.3.7 +- ~org-mac-iCal.el~ now supports MacOSX version up to 10.8 +- Various improvements to ~org-contacts.el~ and =orgpan.el= + +** Outside Org + +*** Spanish translation of the Org guide by David Arroyo Menéndez + +David (and others) translated the Org compact guide in spanish: + +You can read the [[http://orgmode.org/worg/orgguide/orgguide.es.pdf][PDF guide]]. + +*** ~poporg.el~ and ~outorg.el~ + +Two new libraries (~poporg.el~ by François Pinard and ~outorg.el~ by +Thorsten Jolitz) now enable editing of comment-sections from source-code +buffers in temporary Org-mode buffers, making the full editing power of +Org-mode available. ~outorg.el~ comes together with ~outshine.el~ and +~navi-mode.el~, two more libraries by Thorsten Jolitz with the goal to give +source-code buffers the /look & feel/ of Org-mode buffers while greatly +improving navigation and structure editing. A detailed description can be +found here: http://orgmode.org/worg/org-tutorials/org-outside-org.html + +Here are two screencasts demonstrating Thorsten's tools: + +- [[http://youtu.be/nqE6YxlY0rw]["Modern conventions for Emacs Lisp files"]] +- [[http://www.youtube.com/watch?v%3DII-xYw5VGFM][Exploring Bernt Hansen's Org-mode tutorial with 'navi-mode']] + +*** MobileOrg for iOS + +MobileOrg for iOS back in the App Store The 1.6.0 release was focused on +the new Dropbox API and minor bug fixes but also includes a new ability to +launch in Capture mode. Track development and contribute [[https://github.com/MobileOrg/mobileorg/issues][on github]]. + +* Version 7.9.3 + +** New option [[doc::org-agenda-use-tag-inheritance][org-agenda-use-tag-inheritance]] + +[[doc::org-use-tag-inheritance][org-use-tag-inheritance]] controls whether tags are inherited when +org-tags-view is called (either in =tags=, =tags-tree= or =tags-todo= +agenda views.) + +When generating other agenda types such as =agenda=, =todo= and +=todo-tree=, tags inheritance is not used when selecting the entries +to display. Still, you might want to have all tag information correct +in the agenda buffer, e.g. for tag filtering. In that case, add the +agenda type to this variable. + +Setting this variable to nil should considerably speeds up the agenda +generation. + +Note that the default was to display inherited tags in the agenda +lines even if `org-use-tag-inheritance' was nil. The default is now +to *never* display inherited tags in agenda lines, but to /know/ about +them when the agenda type is listed in [[doc::org-agenda-use-tag-inheritance][org-agenda-use-tag-inheritance]]. + +** New default value nil for [[doc::org-agenda-dim-blocked-tasks][org-agenda-dim-blocked-tasks]] + +Using `nil' as the default value speeds up the agenda generation. You +can hit `#' (or `C-u #') in agenda buffers to temporarily dim (or turn +invisible) blocked tasks. + +** New speedy keys for [[doc::org-speed-commands-default][org-speed-commands-default]] + +You can now use `:' (instead of `;') for setting tags---this is +consistent with using the `:' key in agenda view. + +You can now use `=' for [[doc::org-columns][org-columns]]. + +** =org-float= is now obsolete, use =diary-float= instead +** No GPL manual anymore + +There used to be a GPL version of the Org manual, but this is not the +case anymore, the Free Software Foundation does not permit this. + +The GNU FDL license is now included in the manual directly. + +** Enhanced compatibility with Emacs 22 and XEmacs + +Thanks to Achim for his work on enhancing Org's compatibility with +various Emacsen. Things may not be perfect, but Org should work okay +in most environments. + +* Version 7.9.2 + +** New ELPA repository for Org packages + +You can now add the Org ELPA repository like this: + +#+BEGIN_SRC emacs-lisp +(add-to-list 'package-archives '("org" . "http://orgmode.org/elpa/") t) +#+END_SRC + +It contains both the =org-*.tar= package (the core Org distribution, also +available through http://elpa.gnu.org) and the =org-plus*.tar= package (the +extended Org distribution, with non-GNU packages from the =contrib/= +directory.) + +See http://orgmode.org/elpa/ + +** Overview of the new keybindings + + | Keybinding | Speedy | Command | + |-----------------+--------+-----------------------------| + | =C-c C-x C-z= | | [[doc::org-clock-resolve][org-clock-resolve]] | + | =C-c C-x C-q= | | [[doc::org-clock-cancel][org-clock-cancel]] | + | =C-c C-x C-x= | | [[doc::org-clock-in-last][org-clock-in-last]] | + | =M-h= | | [[doc::org-mark-element][org-mark-element]] | + | =*= | | [[doc::org-agenda-bulk-mark-all][org-agenda-bulk-mark-all]] | + | =C-c C-M-l= | | [[doc::org-insert-all-links][org-insert-all-links]] | + | =C-c C-x C-M-v= | | [[doc::org-redisplay-inline-images][org-redisplay-inline-images]] | + | =C-c C-x E= | =E= | [[doc::org-inc-effort][org-inc-effort]] | + | | =#= | [[doc::org-toggle-comment][org-toggle-comment]] | + | | =:= | [[doc::org-columns][org-columns]] | + | | =W= | Set =APPT_WARNTIME= | + | =k= | | [[doc::org-agenda-capture][org-agenda-capture]] | + | C-c , | , | [[doc::org-priority][org-priority]] | + +** New package and Babel language + +*** =org-eshell.el= by Konrad Hinsen is now in Org + + =org-eshell.el= allows you to create links from [[http://www.gnu.org/software/emacs/manual/html_node/eshell/index.html][Eshell]]. + +*** Support for execution of Scala code blocks (see ob-scala.el) +*** Support for execution of IO code blocks (see ob-io.el) + +** Incompatible changes + + - If your code relies on =org-write-agenda=, please use + [[doc::org-agenda-write][org-agenda-write]] from now on. + + - If your code relies on =org-make-link=, please use =concat= + instead. + + - =org-link-to-org-use-id= has been renamed to + =org-id-link-to-org-use-id= and its default value is nil. The + previous default was =create-if-interactive-and-no-custom-id=. + +** New features and user-visible changes + +*** Org Element + + =org-element.el= is a toolbox for parsing and analyzing "elements" + in an Org-mode buffer. This has been written by Nicolas Goaziou + and has been tested for quite some time. It is now part of Org's + core and many core functions rely on this package. + + Two functions might be particularly handy for users: + =org-element-at-point= and =org-element-context=. + + See the docstrings for more details. + + Below is a list of editing and navigating commands that now rely + on =org-element.el=. + +**** [[doc::org-fill-paragraph][org-fill-paragraph]] has been completely rewritten + + The filling mechanisms now rely on org-element, trying to do the + right thing on each element in various contexts. E.g. filling in + a list item will preserve indentation; filling in message-mode + will fall back on the relevant filling functions; etc. + +**** [[doc::org-metaup][org-metaup]] and [[doc::org-metadown][org-metadown]] will drag the element backward/forward + + If you want to get the old behavior (i.e. moving a line up and + down), you can first select the line as an active region, then + =org-metaup= or =org-metadown= to move the region backward or + forward. This also works with regions bigger than just one line. + +**** [[doc::org-up-element][org-up-element]] and [[doc::org-down-element][org-down-element]] (respectively =C-c C-^= and =C-c C-_=) + + This will move the point up/down in the hierarchy of elements. + +**** [[doc::org-backward-element][org-backward-element]] and [[doc::org-forward-element][org-forward-element]] (respectively =M-{= and =M-}=) + + This will move the point backward/forward in the hierarchy of + elements. + +**** [[doc::org-narrow-to-element][org-narrow-to-element]] will narrow to the element at point +**** [[doc::org-mark-element][org-mark-element]] will mark the element at point + + This command is bound to =M-h= and will mark the element at + point. If the point is at a paragraph, it will mark the + paragraph. If the point is at a list item, it will mark the list + item. Etc. + + Note that if point is at the beginning of a list, it will mark + the whole list. + + To mark a subtree, you can either use =M-h= on the headline + (since there is no ambiguity about the element you're at) or + [[doc::org-mark-subtree][org-mark-subtree]] (=C-c @=) anywhere in the subtree. + + Invoking [[doc::org-mark-element][org-mark-element]] repeatedly will try to mark the next + element on top of the previous one(s). E.g. hitting =M-h= twice + on a headline will mark the current subtree and the next one on + the same level. + +*** Org Agenda + +**** New option [[doc::org-agenda-sticky][org-agenda-sticky]] + + There is a new option =org-agenda-sticky= which enables "sticky" + agendas. Sticky agendas remain opened in the background so that + you don't need to regenerate them each time you hit the + corresponding keystroke. This is a big time saver. + + When [[doc::org-agenda-sticky][org-agenda-sticky]] is =non-nil=, the agenda buffer will be + named using the agenda key and its description. In sticky + agendas, the =q= key will just bury the agenda buffers and + further agenda commands will show existing buffer instead of + generating new ones. + + If [[doc::org-agenda-sticky][org-agenda-sticky]] is set to =nil=, =q= will kill the single + agenda buffer. + +**** New option [[doc::org-agenda-custom-commands-contexts][org-agenda-custom-commands-contexts]] + + Setting this option allows you to define specific context where + agenda commands should be available from. For example, when set + to this value + + #+BEGIN_SRC emacs-lisp + (setq org-agenda-custom-commands-contexts + '(("p" (in-file . "\\.txt")))) +#+END_SRC + + then the =p= agenda command will only be available from buffers + visiting *.txt files. See the docstring and the manual for more + details on how to use this. + +**** Changes in bulk actions + + The set of commands starting with =k ...= as been deleted and the + features have been merged into the "bulk action" feature. + + After you marked some entries in the agenda, if you call =B s=, + the agenda entries will be rescheduled using the date at point if + on a date header. If you are on an entry with a timestamp, you + will be prompted for a date to reschedule your marked entries to, + using the timestamp at point as the default prompt. + + You can now use =k= to capture the marked entry and use the date + at point as an overriding date for the capture template. + + To bind this behavior to =M-x org-capture RET= (or its + keybinding), set the new option [[doc::org-capture-use-agenda-date][org-capture-use-agenda-date]] to + =t=. + +**** =N= and =P= in the agenda will move to the next/previous item + +**** New command [[doc::org-agenda-bulk-mark-all][org-agenda-bulk-mark-all]] to mark all items + + This new command is bound to =*= in agenda mode. + + There is also a new option [[doc::org-agenda-bulk-mark-char][org-agenda-bulk-mark-char]] to set the + character to use as a mark for bulk actions. + +**** New option [[doc::org-agenda-persistent-marks][org-agenda-persistent-marks]] + + When set to =non-nil=, marks will remain visible after a bulk + action. You can temporarily toggle this by pressing =p= when + invoking [[doc::org-agenda-bulk-action][org-agenda-bulk-action]]. Marks are deleted if your + rebuild the agenda buffer or move to another date/span (e.g. with + =f= or =w=). + +**** New option [[doc::org-agenda-skip-timestamp-if-deadline-is-shown][org-agenda-skip-timestamp-if-deadline-is-shown]] + + =Non-nil= means skip timestamp line if same entry shows because + of deadline. + + In the agenda of today, an entry can show up multiple times + because it has both a plain timestamp and has a nearby deadline. + When this variable is t, then only the deadline is shown and the + fact that the entry has a timestamp for or including today is not + shown. When this variable is =nil=, the entry will be shown + several times. + +**** New =todo-unblocked= and =nottodo-unblocked= skip conditions + + See the [[http://orgmode.org/cgit.cgi/org-mode.git/commit/?id=f426da][git commit]] for more explanations. + +**** Allow category filtering in the agenda + + You can now filter the agenda by category. Pressing "<" will + filter by the category of the item on the current line, and + pressing "<" again will remove the filter. You can combine tag + filters and category filters. + + You can use =org-agenda-category-filter= in your custom agenda + views and =org-agenda-category-filter-preset= in your main + configuration. + + See also the new command [[doc::org-agenda-filter-by-top-category][org-agenda-filter-by-top-category]]: + hitting =^= will filter by "Top" category: only show entries that + are of the same category than the Top category of the entry at + point. + +*** Org Links + +**** Inserting links + + When inserting links through [[doc::org-insert-link][org-insert-link]], the description is + now displayed first, followed by the literal link, as the + description is often more useful when you look for the link you + want to insert. + + Completion now complete both literal links and description. If + you complete a description, the literal link and its description + will be inserted directly, whereas when you complete the literal + link, you will be prompted for a description (as with Org 7.8.) + + In the completion buffer, links to the current buffer are now + highlighted. + +**** New templates =%h= and =%(sexp)= for abbreviated links + + On top of =%s= template, which is replaced by the link tag in + abbreviated links, you can now use =%h= (which does the same than =%s= + but does not hexify the tag) and =%(sexp)= (which can run a function + that takes the tag as its own argument.) + +**** New link type =help= + + You can now create links from =help= buffers. + + For example, if you request help for the command [[doc::org-agenda][org-agenda]] with + =C-h f org-agenda RET=, creating a link from this buffer will let + you go back to the same buffer. + +**** New command [[doc::org-insert-all-links][org-insert-all-links]] + + This will insert all links as list items. With a universal + prefix argument, links will not be deleted from the variable + =org-stored-links=. + + This new command is bound to =C-c C-M-l=. + +**** New option [[doc::org-url-hexify-p][org-url-hexify-p]] + + When set to =nil=, the =URL= part of a link will not be hexified. + +**** Org can now open multiple shell links + +**** New option [[doc::org-doi-server-url][org-doi-server-url]] to specify an alternate DOI server + +**** RET now follows time stamps links + +*** Org Editing + +**** [[doc::org-todo][org-todo]] and =org-archive-*= can now loop in the active region + + When [[doc::org-loop-over-headlines-in-active-region][org-loop-over-headlines-in-active-region]] is =non-nil=, using + [[doc::org-todo][org-todo]] or =org-archive-*= commands in the active region will + loop over headlines. This is handy if you want to set the TODO + keyword for several items, or archive them quickly. + +**** You can now set tags for headlines in a region + + If [[doc::org-loop-over-headlines-in-active-region][org-loop-over-headlines-in-active-region]] is =non-nil=, then + selecting the region and hitting =C-c C-q= will set the tags for + all headlines in the region. + +**** New command [[doc::org-insert-drawer][org-insert-drawer]] to insert a drawer interactively + +**** Comments start with "^[ \t]*# " anywhere on a line + + Note that the space after the hashtag is mandatory. Comments + with "^#+" are not supported anymore. + +**** New speed key =#= to toggle the COMMENT cookie on a headline + +**** =indent-region-function= is now set to [[doc::org-indent-region][org-indent-region]] + + =C-M-\= should now produce useful results. + + You can unindent the buffer with [[doc::org-unindent-buffer][org-unindent-buffer]]. + +**** New option [[doc::org-allow-promoting-top-level-subtree][org-allow-promoting-top-level-subtree]] + + When =non-nil=, =S-M-= will promote level-1 subtrees + containing other subtrees. The level-1 headline will be + commented out. You can revert to the previous state with =M-x + undo RET=. + +*** Org Clock + +**** New keybinding =C-c C-x C-z= for [[doc::org-clock-resolve][org-clock-resolve]] + +**** New keybinding =C-c C-x C-q= for [[doc::org-clock-cancel][org-clock-cancel]] + +**** New command [[doc::org-clock-in-last][org-clock-in-last]] to clock in the last clocked item + + This command is bound to =C-c C-x C-x= and will clock in the last + clocked entry, if any. + +**** =C-u M-x= [[doc::org-clock-out][org-clock-out]] =RET= now prompts for a state to switch to + +**** =S-M-= on a clock timestamps adjusts the previous/next clock + +**** New option [[doc::org-clock-continuously][org-clock-continuously]] + + When set to =nil=, clocking in a task will first try to find the + last clocked out task and restart from when that task was clocked + out. + + You can temporarily activate continuous clocking with =C-u C-u + C-u M-x= [[doc::org-clock-in][org-clock-in]] =RET= (three universal prefix arguments) + and =C-u C-u M-x= [[org-clock-in-last][org-clock-in-last]] =RET= (two universal prefix + arguments). + + +**** New option [[doc::org-clock-frame-title-format][org-clock-frame-title-format]] + + This option sets the value of =frame-title-format= when clocking + in. + +**** New options for controlling the clockreport display + + [[doc::org-clock-file-time-cell-format][org-clock-file-time-cell-format]]: Format string for the file time + cells in clockreport. + + [[doc::org-clock-total-time-cell-format][org-clock-total-time-cell-format]]: Format string for the total + time cells in clockreport. + + +**** New options for controlling the clock/timer display + + [[doc::org-clock-clocked-in-display][org-clock-clocked-in-display]]: control whether the current clock + is displayed in the mode line and/or frame title. + + [[doc::org-timer-display][org-timer-display]]: control whether the current timer is displayed + in the mode line and/or frame title. + + This allows the clock and timer to be displayed in the frame + title instead of, or as well as, the mode line. This is useful + for people with limited space in the mode line but with ample + space in the frame title. + +*** Org Appearance + +**** New option [[doc::org-custom-properties][org-custom-properties]] + + The visibility of properties listed in this options can be turn + on/off with [[doc::org-toggle-custom-properties-visibility][org-toggle-custom-properties-visibility]]. This might + be useful for properties used by third-part tools or that you + don't want to see temporarily. + +**** New command [[doc::org-redisplay-inline-images][org-redisplay-inline-images]] + + This will redisplay all images. It is bound to =C-c C-x C-M-v=. + +**** New entities in =org-entities.el= + + There are these new entities: + + : ("tilde" "\\~{}" nil "˜" "~" "~" "~") + : ("slash" "/" nil "/" "/" "/" "/") + : ("plus" "+" nil "+" "+" "+" "+") + : ("under" "\\_" nil "_" "_" "_" "_") + : ("equal" "=" nil "=" "=" "=" "=") + : ("asciicirc" "\\textasciicircum{}" nil "^" "^" "^" "^") + +**** New face =org-list-dt= for definition terms +**** New face =org-date-selected= for the selected calendar day +**** New face value for =org-document-title= + + The face is back to a normal height. + +*** Org Columns + +**** New speed command =:= to activate the column view +**** New special property =CLOCKSUM_T= to display today's clocked time + + You can use =CLOCKSUM_T= the same way you use =CLOCKSUM=. It + will display the time spent on tasks for today only. + +**** Use the =:COLUMNS:= property in columnview dynamic blocks + + If the =:COLUMNS:= is set in a subtree, the columnview dynamic + block will use its value as the column format. + +**** Consider inline tasks when computing a sum + +*** Org Dates and Time Stamps + +**** Enhanced [[doc::org-sparse-tree][org-sparse-tree]] + + =C-c /= can now check for time ranges. + + When checking for dates with =C-c /= it is useful to change the + type of dates that you are interested in. You can now do this + interactively with =c= after =C-c /= and/or by setting + [[doc::org-sparse-tree-default-date-type][org-sparse-tree-default-date-type]] to the default value you want. + +**** Support for hourly repeat cookies + + You can now use + + : SCHEDULED: <2012-08-20 lun. 08:00 +1h> + + if you want to add an hourly repeater to an entry. + +**** =C-u C-u C-c .= inserts a time-stamp with no prompt + +**** When (setq [[doc::org-read-date-prefer-future][org-read-date-prefer-future]] 'time), accept days in the prompt + + "8am Wed" and "Wed 8am" are now acceptable values when entering a + date from the prompt. If [[doc::org-read-date-prefer-future][org-read-date-prefer-future]] is set to + =time=, this will produce the expected prompt indication. + +**** New option [[doc::org-datetree-add-timestamp][org-datetree-add-timestamp]] + + When set to =non-nil=, datetree entries will also have a + timestamp. This is useful if you want to see these entries in a + sparse tree with =C-c /=. + +*** Org Capture + +**** New command [[doc::org-capture-string][org-capture-string]] + + M-x [[doc::org-capture-string][org-capture-string]] RET will prompt for a string and a capture + template. The string will be used as an annotation for the + template. This is useful when capturing in batch mode as it lets + you define the content of the template without being in Emacs. + +**** New option [[doc::org-capture-templates-contexts][org-capture-templates-contexts]] + + Setting this option allows you to define specific context where + capture templates should be available from. For example, when + set to this value + + #+BEGIN_SRC emacs-lisp + (setq org-capture-templates-contexts + '(("c" (in-mode . "message-mode")))) +#+END_SRC + + then the =c= capture template will only be available from + =message-mode= buffers. See the docstring and the manual for + more details on how to use this. + +**** New =%l= template to insert the literal link +**** New option [[doc::org-capture-bookmark][org-capture-bookmark]] + + Org used to automatically add a bookmark with capture a note. + You can now turn this on by setting [[doc::org-capture-bookmark][org-capture-bookmark]] to + =nil=. + +**** Expand =%= escape sequences into text entered for 'th =%^{PROMPT}= escape + + See the manual for more explanations. + +**** More control over empty lines + + You can use =:empty-lines-before= and =:empty-lines-after= to + control the insertion of empty lines. Check the manual for more + explanations. + +**** New hook [[doc::org-capture-prepare-finalize-hook][org-capture-prepare-finalize-hook]] + + This new hook runs before the finalization process starts. + +*** Org Export + +**** New functions =orgtbl-to-table.el= and =orgtbl-to-unicode= + + =orgtbl-to-table.el= convert the table to a =table.el= table, and + =orgtbl-to-unicode= will use =ascii-art-to-unicode.el= (when + available) to print beautiful tables. + +**** [[doc::org-table-export][org-table-export]] now a bit clever about the target format + + When you specify a file name like =table.csv=, [[doc::org-table-export][org-table-export]] + will now suggest =orgtbl-to-csv= the default method for exporting + the table. + +**** New option [[doc::org-export-date-timestamp-format][org-export-date-timestamp-format]] + + The option allows to set a time string format for Org timestamps + in the #+DATE option. + +**** LaTeX: New options for exporting table rules :tstart, :hline and :tend + + See [[doc::org-export-latex-tables-hline][org-export-latex-tables-hline]] and [[doc::org-export-latex-tables-tend][org-export-latex-tables-tend]]. + +**** LaTeX: You can now set =:hfmt= from =#+ATTR_LaTeX= +**** Beamer: Add support and keybinding for the =exampleblock= environment + + Add support for these languages in [[doc::org-export-language-setup][org-export-language-setup]]. + More languages are always welcome. + +**** Beamer: New option [[doc::org-beamer-inherited-properties][org-beamer-inherited-properties]] + + This option allows Beamer export to inherit some properties. + Thanks to Carsten for implementing this. + +**** ODT: Add support for ODT export in org-bbdb.el +**** ODT: Add support for indented tables (see [[http://orgmode.org/cgit.cgi/org-mode.git/commit/?id=e9fd33][this commit]] for details) +**** ODT: Improve the conversion from ODT to other formats +**** ASCII: Swap the level-1/level-2 characters to underline the headlines +**** Support for Chinese, simplified Chinese, Russian, Ukrainian and Japanese +**** HTML: New option [[doc::org-export-html-date-format-string][org-export-html-date-format-string]] + + Format string to format the date and time in HTML export. Thanks + to Sébastien Vauban for this patch. + +*** Org Babel + +**** New =:results drawer= parameter + +=:results drawer= replaces =:results wrap=, which is deprecated but still +supported. + +**** =:results org= now put results in a =#+BEGIN_SRC org= block + +=:results org= used to put results in a =#+BEGIN_ORG= block but it now puts +results in a =#+BEGIN_SRC org= block, with comma-escaped lines. + +=#+BEGIN_ORG= blocks are obsolete. + +**** Exporting =#+BEGIN_SRC org= blocks exports the code + +It used to exports the results of the code. + +*** Miscellaneous + +**** New menu entry for [[doc::org-refile][org-refile]] +**** Allow capturing to encrypted entries + +If you capture to an encrypted entry, it will be decrypted before +inserting the template then re-encrypted after finalizing the capture. + +**** Inactive timestamps are now handled in tables + +Calc can do computation on active time-stamps like <2012-09-29 sat.>. +Inactive time-stamps in a table's cell are now internally deactivated so +that Calc formulas can operate on them. + +**** [[doc::org-table-number-regexp][org-table-number-regexp]] can now accept comma as decimal mark +**** Org allows a new property =APPT_WARNTIME= + + You can set it with the =W= speedy key or set it manually. When + set, exporting to iCalendar and [[doc::org-agenda-to-appt][org-agenda-to-appt]] will use the + value of this property as the number of minutes for the warning + alarm. + +**** New command [[doc::org-inc-effort][org-inc-effort]] + + This will increment the effort value. + + It is bound to =C-c C-x E= and to =E= as a speedy command. + +**** Attach: Add support for creating symbolic links + + =org-attach-method= now supports a new method =lns=, allowing to + attach symbolic links. + +**** Archive: you can now archive to a datetree + +**** New option [[doc::org-inlinetask-show-first-star][org-inlinetask-show-first-star]] + + =Non-nil= means display the first star of an inline task as + additional marker. When =nil=, the first star is not shown. + +**** New option [[doc::org-latex-preview-ltxpng-directory][org-latex-preview-ltxpng-directory]] + + This lets you define the path for the =ltxpng/= directory. + +**** You can now use imagemagick instead of dvipng to preview LaTeX fragments +**** You can now turn off [[doc::orgstruct++-mode][orgstruct++-mode]] safely +**** =C-u C-c C-c= on list items to add check boxes + + =C-u C-c C-c= will add an empty check box on a list item. + + When hit from the top of the list, it will add check boxes for + all top level list items. + +**** =org-list-ending-method= and =org-list-end-regexp= are now obsolete + + Fall back on using =org-list-end-re= only, which see. + +**** org-feed.el now expands =%(sexp)= templates +**** New option [[doc::org-protocol-data-separator][org-protocol-data-separator]] + +**** New option [[doc::org-ditaa-jar-option][org-ditaa-jar-option]] to specify the ditaa jar file + +**** New possible value for [[doc::org-loop-over-headlines-in-active-region][org-loop-over-headlines-in-active-region]] + + When [[doc::org-loop-over-headlines-in-active-region][org-loop-over-headlines-in-active-region]] is set to + =start-level=, the command will loop over the active region but + will only act upon entries that are of the same level than the + first headline in the region. + +**** New option [[doc::org-habit-show-all-today][org-habit-show-all-today]] + + When set to =t=, show all (even unscheduled) habits on today's + agenda. + +** Important bug fixes + +*** M-TAB on options keywords perform completion correctly again + + If you hit =M-TAB= on keywords like =#+TITLE=, Org will try to + perform completion with meaningful values. + +*** Add licenses to javascript embedded and external code snippets + + Embedded javascript code produced when exporting an Org file to + HTML is now licensed under GPLv3 (or later), and the copyright is + owned by the Free Software Foundation, Inc. + + The javascript code for embedding MathJax in the browser mentions + the MathJax copyright and the Apache 2.0 license. + + The javascript code for embedding =org-injo.js= in the browser + mentions the copyright of Sebastian Rose and the GPLv3 (or later) + license. + + =org-export-html-scripts= is now a variable, so that you can adapt + the code and the license to your needs. + + See http://www.gnu.org/philosophy/javascript-trap.html for + explanations on why these changes were necessary. + +* Version 7.8.11 + +** Incompatible changes + +*** Emacs 21 support has been dropped + + Do not use Org mode 7.xx with Emacs 21, use [[http://orgmode.org/org-6.36c.zip][version 6.36c]] instead. + +*** XEmacs support requires the XEmacs development version + + To use Org mode 7.xx with XEmacs, you need to run the developer + version of XEmacs. We were about to drop XEmacs support entirely, + but Michael Sperber stepped in and made changes to XEmacs that + made it easier to keep the support. Thanks to Michael for this + last-minute save. + +*** New keys for TODO sparse trees + + The key =C-c C-v= is now reserved for Org Babel action. TODO + sparse trees can still be made with =C-c / t= (all not-done + states) and =C-c / T= (specific states). + +*** The Agenda =org-agenda-ndays= is now obsolete + + The variable =org-agenda-ndays= is obsolete - please use + =org-agenda-span= instead. + + Thanks to Julien Danjou for this. + +*** Changes to the intended use of =org-export-latex-classes= + + So far this variable has been used to specify the complete header + of the LaTeX document, including all the =\usepackage= calls + necessary for the document. This setup makes it difficult to + maintain the list of packages that Org itself would like to call, + for example for the special symbol support it needs. + + First of all, you can *opt out of this change* in the following + way: You can say: /I want to have full control over headers, and I + will take responsibility to include the packages Org needs/. If + that is what you want, add this to your configuration and skip the + rest of this section (except maybe for the description of the + =[EXTRA]= place holder): + + #+begin_src emacs-lisp + (setq org-export-latex-default-packages-alist nil + org-export-latex-packages-alist nil) + #+end_src + + /Continue to read here if you want to go along with the modified + setup./ + + There are now two variables that should be used to list the LaTeX + packages that need to be included in all classes. The header + definition in =org-export-latex-classes= should then not contain + the corresponding =\usepackage= calls (see below). + + The two new variables are: + + 1. =org-export-latex-default-packages-alist= :: This is the + variable where Org-mode itself puts the packages it needs. + Normally you should not change this variable. The only + reason to change it anyway is when one of these packages + causes a conflict with another package you want to use. Then + you can remove that packages and hope that you are not using + Org-mode functionality that needs it. + + 2. =org-export-latex-packages-alist= :: This is the variable where + you can put the packages that you'd like to use across all + classes. + + The sequence how these customizations will show up in the LaTeX + document are: + + 1. Header from =org-export-latex-classes= + 2. =org-export-latex-default-packages-alist= + 3. =org-export-latex-packages-alist= + 4. Buffer-specific things set with =#+LaTeX_HEADER:= + + If you want more control about which segment is placed where, or + if you want, for a specific class, have full control over the + header and exclude some of the automatic building blocks, you can + put the following macro-like place holders into the header: + + #+begin_example + [DEFAULT-PACKAGES] \usepackage statements for default packages + [NO-DEFAULT-PACKAGES] do not include any of the default packages + [PACKAGES] \usepackage statements for packages + [NO-PACKAGES] do not include the packages + [EXTRA] the stuff from #+LaTeX_HEADER + [NO-EXTRA] do not include #+LaTeX_HEADER stuff + #+end_example + + If you have currently customized =org-export-latex-classes=, you + should revise that customization and remove any package calls that + are covered by =org-export-latex-default-packages-alist=. This + applies to the following packages: + + - inputenc + - fontenc + - fixltx2e + - graphicx + - longtable + - float + - wrapfig + - soul + - t1enc + - textcomp + - marvosym + - wasysym + - latexsym + - amssymb + - hyperref + + If one of these packages creates a conflict with another package + you are using, you can remove it from + =org-export-latex-default-packages-alist=. But then you risk that + some of the advertised export features of Org will not work + properly. + + You can also consider moving packages that you use in all classes + to =org-export-latex-packages-alist=. If necessary, put the place + holders so that the packages get loaded in the right sequence. As + said above, for backward compatibility, if you omit the place + holders, all the variables will dump their content at the end of + the header. + +*** The constant =org-html-entities= is obsolete + + Its content is now part of the new constant =org-entities=, which + is defined in the file org-entities.el. =org-html-entities= was + an internal variable, but it is possible that some users did write + code using it. + +*** =org-bbdb-anniversary-format-alist= has changed + + Please check the docstring and update your settings accordingly. + +*** Deleted =org-mode-p= + + This function has been deleted: please update your code. + +** Important new features + +*** New Org to ODT exporter + + Jambunathan's Org to ODT exporter is now part of Org. + + To use it, it `C-c C-e o' in an Org file. See the documentation + for more information on how to customize it. + +*** org-capture.el is now the default capture system + + This replaces the earlier system org-remember. The manual only + describes org-capture, but for people who prefer to continue to + use org-remember, we keep a static copy of the former manual + section [[http://orgmode.org/org-remember.pdf][chapter about remember]]. + + The new system has a technically cleaner implementation and more + possibilities for capturing different types of data. See + [[http://thread.gmane.org/gmane.emacs.orgmode/26441/focus%3D26441][Carsten's announcement]] for more details. + + To switch over to the new system: + + 1. Run + + : M-x org-capture-import-remember-templates RET + + to get a translated version of your remember templates into the + new variable =org-capture-templates=. This will "mostly" work, + but maybe not for all cases. At least it will give you a good + place to modify your templates. After running this command, + enter the customize buffer for this variable with + + : M-x customize-variable RET org-capture-templates RET + + and convince yourself that everything is OK. Then save the + customization. + + 2. Bind the command =org-capture= to a key, similar to what you did + with org-remember: + + : (define-key global-map "\C-cc" 'org-capture) + + If your fingers prefer =C-c r=, you can also use this key once + you have decided to move over completely to the new + implementation. During a test time, there is nothing wrong + with using both system in parallel. + +** New libraries + +*** New Org libraries +**** org-eshell.el (Konrad Hinsen) + + Implement links to eshell buffers. + +**** org-special-blocks (Carsten Dominik) + + This package generalizes the #+begin_foo and #+end_foo tokens. + + To use, put the following in your init file: + + #+BEGIN_EXAMPLE +(require 'org-special-blocks) +#+END_EXAMPLE + + The tokens #+begin_center, #+begin_verse, etc. existed + previously. This package generalizes them (at least for the + LaTeX and html exporters). When a #+begin_foo token is + encountered by the LaTeX exporter, it is expanded + into \begin{foo}. The text inside the environment is not + protected, as text inside environments generally is. + When #+begin_foo is encountered by the html exporter, a div with + class foo is inserted into the HTML file. It is up to the user + to add this class to his or her stylesheet if this div is to mean + anything. + +**** org-taskjuggler.el (Christian Egli) + + Christian Egli's /org-taskjuggler.el/ module is now part of Org. + He also wrote a [[http://orgmode.org/worg/org-tutorials/org-taskjuggler.php][tutorial]] for it. + +**** org-ctags.el (Paul Sexton) + + Targets like =<>= can now be found by Emacs' etag + functionality, and Org-mode links can be used to to link to + etags, also in non-Org-mode files. For details, see the file + /org-ctags.el/. + + This feature uses a new hook =org-open-link-functions= which will + call function to do something special with text links. + + Thanks to Paul Sexton for this contribution. + +**** org-docview.el (Jan Böcker) + + This new module allows links to various file types using docview, where + Emacs displays images of document pages. Docview link types can point + to a specific page in a document, for example to page 131 of the + Org-mode manual: + + : [[docview:~/.elisp/org/doc/org.pdf::131][Org-Mode Manual]] + + Thanks to Jan Böcker for this contribution. + +*** New Babel libraries + +- ob-picolisp.el (Thorsten Jolitz) +- ob-fortran.el (Sergey Litvinov) +- ob-shen.el (Eric Schulte) +- ob-maxima.el (Eric S Fraga) +- ob-java.el (Eric Schulte) +- ob-lilypond.el (Martyn Jago) +- ob-awk.el (Eric Schulte) + +** Other new features and various enhancements + +*** Hyperlinks + +**** Org-Bibtex -- major improvements + + Provides support for managing bibtex bibliographical references + data in headline properties. Each headline corresponds to a + single reference and the relevant bibliographic meta-data is + stored in headline properties, leaving the body of the headline + free to hold notes and comments. Org-bibtex is aware of all + standard bibtex reference types and fields. + + The key new functions are + + - org-bibtex-check :: queries the user to flesh out all required + (and with prefix argument optional) bibtex fields available + for the specific reference =type= of the current headline. + + - org-bibtex-create :: Create a new entry at the given level, + using org-bibtex-check to flesh out the relevant fields. + + - org-bibtex-yank :: Yank a bibtex entry on the kill ring as a + formatted Org-mode headline into the current buffer + + - org-bibtex-export-to-kill-ring :: Export the current headline + to the kill ring as a formatted bibtex entry. + +**** org-gnus.el now allows link creation from messages + + You can now create links from messages. This is particularly + useful when the user wants to stored messages that he sends, for + later check. Thanks to Ulf Stegemann for the patch. + +**** Modified link escaping + + David Maus worked on `org-link-escape'. See [[http://article.gmane.org/gmane.emacs.orgmode/37888][his message]]: + + : 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 + : a particular link type (e.g. non-ascii characters in a http: + : link). + : + : With this change in place Org will apply percent escaping and + : unescaping more consistently especially for non-ascii characters. + : Additionally some of the outstanding bugs or glitches concerning + : percent escaped links are solved. + + Thanks a lot to David for this work. + +**** Make =org-store-link= point to directory in a dired buffer + + When, in a dired buffer, the cursor is not in a line listing a + file, `org-store-link' will store a link to the directory. + + Patch by Stephen Eglen. + +**** Allow regexps in =org-file-apps= to capture link parameters + + The way extension regexps in =org-file-apps= are handled has + changed. Instead of matching against the file name, the regexps + are now matched against the whole link, and you can use grouping + to extract link parameters which you can then use in a command + string to be executed. + + For example, to allow linking to PDF files using the syntax + =file:/doc.pdf::=, you can add the following entry + to org-file-apps: + + #+begin_example + Extension: \.pdf::\([0-9]+\)\' + Command: evince "%s" -p %1 + #+end_example + + Thanks to Jan Böcker for a patch to this effect. + +*** Dates and time + +**** Allow relative time when scheduling/adding a deadline + + You can now use relative duration strings like "-2d" or "++3w" + when calling =org-schedule= or =org-deadline=: it will schedule + (or set the deadline for) the item respectively two days before + today and three weeks after the current timestamp, if any. + + You can use this programmatically: =(org-schedule nil "+2d")= + will work on the current entry. + + You can also use this while (bulk-)rescheduling and + (bulk-)resetting the deadline of (several) items from the agenda. + + Thanks to Memnon Anon for a heads up about this! + +**** American-style dates are now understood by =org-read-date= + + So when you are prompted for a date, you can now answer like this + + #+begin_example + 2/5/3 --> 2003-02-05 + 2/5 --> -02-05 + #+end_example + +*** Agenda + +**** =org-agenda-custom-commands= has a default value + + This option used to be `nil' by default. This now has a default + value, displaying an agenda and all TODOs. See the docstring for + details. Thanks to Carsten for this. + +**** Improved filtering through =org-agenda-to-appt= + + The new function allows the user to refine the scope of entries + to pass to =org-agenda-get-day-entries= and allows to filter out + entries using a function. + + Thanks to Peter Münster for raising a related issue and to + Tassilo Horn for this idea. Also thanks to Peter Münster for + [[git:68ffb7a7][fixing a small bug]] in the final implementation. + +**** Allow ap/pm times in agenda time grid + + Times in the agenda can now be displayed in am/pm format. See + the new variable =org-agenda-timegrid-use-ampm=. Thanks to + C. A. Webber for a patch to this effect. + +**** Agenda: Added a bulk "scattering" command + + =B S= in the agenda buffer will cause tasks to be rescheduled a + random number of days into the future, with 7 as the default. + This is useful if you've got a ton of tasks scheduled for today, + you realize you'll never deal with them all, and you just want + them to be distributed across the next N days. When called with + a prefix arg, rescheduling will avoid weekend days. + + Thanks to John Wiegley for this. + +*** Exporting + +**** Simplification of org-export-html-preamble/postamble + + When set to `t', export the preamble/postamble as usual, honoring + the =org-export-email/author/creator-info= variables. + + When set to a formatting string, insert this string. See the + docstring of these variable for details about available + %-sequences. + + You can set =:html-preamble= in publishing project in the same + way: `t' means to honor =:email/creator/author-info=, and a + formatting string will insert a string. + +**** New exporters to Latin-1 and UTF-8 + + While Ulf Stegemann was going through the entities list to + improve the LaTeX export, he had the great idea to provide + representations for many of the entities in Latin-1, and for all + of them in UTF-8. This means that we can now export files rich + in special symbols to Latin-1 and to UTF-8 files. These new + exporters can be reached with the commands =C-c C-e n= and =C-c + C-e u=, respectively. + + When there is no representation for a given symbol in the + targeted coding system, you can choose to keep the TeX-macro-like + representation, or to get an "explanatory" representation. For + example, =\simeq= could be represented as "[approx. equal to]". + Please use the variable =org-entities-ascii-explanatory= to state + your preference. + +**** HTML export: Add class to outline containers using property + + The =HTML_CONTAINER_CLASS= property can now be used to add a + class name to the outline container of a node in HTML export. + +**** Throw an error when creating an image from a LaTeX snippet fails + + This behavior can be configured with the new option variable + =org-format-latex-signal-error=. + +**** Support for creating BEAMER presentations from Org-mode documents + + Org-mode documents or subtrees can now be converted directly in + to BEAMER presentation. Turning a tree into a simple + presentations is straight forward, and there is also quite some + support to make richer presentations as well. See the [[http://orgmode.org/manual/Beamer-class-export.html#Beamer-class-export][BEAMER + section]] in the manual for more details. + + Thanks to everyone who has contributed to the discussion about + BEAMER support and how it should work. This was a great example + for how this community can achieve a much better result than any + individual could. + +*** Refiling + +**** Refile targets can now be cached + + You can turn on caching of refile targets by setting the variable + =org-refile-use-cache=. This should speed up refiling if you + have many eligible targets in many files. If you need to update + the cache because Org misses a newly created entry or still + offers a deleted one, press =C-0 C-c C-w=. + +**** New logging support for refiling + + Whenever you refile an item, a time stamp and even a note can be + added to this entry. For details, see the new option + =org-log-refile=. + + Thanks to Charles Cave for this idea. + +*** Completion + +**** In-buffer completion is now done using John Wiegley's pcomplete.el + + Thanks to John Wiegley for much of this code. + +*** Tables + +**** New command =org-table-transpose-table-at-point= + + See the docstring. This hack from Juan Pechiar is now part of + Org's core. Thanks to Juan! + +**** Display field's coordinates when editing it with =C-c `= + + When editing a field with =C-c `=, the field's coordinate will + the displayed in the buffer. + + Thanks to Michael Brand for a patch to this effect. + +**** Spreadsheet computation of durations and time values + + If you want to compute time values use the =T= flag, either in + Calc formulas or Elisp formulas: + + | Task 1 | Task 2 | Total | + |--------+--------+---------| + | 35:00 | 35:00 | 1:10:00 | + #+TBLFM: @2$3=$1+$2;T + + Values must be of the form =[HH:]MM:SS=, where hours are + optional. + + Thanks to Martin Halder, Eric Schulte and Carsten for code and + feedback on this. + +**** Implement formulas applying to field ranges + + Carsten implemented this field-ranges formulas. + + : A frequently requested feature for tables has been to be able to define + : row formulas in a way similar to column formulas. The patch below allows + : things like + : + : @3= + : @2$2..@5$7= + : @I$2..@II$4= + : + : as the left hand side for table formulas in order to write a formula that + : is valid for an entire column or for a rectangular section in a + : table. + + Thanks a lot to Carsten for this. + +**** Sending radio tables from org buffers is now allowed + + Org radio tables can no also be sent inside Org buffers. Also, + there is a new hook which get called after a table has been sent. + + Thanks to Seweryn Kokot. + +*** Lists + +**** Improved handling of lists + + Nicolas Goaziou extended and improved the way Org handles lists. + + 1. Indentation of text determines again end of items in + lists. So, some text less indented than the previous item + doesn't close the whole list anymore, only all items more + indented than it. + + 2. Alphabetical bullets are implemented, through the use of the + variable `org-alphabetical-lists'. This also adds alphabetical + counters like [@c] or [@W]. + + 3. Lists can now safely contain drawers, inline tasks, or various + blocks, themselves containing lists. Two variables are + controlling this: `org-list-forbidden-blocks', and + `org-list-export-context'. + + 4. Improve `newline-and-indent' (C-j): used in an item, it will + keep text from moving at column 0. This allows to split text + and make paragraphs and still not break the list. + + 5. Improve `org-toggle-item' (C-c -): used on a region with + standard text, it will change the region into one item. With a + prefix argument, it will fallback to the previous behavior and + make every line in region an item. It permits to easily + integrate paragraphs inside a list. + + 6. `fill-paragraph' (M-q) now understands lists. It can freely be + used inside items, or on text just after a list, even with no + blank line around, without breaking list structure. + + Thanks a lot to Nicolas for all this! + +*** Inline display of linked images + + Images can now be displayed inline. The key C-c C-x C-v does + toggle the display of such images. Note that only image links + that have no description part will be inlined. + +*** Implement offsets for ordered lists + + If you want to start an ordered plain list with a number different + from 1, you can now do it like this: + + : 1. [@start:12] will star a lit a number 12 + +*** Babel: code block body expansion for table and preview + + In org-babel, code is "expanded" prior to evaluation. I.e. the + code that is actually evaluated comprises the code block contents, + augmented with the extra code which assigns the referenced data to + variables. It is now possible to preview expanded contents, and + also to expand code during during tangling. This expansion takes + into account all header arguments, and variables. + + A new keybinding `C-c M-b p' bound to `org-babel-expand-src-block' + can be used from inside of a source code block to preview its + expanded contents (which can be very useful for debugging). + tangling + + The expanded body can now be tangled, this includes variable + values which may be the results of other source-code blocks, or + stored in headline properties or tables. One possible use for this + is to allow those using org-babel for their emacs initialization + to store values (e.g. usernames, passwords, etc...) in headline + properties or in tables. + + Org-babel now supports three new header arguments, and new default + behavior for handling horizontal lines in tables (hlines), column + names, and rownames across all languages. + +*** Editing Convenience and Appearance + +**** New command =org-copy-visible= (=C-c C-x v=) + + This command will copy the visible text in the region into the + kill ring. Thanks to Florian Beck for this function and to + Carsten for adding it to org.el and documenting it! + +**** Make it possible to protect hidden subtrees from being killed by =C-k= + + See the new variable =org-ctrl-k-protect-subtree=. This was a + request by Scott Otterson. + +**** Implement pretty display of entities, sub-, and superscripts. + + The command =C-c C-x \= toggles the display of Org's special + entities like =\alpha= as pretty unicode characters. Also, sub + and superscripts are displayed in a pretty way (raised/lower + display, in a smaller font). If you want to exclude sub- and + superscripts, see the variable + =org-pretty-entities-include-sub-superscripts=. + + Thanks to Eric Schulte and Ulf Stegeman for making this possible. + +**** New faces for title, date, author and email address lines + + The keywords in these lines are now dimmed out, and the title is + displayed in a larger font, and a special font is also used for + author, date, and email information. This is implemented by the + following new faces: + + =org-document-title= + =org-document-info= + =org-document-info-keyword= + + In addition, the variable =org-hidden-keywords= can be used to + make the corresponding keywords disappear. + + Thanks to Dan Davison for this feature. + +**** Simpler way to specify faces for tags and todo keywords + + The variables =org-todo-keyword-faces=, =org-tag-faces=, and + =org-priority-faces= now accept simple color names as + specifications. The colors will be used as either foreground or + background color for the corresponding keyword. See also the + variable =org-faces-easy-properties=, which governs which face + property is affected by this setting. + + This is really a great simplification for setting keyword faces. + The change is based on an idea and patch by Ryan Thompson. + +**** in tables now means fixed width, not maximum width + + Requested by Michael Brand. + +**** Better level cycling function + + =TAB= in an empty headline cycles the level of that headline + through likely states. Ryan Thompson implemented an improved + version of this function, which does not depend upon when exactly + this command is used. Thanks to Ryan for this improvement. + +**** Adaptive filling + + For paragraph text, =org-adaptive-fill-function= did not handle + the base case of regular text which needed to be filled. This is + now fixed. Among other things, it allows email-style ">" + comments to be filled correctly. + + Thanks to Dan Hackney for this patch. + +**** `org-reveal' (=C-c C-r=) also decrypts encrypted entries (org-crypt.el) + + Thanks to Richard Riley for triggering this change. + +**** Better automatic letter selection for TODO keywords + + When all first letters of keywords have been used, Org now + assigns more meaningful characters based on the keywords. + + Thanks to Mikael Fornius for this patch. + +*** Clocking + +**** Clock: Allow synchronous update of timestamps in CLOCK log + + Using =S-M-= on CLOCK log timestamps will + increase/decrease the two timestamps on this line so that + duration will keep the same. Note that duration can still be + slightly modified in case a timestamp needs some rounding. + + Thanks to Rainer Stengele for this idea. + +**** Localized clock tables + + Clock tables now support a new new =:lang= parameter, allowing + the user to customize the localization of the table headers. See + the variable =org-clock-clocktable-language-setup= which controls + available translated strings. + +**** Show clock overruns in mode line + + When clocking an item with a planned effort, overrunning the + planned time is now made visible in the mode line, for example + using the new face =org-mode-line-clock-overrun=, or by adding an + extra string given by =org-task-overrun-text=. + + Thanks to Richard Riley for a patch to this effect. + +**** Clock reports can now include the running, incomplete clock + + If you have a clock running, and the entry being clocked falls + into the scope when creating a clock table, the time so far spent + can be added to the total. This behavior depends on the setting + of =org-clock-report-include-clocking-task=. The default is + =nil=. + + Thanks to Bernt Hansen for this useful addition. + +*** Misc + +**** Improvements with inline tasks and indentation + + There is now a configurable way on how to export inline tasks. + See the new variable =org-inlinetask-export-templates=. + + Thanks to Nicolas Goaziou for coding these changes. + +**** A property value of "nil" now means to unset a property + + This can be useful in particular with property inheritance, if + some upper level has the property, and some grandchild of it + would like to have the default settings (i.e. not overruled by a + property) back. + + Thanks to Robert Goldman and Bernt Hansen for suggesting this + change. + +**** New helper functions in org-table.el + + There are new functions to access and write to a specific table field. + This is for hackers, and maybe for the org-babel people. + + #+begin_example + org-table-get + org-table-put + org-table-current-line + org-table-goto-line + #+end_example + +**** Archiving: Allow to reverse order in target node + + The new option =org-archive-reversed-order= allows to have + archived entries inserted in a last-on-top fashion in the target + node. + + This was requested by Tom. + +**** Org-reveal: Double prefix arg shows the entire subtree of the parent + + This can help to get out of an inconsistent state produced for + example by viewing from the agenda. + + This was a request by Matt Lundin. + +* License + + 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 . diff --git a/elpa/org-20150629/etc/styles/OrgOdtContentTemplate.xml b/elpa/org-20160215/etc/styles/OrgOdtContentTemplate.xml similarity index 100% rename from elpa/org-20150629/etc/styles/OrgOdtContentTemplate.xml rename to elpa/org-20160215/etc/styles/OrgOdtContentTemplate.xml diff --git a/elpa/org-20150629/etc/styles/OrgOdtStyles.xml b/elpa/org-20160215/etc/styles/OrgOdtStyles.xml similarity index 97% rename from elpa/org-20150629/etc/styles/OrgOdtStyles.xml rename to elpa/org-20160215/etc/styles/OrgOdtStyles.xml index f41d9840..1a8edee9 100644 --- a/elpa/org-20150629/etc/styles/OrgOdtStyles.xml +++ b/elpa/org-20160215/etc/styles/OrgOdtStyles.xml @@ -109,33 +109,53 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/elpa/org-20150629/etc/styles/README b/elpa/org-20160215/etc/styles/README similarity index 100% rename from elpa/org-20150629/etc/styles/README rename to elpa/org-20160215/etc/styles/README diff --git a/elpa/org-20160215/ob-C.el b/elpa/org-20160215/ob-C.el new file mode 100644 index 00000000..a6d4d5e7 --- /dev/null +++ b/elpa/org-20160215/ob-C.el @@ -0,0 +1,439 @@ +;;; ob-C.el --- org-babel functions for C and similar languages + +;; Copyright (C) 2010-2016 Free Software Foundation, Inc. + +;; Author: Eric Schulte +;; Thierry Banel +;; Keywords: literate programming, reproducible research +;; Homepage: http://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 . + +;;; Commentary: + +;; Org-Babel support for evaluating C, C++, D code. +;; +;; very limited implementation: +;; - currently only support :results output +;; - not much in the way of error feedback + +;;; Code: +(require 'ob) +(require 'cc-mode) + +(declare-function org-entry-get "org" + (pom property &optional inherit literal-nil)) +(declare-function org-remove-indentation "org" (code &optional n)) + +(defvar org-babel-tangle-lang-exts) +(add-to-list 'org-babel-tangle-lang-exts '("C++" . "cpp")) +(add-to-list 'org-babel-tangle-lang-exts '("D" . "d")) + +(defvar org-babel-default-header-args:C '()) + +(defcustom org-babel-C-compiler "gcc" + "Command used to compile a C source code file into an executable. +May be either a command in the path, like gcc +or an absolute path name, like /usr/local/bin/gcc +parameter may be used, like gcc -v" + :group 'org-babel + :version "24.3" + :type 'string) + +(defcustom org-babel-C++-compiler "g++" + "Command used to compile a C++ source code file into an executable. +May be either a command in the path, like g++ +or an absolute path name, like /usr/local/bin/g++ +parameter may be used, like g++ -v" + :group 'org-babel + :version "24.3" + :type 'string) + +(defcustom org-babel-D-compiler "rdmd" + "Command used to compile and execute a D source code file. +May be either a command in the path, like rdmd +or an absolute path name, like /usr/local/bin/rdmd +parameter may be used, like rdmd --chatty" + :group 'org-babel + :version "24.3" + :type 'string) + +(defvar org-babel-c-variant nil + "Internal variable used to hold which type of C (e.g. C or C++ or D) +is currently being evaluated.") + +(defun org-babel-execute:cpp (body params) + "Execute BODY according to PARAMS. +This function calls `org-babel-execute:C++'." + (org-babel-execute:C++ body params)) + +(defun org-babel-expand-body:cpp (body params) + "Expand a block of C++ code with org-babel according to its +header arguments." + (org-babel-expand-body:C++ body params)) + +(defun org-babel-execute:C++ (body params) + "Execute a block of C++ code with org-babel. +This function is called by `org-babel-execute-src-block'." + (let ((org-babel-c-variant 'cpp)) (org-babel-C-execute body params))) + +(defun org-babel-expand-body:C++ (body params) + "Expand a block of C++ code with org-babel according to its +header arguments." + (let ((org-babel-c-variant 'cpp)) (org-babel-C-expand-C++ body params))) + +(defun org-babel-execute:D (body params) + "Execute a block of D code with org-babel. +This function is called by `org-babel-execute-src-block'." + (let ((org-babel-c-variant 'd)) (org-babel-C-execute body params))) + +(defun org-babel-expand-body:D (body params) + "Expand a block of D code with org-babel according to its +header arguments." + (let ((org-babel-c-variant 'd)) (org-babel-C-expand-D body params))) + +(defun org-babel-execute:C (body params) + "Execute a block of C code with org-babel. +This function is called by `org-babel-execute-src-block'." + (let ((org-babel-c-variant 'c)) (org-babel-C-execute body params))) + +(defun org-babel-expand-body:C (body params) + "Expand a block of C code with org-babel according to its +header arguments." + (let ((org-babel-c-variant 'c)) (org-babel-C-expand-C body params))) + +(defun org-babel-C-execute (body params) + "This function should only be called by `org-babel-execute:C' +or `org-babel-execute:C++' or `org-babel-execute:D'." + (let* ((tmp-src-file (org-babel-temp-file + "C-src-" + (case org-babel-c-variant + (c ".c" ) + (cpp ".cpp") + (d ".d" )))) + (tmp-bin-file (org-babel-temp-file "C-bin-" org-babel-exeext)) ;; not used for D + (cmdline (cdr (assoc :cmdline params))) + (cmdline (if cmdline (concat " " cmdline) "")) + (flags (cdr (assoc :flags params))) + (flags (mapconcat 'identity + (if (listp flags) flags (list flags)) " ")) + (full-body + (case org-babel-c-variant + (c (org-babel-C-expand-C body params)) + (cpp (org-babel-C-expand-C++ body params)) + (d (org-babel-C-expand-D body params))))) + (with-temp-file tmp-src-file (insert full-body)) + (case org-babel-c-variant + ((c cpp) + (org-babel-eval + (format "%s -o %s %s %s" + (case org-babel-c-variant + (c org-babel-C-compiler) + (cpp org-babel-C++-compiler)) + (org-babel-process-file-name tmp-bin-file) + flags + (org-babel-process-file-name tmp-src-file)) "")) + (d nil)) ;; no separate compilation for D + (let ((results + (org-babel-eval + (case org-babel-c-variant + ((c cpp) + (concat tmp-bin-file cmdline)) + (d + (format "%s %s %s %s" + org-babel-D-compiler + flags + (org-babel-process-file-name tmp-src-file) + cmdline))) + ""))) + (when results + (setq results (org-babel-trim (org-remove-indentation results))) + (org-babel-reassemble-table + (org-babel-result-cond (cdr (assoc :result-params params)) + (org-babel-read results t) + (let ((tmp-file (org-babel-temp-file "c-"))) + (with-temp-file tmp-file (insert results)) + (org-babel-import-elisp-from-file tmp-file))) + (org-babel-pick-name + (cdr (assoc :colname-names params)) (cdr (assoc :colnames params))) + (org-babel-pick-name + (cdr (assoc :rowname-names params)) (cdr (assoc :rownames params))))) + ))) + +(defun org-babel-C-expand-C++ (body params) + "Expand a block of C or C++ code with org-babel according to +its header arguments." + (org-babel-C-expand-C body params)) + +(defun org-babel-C-expand-C (body params) + "Expand a block of C or C++ code with org-babel according to +its header arguments." + (let ((vars (mapcar #'cdr (org-babel-get-header params :var))) + (colnames (cdar (org-babel-get-header params :colname-names))) + (main-p (not (string= (cdr (assoc :main params)) "no"))) + (includes (org-babel-read + (or (cdr (assoc :includes params)) + (org-entry-get nil "includes" t)) + nil)) + (defines (org-babel-read + (or (cdr (assoc :defines params)) + (org-entry-get nil "defines" t)) + nil))) + (when (stringp includes) + (setq includes (split-string includes))) + (when (stringp defines) + (let ((y nil) + (result (list t))) + (dolist (x (split-string defines)) + (if (null y) + (setq y x) + (nconc result (list (concat y " " x))) + (setq y nil))) + (setq defines (cdr result)))) + (mapconcat 'identity + (list + ;; includes + (mapconcat + (lambda (inc) (format "#include %s" inc)) + includes "\n") + ;; defines + (mapconcat + (lambda (inc) (format "#define %s" inc)) + (if (listp defines) defines (list defines)) "\n") + ;; variables + (mapconcat 'org-babel-C-var-to-C vars "\n") + ;; table sizes + (mapconcat 'org-babel-C-table-sizes-to-C vars "\n") + ;; tables headers utility + (when colnames + (org-babel-C-utility-header-to-C)) + ;; tables headers + (mapconcat 'org-babel-C-header-to-C colnames "\n") + ;; body + (if main-p + (org-babel-C-ensure-main-wrap body) + body) "\n") "\n"))) + +(defun org-babel-C-expand-D (body params) + "Expand a block of D code with org-babel according to +its header arguments." + (let ((vars (mapcar #'cdr (org-babel-get-header params :var))) + (colnames (cdar (org-babel-get-header params :colname-names))) + (main-p (not (string= (cdr (assoc :main params)) "no"))) + (imports (or (cdr (assoc :imports params)) + (org-babel-read (org-entry-get nil "imports" t))))) + (when (stringp imports) + (setq imports (split-string imports))) + (setq imports (append imports '("std.stdio" "std.conv"))) + (mapconcat 'identity + (list + "module mmm;" + ;; imports + (mapconcat + (lambda (inc) (format "import %s;" inc)) + imports "\n") + ;; variables + (mapconcat 'org-babel-C-var-to-C vars "\n") + ;; table sizes + (mapconcat 'org-babel-C-table-sizes-to-C vars "\n") + ;; tables headers utility + (when colnames + (org-babel-C-utility-header-to-C)) + ;; tables headers + (mapconcat 'org-babel-C-header-to-C colnames "\n") + ;; body + (if main-p + (org-babel-C-ensure-main-wrap body) + body) "\n") "\n"))) + +(defun org-babel-C-ensure-main-wrap (body) + "Wrap BODY in a \"main\" function call if none exists." + (if (string-match "^[ \t]*[intvod]+[ \t\n\r]*main[ \t]*(.*)" body) + body + (format "int main() {\n%s\nreturn 0;\n}\n" body))) + +(defun org-babel-prep-session:C (session params) + "This function does nothing as C is a compiled language with no +support for sessions" + (error "C is a compiled languages -- 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" + (error "C is a compiled languages -- no support for sessions")) + +;; helper functions + +(defun org-babel-C-format-val (type val) + "Handle the FORMAT part of TYPE with the data from VAL." + (let ((format-data (cadr type))) + (if (stringp format-data) + (cons "" (format format-data val)) + (funcall format-data val)))) + +(defun org-babel-C-val-to-C-type (val) + "Determine the type of VAL. +Return a list (TYPE-NAME FORMAT). TYPE-NAME should be the name of the type. +FORMAT can be either a format string or a function which is called with VAL." + (let* ((basetype (org-babel-C-val-to-base-type val)) + (type + (case basetype + (integerp '("int" "%d")) + (floatp '("double" "%f")) + (stringp + (list + (if (equal org-babel-c-variant 'd) "string" "const char*") + "\"%s\"")) + (t (error "unknown type %S" basetype))))) + (cond + ((integerp val) type) ;; an integer declared in the #+begin_src line + ((floatp val) type) ;; a numeric declared in the #+begin_src line + ((and (listp val) (listp (car val))) ;; a table + `(,(car type) + (lambda (val) + (cons + (format "[%d][%d]" (length val) (length (car val))) + (concat + (if (equal org-babel-c-variant 'd) "[\n" "{\n") + (mapconcat + (lambda (v) + (concat + (if (equal org-babel-c-variant 'd) " [" " {") + (mapconcat (lambda (w) (format ,(cadr type) w)) v ",") + (if (equal org-babel-c-variant 'd) "]" "}"))) + val + ",\n") + (if (equal org-babel-c-variant 'd) "\n]" "\n}")))))) + ((or (listp val) (vectorp val)) ;; a list declared in the #+begin_src line + `(,(car type) + (lambda (val) + (cons + (format "[%d]" (length val)) + (concat + (if (equal org-babel-c-variant 'd) "[" "{") + (mapconcat (lambda (v) (format ,(cadr type) v)) val ",") + (if (equal org-babel-c-variant 'd) "]" "}")))))) + (t ;; treat unknown types as string + type)))) + +(defun org-babel-C-val-to-base-type (val) + "Determine the base type of VAL which may be +`integerp' if all base values are integers +`floatp' if all base values are either floating points or integers +`stringp' otherwise." + (cond + ((integerp val) 'integerp) + ((floatp val) 'floatp) + ((or (listp val) (vectorp val)) + (let ((type nil)) + (mapc (lambda (v) + (case (org-babel-C-val-to-base-type v) + (stringp (setq type 'stringp)) + (floatp + (if (or (not type) (eq type 'integerp)) + (setq type 'floatp))) + (integerp + (unless type (setq type 'integerp))))) + val) + type)) + (t 'stringp))) + +(defun org-babel-C-var-to-C (pair) + "Convert an elisp val into a string of C code specifying a var +of the same value." + ;; TODO list support + (let ((var (car pair)) + (val (cdr pair))) + (when (symbolp val) + (setq val (symbol-name val)) + (when (= (length val) 1) + (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))) + (format "%s %s%s = %s;" + type + var + suffix + data)))) + +(defun org-babel-C-table-sizes-to-C (pair) + "Create constants of table dimensions, if PAIR is a table." + (when (listp (cdr pair)) + (cond + ((listp (cadr pair)) ;; a table + (concat + (format "const int %s_rows = %d;" (car pair) (length (cdr pair))) + "\n" + (format "const int %s_cols = %d;" (car pair) (length (cadr pair))))) + (t ;; a list declared in the #+begin_src line + (format "const int %s_cols = %d;" (car pair) (length (cdr pair))))))) + +(defun org-babel-C-utility-header-to-C () + "Generate a utility function to convert a column name +into a column number." + (case org-babel-c-variant + ((c cpp) + "int get_column_num (int nbcols, const char** header, const char* column) +{ + int c; + for (c=0; c. + +;;; Commentary: + +;; Org-Babel support for evaluating J code. +;; +;; Session interaction depends on `j-console' from package `j-mode' +;; (available in MELPA). + +;;; Code: +(require 'ob) + +(declare-function org-trim "org" (S)) +(declare-function j-console-ensure-session "ext:j-console" ()) + +(defun org-babel-expand-body:J (body params &optional processed-params) + "Expand BODY according to PARAMS, return the expanded body. +PROCESSED-PARAMS isn't used yet." + (org-babel-J-interleave-echos-except-functions body)) + +(defun org-babel-J-interleave-echos (body) + "Interleave echo',' between each source line of BODY." + (mapconcat #'identity (split-string body "\n") "\necho','\n")) + +(defun org-babel-J-interleave-echos-except-functions (body) + "Interleave echo',' between source lines of BODY that aren't functions." + (if (obj-string-match-m "\\(?:^\\|\n\\)[^\n]*\\(?:0\\|1\\|2\\|3\\|4\\|dyad\\) : 0\n.*\n)\\(?:\n\\|$\\)" body) + (let ((s1 (substring body 0 (match-beginning 0))) + (s2 (match-string 0 body)) + (s3 (substring body (match-end 0)))) + (concat + (if (string= s1 "") + "" + (concat (org-babel-J-interleave-echos s1) + "\necho','\n")) + s2 + "\necho','\n" + (org-babel-J-interleave-echos-except-functions s3))) + (org-babel-J-interleave-echos body))) + +(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'" + (message "executing J source code block") + (let* ((processed-params (org-babel-process-params params)) + (sessionp (cdr (assoc :session params))) + (session (org-babel-j-initiate-session sessionp)) + (vars (nth 2 processed-params)) + (result-params (nth 3 processed-params)) + (result-type (nth 4 processed-params)) + (full-body (org-babel-expand-body:J + body params processed-params)) + (tmp-script-file (org-babel-temp-file "J-src"))) + (org-babel-J-strip-whitespace + (if (string= sessionp "none") + (progn + (with-temp-file tmp-script-file + (insert full-body)) + (org-babel-eval (format "jconsole < %s" tmp-script-file) "")) + (org-babel-J-eval-string full-body))))) + +(defun org-babel-J-eval-string (str) + "Sends STR to the `j-console-cmd' session and exectues it." + (let ((session (j-console-ensure-session))) + (with-current-buffer (process-buffer session) + (goto-char (point-max)) + (insert (format "\n%s\n" str)) + (let ((beg (point))) + (comint-send-input) + (sit-for .1) + (buffer-substring-no-properties + beg (point-max)))))) + +(defun org-babel-J-strip-whitespace (str) + "Remove whitespace from jconsole output STR." + (mapconcat + #'identity + (delete "" (mapcar + #'org-babel-J-print-block + (split-string str "^ *,\n" t))) + "\n\n")) + +(defun obj-get-string-alignment (str) + "Return a number to describe STR alignment. +STR represents a table. +Positive/negative/zero result means right/left/undetermined. +Don't trust first line." + (let* ((str (org-trim str)) + (lines (split-string str "\n" t)) + n1 n2) + (cond ((<= (length lines) 1) + 0) + ((= (length lines) 2) + ;; numbers are right-aligned + (if (and + (numberp (read (car lines))) + (numberp (read (cadr lines))) + (setq n1 (obj-match-second-space-right (nth 0 lines))) + (setq n2 (obj-match-second-space-right (nth 1 lines)))) + n2 + 0)) + ((not (obj-match-second-space-left (nth 0 lines))) + 0) + ((and + (setq n1 (obj-match-second-space-left (nth 1 lines))) + (setq n2 (obj-match-second-space-left (nth 2 lines))) + (= n1 n2)) + n1) + ((and + (setq n1 (obj-match-second-space-right (nth 1 lines))) + (setq n2 (obj-match-second-space-right (nth 2 lines))) + (= n1 n2)) + (- n1)) + (t 0)))) + +(defun org-babel-J-print-block (x) + "Prettify jconsole output X." + (let* ((x (org-trim x)) + (a (obj-get-string-alignment x)) + (lines (split-string x "\n" t)) + b) + (cond ((< a 0) + (setq b (obj-match-second-space-right (nth 0 lines))) + (concat (make-string (+ a b) ? ) x)) + ((> a 0) + (setq b (obj-match-second-space-left (nth 0 lines))) + (concat (make-string (- a b) ? ) x)) + (t x)))) + +(defun obj-match-second-space-left (s) + "Return position of leftmost space in second space block of S or nil." + (and (string-match "^ *[^ ]+\\( \\)" s) + (match-beginning 1))) + +(defun obj-match-second-space-right (s) + "Return position of rightmost space in second space block of S or nil." + (and (string-match "^ *[^ ]+ *\\( \\)[^ ]" s) + (match-beginning 1))) + +(defun obj-string-match-m (regexp string &optional start) + "Call (string-match REGEXP STRING START). +REGEXP is modified so that .* matches newlines as well." + (string-match + (replace-regexp-in-string "\\.\\*" "[\0-\377[:nonascii:]]*" regexp) + string + start)) + +(defun org-babel-j-initiate-session (&optional session) + "Initiate a J session. +SESSION is a parameter given by org-babel." + (unless (string= session "none") + (require 'j-console) + (j-console-ensure-session))) + +(provide 'ob-J) + +;;; ob-J.el ends here diff --git a/elpa/org-20150629/ob-R.el b/elpa/org-20160215/ob-R.el similarity index 67% rename from elpa/org-20150629/ob-R.el rename to elpa/org-20160215/ob-R.el index b97fd912..4b37c185 100644 --- a/elpa/org-20150629/ob-R.el +++ b/elpa/org-20160215/ob-R.el @@ -1,6 +1,6 @@ ;;; ob-R.el --- org-babel functions for R code evaluation -;; Copyright (C) 2009-2014 Free Software Foundation, Inc. +;; Copyright (C) 2009-2016 Free Software Foundation, Inc. ;; Author: Eric Schulte ;; Dan Davison @@ -35,8 +35,11 @@ (declare-function inferior-ess-send-input "ext:ess-inf" ()) (declare-function ess-make-buffer-current "ext:ess-inf" ()) (declare-function ess-eval-buffer "ext:ess-inf" (vis)) +(declare-function ess-wait-for-process "ext:ess-inf" + (proc &optional sec-prompt wait force-redisplay)) (declare-function org-number-sequence "org-compat" (from &optional to inc)) (declare-function org-remove-if-not "org" (predicate seq)) +(declare-function org-every "org" (pred seq)) (defconst org-babel-header-args:R '((width . :any) @@ -60,12 +63,25 @@ (useDingbats . :any) (horizontal . :any) (results . ((file list vector table scalar verbatim) - (raw org html latex code pp wrap) - (replace silent append prepend) + (raw html latex org code pp drawer) + (replace silent none append prepend) (output value graphics)))) "R-specific header arguments.") +(defconst ob-R-safe-header-args + (append org-babel-safe-header-args + '(:width :height :bg :units :pointsize :antialias :quality + :compression :res :type :family :title :fonts + :version :paper :encoding :pagecentre :colormodel + :useDingbats :horizontal)) + "Header args which are safe for R babel blocks. + +See `org-babel-safe-header-args' for documentation of the format of +this variable.") + (defvar org-babel-default-header-args:R '()) +(put 'org-babel-default-header-args:R 'safe-local-variable + (org-babel-header-args-safe-fn ob-R-safe-header-args)) (defcustom org-babel-R-command "R --slave --no-save" "Name of command to use for executing R code." @@ -73,34 +89,67 @@ :version "24.1" :type 'string) -(defvar ess-local-process-name) ; dynamically scoped +(defvar ess-current-process-name) ; dynamically scoped +(defvar ess-local-process-name) ; dynamically scoped (defun org-babel-edit-prep:R (info) (let ((session (cdr (assoc :session (nth 2 info))))) (when (and session (string-match "^\\*\\(.+?\\)\\*$" session)) (save-match-data (org-babel-R-initiate-session session nil))))) +;; The usage of utils::read.table() ensures that the command +;; read.table() can be found even in circumstances when the utils +;; package is not in the search path from R. +(defconst ob-R-transfer-variable-table-with-header + "%s <- local({ + con <- textConnection( + %S + ) + res <- utils::read.table( + con, + header = %s, + row.names = %s, + sep = \"\\t\", + as.is = TRUE + ) + close(con) + res + })" + "R code used to transfer a table defined as a variable from org to R. + +This function is used when the table contains a header.") + +(defconst ob-R-transfer-variable-table-without-header + "%s <- local({ + con <- textConnection( + %S + ) + res <- utils::read.table( + con, + header = %s, + row.names = %s, + sep = \"\\t\", + as.is = TRUE, + fill = TRUE, + col.names = paste(\"V\", seq_len(%d), sep =\"\") + ) + close(con) + res + })" + "R code used to transfer a table defined as a variable from org to R. + +This function is used when the table does not contain a header.") + (defun org-babel-expand-body:R (body params &optional graphics-file) "Expand BODY according to PARAMS, return the expanded body." - (let ((graphics-file - (or graphics-file (org-babel-R-graphical-output-file params)))) - (mapconcat - #'identity - (let ((inside - (append - (when (cdr (assoc :prologue params)) - (list (cdr (assoc :prologue params)))) - (org-babel-variable-assignments:R params) - (list body) - (when (cdr (assoc :epilogue params)) - (list (cdr (assoc :epilogue params))))))) - (if graphics-file - (append - (list (org-babel-R-construct-graphics-device-call - graphics-file params)) - inside - (list "dev.off()")) - inside)) - "\n"))) + (mapconcat 'identity + (append + (when (cdr (assoc :prologue params)) + (list (cdr (assoc :prologue params)))) + (org-babel-variable-assignments:R params) + (list body) + (when (cdr (assoc :epilogue params)) + (list (cdr (assoc :epilogue params))))) + "\n")) (defun org-babel-execute:R (body params) "Execute a block of R code. @@ -112,8 +161,20 @@ This function is called by `org-babel-execute-src-block'." (cdr (assoc :session params)) params)) (colnames-p (cdr (assoc :colnames params))) (rownames-p (cdr (assoc :rownames params))) - (graphics-file (org-babel-R-graphical-output-file params)) - (full-body (org-babel-expand-body:R body params graphics-file)) + (graphics-file (and (member "graphics" (assq :result-params params)) + (org-babel-graphical-output-file params))) + (full-body + (let ((inside + (list (org-babel-expand-body:R body params graphics-file)))) + (mapconcat 'identity + (if graphics-file + (append + (list (org-babel-R-construct-graphics-device-call + graphics-file params)) + inside + (list "},error=function(e){plot(x=-1:1, y=-1:1, type='n', xlab='', ylab='', axes=FALSE); text(x=0, y=0, labels=e$message, col='red'); paste('ERROR', e$message, sep=' : ')}); dev.off()")) + inside) + "\n"))) (result (org-babel-R-evaluate session full-body result-type result-params @@ -148,7 +209,7 @@ This function is called by `org-babel-execute-src-block'." (defun org-babel-variable-assignments:R (params) "Return list of R statements assigning the block's variables." - (let ((vars (mapcar #'cdr (org-babel-get-header params :var)))) + (let ((vars (mapcar 'cdr (org-babel-get-header params :var)))) (mapcar (lambda (pair) (org-babel-R-assign-elisp @@ -175,33 +236,23 @@ This function is called by `org-babel-execute-src-block'." (if (listp value) (let* ((lengths (mapcar 'length (org-remove-if-not 'sequencep value))) (max (if lengths (apply 'max lengths) 0)) - (min (if lengths (apply 'min lengths) 0)) - (transition-file (org-babel-temp-file "R-import-"))) + (min (if lengths (apply 'min lengths) 0))) ;; Ensure VALUE has an orgtbl structure (depth of at least 2). (unless (listp (car value)) (setq value (list value))) - (with-temp-file transition-file - (insert - (orgtbl-to-tsv value '(:fmt org-babel-R-quote-tsv-field)) - "\n")) - (let ((file (org-babel-process-file-name transition-file 'noquote)) + (let ((file (orgtbl-to-tsv value '(:fmt org-babel-R-quote-tsv-field))) (header (if (or (eq (nth 1 value) 'hline) colnames-p) "TRUE" "FALSE")) (row-names (if rownames-p "1" "NULL"))) (if (= max min) - (format "%s <- read.table(\"%s\", - header=%s, - row.names=%s, - sep=\"\\t\", - as.is=TRUE)" name file header row-names) - (format "%s <- read.table(\"%s\", - header=%s, - row.names=%s, - sep=\"\\t\", - as.is=TRUE, - fill=TRUE, - col.names = paste(\"V\", seq_len(%d), sep =\"\"))" + (format ob-R-transfer-variable-table-with-header + name file header row-names) + (format ob-R-transfer-variable-table-without-header name file header row-names max)))) - (format "%s <- %s" name (org-babel-R-quote-tsv-field value)))) + (cond ((integerp value) (format "%s <- %s" name (concat (number-to-string value) "L"))) + ((floatp value) (format "%s <- %s" name value)) + ((stringp value) (format "%s <- %S" name (org-no-properties value))) + (t (format "%s <- %S" name (prin1-to-string value)))))) + (defvar ess-ask-for-ess-directory) ; dynamically scoped (defun org-babel-R-initiate-session (session params) @@ -209,7 +260,8 @@ This function is called by `org-babel-execute-src-block'." (unless (string= session "none") (let ((session (or session "*R*")) (ess-ask-for-ess-directory - (and (and (boundp 'ess-ask-for-ess-directory) ess-ask-for-ess-directory) + (and (boundp 'ess-ask-for-ess-directory) + ess-ask-for-ess-directory (not (cdr (assoc :dir params)))))) (if (org-babel-comint-buffer-livep session) session @@ -218,6 +270,10 @@ This function is called by `org-babel-execute-src-block'." ;; Session buffer exists, but with dead process (set-buffer session)) (require 'ess) (R) + (let ((R-proc (get-process (or ess-local-process-name + ess-current-process-name)))) + (while (process-get R-proc 'callbacks) + (ess-wait-for-process R-proc))) (rename-buffer (if (bufferp session) (buffer-name session) @@ -234,11 +290,6 @@ current code buffer." (process-name (get-buffer-process session))) (ess-make-buffer-current)) -(defun org-babel-R-graphical-output-file (params) - "Name of file to which R should send graphical output." - (and (member "graphics" (cdr (assq :result-params params))) - (cdr (assq :file params)))) - (defvar org-babel-R-graphics-devices '((:bmp "bmp" "filename") (:jpg "jpeg" "filename") @@ -280,14 +331,43 @@ Each member of this list is a list with three members: (substring (symbol-name (car pair)) 1) (cdr pair)) "")) params "")) - (format "%s(%s=\"%s\"%s%s%s)" + (format "%s(%s=\"%s\"%s%s%s); tryCatch({" device filearg out-file args (if extra-args "," "") (or extra-args "")))) -(defvar org-babel-R-eoe-indicator "'org_babel_R_eoe'") -(defvar org-babel-R-eoe-output "[1] \"org_babel_R_eoe\"") - -(defvar org-babel-R-write-object-command "{function(object,transfer.file){object;invisible(if(inherits(try({tfile<-tempfile();write.table(object,file=tfile,sep=\"\\t\",na=\"nil\",row.names=%s,col.names=%s,quote=FALSE);file.rename(tfile,transfer.file)},silent=TRUE),\"try-error\")){if(!file.exists(transfer.file))file.create(transfer.file)})}}(object=%s,transfer.file=\"%s\")") +(defconst org-babel-R-eoe-indicator "'org_babel_R_eoe'") +(defconst org-babel-R-eoe-output "[1] \"org_babel_R_eoe\"") + +(defconst org-babel-R-write-object-command "{ + function(object,transfer.file) { + object + invisible( + if ( + inherits( + try( + { + tfile<-tempfile() + write.table(object, file=tfile, sep=\"\\t\", + na=\"nil\",row.names=%s,col.names=%s, + quote=FALSE) + file.rename(tfile,transfer.file) + }, + silent=TRUE), + \"try-error\")) + { + if(!file.exists(transfer.file)) + file.create(transfer.file) + } + ) + } +}(object=%s,transfer.file=\"%s\")" + "A template for an R command to evaluate a block of code and write the result to a file. + +Has four %s escapes to be filled in: +1. Row names, \"TRUE\" or \"FALSE\" +2. Column names, \"TRUE\" or \"FALSE\" +3. The code to be run (must be an expression, not a statement) +4. The name of the file to write to") (defun org-babel-R-evaluate (session body result-type result-params column-names-p row-names-p) @@ -301,8 +381,8 @@ Each member of this list is a list with three members: (defun org-babel-R-evaluate-external-process (body result-type result-params column-names-p row-names-p) "Evaluate BODY in external R 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." (case result-type (value @@ -329,8 +409,8 @@ last statement in BODY, as elisp." (defun org-babel-R-evaluate-session (session body result-type result-params column-names-p row-names-p) "Evaluate BODY 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." (case result-type (value @@ -358,7 +438,7 @@ last statement in BODY, as elisp." column-names-p))) (output (mapconcat - #'org-babel-chomp + 'org-babel-chomp (butlast (delq nil (mapcar @@ -370,7 +450,7 @@ last statement in BODY, as elisp." (substring line (match-end 1)) line)) (org-babel-comint-with-output (session org-babel-R-eoe-output) - (insert (mapconcat #'org-babel-chomp + (insert (mapconcat 'org-babel-chomp (list body org-babel-R-eoe-indicator) "\n")) (inferior-ess-send-input)))))) "\n")))) diff --git a/elpa/org-20160215/ob-abc.el b/elpa/org-20160215/ob-abc.el new file mode 100644 index 00000000..36ad55d0 --- /dev/null +++ b/elpa/org-20160215/ob-abc.el @@ -0,0 +1,94 @@ +;;; ob-abc.el --- org-babel functions for template evaluation + +;; Copyright (C) 2013-2016 Free Software Foundation, Inc. + +;; Author: William Waites +;; Keywords: literate programming, music +;; Homepage: http://www.tardis.ed.ac.uk/wwaites +;; Version: 0.01 + +;;; License: + +;; 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, 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 GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +;; Boston, MA 02110-1301, USA. + +;;; Commentary: + +;;; This file adds support to Org Babel for music in ABC notation. +;;; It requires that the abcm2ps program is installed. +;;; See http://moinejf.free.fr/ + +(require 'ob) + +;; optionally define a file extension for this language +(add-to-list 'org-babel-tangle-lang-exts '("abc" . "abc")) + +;; optionally declare default header arguments for this language +(defvar org-babel-default-header-args:abc + '((:results . "file") (:exports . "results")) + "Default arguments to use when evaluating an ABC source block.") + +(defun org-babel-expand-body:abc (body params) + "Expand BODY according to PARAMS, return the expanded body." + (let ((vars (mapcar #'cdr (org-babel-get-header params :var)))) + (mapc + (lambda (pair) + (let ((name (symbol-name (car pair))) + (value (cdr pair))) + (setq body + (replace-regexp-in-string + (concat "\$" (regexp-quote name)) + (if (stringp value) value (format "%S" value)) + body)))) + vars) + body)) + +(defun org-babel-execute:abc (body params) + "Execute a block of ABC code with org-babel. This function is + called by `org-babel-execute-src-block'" + (message "executing Abc source code block") + (let* ((result-params (split-string (or (cdr (assoc :results params))))) + (cmdline (cdr (assoc :cmdline params))) + (out-file ((lambda (el) + (or el + (error "abc code block requires :file header argument"))) + (replace-regexp-in-string "\.pdf$" ".ps" (cdr (assoc :file params))))) + (in-file (org-babel-temp-file "abc-")) + (render (concat "abcm2ps" " " cmdline + " -O " (org-babel-process-file-name out-file) + " " (org-babel-process-file-name in-file)))) + (with-temp-file in-file (insert (org-babel-expand-body:abc body params))) + (org-babel-eval render "") + ;;; handle where abcm2ps changes the file name (to support multiple files + (when (or (string= (file-name-extension out-file) "eps") + (string= (file-name-extension out-file) "svg")) + (rename-file (concat + (file-name-sans-extension out-file) "001." + (file-name-extension out-file)) + out-file t)) + ;;; if we were asked for a pdf... + (when (string= (file-name-extension (cdr (assoc :file params))) "pdf") + (org-babel-eval (concat "ps2pdf" " " out-file " " (cdr (assoc :file params))) "")) + ;;; indicate that the file has been written + nil)) + +;; This function should be used to assign any variables in params in +;; the context of the session environment. +(defun org-babel-prep-session:abc (session params) + "Return an error because abc does not support sessions." + (error "ABC does not support sessions")) + +(provide 'ob-abc) +;;; ob-abc.el ends here diff --git a/elpa/org-20150629/ob-asymptote.el b/elpa/org-20160215/ob-asymptote.el similarity index 96% rename from elpa/org-20150629/ob-asymptote.el rename to elpa/org-20160215/ob-asymptote.el index 21c0a170..f6492aec 100644 --- a/elpa/org-20150629/ob-asymptote.el +++ b/elpa/org-20160215/ob-asymptote.el @@ -1,6 +1,6 @@ ;;; ob-asymptote.el --- org-babel functions for asymptote evaluation -;; Copyright (C) 2009-2014 Free Software Foundation, Inc. +;; Copyright (C) 2009-2016 Free Software Foundation, Inc. ;; Author: Eric Schulte ;; Keywords: literate programming, reproducible research @@ -45,9 +45,6 @@ (require 'ob) (eval-when-compile (require 'cl)) -(declare-function orgtbl-to-generic "org-table" (table params)) -(declare-function org-combine-plists "org" (&rest plists)) - (defvar org-babel-tangle-lang-exts) (add-to-list 'org-babel-tangle-lang-exts '("asymptote" . "asy")) diff --git a/elpa/org-20150629/ob-awk.el b/elpa/org-20160215/ob-awk.el similarity index 85% rename from elpa/org-20150629/ob-awk.el rename to elpa/org-20160215/ob-awk.el index ed98afdf..021dd78c 100644 --- a/elpa/org-20150629/ob-awk.el +++ b/elpa/org-20160215/ob-awk.el @@ -1,6 +1,6 @@ ;;; ob-awk.el --- org-babel functions for awk evaluation -;; Copyright (C) 2011-2014 Free Software Foundation, Inc. +;; Copyright (C) 2011-2016 Free Software Foundation, Inc. ;; Author: Eric Schulte ;; Keywords: literate programming, reproducible research @@ -46,9 +46,6 @@ (defun org-babel-expand-body:awk (body params) "Expand BODY according to PARAMS, return the expanded body." - (dolist (pair (mapcar #'cdr (org-babel-get-header params :var))) - (setf body (replace-regexp-in-string - (regexp-quote (format "$%s" (car pair))) (cdr pair) body))) body) (defun org-babel-execute:awk (body params) @@ -68,10 +65,17 @@ called by `org-babel-execute-src-block'" (with-temp-file tmp (insert (org-babel-awk-var-to-awk res))) tmp)))) - (cmd (mapconcat #'identity (remove nil (list org-babel-awk-command - "-f" code-file - cmd-line - in-file)) + (cmd (mapconcat #'identity + (append + (list org-babel-awk-command + "-f" code-file cmd-line) + (mapcar (lambda (pair) + (format "-v %s='%s'" + (cadr pair) + (org-babel-awk-var-to-awk + (cddr pair)))) + (org-babel-get-header params :var)) + (list in-file)) " "))) (org-babel-reassemble-table (let ((results @@ -101,11 +105,6 @@ called by `org-babel-execute-src-block'" (mapconcat echo-var var "\n")) (t (funcall echo-var var))))) -(defun org-babel-awk-table-or-string (results) - "If the results look like a table, then convert them into an -Emacs-lisp table, otherwise return the results as a string." - (org-babel-script-escape results)) - (provide 'ob-awk) diff --git a/elpa/org-20150629/ob-calc.el b/elpa/org-20160215/ob-calc.el similarity index 98% rename from elpa/org-20150629/ob-calc.el rename to elpa/org-20160215/ob-calc.el index cdb528a5..f5e70de9 100644 --- a/elpa/org-20150629/ob-calc.el +++ b/elpa/org-20160215/ob-calc.el @@ -1,6 +1,6 @@ ;;; ob-calc.el --- org-babel functions for calc code evaluation -;; Copyright (C) 2010-2014 Free Software Foundation, Inc. +;; Copyright (C) 2010-2016 Free Software Foundation, Inc. ;; Author: Eric Schulte ;; Keywords: literate programming, reproducible research diff --git a/elpa/org-20150629/ob-clojure.el b/elpa/org-20160215/ob-clojure.el similarity index 50% rename from elpa/org-20150629/ob-clojure.el rename to elpa/org-20160215/ob-clojure.el index 78f3c6d3..5b023e67 100644 --- a/elpa/org-20150629/ob-clojure.el +++ b/elpa/org-20160215/ob-clojure.el @@ -1,9 +1,9 @@ ;;; ob-clojure.el --- org-babel functions for clojure evaluation -;; Copyright (C) 2009-2014 Free Software Foundation, Inc. +;; Copyright (C) 2009-2016 Free Software Foundation, Inc. -;; Author: Joel Boehland -;; Eric Schulte +;; Author: Joel Boehland, Eric Schulte, Oleh Krehel +;; ;; Keywords: literate programming, reproducible research ;; Homepage: http://orgmode.org @@ -24,21 +24,30 @@ ;;; Commentary: -;; Support for evaluating clojure code, relies on slime for all eval. +;; Support for evaluating clojure code -;;; Requirements: +;; Requirements: ;; - clojure (at least 1.2.0) ;; - clojure-mode -;; - slime +;; - either cider or SLIME -;; By far, the best way to install these components is by following +;; For Cider, see https://github.com/clojure-emacs/cider + +;; For SLIME, the best way to install these components is by following ;; the directions as set out by Phil Hagelberg (Technomancy) on the ;; web page: http://technomancy.us/126 ;;; Code: (require 'ob) - +(eval-when-compile + (require 'cl)) + +(declare-function cider-current-connection "ext:cider-client" (&optional type)) +(declare-function cider-current-session "ext:cider-client" ()) +(declare-function nrepl-dict-get "ext:nrepl-client" (dict key)) +(declare-function nrepl-sync-request:eval "ext:nrepl-client" + (input connection session &optional ns)) (declare-function slime-eval "ext:slime" (sexp &optional package)) (defvar org-babel-tangle-lang-exts) @@ -47,6 +56,15 @@ (defvar org-babel-default-header-args:clojure '()) (defvar org-babel-header-args:clojure '((package . :any))) +(defcustom org-babel-clojure-backend + (cond ((featurep 'cider) 'cider) + (t 'slime)) + "Backend used to evaluate Clojure code blocks." + :group 'org-babel + :type '(choice + (const :tag "cider" cider) + (const :tag "SLIME" slime))) + (defun org-babel-expand-body:clojure (body params) "Expand BODY according to PARAMS, return the expanded body." (let* ((vars (mapcar #'cdr (org-babel-get-header params :var))) @@ -61,35 +79,41 @@ vars "\n ") "]\n" body ")") body)))) - (cond ((or (member "code" result-params) (member "pp" result-params)) - (format (concat "(let [org-mode-print-catcher (java.io.StringWriter.)] " - "(clojure.pprint/with-pprint-dispatch clojure.pprint/%s-dispatch " - "(clojure.pprint/pprint (do %s) org-mode-print-catcher) " - "(str org-mode-print-catcher)))") - (if (member "code" result-params) "code" "simple") body)) - ;; if (:results output), collect printed output - ((member "output" result-params) - (format "(clojure.core/with-out-str %s)" body)) - (t body)))) + (if (or (member "code" result-params) + (member "pp" result-params)) + (format "(clojure.pprint/pprint (do %s))" body) + body))) (defun org-babel-execute:clojure (body params) "Execute a block of Clojure code with Babel." - (require 'slime) - (with-temp-buffer - (insert (org-babel-expand-body:clojure body params)) - (let ((result - (slime-eval - `(swank:eval-and-grab-output - ,(buffer-substring-no-properties (point-min) (point-max))) - (cdr (assoc :package params))))) - (let ((result-params (cdr (assoc :result-params params)))) - (org-babel-result-cond result-params - result - (condition-case nil (org-babel-script-escape result) - (error result))))))) + (let ((expanded (org-babel-expand-body:clojure body params)) + result) + (case org-babel-clojure-backend + (cider + (require 'cider) + (let ((result-params (cdr (assoc :result-params params)))) + (setq result + (nrepl-dict-get + (nrepl-sync-request:eval + expanded (cider-current-connection) (cider-current-session)) + (if (or (member "output" result-params) + (member "pp" result-params)) + "out" + "value"))))) + (slime + (require 'slime) + (with-temp-buffer + (insert expanded) + (setq result + (slime-eval + `(swank:eval-and-grab-output + ,(buffer-substring-no-properties (point-min) (point-max))) + (cdr (assoc :package params))))))) + (org-babel-result-cond (cdr (assoc :result-params params)) + result + (condition-case nil (org-babel-script-escape result) + (error result))))) (provide 'ob-clojure) - - ;;; ob-clojure.el ends here diff --git a/elpa/org-20150629/ob-comint.el b/elpa/org-20160215/ob-comint.el similarity index 73% rename from elpa/org-20150629/ob-comint.el rename to elpa/org-20160215/ob-comint.el index 40bfaf7c..8145d2cf 100644 --- a/elpa/org-20150629/ob-comint.el +++ b/elpa/org-20160215/ob-comint.el @@ -1,6 +1,6 @@ ;;; ob-comint.el --- org-babel functions for interaction with comint buffers -;; Copyright (C) 2009-2014 Free Software Foundation, Inc. +;; Copyright (C) 2009-2016 Free Software Foundation, Inc. ;; Author: Eric Schulte ;; Keywords: literate programming, reproducible research, comint @@ -48,12 +48,13 @@ BUFFER is checked with `org-babel-comint-buffer-livep'. BODY is executed inside the protection of `save-excursion' and `save-match-data'." (declare (indent 1)) - `(save-excursion + `(progn + (unless (org-babel-comint-buffer-livep ,buffer) + (error "Buffer %s does not exist or has no process" ,buffer)) (save-match-data - (unless (org-babel-comint-buffer-livep ,buffer) - (error "Buffer %s does not exist or has no process" ,buffer)) - (set-buffer ,buffer) - ,@body))) + (with-current-buffer ,buffer + (let ((comint-input-filter (lambda (input) nil))) + ,@body))))) (def-edebug-spec org-babel-comint-in-buffer (form body)) (defmacro org-babel-comint-with-output (meta &rest body) @@ -69,46 +70,42 @@ elements are optional. This macro ensures that the filter is removed in case of an error or user `keyboard-quit' during execution of body." (declare (indent 1)) - (let ((buffer (car meta)) - (eoe-indicator (cadr meta)) - (remove-echo (cadr (cdr meta))) - (full-body (cadr (cdr (cdr meta))))) + (let ((buffer (nth 0 meta)) + (eoe-indicator (nth 1 meta)) + (remove-echo (nth 2 meta)) + (full-body (nth 3 meta))) `(org-babel-comint-in-buffer ,buffer - (let ((string-buffer "") dangling-text raw) - ;; setup filter - (setq comint-output-filter-functions + (let* ((string-buffer "") + (comint-output-filter-functions (cons (lambda (text) (setq string-buffer (concat string-buffer text))) comint-output-filter-functions)) - (unwind-protect - (progn - ;; got located, and save dangling text - (goto-char (process-mark (get-buffer-process (current-buffer)))) - (let ((start (point)) - (end (point-max))) - (setq dangling-text (buffer-substring start end)) - (delete-region start end)) - ;; pass FULL-BODY to process - ,@body - ;; wait for end-of-evaluation indicator - (while (progn - (goto-char comint-last-input-end) - (not (save-excursion - (and (re-search-forward - (regexp-quote ,eoe-indicator) nil t) - (re-search-forward - comint-prompt-regexp nil t))))) - (accept-process-output (get-buffer-process (current-buffer))) - ;; thought the following this would allow async - ;; background running, but I was wrong... - ;; (run-with-timer .5 .5 'accept-process-output - ;; (get-buffer-process (current-buffer))) - ) - ;; replace cut dangling text - (goto-char (process-mark (get-buffer-process (current-buffer)))) - (insert dangling-text)) - ;; remove filter - (setq comint-output-filter-functions - (cdr comint-output-filter-functions))) + dangling-text raw) + ;; got located, and save dangling text + (goto-char (process-mark (get-buffer-process (current-buffer)))) + (let ((start (point)) + (end (point-max))) + (setq dangling-text (buffer-substring start end)) + (delete-region start end)) + ;; pass FULL-BODY to process + ,@body + ;; wait for end-of-evaluation indicator + (while (progn + (goto-char comint-last-input-end) + (not (save-excursion + (and (re-search-forward + (regexp-quote ,eoe-indicator) nil t) + (re-search-forward + comint-prompt-regexp nil t))))) + (accept-process-output (get-buffer-process (current-buffer))) + ;; thought the following this would allow async + ;; background running, but I was wrong... + ;; (run-with-timer .5 .5 'accept-process-output + ;; (get-buffer-process (current-buffer))) + ) + ;; replace cut dangling text + (goto-char (process-mark (get-buffer-process (current-buffer)))) + (insert dangling-text) + ;; remove echo'd FULL-BODY from input (if (and ,remove-echo ,full-body (string-match @@ -151,7 +148,7 @@ FILE exists at end of evaluation." (if (file-exists-p file) (delete-file file)) (process-send-string (get-buffer-process buffer) - (if (string-match "\n$" string) string (concat string "\n"))) + (if (= (aref string (1- (length string))) ?\n) string (concat string "\n"))) ;; From Tramp 2.1.19 the following cache flush is not necessary (if (file-remote-p default-directory) (let (v) diff --git a/elpa/org-20160215/ob-coq.el b/elpa/org-20160215/ob-coq.el new file mode 100644 index 00000000..210f1a25 --- /dev/null +++ b/elpa/org-20160215/ob-coq.el @@ -0,0 +1,77 @@ +;;; ob-coq.el --- org-babel functions for Coq + +;; Copyright (C) 2010-2016 Free Software Foundation, Inc. + +;; Author: Eric Schulte +;; Keywords: literate programming, reproducible research +;; Homepage: http://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 . + +;;; Commentary: + +;; Rudimentary support for evaluating Coq code blocks. Currently only +;; session evaluation is supported. Requires both coq.el and +;; coq-inferior.el, both of which are distributed with Coq. +;; +;; http://coq.inria.fr/ + +;;; Code: +(require 'ob) + +(declare-function run-coq "ext:coq-inferior.el" (cmd)) +(declare-function coq-proc "ext:coq-inferior.el" ()) + +(defvar org-babel-coq-buffer "*coq*" + "Buffer in which to evaluate coq code blocks.") + +(defvar org-babel-coq-eoe "org-babel-coq-eoe") + +(defun org-babel-coq-clean-prompt (string) + (if (string-match "^[^[:space:]]+ < " string) + (substring string 0 (match-beginning 0)) + string)) + +(defun org-babel-execute:coq (body params) + (let ((full-body (org-babel-expand-body:generic body params)) + (session (org-babel-coq-initiate-session)) + (pt (lambda () + (marker-position + (process-mark (get-buffer-process (current-buffer))))))) + (org-babel-coq-clean-prompt + (org-babel-comint-in-buffer session + (let ((start (funcall pt))) + (with-temp-buffer + (insert full-body) + (comint-send-region (coq-proc) (point-min) (point-max)) + (comint-send-string (coq-proc) + (if (string= (buffer-substring (- (point-max) 1) (point-max)) ".") + "\n" + ".\n"))) + (while (equal start (funcall pt)) (sleep-for 0.1)) + (buffer-substring start (funcall pt))))))) + +(defun org-babel-coq-initiate-session () + "Initiate a coq session. +If there is not a current inferior-process-buffer in SESSION then +create one. Return the initialized session." + (unless (fboundp 'run-coq) + (error "`run-coq' not defined, load coq-inferior.el")) + (save-window-excursion (run-coq "coqtop")) + (sit-for 0.1) + (get-buffer org-babel-coq-buffer)) + +(provide 'ob-coq) diff --git a/elpa/org-20150629/ob-core.el b/elpa/org-20160215/ob-core.el similarity index 76% rename from elpa/org-20150629/ob-core.el rename to elpa/org-20160215/ob-core.el index a6ffcc48..fcd15c42 100644 --- a/elpa/org-20150629/ob-core.el +++ b/elpa/org-20160215/ob-core.el @@ -1,6 +1,6 @@ ;;; ob-core.el --- working with code blocks in org-mode -;; Copyright (C) 2009-2014 Free Software Foundation, Inc. +;; Copyright (C) 2009-2016 Free Software Foundation, Inc. ;; Authors: Eric Schulte ;; Dan Davison @@ -33,12 +33,17 @@ (if (memq system-type '(windows-nt cygwin)) ".exe" nil)) + ;; dynamically scoped for tramp (defvar org-babel-call-process-region-original nil) -(defvar org-src-lang-modes) (defvar org-babel-library-of-babel) -(declare-function show-all "outline" ()) +(defvar org-edit-src-content-indentation) +(defvar org-src-lang-modes) + +(declare-function outline-show-all "outline" ()) (declare-function org-every "org" (pred seq)) +(declare-function org-get-indentation "org" (&optional line)) +(declare-function org-remove-indentation "org" (code &optional n)) (declare-function org-reduce "org" (CL-FUNC CL-SEQ &rest CL-KEYS)) (declare-function org-mark-ring-push "org" (&optional pos buffer)) (declare-function tramp-compat-make-temp-file "tramp-compat" @@ -48,9 +53,8 @@ (declare-function tramp-file-name-host "tramp" (vec)) (declare-function with-parsed-tramp-file-name "tramp" (filename var &rest body)) (declare-function org-icompleting-read "org" (&rest args)) -(declare-function org-edit-src-code "org-src" - (&optional context code edit-buffer-name quietp)) -(declare-function org-edit-src-exit "org-src" (&optional context)) +(declare-function org-edit-src-code "org-src" (&optional code edit-buffer-name)) +(declare-function org-edit-src-exit "org-src" ()) (declare-function org-open-at-point "org" (&optional in-emacs reference-buffer)) (declare-function org-save-outline-visibility "org-macs" (use-markers &rest body)) (declare-function org-outline-overlay-data "org" (&optional use-markers)) @@ -98,6 +102,11 @@ (declare-function org-reverse-string "org" (string)) (declare-function org-element-context "org-element" (&optional element)) (declare-function org-element-type "org-element" (element)) +(declare-function org-element-at-point "org-element" ()) +(declare-function org-element-normalize-string "org-element" (s)) +(declare-function org-element-property "org-element" (property element)) +(declare-function org-every "org" (pred seq)) +(declare-function org-macro-escape-arguments "org-macro" (&rest args)) (defgroup org-babel nil "Code block evaluation and management in `org-mode' documents." @@ -106,6 +115,7 @@ (defcustom org-confirm-babel-evaluate t "Confirm before evaluation. +\\\ Require confirmation before interactively evaluating code blocks in Org-mode buffers. The default value of this variable is t, meaning confirmation is required for any code block @@ -118,10 +128,11 @@ execution or nil if no prompt is required. Warning: Disabling confirmation may result in accidental evaluation of potentially harmful code. It may be advisable -remove code block execution from C-c C-c as further protection +remove code block execution from \\[org-ctrl-c-ctrl-c] \ +as further protection against accidental code block evaluation. The `org-babel-no-eval-on-ctrl-c-ctrl-c' variable can be used to -remove code block execution from the C-c C-c keybinding." +remove code block execution from the \\[org-ctrl-c-ctrl-c] keybinding." :group 'org-babel :version "24.1" :type '(choice boolean function)) @@ -129,19 +140,24 @@ remove code block execution from the C-c C-c keybinding." (put 'org-confirm-babel-evaluate 'safe-local-variable (lambda (x) (eq x t))) (defcustom org-babel-no-eval-on-ctrl-c-ctrl-c nil - "Remove code block evaluation from the C-c C-c key binding." + "\\\ +Remove code block evaluation from the \\[org-ctrl-c-ctrl-c] key binding." :group 'org-babel :version "24.1" :type 'boolean) (defcustom org-babel-results-keyword "RESULTS" "Keyword used to name results generated by code blocks. -Should be either RESULTS or NAME however any capitalization may -be used." +It should be \"RESULTS\". However any capitalization may be +used." :group 'org-babel :version "24.4" :package-version '(Org . "8.0") - :type 'string) + :type 'string + :safe (lambda (v) + (and (stringp v) + (eq (compare-strings "RESULTS" nil nil v nil nil t) + t)))) (defcustom org-babel-noweb-wrap-start "<<" "String used to begin a noweb reference in a code block. @@ -160,6 +176,11 @@ See also `org-babel-noweb-wrap-start'." This string must include a \"%s\" which will be replaced by the results." :group 'org-babel :type 'string) +(put 'org-babel-inline-result-wrap + 'safe-local-variable + (lambda (value) + (and (stringp value) + (string-match-p "%s" value)))) (defun org-babel-noweb-wrap (&optional regexp) (concat org-babel-noweb-wrap-start @@ -174,14 +195,6 @@ This string must include a \"%s\" which will be replaced by the results." "^[ \t]*#\\+headers?:[ \t]*\\([^\n]*\\)$" "Regular expression used to match multi-line header arguments.") -(defvar org-babel-src-name-w-name-regexp - (concat org-babel-src-name-regexp - "\\(" - org-babel-multi-line-header-regexp - "\\)*" - "\\([^ ()\f\t\n\r\v]+\\)") - "Regular expression matching source name lines with a name.") - (defvar org-babel-src-block-regexp (concat ;; (1) indentation (2) lang @@ -197,9 +210,9 @@ This string must include a \"%s\" which will be replaced by the results." (defvar org-babel-inline-src-block-regexp (concat ;; (1) replacement target (2) lang - "\\(?:^\\|[^-[:alnum:]]\\)\\(src_\\([^ \f\t\n\r\v]+\\)" + "\\(?:^\\|[^-[:alnum:]]?\\)\\(src_\\([^ \f\t\n\r\v[]+\\)" ;; (3,4) (unused, headers) - "\\(\\|\\[\\(.*?\\)\\]\\)" + "\\(\\|\\[[ \t]*\\(.*?\\)\\]\\)" ;; (5) body "{\\([^\f\n\r\v]+?\\)}\\)") "Regexp used to identify inline src-blocks.") @@ -213,35 +226,24 @@ not match KEY should be returned." (lambda (p) (when (funcall (if others #'not #'identity) (eq (car p) key)) p)) params))) -(defun org-babel-get-inline-src-block-matches() +(defun org-babel-get-inline-src-block-matches () "Set match data if within body of an inline source block. Returns non-nil if match-data set" - (let ((src-at-0-p (save-excursion - (beginning-of-line 1) - (string= "src" (thing-at-point 'word)))) - (first-line-p (= (line-beginning-position) (point-min))) - (orig (point))) - (let ((search-for (cond ((and src-at-0-p first-line-p "src_")) - (first-line-p "[[:punct:] \t]src_") - (t "[[:punct:] \f\t\n\r\v]src_"))) - (lower-limit (if first-line-p - nil - (- (point-at-bol) 1)))) - (save-excursion - (when (or (and src-at-0-p (bobp)) - (and (re-search-forward "}" (point-at-eol) t) - (re-search-backward search-for lower-limit t) - (> orig (point)))) - (when (looking-at org-babel-inline-src-block-regexp) - t )))))) + (save-excursion + (let ((datum (org-element-context))) + (when (eq (org-element-type datum) 'inline-src-block) + (goto-char (org-element-property :begin datum)) + (when (looking-at org-babel-inline-src-block-regexp) + t ))))) (defvar org-babel-inline-lob-one-liner-regexp) -(defun org-babel-get-lob-one-liner-matches() +(defun org-babel-get-lob-one-liner-matches () "Set match data if on line of an lob one liner. Returns non-nil if match-data set" (save-excursion - (unless (= (point) (point-at-bol)) ;; move before inline block - (re-search-backward "[ \f\t\n\r\v]" nil t)) + (let ((datum (org-element-context))) + (when (eq (org-element-type datum) 'inline-babel-call) + (goto-char (org-element-property :begin datum)))) (if (looking-at org-babel-inline-lob-one-liner-regexp) t nil))) @@ -263,23 +265,30 @@ Returns a list (setq info (org-babel-parse-src-block-match)) (setq indent (car (last info))) (setq info (butlast info)) - (while (and (forward-line -1) + (while (and (= 0 (forward-line -1)) (looking-at org-babel-multi-line-header-regexp)) (setf (nth 2 info) (org-babel-merge-params (nth 2 info) (org-babel-parse-header-arguments (match-string 1))))) - (when (looking-at org-babel-src-name-w-name-regexp) - (setq name (org-no-properties (match-string 3))))) + (when (looking-at (org-babel-named-src-block-regexp-for-name)) + (setq name (org-match-string-no-properties 9)))) ;; inline source block (when (org-babel-get-inline-src-block-matches) + (setq head (match-beginning 0)) (setq info (org-babel-parse-inline-src-block-match)))) ;; resolve variable references and add summary parameters (when (and info (not light)) (setf (nth 2 info) (org-babel-process-params (nth 2 info)))) + (when info + (setf (nth 2 info) (org-babel-generate-file-param name (nth 2 info)))) (when info (append info (list name indent head))))) -(defvar org-current-export-file) ; dynamically bound +(defvar org-babel-exp-reference-buffer nil + "Buffer containing original contents of the exported buffer. +This is used by Babel to resolve references in source blocks. +Its value is dynamically bound during export.") + (defmacro org-babel-check-confirm-evaluate (info &rest body) "Evaluate BODY with special execution confirmation variables set. @@ -289,27 +298,32 @@ hold the language of the code block, and BLOCK-NAME will hold the name of the code block." (declare (indent defun)) (org-with-gensyms - (lang block-body headers name eval eval-no export eval-no-export) + (lang block-body headers name head eval eval-no export eval-no-export) `(let* ((,lang (nth 0 ,info)) (,block-body (nth 1 ,info)) (,headers (nth 2 ,info)) (,name (nth 4 ,info)) + (,head (nth 6 ,info)) (,eval (or (cdr (assoc :eval ,headers)) (when (assoc :noeval ,headers) "no"))) (,eval-no (or (equal ,eval "no") (equal ,eval "never"))) - (,export (org-bound-and-true-p org-current-export-file)) + (,export org-babel-exp-reference-buffer) (,eval-no-export (and ,export (or (equal ,eval "no-export") (equal ,eval "never-export")))) (noeval (or ,eval-no ,eval-no-export)) (query (or (equal ,eval "query") (and ,export (equal ,eval "query-export")) (if (functionp org-confirm-babel-evaluate) - (funcall org-confirm-babel-evaluate - ,lang ,block-body) + (save-excursion + (goto-char ,head) + (funcall org-confirm-babel-evaluate + ,lang ,block-body)) org-confirm-babel-evaluate))) (code-block (if ,info (format " %s " ,lang) " ")) (block-name (if ,name (format " (%s) " ,name) " "))) + ;; Silence byte-compiler if `body' doesn't use those vars. + (ignore noeval query) ,@body))) (defsubst org-babel-check-evaluate (info) @@ -317,8 +331,8 @@ name of the code block." Do not query the user." (org-babel-check-confirm-evaluate info (not (when noeval - (message (format "Evaluation of this%scode-block%sis disabled." - code-block block-name)))))) + (message "Evaluation of this%scode-block%sis disabled." + code-block block-name))))) ;; dynamically scoped for asynchronous export (defvar org-babel-confirm-evaluate-answer-no) @@ -344,8 +358,8 @@ of potentially harmful code." (yes-or-no-p (format "Evaluate this%scode block%son your system? " code-block block-name))) - (message (format "Evaluation of this%scode-block%sis aborted." - code-block block-name))))))) + (message "Evaluation of this%scode-block%sis aborted." + code-block block-name)))))) ;;;###autoload (defun org-babel-execute-safely-maybe () @@ -397,12 +411,16 @@ a window into the `org-babel-get-src-block-info' function." (header-args (nth 2 info))) (when name (funcall printf "Name: %s\n" name)) (when lang (funcall printf "Lang: %s\n" lang)) + (funcall printf "Properties:\n") + (funcall printf "\t:header-args \t%s\n" (org-entry-get (point) "header-args" t)) + (funcall printf "\t:header-args:%s \t%s\n" lang (org-entry-get (point) (concat "header-args:" lang) t)) + (when (funcall full switches) (funcall printf "Switches: %s\n" switches)) (funcall printf "Header Arguments:\n") (dolist (pair (sort header-args (lambda (a b) (string< (symbol-name (car a)) (symbol-name (car b)))))) - (when (funcall full (cdr pair)) + (when (funcall full (format "%s" (cdr pair))) (funcall printf "\t%S%s\t%s\n" (car pair) (if (> (length (format "%S" (car pair))) 7) "" "\t") @@ -445,11 +463,13 @@ then run `org-babel-switch-to-session'." (colnames . ((nil no yes))) (comments . ((no link yes org both noweb))) (dir . :any) - (eval . ((never query))) + (eval . ((yes no no-export strip-export never-export eval never + query))) (exports . ((code results both none))) (epilogue . :any) (file . :any) (file-desc . :any) + (file-ext . :any) (hlines . ((no yes))) (mkdirp . ((yes no))) (no-expand) @@ -457,6 +477,7 @@ then run `org-babel-switch-to-session'." (noweb . ((yes no tangle no-export strip-export))) (noweb-ref . :any) (noweb-sep . :any) + (output-dir . :any) (padline . ((yes no))) (post . :any) (prologue . :any) @@ -479,14 +500,55 @@ then run `org-babel-switch-to-session'." Note that individual languages may define their own language specific header arguments as well.") +(defconst org-babel-safe-header-args + '(:cache :colnames :comments :exports :epilogue :hlines :noeval + :noweb :noweb-ref :noweb-sep :padline :prologue :rownames + :sep :session :tangle :wrap + (:eval . ("never" "query")) + (:results . (lambda (str) (not (string-match "file" str))))) + "A list of safe header arguments for babel source blocks. + +The list can have entries of the following forms: +- :ARG -> :ARG is always a safe header arg +- (:ARG . (VAL1 VAL2 ...)) -> :ARG is safe as a header arg if it is + `equal' to one of the VALs. +- (:ARG . FN) -> :ARG is safe as a header arg if the function FN + returns non-nil. FN is passed one + argument, the value of the header arg + (as a string).") + +(defmacro org-babel-header-args-safe-fn (safe-list) + "Return a function that determines whether a list of header args are safe. + +Intended usage is: +\(put \\='org-babel-default-header-args \\='safe-local-variable + (org-babel-header-args-safe-p org-babel-safe-header-args) + +This allows org-babel languages to extend the list of safe values for +their `org-babel-default-header-args:foo' variable. + +For the format of SAFE-LIST, see `org-babel-safe-header-args'." + `(lambda (value) + (and (listp value) + (org-every + (lambda (pair) + (and (consp pair) + (org-babel-one-header-arg-safe-p pair ,safe-list))) + value)))) + (defvar org-babel-default-header-args '((:session . "none") (:results . "replace") (:exports . "code") (:cache . "no") (:noweb . "no") (:hlines . "no") (:tangle . "no")) "Default arguments to use when evaluating a source block.") +(put 'org-babel-default-header-args 'safe-local-variable + (org-babel-header-args-safe-fn org-babel-safe-header-args)) (defvar org-babel-default-inline-header-args - '((:session . "none") (:results . "replace") (:exports . "results")) + '((:session . "none") (:results . "replace") + (:exports . "results") (:hlines . "yes")) "Default arguments to use when evaluating an inline source block.") +(put 'org-babel-default-inline-header-args 'safe-local-variable + (org-babel-header-args-safe-fn org-babel-safe-header-args)) (defvar org-babel-data-names '("tblname" "results" "name")) @@ -503,7 +565,7 @@ be saved in the second match data.") (defvar org-babel-result-w-name-regexp (concat org-babel-result-regexp - "\\([^ ()\f\t\n\r\v]+\\)\\(\(\\(.*\\)\)\\|\\)")) + "\\([^ ()\f\t\n\r\v]+\\)\\((\\(.*\\))\\|\\)")) (defvar org-babel-min-lines-for-block-output 10 "The minimum number of lines for block output. @@ -513,11 +575,17 @@ block. Otherwise the output is marked as literal by inserting colons at the starts of the lines. This variable only takes effect if the :results output option is in effect.") +(defvar org-babel-noweb-error-all-langs nil + "Raise errors when noweb references don't resolve. +Also see `org-babel-noweb-error-langs' to control noweb errors on +a language by language bases.") + (defvar org-babel-noweb-error-langs nil "Languages for which Babel will raise literate programming errors. List of languages for which errors should be raised when the source code block satisfying a noweb reference in this language -can not be resolved.") +can not be resolved. Also see `org-babel-noweb-error-all-langs' +to raise errors for all languages.") (defvar org-babel-hash-show 4 "Number of initial characters to show of a hidden results hash.") @@ -528,10 +596,15 @@ can not be resolved.") (defvar org-babel-after-execute-hook nil "Hook for functions to be called after `org-babel-execute-src-block'") -(defun org-babel-named-src-block-regexp-for-name (name) - "This generates a regexp used to match a src block named NAME." - (concat org-babel-src-name-regexp (regexp-quote name) - "[ \t(]*[\r\n]\\(?:^#.*[\r\n]\\)*" +(defun org-babel-named-src-block-regexp-for-name (&optional name) + "This generates a regexp used to match a src 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'." + (concat org-babel-src-name-regexp + (concat (if name (regexp-quote name) "\\(?9:.*?\\)") "[ \t]*" ) + "\\(?:\n[ \t]*#\\+\\S-+:.*\\)*?" + "\n" (substring org-babel-src-block-regexp 1))) (defun org-babel-named-data-regexp-for-name (name) @@ -547,6 +620,8 @@ multiple blocks are being executed (e.g., in chained execution through use of the :var header argument) this marker points to the outer-most code block.") +(defvar *this*) + ;;;###autoload (defun org-babel-execute-src-block (&optional arg info params) "Execute the current source code block. @@ -567,7 +642,10 @@ block." (let* ((org-babel-current-src-block-location (or org-babel-current-src-block-location (nth 6 info) - (org-babel-where-is-src-block-head))) + (org-babel-where-is-src-block-head) + ;; inline src block + (and (org-babel-get-inline-src-block-matches) + (match-beginning 0)))) (info (if info (copy-tree info) (org-babel-get-src-block-info))) @@ -587,10 +665,12 @@ block." (cache-current-p (save-excursion ;; return cached result (goto-char (org-babel-where-is-src-block-result nil info)) - (end-of-line 1) (forward-char 1) + (forward-line) + (skip-chars-forward " \t") (let ((result (org-babel-read-result))) (message (replace-regexp-in-string - "%" "%%" (format "%S" result))) result))) + "%" "%%" (format "%S" result))) + result))) ((org-babel-confirm-evaluate (let ((i info)) (setf (nth 2 i) merged-params) i)) (let* ((lang (nth 0 info)) @@ -686,7 +766,7 @@ org-babel-expand-body:lang function." "\n"))) ;;;###autoload -(defun org-babel-expand-src-block (&optional arg info params) +(defun org-babel-expand-src-block (&optional _arg info params) "Expand the current source code block. Expand according to the source code block's header arguments and pop open the results in a preview buffer." @@ -710,8 +790,7 @@ arguments and pop open the results in a preview buffer." (funcall assignments-cmd params)))))) (if (org-called-interactively-p 'any) (org-edit-src-code - nil expanded - (concat "*Org-Babel Preview " (buffer-name) "[ " lang " ]*")) + expanded (concat "*Org-Babel Preview " (buffer-name) "[ " lang " ]*")) expanded))) (defun org-babel-edit-distance (s1 s2) @@ -740,8 +819,7 @@ arguments and pop open the results in a preview buffer." (let ((results (copy-sequence original))) (dolist (new-list others) (dolist (arg-pair new-list) - (let ((header (car arg-pair)) - (args (cdr arg-pair))) + (let ((header (car arg-pair))) (setq results (cons arg-pair (org-remove-if (lambda (pair) (equal header (car pair))) @@ -771,37 +849,43 @@ arguments and pop open the results in a preview buffer." (message "No suspicious header arguments found."))) ;;;###autoload -(defun org-babel-insert-header-arg () +(defun org-babel-insert-header-arg (&optional header-arg value) "Insert a header argument selecting from lists of common args and values." (interactive) - (let* ((lang (car (org-babel-get-src-block-info 'light))) + (let* ((info (org-babel-get-src-block-info 'light)) + (lang (car info)) + (begin (nth 6 info)) (lang-headers (intern (concat "org-babel-header-args:" lang))) (headers (org-babel-combine-header-arg-lists org-babel-common-header-args-w-values (when (boundp lang-headers) (eval lang-headers)))) - (arg (org-icompleting-read - "Header Arg: " - (mapcar - (lambda (header-spec) (symbol-name (car header-spec))) - headers)))) - (insert ":" arg) - (let ((vals (cdr (assoc (intern arg) headers)))) - (when vals - (insert - " " - (cond - ((eq vals :any) - (read-from-minibuffer "value: ")) - ((listp vals) - (mapconcat - (lambda (group) - (let ((arg (org-icompleting-read - "value: " - (cons "default" (mapcar #'symbol-name group))))) - (if (and arg (not (string= "default" arg))) - (concat arg " ") - ""))) - vals "")))))))) + (header-arg (or header-arg + (org-icompleting-read + "Header Arg: " + (mapcar + (lambda (header-spec) (symbol-name (car header-spec))) + headers)))) + (vals (cdr (assoc (intern header-arg) headers))) + (value (or value + (cond + ((eq vals :any) + (read-from-minibuffer "value: ")) + ((listp vals) + (mapconcat + (lambda (group) + (let ((arg (org-icompleting-read + "Value: " + (cons "default" + (mapcar #'symbol-name group))))) + (if (and arg (not (string= "default" arg))) + (concat arg " ") + ""))) + vals "")))))) + (save-excursion + (goto-char begin) + (goto-char (point-at-eol)) + (unless (= (char-before (point)) ?\ ) (insert " ")) + (insert ":" header-arg) (when value (insert " " value))))) ;; Add support for completing-read insertion of header arguments after ":" (defun org-babel-header-arg-expand () @@ -828,7 +912,7 @@ arguments and pop open the results in a preview buffer." (add-hook 'org-tab-first-hook 'org-babel-header-arg-expand) ;;;###autoload -(defun org-babel-load-in-session (&optional arg info) +(defun org-babel-load-in-session (&optional _arg info) "Load the body of the current source-code block. Evaluate the header arguments for the source block before entering the session. After loading the body this pops open the @@ -897,7 +981,7 @@ with a prefix argument then this is passed on to (defvar org-src-window-setup) ;;;###autoload -(defun org-babel-switch-to-session-with-code (&optional arg info) +(defun org-babel-switch-to-session-with-code (&optional arg _info) "Switch to code buffer and display session." (interactive "P") (let ((swap-windows @@ -913,15 +997,15 @@ with a prefix argument then this is passed on to (org-edit-src-code) (funcall swap-windows))) +;;;###autoload (defmacro org-babel-do-in-edit-buffer (&rest body) "Evaluate BODY in edit buffer if there is a code block at point. Return t if a code block was found at point, nil otherwise." `(let ((org-src-window-setup 'switch-invisibly)) (when (and (org-babel-where-is-src-block-head) - (org-edit-src-code nil nil nil)) + (org-edit-src-code)) (unwind-protect (progn ,@body) - (if (org-bound-and-true-p org-edit-src-from-org-mode) - (org-edit-src-exit))) + (org-edit-src-exit)) t))) (def-edebug-spec org-babel-do-in-edit-buffer (body)) @@ -1023,7 +1107,13 @@ end-body --------- point at the end of the body" (body (match-string 5)) (beg-body (match-beginning 5)) (end-body (match-end 5))) - ,@body + ;; Silence byte-compiler in case `body' doesn't use all + ;; those variables. + (ignore full-block beg-block end-block lang + beg-lang end-lang switches beg-switches + end-switches header-args beg-header-args + end-header-args body beg-body end-body) + ,@body (goto-char end-block))))) (unless visited-p (kill-buffer to-be-removed)) (goto-char point)))) @@ -1161,7 +1251,20 @@ the current subtree." (member (car arg) '(:results :exports))) (mapconcat #'identity (sort (funcall rm (split-string v)) #'string<) " ")) - (t v))))))) + (t v)))))) + ;; expanded body + (lang (nth 0 info)) + (params (nth 2 info)) + (body (if (org-babel-noweb-p params :eval) + (org-babel-expand-noweb-references info) (nth 1 info))) + (expand-cmd (intern (concat "org-babel-expand-body:" lang))) + (assignments-cmd (intern (concat "org-babel-variable-assignments:" + lang))) + (expanded + (if (fboundp expand-cmd) (funcall expand-cmd body params) + (org-babel-expand-body:generic + body params (and (fboundp assignments-cmd) + (funcall assignments-cmd params)))))) (let* ((it (format "%s-%s" (mapconcat #'identity @@ -1170,19 +1273,19 @@ the current subtree." (when normalized (format "%S" normalized)))) (nth 2 info))) ":") - (nth 1 info))) + expanded)) (hash (sha1 it))) (when (org-called-interactively-p 'interactive) (message hash)) hash)))) -(defun org-babel-current-result-hash () +(defun org-babel-current-result-hash (&optional info) "Return the current in-buffer hash." - (org-babel-where-is-src-block-result) + (org-babel-where-is-src-block-result nil info) (org-no-properties (match-string 5))) -(defun org-babel-set-current-result-hash (hash) +(defun org-babel-set-current-result-hash (hash info) "Set the current in-buffer hash to HASH." - (org-babel-where-is-src-block-result) + (org-babel-where-is-src-block-result nil info) (save-excursion (goto-char (match-beginning 5)) (mapc #'delete-overlay (overlays-at (point))) (forward-char org-babel-hash-show) @@ -1224,8 +1327,9 @@ the `org-mode-hook'." (defun org-babel-hash-at-point (&optional point) "Return the value of the hash at POINT. +\\\ The hash is also added as the last element of the kill ring. -This can be called with C-c C-c." +This can be called with \\[org-ctrl-c-ctrl-c]." (interactive) (let ((hash (car (delq nil (mapcar (lambda (ol) (overlay-get ol 'babel-hash)) @@ -1324,48 +1428,45 @@ specified in the properties of the current outline entry." (save-match-data (list ;; DEPRECATED header arguments specified as separate property at - ;; point of definition - (let (val sym) - (org-babel-parse-multiple-vars - (delq nil - (mapcar - (lambda (header-arg) - (and (setq val (org-entry-get (point) header-arg t)) - (cons (intern (concat ":" header-arg)) - (org-babel-read val)))) - (mapcar - #'symbol-name - (mapcar - #'car - (org-babel-combine-header-arg-lists - org-babel-common-header-args-w-values - (progn - (setq sym (intern (concat "org-babel-header-args:" lang))) - (and (boundp sym) (eval sym)))))))))) + ;; point of definition. + (org-babel-parse-multiple-vars + (delq nil + (mapcar + (lambda (header) + (let* ((arg (symbol-name (car header))) + (val (org-entry-get (point) arg t))) + (and val + (cons (intern (concat ":" arg)) + (org-babel-read val))))) + (org-babel-combine-header-arg-lists + org-babel-common-header-args-w-values + (let ((sym (intern (concat "org-babel-header-args:" lang)))) + (and (boundp sym) (symbol-value sym))))))) ;; header arguments specified with the header-args property at - ;; point of call + ;; point of call. (org-babel-parse-header-arguments (org-entry-get org-babel-current-src-block-location - "header-args" 'inherit)) - (when lang ;; language-specific header arguments at point of call - (org-babel-parse-header-arguments - (org-entry-get org-babel-current-src-block-location - (concat "header-args:" lang) 'inherit)))))) + "header-args" + 'inherit)) + (and lang ; language-specific header arguments at point of call + (org-babel-parse-header-arguments + (org-entry-get org-babel-current-src-block-location + (concat "header-args:" lang) + 'inherit)))))) (defvar org-src-preserve-indentation) ;; declare defcustom from org-src (defun org-babel-parse-src-block-match () "Parse the results from a match of the `org-babel-src-block-regexp'." - (let* ((block-indentation (length (match-string 1))) - (lang (org-no-properties (match-string 2))) + (let* ((block-indentation (string-width (match-string 1))) + (lang (org-match-string-no-properties 2)) (lang-headers (intern (concat "org-babel-default-header-args:" lang))) (switches (match-string 3)) - (body (org-no-properties - (let* ((body (match-string 5)) - (sub-length (- (length body) 1))) - (if (and (> sub-length 0) - (string= "\n" (substring body sub-length))) - (substring body 0 sub-length) - (or body ""))))) + (body (let* ((body (org-match-string-no-properties 5)) + (sub-length (- (length body) 1))) + (if (and (> sub-length 0) + (string= "\n" (substring body sub-length))) + (substring body 0 sub-length) + (or body "")))) (preserve-indentation (or org-src-preserve-indentation (save-match-data (string-match "-i\\>" switches))))) @@ -1398,14 +1499,15 @@ specified in the properties of the current outline entry." (append (org-babel-params-from-properties lang) (list (org-babel-parse-header-arguments - (org-no-properties (or (match-string 4) ""))))))))) + (org-no-properties (or (match-string 4) "")))))) + nil))) (defun org-babel-balanced-split (string alts) "Split STRING on instances of ALTS. ALTS is a cons of two character options where each option may be either the numeric code of a single character or a list of character alternatives. For example to split on balanced -instances of \"[ \t]:\" set ALTS to '((32 9) . 58)." +instances of \"[ \t]:\" set ALTS to ((32 9) . 58)." (let* ((matches (lambda (ch spec) (if (listp spec) (member ch spec) (equal spec ch)))) (matched (lambda (ch last) (if (consp alts) @@ -1510,12 +1612,15 @@ shown below. (cons :result-type (cond ((member "output" result-params) 'output) ((member "value" result-params) 'value) (t 'value)))) - (org-babel-get-header params :var 'other)))) + (org-remove-if + (lambda (x) (memq (car x) '(:colname-names :rowname-names :result-params + :result-type :var))) + params)))) ;; row and column names (defun org-babel-del-hlines (table) - "Remove all 'hlines from TABLE." - (remove 'hline table)) + "Remove all `hline's from TABLE." + (remq 'hline table)) (defun org-babel-get-colnames (table) "Return the column names of TABLE. @@ -1535,7 +1640,7 @@ Note: this function removes any hlines in TABLE." (rownames (funcall (lambda () (let ((tp table)) (mapcar - (lambda (row) + (lambda (_row) (prog1 (pop (car tp)) (setq tp (cdr tp)))) @@ -1609,35 +1714,26 @@ to the table for reinsertion to org-mode." (org-babel-put-colnames table colnames) table)) table)) -(defun org-babel-where-is-src-block-head () +(defun org-babel-where-is-src-block-head (&optional src-block) "Find where the current source block begins. -Return the point at the beginning of the current source -block. Specifically at the beginning of the #+BEGIN_SRC line. + +If optional argument SRC-BLOCK is `src-block' type element, find +its current beginning instead. + +Return the point at the beginning of the current source block. +Specifically at the beginning of the #+BEGIN_SRC line. Also set +match-data relatively to `org-babel-src-block-regexp', which see. If the point is not on a source block then return nil." - (let ((initial (point)) (case-fold-search t) top bottom) - (or - (save-excursion ;; on a source name line or a #+header line - (beginning-of-line 1) - (and (or (looking-at org-babel-src-name-regexp) - (looking-at org-babel-multi-line-header-regexp)) - (progn - (while (and (forward-line 1) - (or (looking-at org-babel-src-name-regexp) - (looking-at org-babel-multi-line-header-regexp)))) - (looking-at org-babel-src-block-regexp)) - (point))) - (save-excursion ;; on a #+begin_src line - (beginning-of-line 1) - (and (looking-at org-babel-src-block-regexp) - (point))) - (save-excursion ;; inside a src block - (and - (re-search-backward "^[ \t]*#\\+begin_src" nil t) (setq top (point)) - (re-search-forward "^[ \t]*#\\+end_src" nil t) (setq bottom (point)) - (< top initial) (< initial bottom) - (progn (goto-char top) (beginning-of-line 1) - (looking-at org-babel-src-block-regexp)) - (point-marker)))))) + (let ((element (or src-block (org-element-at-point)))) + (when (eq (org-element-type element) 'src-block) + (let ((end (org-element-property :end element))) + (org-with-wide-buffer + ;; Ensure point is not on a blank line after the block. + (beginning-of-line) + (skip-chars-forward " \r\t\n" end) + (when (< (point) end) + (prog1 (goto-char (org-element-property :post-affiliated element)) + (looking-at org-babel-src-block-regexp)))))))) ;;;###autoload (defun org-babel-goto-src-block-head () @@ -1680,28 +1776,27 @@ If the point is not on a source block then return nil." (if point ;; taken from `org-open-at-point' (progn (org-mark-ring-push) (goto-char point) (org-show-context)) - (message "source-code block '%s' not found in this buffer" name)))) + (message "source-code block `%s' not found in this buffer" name)))) (defun org-babel-find-named-block (name) "Find a named source-code block. Return the location of the source block identified by source -NAME, or nil if no such block exists. Set match data according to -org-babel-named-src-block-regexp." +NAME, or nil if no such block exists. Set match data according +to `org-babel-named-src-block-regexp'." (save-excursion - (let ((case-fold-search t) - (regexp (org-babel-named-src-block-regexp-for-name name)) msg) - (goto-char (point-min)) - (when (or (re-search-forward regexp nil t) - (re-search-backward regexp nil t)) - (match-beginning 0))))) + (goto-char (point-min)) + (ignore-errors + (org-next-block 1 nil (org-babel-named-src-block-regexp-for-name name))))) (defun org-babel-src-block-names (&optional file) "Returns the names of source blocks in FILE or the current buffer." + (when file (find-file file)) (save-excursion - (when file (find-file file)) (goto-char (point-min)) - (let ((case-fold-search t) names) - (while (re-search-forward org-babel-src-name-w-name-regexp nil t) - (setq names (cons (match-string 3) names))) + (goto-char (point-min)) + (let ((re (org-babel-named-src-block-regexp-for-name)) + names) + (while (ignore-errors (org-next-block 1 nil re)) + (push (org-match-string-no-properties 9) names)) names))) ;;;###autoload @@ -1715,7 +1810,7 @@ org-babel-named-src-block-regexp." (if point ;; taken from `org-open-at-point' (progn (goto-char point) (org-show-context)) - (message "result '%s' not found in this buffer" name)))) + (message "result `%s' not found in this buffer" name)))) (defun org-babel-find-named-result (name &optional point) "Find a named result. @@ -1727,7 +1822,8 @@ buffer or nil if no such result exists." (catch 'is-a-code-block (when (re-search-forward (concat org-babel-result-regexp - "[ \t]" (regexp-quote name) "[ \t]*[\n\f\v\r]") nil t) + "[ \t]" (regexp-quote name) "[ \t]*[\n\f\v\r]") + nil t) (when (and (string= "name" (downcase (match-string 1))) (or (beginning-of-line 1) (looking-at org-babel-src-block-regexp) @@ -1780,10 +1876,14 @@ split. When called from outside of a code block a new code block is created. In both cases if the region is demarcated and if the region is not active then the point is demarcated." (interactive "P") - (let ((info (org-babel-get-src-block-info 'light)) - (headers (progn (org-babel-where-is-src-block-head) - (match-string 4))) - (stars (concat (make-string (or (org-current-level) 1) ?*) " "))) + (let* ((info (org-babel-get-src-block-info 'light)) + (start (org-babel-where-is-src-block-head)) + (block (and start (match-string 0))) + (headers (and start (match-string 4))) + (stars (concat (make-string (or (org-current-level) 1) ?*) " ")) + (lower-case-p (and block + (let (case-fold-search) + (org-string-match-p "#\\+begin_src" block))))) (if info (mapc (lambda (place) @@ -1797,9 +1897,10 @@ region is not active then the point is demarcated." (delete-region (point-at-bol) (point-at-eol))) (insert (concat (if (looking-at "^") "" "\n") - indent "#+end_src\n" + indent (funcall (if lower-case-p 'downcase 'upcase) "#+end_src\n") (if arg stars indent) "\n" - indent "#+begin_src " lang + indent (funcall (if lower-case-p 'downcase 'upcase) "#+begin_src ") + lang (if (> (length headers) 1) (concat " " headers) headers) (if (looking-at "[\n\r]") @@ -1819,11 +1920,12 @@ region is not active then the point is demarcated." (if (org-region-active-p) (mark) (point)) (point)))) (insert (concat (if (looking-at "^") "" "\n") (if arg (concat stars "\n") "") - "#+begin_src " lang "\n" + (funcall (if lower-case-p 'downcase 'upcase) "#+begin_src ") + lang "\n" body (if (or (= (length body) 0) (string-match "[\r\n]$" body)) "" "\n") - "#+end_src\n")) + (funcall (if lower-case-p 'downcase 'upcase) "#+end_src\n"))) (goto-char start) (move-end-of-line 1))))) (defvar org-babel-lob-one-liner-regexp) @@ -1868,32 +1970,36 @@ following the source block." (progn (end-of-line 1) (if (eobp) (insert "\n") (forward-char 1)) (setq end (point)) - (or (and - (not name) - (progn ;; unnamed results line already exists - (catch 'non-comment - (while (re-search-forward "[^ \f\t\n\r\v]" nil t) - (beginning-of-line 1) - (cond - ((looking-at (concat org-babel-result-regexp "\n")) - (throw 'non-comment t)) - ((looking-at "^[ \t]*#") (end-of-line 1)) - (t (throw 'non-comment nil)))))) - (let ((this-hash (match-string 5))) - (prog1 (point) - ;; must remove and rebuild if hash!=old-hash - (if (and hash (not (string= hash this-hash))) - (prog1 nil - (forward-line 1) - (delete-region - end (org-babel-result-end))) - (setq end nil))))))))))) + (and + (not name) + (progn ;; unnamed results line already exists + (catch 'non-comment + (while (re-search-forward "[^ \f\t\n\r\v]" nil t) + (beginning-of-line 1) + (cond + ((looking-at (concat org-babel-result-regexp "\n")) + (throw 'non-comment t)) + ((and (looking-at "^[ \t]*#") + (not (looking-at + org-babel-lob-one-liner-regexp))) + (end-of-line 1)) + (t (throw 'non-comment nil)))))) + (let ((this-hash (match-string 5))) + (prog1 (point) + ;; must remove and rebuild if hash!=old-hash + (if (and hash (not (string= hash this-hash))) + (progn + (setq end (point-at-bol)) + (forward-line 1) + (delete-region end (org-babel-result-end)) + (setq beg end)) + (setq end nil)))))))))) (if (not (and insert end)) found (goto-char end) (unless beg (if (looking-at "[\n\r]") (forward-char 1) (insert "\n"))) + (when (wholenump indent) (indent-to indent)) (insert (concat - (when (wholenump indent) (make-string indent ? )) "#+" org-babel-results-keyword (when hash (if org-babel-hash-show-time @@ -1904,7 +2010,7 @@ following the source block." (when name (concat " " name)) "\n")) (unless beg (insert "\n") (backward-char)) (beginning-of-line 0) - (if hash (org-babel-hide-hash)) + (when hash (org-babel-hide-hash)) (point))))) (defvar org-block-regexp) @@ -1915,7 +2021,7 @@ following the source block." ((org-at-table-p) (org-babel-read-table)) ((org-at-item-p) (org-babel-read-list)) ((looking-at org-bracket-link-regexp) (org-babel-read-link)) - ((looking-at org-block-regexp) (org-babel-trim (match-string 4))) + ((looking-at org-block-regexp) (org-remove-indentation (match-string 4))) ((or (looking-at "^[ \t]*: ") (looking-at "^[ \t]*:$")) (setq result-string (org-babel-trim @@ -1972,23 +2078,29 @@ If the path of the link is a file path it is expanded using (funcall echo-res result)))) (defun org-babel-insert-result - (result &optional result-params info hash indent lang) + (result &optional result-params info hash indent lang) "Insert RESULT into the current buffer. -By default RESULT is inserted after the end of the -current source block. With optional argument RESULT-PARAMS -controls insertion of results in the org-mode file. -RESULT-PARAMS can take the following values: + +By default RESULT is inserted after the end of the current source +block. The RESULT of an inline source block usually will be +wrapped inside a `results' macro and placed on the same line as +the inline source block. The macro is stripped upon export. +Multiline and non-scalar RESULTS from inline source blocks are +not allowed. With optional argument RESULT-PARAMS controls +insertion of results in the Org mode file. RESULT-PARAMS can +take the following values: replace - (default option) insert results after the source block - replacing any previously inserted results + or inline source block replacing any previously + inserted results. silent -- no results are inserted into the Org-mode buffer but the results are echoed to the minibuffer and are ingested by Emacs (a potentially time consuming - process) + process). file ---- the results are interpreted as a file path, and are - inserted into the buffer using the Org-mode file syntax + inserted into the buffer using the Org-mode file syntax. list ---- the results are interpreted as an Org-mode list. @@ -1997,26 +2109,49 @@ raw ----- results are added directly to the Org-mode file. This formatted text. drawer -- results are added directly to the Org-mode file as with - \"raw\", but are wrapped in a RESULTS drawer, allowing - them to later be replaced or removed automatically. + \"raw\", but are wrapped in a RESULTS drawer or results + macro, allowing them to later be replaced or removed + automatically. + +org ----- results are added inside of a \"src_org{}\" or \"#+BEGIN_SRC + org\" block depending on whether the current source block is + inline or not. They are not comma-escaped when inserted, + but Org syntax here will be discarded when exporting the + file. + +html ---- results are added inside of a #+BEGIN_HTML block or + html export snippet depending on whether the current + source block is inline or not. This is a good option + if your code block will output html formatted text. + +latex --- results are added inside of a #+BEGIN_LATEX block or + latex export snippet depending on whether the current + source block is inline or not. This is a good option + if your code block will output latex formatted text. -org ----- results are added inside of a \"#+BEGIN_SRC org\" block. - They are not comma-escaped when inserted, but Org syntax - here will be discarded when exporting the file. +code ---- the results are extracted in the syntax of the source + code of the language being evaluated and are added + inside of a source block with the source-code language + set appropriately. Also, source block inlining is + preserved in this case. Note this relies on the + optional LANG argument. -html ---- results are added inside of a #+BEGIN_HTML block. This - is a good option if you code block will output html - formatted text. +list ---- the results are rendered as a list. This option not + allowed for inline src blocks. -latex --- results are added inside of a #+BEGIN_LATEX block. - This is a good option if you code block will output - latex formatted text. +table --- the results are rendered as a table. This option not + allowed for inline src blocks. + +INFO may provide the values of these header arguments (in the +`header-arguments-alist' see the docstring for +`org-babel-get-src-block-info'): + +:file --- the name of the file to which output should be written. + +:wrap --- the effect is similar to `latex' in RESULT-PARAMS but + using the argument supplied to specify the export block + or snippet type." -code ---- the results are extracted in the syntax of the source - code of the language being evaluated and are added - inside of a #+BEGIN_SRC block with the source-code - language set appropriately. Note this relies on the - optional LANG argument." (if (stringp result) (progn (setq result (org-no-properties result)) @@ -2036,15 +2171,23 @@ code ---- the results are extracted in the syntax of the source (when (or (org-babel-get-inline-src-block-matches) (org-babel-get-lob-one-liner-matches)) (goto-char (match-end 0)) - (insert (if (listp result) "\n" " ")) + (org-babel-remove-inline-result) + (insert " ") (point)))) - (existing-result (unless inlinep - (org-babel-where-is-src-block-result - t info hash indent))) + (existing-result + (unless inlinep + (org-babel-where-is-src-block-result t info hash indent))) + (bad-inline-p + (when inlinep + (or + (and (member "table" result-params) "`:results table'") + (and (listp result) "list result") + (and (org-string-match-p "\n." result) "multiline result") + (and (member "list" result-params) "`:results list'")))) (results-switches (cdr (assoc :results_switches (nth 2 info)))) - (visible-beg (copy-marker (point-min))) - (visible-end (copy-marker (point-max))) + (visible-beg (point-min-marker)) + (visible-end (point-max-marker)) ;; When results exist outside of the current visible ;; region of the buffer, be sure to widen buffer to ;; update them. @@ -2077,18 +2220,37 @@ code ---- the results are extracted in the syntax of the source ((member "prepend" result-params)))) ; already there (setq results-switches (if results-switches (concat " " results-switches) "")) - (let ((wrap (lambda (start finish &optional no-escape) - (goto-char end) (insert (concat finish "\n")) - (goto-char beg) (insert (concat start "\n")) + (let ((wrap (lambda (start finish &optional no-escape no-newlines + inline-start inline-finish) + (when inlinep + (setq start inline-start) + (setq finish inline-finish) + (setq no-newlines t)) + (goto-char end) + (insert (concat finish (unless no-newlines "\n"))) + (goto-char beg) + (insert (concat start (unless no-newlines "\n"))) (unless no-escape (org-escape-code-in-region (min (point) end) end)) - (goto-char end) (goto-char (point-at-eol)) + (goto-char end) + (unless no-newlines (goto-char (point-at-eol))) (setq end (point-marker)))) - (proper-list-p (lambda (it) (and (listp it) (null (cdr (last it))))))) + (tabulablep + (lambda (r) + ;; Non-nil when result R can be turned into + ;; a table. + (and (listp r) + (null (cdr (last r))) + (org-every + (lambda (e) (or (atom e) (null (cdr (last e))))) + result))))) ;; insert results based on type (cond - ;; do nothing for an empty result + ;; Do nothing for an empty result. ((null result)) + ;; Illegal inline result or params. + (bad-inline-p + (error "Inline error: %s cannot be used" bad-inline-p)) ;; insert a list if preferred ((member "list" result-params) (insert @@ -2100,51 +2262,78 @@ code ---- the results are extracted in the syntax of the source (if (listp result) result (split-string result "\n" t)))) '(:splicep nil :istart "- " :iend "\n"))) "\n")) - ;; assume the result is a table if it's not a string - ((funcall proper-list-p result) + ;; Try hard to print RESULT as a table. Give up if + ;; it contains an improper list. + ((funcall tabulablep result) (goto-char beg) (insert (concat (orgtbl-to-orgtbl (if (org-every - (lambda (el) (or (listp el) (eq el 'hline))) + (lambda (e) + (or (eq e 'hline) (listp e))) result) - result (list result)) - '(:fmt (lambda (cell) (format "%s" cell)))) "\n")) - (goto-char beg) (when (org-at-table-p) (org-table-align))) - ((and (listp result) (not (funcall proper-list-p result))) - (insert (format "%s\n" result))) + result + (list result)) + nil) + "\n")) + (goto-char beg) + (when (org-at-table-p) (org-table-align)) + (goto-char (org-table-end))) + ;; Print verbatim a list that cannot be turned into + ;; a table. + ((listp result) (insert (format "%s\n" result))) ((member "file" result-params) - (when inlinep (goto-char inlinep)) + (when inlinep + (goto-char inlinep) + (setq result (org-macro-escape-arguments result))) (insert result)) + ((and inlinep + (not (member "raw" result-params))) + (goto-char inlinep) + (insert (org-macro-escape-arguments + (org-babel-chomp result "\n")))) (t (goto-char beg) (insert result))) - (when (funcall proper-list-p result) (goto-char (org-table-end))) (setq end (point-marker)) ;; possibly wrap result (cond + (bad-inline-p) ; Do nothing. ((assoc :wrap (nth 2 info)) (let ((name (or (cdr (assoc :wrap (nth 2 info))) "RESULTS"))) (funcall wrap (concat "#+BEGIN_" name) - (concat "#+END_" (car (org-split-string name)))))) + (concat "#+END_" (car (org-split-string name))) + nil nil (concat "{{{results(@@" name ":") "@@)}}}"))) ((member "html" result-params) - (funcall wrap "#+BEGIN_HTML" "#+END_HTML")) + (funcall wrap "#+BEGIN_HTML" "#+END_HTML" nil nil + "{{{results(@@html:" "@@)}}}")) ((member "latex" result-params) - (funcall wrap "#+BEGIN_LaTeX" "#+END_LaTeX")) + (funcall wrap "#+BEGIN_LaTeX" "#+END_LaTeX" nil nil + "{{{results(@@latex:" "@@)}}}")) ((member "org" result-params) (goto-char beg) (if (org-at-table-p) (org-cycle)) - (funcall wrap "#+BEGIN_SRC org" "#+END_SRC")) + (funcall wrap "#+BEGIN_SRC org" "#+END_SRC" nil nil + "{{{results(src_org{" "})}}}")) ((member "code" result-params) - (funcall wrap (format "#+BEGIN_SRC %s%s" (or lang "none") results-switches) - "#+END_SRC")) + (let ((lang (or lang "none"))) + (funcall wrap (format "#+BEGIN_SRC %s%s" lang results-switches) + "#+END_SRC" nil nil + (format "{{{results(src_%s[%s]{" lang results-switches) + "})}}}"))) ((member "raw" result-params) (goto-char beg) (if (org-at-table-p) (org-cycle))) ((or (member "drawer" result-params) ;; Stay backward compatible with <7.9.2 (member "wrap" result-params)) (goto-char beg) (if (org-at-table-p) (org-cycle)) - (funcall wrap ":RESULTS:" ":END:" 'no-escape)) - ((and (not (funcall proper-list-p result)) + (funcall wrap ":RESULTS:" ":END:" 'no-escape nil + "{{{results(" ")}}}")) + ((and inlinep (member "file" result-params)) + (funcall wrap nil nil nil nil "{{{results(" ")}}}")) + ((and (not (funcall tabulablep result)) (not (member "file" result-params))) - (org-babel-examplize-region beg end results-switches) - (setq end (point))))) + (let ((org-babel-inline-result-wrap + ;; Hard code {{{results(...)}}} on top of customization. + (format "{{{results(%s)}}}" org-babel-inline-result-wrap))) + (org-babel-examplify-region beg end results-switches) + (setq end (point)))))) ;; possibly indent the results to match the #+results line (when (and (not inlinep) (numberp indent) indent (> indent 0) ;; in this case `table-align' does the work for us @@ -2160,15 +2349,44 @@ code ---- the results are extracted in the syntax of the source (set-marker visible-beg nil) (set-marker visible-end nil)))))) -(defun org-babel-remove-result (&optional info) +(defun org-babel-remove-result (&optional info keep-keyword) "Remove the result of the current source block." (interactive) - (let ((location (org-babel-where-is-src-block-result nil info)) start) + (let ((location (org-babel-where-is-src-block-result nil info))) (when location - (setq start (- location 1)) (save-excursion - (goto-char location) (forward-line 1) - (delete-region start (org-babel-result-end)))))) + (goto-char location) + (when (looking-at (concat org-babel-result-regexp ".*$")) + (delete-region + (if keep-keyword (1+ (match-end 0)) (1- (match-beginning 0))) + (progn (forward-line 1) (org-babel-result-end)))))))) + +(defun org-babel-remove-inline-result () + "Remove the result of the current inline-src-block or babel call. +The result must be wrapped in a `results' macro to be removed. +Leading whitespace is trimmed." + (interactive) + (let* ((el (org-element-context)) + (post-blank (org-element-property :post-blank el))) + (when (memq (org-element-type el) '(inline-src-block inline-babel-call)) + (org-with-wide-buffer + (goto-char (org-element-property :end el)) + (let ((el (org-element-context))) + (when (and (eq (org-element-type el) 'macro) + (string= (org-element-property :key el) "results")) + (delete-region ; And leading whitespace. + (- (org-element-property :begin el) post-blank) + (- (org-element-property :end el) + (org-element-property :post-blank el))))))))) + +(defun org-babel-remove-result-one-or-many (x) + "Remove the result of the current source block. +If called with a prefix argument, remove all result blocks +in the buffer." + (interactive "P") + (if x + (org-babel-map-src-blocks nil (org-babel-remove-result)) + (org-babel-remove-result))) (defun org-babel-result-end () "Return the point at the end of the current set of results." @@ -2206,18 +2424,27 @@ file's directory then expand relative links." result) (if description (concat "[" description "]") "")))) -(defvar org-babel-capitalize-examplize-region-markers nil +(defvar org-babel-capitalize-example-region-markers nil "Make true to capitalize begin/end example markers inserted by code blocks.") -(defun org-babel-examplize-region (beg end &optional results-switches) - "Comment out region using the inline '==' or ': ' org example quote." +(define-obsolete-function-alias + 'org-babel-examplize-region + 'org-babel-examplify-region "25.1") + +(defun org-babel-examplify-region (beg end &optional results-switches) + "Comment out region using the inline `==' or `: ' org example quote." (interactive "*r") (let ((chars-between (lambda (b e) - (not (string-match "^[\\s]*$" (buffer-substring b e))))) - (maybe-cap (lambda (str) (if org-babel-capitalize-examplize-region-markers - (upcase str) str)))) - (if (or (funcall chars-between (save-excursion (goto-char beg) (point-at-bol)) beg) - (funcall chars-between end (save-excursion (goto-char end) (point-at-eol)))) + (not (string-match "^[\\s]*$" + (buffer-substring b e))))) + (maybe-cap (lambda (str) (if org-babel-capitalize-example-region-markers + (upcase str) str))) + (beg-bol (save-excursion (goto-char beg) (point-at-bol))) + (end-bol (save-excursion (goto-char end) (point-at-bol))) + (end-eol (save-excursion (goto-char end) (point-at-eol)))) + (if (and (not (= end end-bol)) + (or (funcall chars-between beg-bol beg) + (funcall chars-between end end-eol))) (save-excursion (goto-char beg) (insert (format org-babel-inline-result-wrap @@ -2242,11 +2469,30 @@ file's directory then expand relative links." (defun org-babel-update-block-body (new-body) "Update the body of the current code block to NEW-BODY." - (if (not (org-babel-where-is-src-block-head)) - (error "Not in a source block") - (save-match-data - (replace-match (concat (org-babel-trim new-body) "\n") nil t nil 5)) - (indent-rigidly (match-beginning 5) (match-end 5) 2))) + (let ((element (org-element-at-point))) + (unless (eq (org-element-type element) 'src-block) + (error "Not in a source block")) + (goto-char (org-babel-where-is-src-block-head element)) + (let* ((ind (org-get-indentation)) + (body-start (line-beginning-position 2)) + (body (org-element-normalize-string + (if (or org-src-preserve-indentation + (org-element-property :preserve-indent element)) + new-body + (with-temp-buffer + (insert (org-remove-indentation new-body)) + (indent-rigidly + (point-min) + (point-max) + (+ ind org-edit-src-content-indentation)) + (buffer-string)))))) + (delete-region body-start + (org-with-wide-buffer + (goto-char (org-element-property :end element)) + (skip-chars-backward " \t\n") + (line-beginning-position))) + (goto-char body-start) + (insert body)))) (defun org-babel-merge-params (&rest plists) "Combine all parameter association lists in PLISTS. @@ -2334,9 +2580,20 @@ parameters when merging lists." (setq exports (funcall e-merge exports-exclusive-groups exports '("results")))) (setq params (cons pair (assq-delete-all (car pair) params))))) + (:file-ext + (when (cdr pair) + (setq results (funcall e-merge results-exclusive-groups + results '("file"))) + (unless (or (member "both" exports) + (member "none" exports) + (member "code" exports)) + (setq exports (funcall e-merge exports-exclusive-groups + exports '("results")))) + (setq params (cons pair (assq-delete-all (car pair) params))))) (:exports (setq exports (funcall e-merge exports-exclusive-groups - exports (split-string (cdr pair))))) + exports + (split-string (or (cdr pair) ""))))) (:tangle ;; take the latest -- always overwrite (setq tangle (or (list (cdr pair)) tangle))) (:noweb @@ -2409,7 +2666,7 @@ CONTEXT may be one of :tangle, :export or :eval." "Expand Noweb references in the body of the current source code block. For example the following reference would be replaced with the -body of the source-code block named 'example-block'. +body of the source-code block named `example-block'. <> @@ -2422,7 +2679,7 @@ This function must be called from inside of the buffer containing the source-code block which holds BODY. In addition the following syntax can be used to insert the -results of evaluating the source-code block named 'example-block'. +results of evaluating the source-code block named `example-block'. <> @@ -2459,7 +2716,7 @@ block but are passed literally to the \"example-block\"." (setq index (point)) (while (and (re-search-forward (org-babel-noweb-wrap) nil t)) (save-match-data (setf source-name (match-string 1))) - (save-match-data (setq evaluate (string-match "\(.*\)" source-name))) + (save-match-data (setq evaluate (string-match "(.*)" source-name))) (save-match-data (setq prefix (buffer-substring (match-beginning 0) @@ -2526,7 +2783,8 @@ block but are passed literally to the \"example-block\"." (and expansion (mapconcat #'identity (nreverse (cdr expansion)) ""))) ;; Possibly raise an error if named block doesn't exist. - (if (member lang org-babel-noweb-error-langs) + (if (or org-babel-noweb-error-all-langs + (member lang org-babel-noweb-error-langs)) (error "%s" (concat (org-babel-noweb-wrap source-name) "could not be resolved (see " @@ -2536,60 +2794,106 @@ block but are passed literally to the \"example-block\"." (funcall nb-add (buffer-substring index (point-max)))) new-body)) +(defun org-babel--script-escape-inner (str) + (let (in-single in-double backslash out) + (mapc + (lambda (ch) + (setq + out + (if backslash + (progn + (setq backslash nil) + (cond + ((and in-single (eq ch ?')) + ;; Escaped single quote inside single quoted string: + ;; emit just a single quote, since we've changed the + ;; outer quotes to double. + (cons ch out)) + ((eq ch ?\") + ;; Escaped double quote + (if in-single + ;; This should be interpreted as backslash+quote, + ;; not an escape. Emit a three backslashes + ;; followed by a quote (because one layer of + ;; quoting will be stripped by `org-babel-read'). + (append (list ch ?\\ ?\\ ?\\) out) + ;; Otherwise we are in a double-quoted string. Emit + ;; a single escaped quote + (append (list ch ?\\) out))) + ((eq ch ?\\) + ;; Escaped backslash: emit a single escaped backslash + (append (list ?\\ ?\\) out)) + ;; Other: emit a quoted backslash followed by whatever + ;; the character was (because one layer of quoting will + ;; be stripped by `org-babel-read'). + (t (append (list ch ?\\ ?\\) out)))) + (case ch + (?\[ (if (or in-double in-single) + (cons ?\[ out) + (cons ?\( out))) + (?\] (if (or in-double in-single) + (cons ?\] out) + (cons ?\) out))) + (?\{ (if (or in-double in-single) + (cons ?\{ out) + (cons ?\( out))) + (?\} (if (or in-double in-single) + (cons ?\} out) + (cons ?\) out))) + (?, (if (or in-double in-single) + (cons ?, out) (cons ?\s out))) + (?\' (if in-double + (cons ?\' out) + (setq in-single (not in-single)) (cons ?\" out))) + (?\" (if in-single + (append (list ?\" ?\\) out) + (setq in-double (not in-double)) (cons ?\" out))) + (?\\ (unless (or in-single in-double) + (error "Can't handle backslash outside string in `org-babel-script-escape'")) + (setq backslash t) + out) + (t (cons ch out)))))) + (string-to-list str)) + (when (or in-single in-double) + (error "Unterminated string in `org-babel-script-escape'")) + (apply #'string (reverse out)))) + (defun org-babel-script-escape (str &optional force) "Safely convert tables into elisp lists." + (unless (stringp str) + (error "`org-babel-script-escape' expects a string")) (let ((escaped - (if (or force - (and (stringp str) - (> (length str) 2) - (or (and (string-equal "[" (substring str 0 1)) - (string-equal "]" (substring str -1))) - (and (string-equal "{" (substring str 0 1)) - (string-equal "}" (substring str -1))) - (and (string-equal "(" (substring str 0 1)) - (string-equal ")" (substring str -1)))))) - (org-babel-read - (concat - "'" - (let (in-single in-double out) - (mapc - (lambda (ch) - (setq - out - (case ch - (91 (if (or in-double in-single) ; [ - (cons 91 out) - (cons 40 out))) - (93 (if (or in-double in-single) ; ] - (cons 93 out) - (cons 41 out))) - (123 (if (or in-double in-single) ; { - (cons 123 out) - (cons 40 out))) - (125 (if (or in-double in-single) ; } - (cons 125 out) - (cons 41 out))) - (44 (if (or in-double in-single) ; , - (cons 44 out) (cons 32 out))) - (39 (if in-double ; ' - (cons 39 out) - (setq in-single (not in-single)) (cons 34 out))) - (34 (if in-single ; " - (append (list 34 32) out) - (setq in-double (not in-double)) (cons 34 out))) - (t (cons ch out))))) - (string-to-list str)) - (apply #'string (reverse out))))) - str))) + (cond + ((and (> (length str) 2) + (or (and (string-equal "[" (substring str 0 1)) + (string-equal "]" (substring str -1))) + (and (string-equal "{" (substring str 0 1)) + (string-equal "}" (substring str -1))) + (and (string-equal "(" (substring str 0 1)) + (string-equal ")" (substring str -1))))) + + (concat "'" (org-babel--script-escape-inner str))) + ((or force + (and (> (length str) 2) + (or (and (string-equal "'" (substring str 0 1)) + (string-equal "'" (substring str -1))) + ;; We need to pass double-quoted strings + ;; through the backslash-twiddling bits, even + ;; though we don't need to change their + ;; delimiters. + (and (string-equal "\"" (substring str 0 1)) + (string-equal "\"" (substring str -1)))))) + (org-babel--script-escape-inner str)) + (t str)))) (condition-case nil (org-babel-read escaped) (error escaped)))) (defun org-babel-read (cell &optional inhibit-lisp-eval) "Convert the string value of CELL to a number if appropriate. -Otherwise if cell looks like lisp (meaning it starts with a -\"(\", \"'\", \"`\" or a \"[\") then read it as lisp, -otherwise return it unmodified as a string. Optional argument -NO-LISP-EVAL inhibits lisp evaluation for situations in which is -it not appropriate." +Otherwise if CELL looks like lisp (meaning it starts with a +\"(\", \"\\='\", \"\\=`\" or a \"[\") then read and evaluate it as +lisp, otherwise return it unmodified as a string. Optional +argument INHIBIT-LISP-EVAL inhibits lisp evaluation for +situations in which is it not appropriate." (if (and (stringp cell) (not (equal cell ""))) (or (org-babel-number-p cell) (if (and (not inhibit-lisp-eval) @@ -2640,9 +2944,9 @@ If the table is trivial, then return it as a scalar." cell) t)) (defun org-babel-chomp (string &optional regexp) - "Strip trailing spaces and carriage returns from STRING. -Default regexp used is \"[ \f\t\n\r\v]\" but can be -overwritten by specifying a regexp as a second argument." + "Strip a trailing space or carriage return from STRING. +The default regexp used is \"[ \\f\\t\\n\\r\\v]\" but another one +can be specified as the REGEXP argument." (let ((regexp (or regexp "[ \f\t\n\r\v]"))) (while (and (> (length string) 0) (string-match regexp (substring string -1))) @@ -2650,12 +2954,12 @@ overwritten by specifying a regexp as a second argument." string)) (defun org-babel-trim (string &optional regexp) - "Strip leading and trailing spaces and carriage returns from STRING. -Like `org-babel-chomp' only it runs on both the front and back -of the string." - (org-babel-chomp (org-reverse-string - (org-babel-chomp (org-reverse-string string) regexp)) - regexp)) + "Strip a leading and trailing space or carriage return from STRING. +Like `org-babel-chomp', but run on both the first and last +character of the string." + (org-babel-chomp + (org-reverse-string + (org-babel-chomp (org-reverse-string string) regexp)) regexp)) (defun org-babel-tramp-handle-call-process-region (start end program &optional delete buffer display &rest args) @@ -2678,11 +2982,7 @@ Fixes a bug in `tramp-handle-call-process-region'." (defun org-babel-local-file-name (file) "Return the local name component of FILE." - (if (file-remote-p file) - (let (localname) - (with-parsed-tramp-file-name file nil - localname)) - file)) + (or (file-remote-p file 'localname) file)) (defun org-babel-process-file-name (name &optional no-quote-p) "Prepare NAME to be used in an external process. @@ -2691,7 +2991,7 @@ 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'" - (let ((f (expand-file-name (org-babel-local-file-name name)))) + (let ((f (org-babel-local-file-name (expand-file-name name)))) (if no-quote-p f (shell-quote-argument f)))) (defvar org-babel-temporary-directory) @@ -2705,6 +3005,11 @@ additionally processed by `shell-quote-argument'" Used by `org-babel-temp-file'. This directory will be removed on Emacs shutdown.")) +(defcustom org-babel-remote-temporary-directory "/tmp/" + "Directory to hold temporary files on remote hosts." + :group 'org-babel + :type 'string) + (defmacro org-babel-result-cond (result-params scalar-form &rest table-forms) "Call the code to parse raw string results according to RESULT-PARAMS." (declare (indent 1) @@ -2717,6 +3022,7 @@ Emacs shutdown.")) (member "html" ,params) (member "code" ,params) (member "pp" ,params) + (member "file" ,params) (and (or (member "output" ,params) (member "raw" ,params) (member "org" ,params) @@ -2734,7 +3040,8 @@ of `org-babel-temporary-directory'." (if (file-remote-p default-directory) (let ((prefix (concat (file-remote-p default-directory) - (expand-file-name prefix temporary-file-directory)))) + (expand-file-name + prefix org-babel-remote-temporary-directory)))) (make-temp-file prefix nil suffix)) (let ((temporary-file-directory (or (and (boundp 'org-babel-temporary-directory) @@ -2769,6 +3076,69 @@ of `org-babel-temporary-directory'." (add-hook 'kill-emacs-hook 'org-babel-remove-temporary-directory) +(defun org-babel-one-header-arg-safe-p (pair safe-list) + "Determine if the PAIR is a safe babel header arg according to SAFE-LIST. + +For the format of SAFE-LIST, see `org-babel-safe-header-args'." + (and (consp pair) + (keywordp (car pair)) + (stringp (cdr pair)) + (or + (memq (car pair) safe-list) + (let ((entry (assq (car pair) safe-list))) + (and entry + (consp entry) + (cond ((functionp (cdr entry)) + (funcall (cdr entry) (cdr pair))) + ((listp (cdr entry)) + (member (cdr pair) (cdr entry))) + (t nil))))))) + +(defun org-babel-generate-file-param (src-name params) + "Calculate the filename for source block results. + +The directory is calculated from the :output-dir property of the +source block; if not specified, use the current directory. + +If the source block has a #+NAME and the :file parameter does not +contain any period characters, then the :file parameter is +treated as an extension, and the output file name is the +concatenation of the directory (as calculated above), the block +name, a period, and the parameter value as a file extension. +Otherwise, the :file parameter is treated as a full file name, +and the output file name is the directory (as calculated above) +plus the parameter value." + (let* ((file-cons (assq :file params)) + (file-ext-cons (assq :file-ext params)) + (file-ext (cdr-safe file-ext-cons)) + (dir (cdr-safe (assq :output-dir params))) + fname) + ;; create the output-dir if it does not exist + (when dir + (make-directory dir t)) + (if file-cons + ;; :file given; add :output-dir if given + (when dir + (setcdr file-cons (concat (file-name-as-directory dir) (cdr file-cons)))) + ;; :file not given; compute from name and :file-ext if possible + (when (and src-name file-ext) + (if dir + (setq fname (concat (file-name-as-directory (or dir "")) + src-name "." file-ext)) + (setq fname (concat src-name "." file-ext))) + (setq params (cons (cons :file fname) params)))) + params)) + +;;; Used by backends: R, Maxima, Octave. +(defun org-babel-graphical-output-file (params) + "File where a babel block should send graphical output, per PARAMS." + (unless (assq :file params) + (if (assq :file-ext params) + (user-error ":file-ext given but no :file generated; did you forget to give a block a #+NAME?") + (user-error "No :file header argument given; cannot create graphical result."))) + (and (member "graphics" (cdr (assq :result-params params))) + (cdr (assq :file params)))) + (provide 'ob-core) ;; Local variables: diff --git a/elpa/org-20150629/ob-css.el b/elpa/org-20160215/ob-css.el similarity index 96% rename from elpa/org-20150629/ob-css.el rename to elpa/org-20160215/ob-css.el index 2fedb354..7f3d81ab 100644 --- a/elpa/org-20150629/ob-css.el +++ b/elpa/org-20160215/ob-css.el @@ -1,6 +1,6 @@ ;;; ob-css.el --- org-babel functions for css evaluation -;; Copyright (C) 2009-2014 Free Software Foundation, Inc. +;; Copyright (C) 2009-2016 Free Software Foundation, Inc. ;; Author: Eric Schulte ;; Keywords: literate programming, reproducible research diff --git a/elpa/org-20150629/ob-ditaa.el b/elpa/org-20160215/ob-ditaa.el similarity index 92% rename from elpa/org-20150629/ob-ditaa.el rename to elpa/org-20160215/ob-ditaa.el index 26f0e4f4..54238f30 100644 --- a/elpa/org-20150629/ob-ditaa.el +++ b/elpa/org-20160215/ob-ditaa.el @@ -1,6 +1,6 @@ ;;; ob-ditaa.el --- org-babel functions for ditaa evaluation -;; Copyright (C) 2009-2014 Free Software Foundation, Inc. +;; Copyright (C) 2009-2016 Free Software Foundation, Inc. ;; Author: Eric Schulte ;; Keywords: literate programming, reproducible research @@ -90,6 +90,14 @@ This function is called by `org-babel-execute-src-block'." (java (cdr (assoc :java params))) (in-file (org-babel-temp-file "ditaa-")) (eps (cdr (assoc :eps params))) + (eps-file (when eps + (org-babel-process-file-name (concat in-file ".eps")))) + (pdf-cmd (when (and (or (string= (file-name-extension out-file) "pdf") + (cdr (assoc :pdf params)))) + (concat + "epstopdf" + " " eps-file + " -o=" (org-babel-process-file-name out-file)))) (cmd (concat org-babel-ditaa-java-cmd " " java " " org-ditaa-jar-option " " (shell-quote-argument @@ -97,13 +105,9 @@ This function is called by `org-babel-execute-src-block'." (if eps org-ditaa-eps-jar-path org-ditaa-jar-path))) " " cmdline " " (org-babel-process-file-name in-file) - " " (org-babel-process-file-name out-file))) - (pdf-cmd (when (and (or (string= (file-name-extension out-file) "pdf") - (cdr (assoc :pdf params)))) - (concat - "epstopdf" - " " (org-babel-process-file-name (concat in-file ".eps")) - " -o=" (org-babel-process-file-name out-file))))) + " " (if pdf-cmd + eps-file + (org-babel-process-file-name out-file))))) (unless (file-exists-p org-ditaa-jar-path) (error "Could not find ditaa.jar at %s" org-ditaa-jar-path)) (with-temp-file in-file (insert body)) diff --git a/elpa/org-20150629/ob-dot.el b/elpa/org-20160215/ob-dot.el similarity index 96% rename from elpa/org-20150629/ob-dot.el rename to elpa/org-20160215/ob-dot.el index b35d7bbc..e2e88578 100644 --- a/elpa/org-20150629/ob-dot.el +++ b/elpa/org-20160215/ob-dot.el @@ -1,6 +1,6 @@ ;;; ob-dot.el --- org-babel functions for dot evaluation -;; Copyright (C) 2009-2014 Free Software Foundation, Inc. +;; Copyright (C) 2009-2016 Free Software Foundation, Inc. ;; Author: Eric Schulte ;; Keywords: literate programming, reproducible research @@ -53,9 +53,11 @@ (value (cdr pair))) (setq body (replace-regexp-in-string - (concat "\$" (regexp-quote name)) + (concat "$" (regexp-quote name)) (if (stringp value) value (format "%S" value)) - body)))) + body + t + t)))) vars) body)) diff --git a/elpa/org-20160215/ob-ebnf.el b/elpa/org-20160215/ob-ebnf.el new file mode 100644 index 00000000..9a78f6ae --- /dev/null +++ b/elpa/org-20160215/ob-ebnf.el @@ -0,0 +1,85 @@ +;;; ob-ebnf.el --- org-babel functions for ebnf evaluation + +;; Copyright (C) 2013-2016 Free Software Foundation, Inc. + +;; Author: Michael Gauland +;; Keywords: literate programming, reproducible research +;; Homepage: http://orgmode.org +;; Version: 1.00 + +;;; License: + +;; 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, 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 GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +;; Boston, MA 02110-1301, USA. + +;;; Commentary: + +;;; Org-Babel support for using ebnf2ps to generate encapsulated postscript +;;; railroad diagrams. It recogises these arguments: +;;; +;;; :file is required; it must include the extension '.eps.' All the rules +;;; in the block will be drawn in the same file. This is done by +;;; inserting a '[' comment at the start of the block (see the +;;; documentation for ebnf-eps-buffer for more information). +;;; +;;; :style specifies a value in ebnf-style-database. This provides the +;;; ability to customise the output. The style can also specify the +;;; grammar syntax (by setting ebnf-syntax); note that only ebnf, +;;; iso-ebnf, and yacc are supported by this file. + +;;; Requirements: + +;;; Code: +(require 'ob) +(require 'ebnf2ps) + +;; optionally declare default header arguments for this language +(defvar org-babel-default-header-args:ebnf '((:style . nil))) + +;; 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'" + (save-excursion + (let* ((dest-file (cdr (assoc :file params))) + (dest-dir (file-name-directory dest-file)) + (dest-root (file-name-sans-extension + (file-name-nondirectory dest-file))) + (dest-ext (file-name-extension dest-file)) + (style (cdr (assoc :style params))) + (current-dir default-directory) + (result nil)) + (with-temp-buffer + (when style (ebnf-push-style style)) + (let ((comment-format + (cond ((string= ebnf-syntax 'yacc) "/*%s*/") + ((string= ebnf-syntax 'ebnf) ";%s") + ((string= ebnf-syntax 'iso-ebnf) "(*%s*)") + (t (setq result + (format "EBNF error: format %s not supported." + ebnf-syntax)))))) + (setq ebnf-eps-prefix dest-dir) + (insert (format comment-format (format "[%s" dest-root))) + (newline) + (insert body) + (newline) + (insert (format comment-format (format "]%s" dest-root))) + (ebnf-eps-buffer) + (when style (ebnf-pop-style)))) + result))) + +(provide 'ob-ebnf) +;;; ob-ebnf.el ends here diff --git a/elpa/org-20150629/ob-emacs-lisp.el b/elpa/org-20160215/ob-emacs-lisp.el similarity index 93% rename from elpa/org-20150629/ob-emacs-lisp.el rename to elpa/org-20160215/ob-emacs-lisp.el index 3219344d..eaa11246 100644 --- a/elpa/org-20150629/ob-emacs-lisp.el +++ b/elpa/org-20160215/ob-emacs-lisp.el @@ -1,6 +1,6 @@ ;;; ob-emacs-lisp.el --- org-babel functions for emacs-lisp code evaluation -;; Copyright (C) 2009-2014 Free Software Foundation, Inc. +;; Copyright (C) 2009-2016 Free Software Foundation, Inc. ;; Author: Eric Schulte ;; Keywords: literate programming, reproducible research @@ -28,12 +28,9 @@ ;;; Code: (require 'ob) -(defvar org-babel-default-header-args:emacs-lisp - '((:hlines . "yes") (:colnames . "no")) +(defvar org-babel-default-header-args:emacs-lisp nil "Default arguments for evaluating an emacs-lisp source block.") -(declare-function orgtbl-to-generic "org-table" (table params)) - (defun org-babel-expand-body:emacs-lisp (body params) "Expand BODY according to PARAMS, return the expanded body." (let* ((vars (mapcar #'cdr (org-babel-get-header params :var))) diff --git a/elpa/org-20150629/ob-eval.el b/elpa/org-20160215/ob-eval.el similarity index 93% rename from elpa/org-20150629/ob-eval.el rename to elpa/org-20160215/ob-eval.el index 057590f0..e3ac3833 100644 --- a/elpa/org-20150629/ob-eval.el +++ b/elpa/org-20160215/ob-eval.el @@ -1,6 +1,6 @@ ;;; ob-eval.el --- org-babel functions for external code evaluation -;; Copyright (C) 2009-2014 Free Software Foundation, Inc. +;; Copyright (C) 2009-2016 Free Software Foundation, Inc. ;; Author: Eric Schulte ;; Keywords: literate programming, reproducible research, comint @@ -57,6 +57,13 @@ STDERR with `org-babel-eval-error-notify'." (progn (with-current-buffer err-buff (org-babel-eval-error-notify exit-code (buffer-string))) + (save-excursion + (when (get-buffer org-babel-error-buffer-name) + (with-current-buffer org-babel-error-buffer-name + (unless (derived-mode-p 'compilation-mode) + (compilation-mode)) + ;; Compilation-mode enforces read-only, but Babel expects the buffer modifiable. + (setq buffer-read-only nil)))) nil) (buffer-string))))) diff --git a/elpa/org-20150629/ob-exp.el b/elpa/org-20160215/ob-exp.el similarity index 55% rename from elpa/org-20150629/ob-exp.el rename to elpa/org-20160215/ob-exp.el index 761c9f17..983d53c1 100644 --- a/elpa/org-20150629/ob-exp.el +++ b/elpa/org-20160215/ob-exp.el @@ -1,6 +1,6 @@ ;;; ob-exp.el --- Exportation of org-babel source blocks -;; Copyright (C) 2009-2014 Free Software Foundation, Inc. +;; Copyright (C) 2009-2016 Free Software Foundation, Inc. ;; Authors: Eric Schulte ;; Dan Davison @@ -28,7 +28,6 @@ (eval-when-compile (require 'cl)) -(defvar org-current-export-file) (defvar org-babel-lob-one-liner-regexp) (defvar org-babel-ref-split-regexp) (defvar org-list-forbidden-blocks) @@ -39,21 +38,23 @@ (start-re end-re &optional lim-up lim-down)) (declare-function org-get-indentation "org" (&optional line)) (declare-function org-heading-components "org" ()) +(declare-function org-in-commented-heading-p "org" (&optional no-inheritance)) (declare-function org-in-block-p "org" (names)) (declare-function org-in-verbatim-emphasis "org" ()) -(declare-function org-link-search "org" (s &optional type avoid-pos stealth)) +(declare-function org-link-search "org" (s &optional avoid-pos stealth)) (declare-function org-fill-template "org" (template alist)) (declare-function org-split-string "org" (string &optional separators)) -(declare-function org-element-at-point "org-element" (&optional keep-trail)) +(declare-function org-element-at-point "org-element" ()) (declare-function org-element-context "org-element" ()) (declare-function org-element-property "org-element" (property element)) (declare-function org-element-type "org-element" (element)) +(declare-function org-id-get "org-id" (&optional pom create prefix)) (declare-function org-escape-code-in-string "org-src" (s)) (defcustom org-export-babel-evaluate t "Switch controlling code evaluation during export. When set to nil no code will be evaluated as part of the export -process. When set to 'inline-only, only inline code blocks will +process. When set to `inline-only', only inline code blocks will be executed." :group 'org-babel :version "24.1" @@ -62,35 +63,35 @@ be executed." (const :tag "Always" t))) (put 'org-export-babel-evaluate 'safe-local-variable (lambda (x) (eq x nil))) -(defun org-babel-exp-get-export-buffer () - "Return the current export buffer if possible." - (cond - ((bufferp org-current-export-file) org-current-export-file) - (org-current-export-file (get-file-buffer org-current-export-file)) - ('otherwise - (error "Requested export buffer when `org-current-export-file' is nil")))) - (defvar org-link-search-inhibit-query) - (defmacro org-babel-exp-in-export-file (lang &rest body) (declare (indent 1)) `(let* ((lang-headers (intern (concat "org-babel-default-header-args:" ,lang))) - (heading (nth 4 (ignore-errors (org-heading-components)))) + (heading-query (or (org-id-get) + ;; CUSTOM_IDs don't work, maybe they are + ;; stripped, or maybe they resolve too + ;; late in `org-link-search'. + ;; (org-entry-get nil "CUSTOM_ID") + (nth 4 (ignore-errors (org-heading-components))))) (export-buffer (current-buffer)) - (original-buffer (org-babel-exp-get-export-buffer)) results) - (when original-buffer - ;; resolve parameters in the original file so that - ;; headline and file-wide parameters are included, attempt - ;; to go to the same heading in the original file - (set-buffer original-buffer) + results) + (when org-babel-exp-reference-buffer + ;; Resolve parameters in the original file so that headline and + ;; file-wide parameters are included, attempt to go to the same + ;; heading in the original file + (set-buffer org-babel-exp-reference-buffer) (save-restriction - (when heading + (when heading-query (condition-case nil (let ((org-link-search-inhibit-query t)) - (org-link-search heading)) - (error (when heading + ;; TODO: When multiple headings have the same title, + ;; this returns the first, which is not always + ;; the right heading. Consider a better way to + ;; find the proper heading. + (org-link-search heading-query)) + (error (when heading-query (goto-char (point-min)) - (re-search-forward (regexp-quote heading) nil t))))) + (re-search-forward (regexp-quote heading-query) nil t))))) (setq results ,@body)) (set-buffer export-buffer) results))) @@ -98,7 +99,7 @@ be executed." (defun org-babel-exp-src-block (&rest headers) "Process source block for export. -Depending on the 'export' headers argument, replace the source +Depending on the `export' headers argument, replace the source code block like this: both ---- display the code and the results @@ -107,18 +108,20 @@ code ---- the default, display the code inside the block but do not process results - just like none only the block is run on export ensuring - that it's results are present in the org-mode buffer + that its results are present in the org-mode buffer none ---- do not display either code or results upon export Assume point is at the beginning of block's starting line." (interactive) - (unless noninteractive (message "org-babel-exp processing...")) (save-excursion (let* ((info (org-babel-get-src-block-info 'light)) + (line (org-current-line)) (lang (nth 0 info)) (raw-params (nth 2 info)) hash) ;; bail if we couldn't get any info from the block + (unless noninteractive + (message "org-babel-exp process %s at line %d..." lang line)) (when info ;; if we're actually going to need the parameters (when (member (cdr (assoc :exports (nth 2 info))) '("both" "results")) @@ -151,138 +154,152 @@ this template." :type 'string) (defvar org-babel-default-lob-header-args) -(defun org-babel-exp-process-buffer () - "Execute all Babel blocks in current buffer." +(defun org-babel-exp-process-buffer (reference-buffer) + "Execute all Babel blocks in current buffer. +REFERENCE-BUFFER is the buffer containing a pristine copy of the +buffer being processed. It is used to properly resolve +references in source blocks, as modifications in current buffer +may make them unreachable." (interactive) (save-window-excursion (save-excursion (let ((case-fold-search t) + (org-babel-exp-reference-buffer reference-buffer) (regexp (concat org-babel-inline-src-block-regexp "\\|" org-babel-lob-one-liner-regexp "\\|" "^[ \t]*#\\+BEGIN_SRC"))) (goto-char (point-min)) (while (re-search-forward regexp nil t) - (let* ((element (save-excursion - ;; If match is inline, point is at its - ;; end. Move backward so - ;; `org-element-context' can get the - ;; object, not the following one. - (backward-char) - (save-match-data (org-element-context)))) - (type (org-element-type element)) - (begin (copy-marker (org-element-property :begin element))) - (end (copy-marker - (save-excursion - (goto-char (org-element-property :end element)) - (skip-chars-backward " \r\t\n") - (point))))) - (case type - (inline-src-block - (let* ((info (org-babel-parse-inline-src-block-match)) - (params (nth 2 info))) - (setf (nth 1 info) - (if (and (cdr (assoc :noweb params)) - (string= "yes" (cdr (assoc :noweb params)))) - (org-babel-expand-noweb-references - info (org-babel-exp-get-export-buffer)) - (nth 1 info))) - (goto-char begin) - (let ((replacement (org-babel-exp-do-export info 'inline))) - (if (equal replacement "") - ;; Replacement code is empty: remove inline src - ;; block, including extra white space that - ;; might have been created when inserting - ;; results. - (delete-region begin - (progn (goto-char end) - (skip-chars-forward " \t") - (point))) - ;; Otherwise: remove inline src block but - ;; preserve following white spaces. Then insert - ;; value. - (delete-region begin end) - (insert replacement))))) - ((babel-call inline-babel-call) - (let* ((lob-info (org-babel-lob-get-info)) - (results - (org-babel-exp-do-export - (list "emacs-lisp" "results" - (apply #'org-babel-merge-params - org-babel-default-header-args - org-babel-default-lob-header-args - (append - (org-babel-params-from-properties) - (list - (org-babel-parse-header-arguments - (org-no-properties - (concat - ":var results=" - (mapconcat 'identity - (butlast lob-info 2) - " "))))))) - "" (nth 3 lob-info) (nth 2 lob-info)) - 'lob)) - (rep (org-fill-template - org-babel-exp-call-line-template - `(("line" . ,(nth 0 lob-info)))))) - ;; If replacement is empty, completely remove the - ;; object/element, including any extra white space - ;; that might have been created when including - ;; results. - (if (equal rep "") - (delete-region - begin - (progn (goto-char end) - (if (not (eq type 'babel-call)) - (progn (skip-chars-forward " \t") (point)) - (skip-chars-forward " \r\t\n") - (line-beginning-position)))) - ;; Otherwise, preserve following white - ;; spaces/newlines and then, insert replacement - ;; string. + (unless (save-match-data (org-in-commented-heading-p)) + (let* ((element (save-excursion + ;; If match is inline, point is at its + ;; end. Move backward so + ;; `org-element-context' can get the + ;; object, not the following one. + (backward-char) + (save-match-data (org-element-context)))) + (type (org-element-type element)) + (begin (copy-marker (org-element-property :begin element))) + (end (copy-marker + (save-excursion + (goto-char (org-element-property :end element)) + (skip-chars-backward " \r\t\n") + (point))))) + (case type + (inline-src-block + (let* ((head (match-beginning 0)) + (info (append (org-babel-parse-inline-src-block-match) + (list nil nil head))) + (params (nth 2 info))) + (setf (nth 1 info) + (if (and (cdr (assoc :noweb params)) + (string= "yes" (cdr (assoc :noweb params)))) + (org-babel-expand-noweb-references + info org-babel-exp-reference-buffer) + (nth 1 info))) (goto-char begin) - (delete-region begin end) - (insert rep)))) - (src-block - (let* ((match-start (copy-marker (match-beginning 0))) - (ind (org-get-indentation)) - (headers - (cons - (org-element-property :language element) - (let ((params (org-element-property :parameters - element))) - (and params (org-split-string params "[ \t]+")))))) - ;; Take care of matched block: compute replacement - ;; string. In particular, a nil REPLACEMENT means - ;; the block should be left as-is while an empty - ;; string should remove the block. - (let ((replacement (progn (goto-char match-start) - (org-babel-exp-src-block headers)))) - (cond ((not replacement) (goto-char end)) - ((equal replacement "") - (goto-char end) - (skip-chars-forward " \r\t\n") - (beginning-of-line) - (delete-region begin (point))) - (t - (goto-char match-start) - (delete-region (point) - (save-excursion (goto-char end) - (line-end-position))) - (insert replacement) - (if (or org-src-preserve-indentation - (org-element-property :preserve-indent - element)) - ;; Indent only the code block markers. - (save-excursion (skip-chars-backward " \r\t\n") - (indent-line-to ind) - (goto-char match-start) - (indent-line-to ind)) - ;; Indent everything. - (indent-rigidly match-start (point) ind))))) - (set-marker match-start nil)))) - (set-marker begin nil) - (set-marker end nil))))))) + (let ((replacement (org-babel-exp-do-export info 'inline))) + (if (equal replacement "") + ;; Replacement code is empty: remove inline + ;; source block, including extra white space + ;; that might have been created when + ;; inserting results. + (delete-region begin + (progn (goto-char end) + (skip-chars-forward " \t") + (point))) + ;; Otherwise: remove inline src block but + ;; preserve following white spaces. Then + ;; insert value. + (delete-region begin end) + (insert replacement))))) + ((babel-call inline-babel-call) + (let* ((lob-info (org-babel-lob-get-info)) + (results + (org-babel-exp-do-export + (list "emacs-lisp" "results" + (apply #'org-babel-merge-params + org-babel-default-header-args + org-babel-default-lob-header-args + (append + (org-babel-params-from-properties) + (list + (org-babel-parse-header-arguments + (org-no-properties + (concat + ":var results=" + (mapconcat 'identity + (butlast lob-info 2) + " "))))))) + "" (nth 3 lob-info) (nth 2 lob-info)) + 'lob)) + (rep (org-fill-template + org-babel-exp-call-line-template + `(("line" . ,(nth 0 lob-info)))))) + ;; If replacement is empty, completely remove the + ;; object/element, including any extra white space + ;; that might have been created when including + ;; results. + (if (equal rep "") + (delete-region + begin + (progn (goto-char end) + (if (not (eq type 'babel-call)) + (progn (skip-chars-forward " \t") (point)) + (skip-chars-forward " \r\t\n") + (line-beginning-position)))) + ;; Otherwise, preserve following white + ;; spaces/newlines and then, insert replacement + ;; string. + (goto-char begin) + (delete-region begin end) + (insert rep)))) + (src-block + (let* ((match-start (copy-marker (match-beginning 0))) + (ind (org-get-indentation)) + (lang (or (org-element-property :language element) + (user-error + "No language for src block: %s" + (or (org-element-property :name element) + "(unnamed)")))) + (headers + (cons lang + (let ((params + (org-element-property + :parameters element))) + (and params (org-split-string params)))))) + ;; Take care of matched block: compute replacement + ;; string. In particular, a nil REPLACEMENT means + ;; the block should be left as-is while an empty + ;; string should remove the block. + (let ((replacement + (progn (goto-char match-start) + (org-babel-exp-src-block headers)))) + (cond ((not replacement) (goto-char end)) + ((equal replacement "") + (goto-char end) + (skip-chars-forward " \r\t\n") + (beginning-of-line) + (delete-region begin (point))) + (t + (goto-char match-start) + (delete-region (point) + (save-excursion (goto-char end) + (line-end-position))) + (insert replacement) + (if (or org-src-preserve-indentation + (org-element-property :preserve-indent + element)) + ;; Indent only the code block markers. + (save-excursion (skip-chars-backward " \r\t\n") + (indent-line-to ind) + (goto-char match-start) + (indent-line-to ind)) + ;; Indent everything. + (indent-rigidly match-start (point) ind))))) + (set-marker match-start nil)))) + (set-marker begin nil) + (set-marker end nil)))))))) (defun org-babel-in-example-or-verbatim () "Return true if point is in example or verbatim code. @@ -303,13 +320,15 @@ The function respects the value of the :exports header argument." (let ((silently (lambda () (let ((session (cdr (assoc :session (nth 2 info))))) (when (not (and session (equal "none" session))) (org-babel-exp-results info type 'silent))))) - (clean (lambda () (unless (eq type 'inline) (org-babel-remove-result info))))) + (clean (lambda () (if (eq type 'inline) + (org-babel-remove-inline-result) + (org-babel-remove-result info))))) (case (intern (or (cdr (assoc :exports (nth 2 info))) "code")) ('none (funcall silently) (funcall clean) "") - ('code (funcall silently) (funcall clean) (org-babel-exp-code info)) + ('code (funcall silently) (funcall clean) (org-babel-exp-code info type)) ('results (org-babel-exp-results info type nil hash) "") ('both (org-babel-exp-results info type nil hash) - (org-babel-exp-code info))))) + (org-babel-exp-code info type))))) (defcustom org-babel-exp-code-template "#+BEGIN_SRC %lang%switches%flags\n%body\n#+END_SRC" @@ -331,7 +350,29 @@ replaced with its value." :group 'org-babel :type 'string) -(defun org-babel-exp-code (info) +(defcustom org-babel-exp-inline-code-template + "src_%lang[%switches%flags]{%body}" + "Template used to export the body of inline code blocks. +This template may be customized to include additional information +such as the code block name, or the values of particular header +arguments. The template is filled out using `org-fill-template', +and the following %keys may be used. + + lang ------ the language of the code block + name ------ the name of the code block + body ------ the body of the code block + switches -- the switches associated to the code block + flags ----- the flags passed to the code block + +In addition to the keys mentioned above, every header argument +defined for the code block may be used as a key and will be +replaced with its value." + :group 'org-babel + :type 'string + :version "25.1" + :package-version '(Org . "8.3")) + +(defun org-babel-exp-code (info type) "Return the original code block formatted for export." (setf (nth 1 info) (if (string= "strip-export" (cdr (assoc :noweb (nth 2 info)))) @@ -339,10 +380,12 @@ replaced with its value." (org-babel-noweb-wrap) "" (nth 1 info)) (if (org-babel-noweb-p (nth 2 info) :export) (org-babel-expand-noweb-references - info (org-babel-exp-get-export-buffer)) + info org-babel-exp-reference-buffer) (nth 1 info)))) (org-fill-template - org-babel-exp-code-template + (if (eq type 'inline) + org-babel-exp-inline-code-template + org-babel-exp-code-template) `(("lang" . ,(nth 0 info)) ("body" . ,(org-escape-code-in-string (nth 1 info))) ("switches" . ,(let ((f (nth 3 info))) @@ -368,7 +411,7 @@ inhibit insertion of results into the buffer." (let ((lang (nth 0 info)) (body (if (org-babel-noweb-p (nth 2 info) :eval) (org-babel-expand-noweb-references - info (org-babel-exp-get-export-buffer)) + info org-babel-exp-reference-buffer) (nth 1 info))) (info (copy-sequence info)) (org-babel-current-src-block-location (point-marker))) diff --git a/elpa/org-20160215/ob-forth.el b/elpa/org-20160215/ob-forth.el new file mode 100644 index 00000000..5a46d361 --- /dev/null +++ b/elpa/org-20160215/ob-forth.el @@ -0,0 +1,86 @@ +;;; ob-forth.el --- org-babel functions for Forth + +;; Copyright (C) 2014-2016 Free Software Foundation, Inc. + +;; Author: Eric Schulte +;; Keywords: literate programming, reproducible research, forth +;; Homepage: http://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 . + +;;; Commentary: + +;; Requires the gforth forth compiler and `forth-mode' (see below). +;; https://www.gnu.org/software/gforth/ + +;;; Requirements: + +;; Session evaluation requires the gforth forth compiler as well as +;; `forth-mode' which is distributed with gforth (in gforth.el). + +;;; Code: +(require 'ob) + +(declare-function forth-proc "ext:gforth" ()) + +(defvar org-babel-default-header-args:forth '((:session . "yes")) + "Default header arguments for forth code blocks.") + +(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'" + (if (string= "none" (cdr (assoc :session params))) + (error "Non-session evaluation not supported for Forth code blocks") + (let ((all-results (org-babel-forth-session-execute body params))) + (if (member "output" (cdr (assoc :result-params params))) + (mapconcat #'identity all-results "\n") + (car (last all-results)))))) + +(defun org-babel-forth-session-execute (body params) + (require 'forth-mode) + (let ((proc (forth-proc)) + (rx " \\(\n:\\|compiled\n\\\|ok\n\\)") + (result-start)) + (with-current-buffer (process-buffer (forth-proc)) + (mapcar (lambda (line) + (setq result-start (progn (goto-char (process-mark proc)) + (point))) + (comint-send-string proc (concat line "\n")) + ;; wait for forth to say "ok" + (while (not (progn (goto-char result-start) + (re-search-forward rx nil t))) + (accept-process-output proc 0.01)) + (let ((case (match-string 1))) + (cond + ((string= "ok\n" case) + ;; Collect intermediate output. + (buffer-substring (+ result-start 1 (length line)) + (match-beginning 0))) + ((string= "compiled\n" case)) + ;; Ignore partial compilation. + ((string= "\n:" case) + ;; Report errors. + (org-babel-eval-error-notify 1 + (buffer-substring + (+ (match-beginning 0) 1) (point-max))) nil)))) + (split-string (org-babel-trim + (org-babel-expand-body:generic + body params)) + "\n" 'omit-nulls))))) + +(provide 'ob-forth) + +;;; ob-forth.el ends here diff --git a/elpa/org-20150629/ob-fortran.el b/elpa/org-20160215/ob-fortran.el similarity index 92% rename from elpa/org-20150629/ob-fortran.el rename to elpa/org-20160215/ob-fortran.el index 0211fda5..ed5d2dc6 100644 --- a/elpa/org-20150629/ob-fortran.el +++ b/elpa/org-20160215/ob-fortran.el @@ -1,6 +1,6 @@ ;;; ob-fortran.el --- org-babel functions for fortran -;; Copyright (C) 2011-2014 Free Software Foundation, Inc. +;; Copyright (C) 2011-2016 Free Software Foundation, Inc. ;; Authors: Sergey Litvinov ;; Eric Schulte @@ -33,6 +33,7 @@ (declare-function org-entry-get "org" (pom property &optional inherit literal-nil)) (declare-function org-every "org" (pred seq)) +(declare-function org-remove-indentation "org" (code &optional n)) (defvar org-babel-tangle-lang-exts) (add-to-list 'org-babel-tangle-lang-exts '("fortran" . "F90")) @@ -62,8 +63,9 @@ (org-babel-process-file-name tmp-src-file)) "")))) (let ((results (org-babel-trim - (org-babel-eval - (concat tmp-bin-file (if cmdline (concat " " cmdline) "")) "")))) + (org-remove-indentation + (org-babel-eval + (concat tmp-bin-file (if cmdline (concat " " cmdline) "")) ""))))) (org-babel-reassemble-table (org-babel-result-cond (cdr (assoc :result-params params)) (org-babel-read results) @@ -77,7 +79,7 @@ (defun org-babel-expand-body:fortran (body params) "Expand a block of fortran or fortran code with org-babel according to -it's header arguments." +its header arguments." (let ((vars (mapcar #'cdr (org-babel-get-header params :var))) (main-p (not (string= (cdr (assoc :main params)) "no"))) (includes (or (cdr (assoc :includes params)) @@ -108,7 +110,7 @@ it's header arguments." "Wrap body in a \"program ... end program\" block if none exists." (if (string-match "^[ \t]*program[ \t]*.*" (capitalize body)) (let ((vars (mapcar #'cdr (org-babel-get-header params :var)))) - (if vars (error "Cannot use :vars if 'program' statement is present")) + (if vars (error "Cannot use :vars if `program' statement is present")) body) (format "program main\n%s\nend program main\n" body))) @@ -147,15 +149,14 @@ of the same value." ;; val is a matrix ((and (listp val) (org-every #'listp val)) (format "real, parameter :: %S(%d,%d) = transpose( reshape( %s , (/ %d, %d /) ) )\n" - var (length val) (length (car val)) + var (length val) (length (car val)) (org-babel-fortran-transform-list val) (length (car val)) (length val))) ((listp val) (format "real, parameter :: %S(%d) = %s\n" var (length val) (org-babel-fortran-transform-list val))) (t - (error (format "the type of parameter %s is not supported by ob-fortran" - var)))))) + (error "the type of parameter %s is not supported by ob-fortran" var))))) (defun org-babel-fortran-transform-list (val) "Return a fortran representation of enclose syntactic lists." diff --git a/elpa/org-20150629/ob-gnuplot.el b/elpa/org-20160215/ob-gnuplot.el similarity index 94% rename from elpa/org-20150629/ob-gnuplot.el rename to elpa/org-20160215/ob-gnuplot.el index ffe5dcf5..237ecec5 100644 --- a/elpa/org-20150629/ob-gnuplot.el +++ b/elpa/org-20160215/ob-gnuplot.el @@ -1,6 +1,6 @@ ;;; ob-gnuplot.el --- org-babel functions for gnuplot evaluation -;; Copyright (C) 2009-2014 Free Software Foundation, Inc. +;; Copyright (C) 2009-2016 Free Software Foundation, Inc. ;; Author: Eric Schulte ;; Keywords: literate programming, reproducible research @@ -64,7 +64,7 @@ (term . :any)) "Gnuplot specific header args.") -(defvar org-babel-gnuplot-timestamp-fmt nil) +(defvar org-babel-gnuplot-timestamp-fmt nil) ; Dynamically scoped. (defvar *org-babel-gnuplot-missing* nil) @@ -118,14 +118,11 @@ code." (timefmt (cdr (assoc :timefmt params))) (time-ind (or (cdr (assoc :timeind params)) (when timefmt 1))) - (missing (cdr (assoc :missing params))) (add-to-body (lambda (text) (setq body (concat text "\n" body)))) output) ;; append header argument settings to body (when title (funcall add-to-body (format "set title '%s'" title))) (when lines (mapc (lambda (el) (funcall add-to-body el)) lines)) - (when missing - (funcall add-to-body (format "set datafile missing '%s'" missing))) (when sets (mapc (lambda (el) (funcall add-to-body (format "set %s" el))) sets)) (when x-labels @@ -267,15 +264,13 @@ then create one. Return the initialized session. The current "Export TABLE to DATA-FILE in a format readable by gnuplot. Pass PARAMS through to `orgtbl-to-generic' when exporting TABLE." (with-temp-file data-file - (make-local-variable 'org-babel-gnuplot-timestamp-fmt) - (setq org-babel-gnuplot-timestamp-fmt (or - (plist-get params :timefmt) - "%Y-%m-%d-%H:%M:%S")) - (insert (orgtbl-to-generic - table - (org-combine-plists - '(:sep "\t" :fmt org-babel-gnuplot-quote-tsv-field) - params)))) + (insert (let ((org-babel-gnuplot-timestamp-fmt + (or (plist-get params :timefmt) "%Y-%m-%d-%H:%M:%S"))) + (orgtbl-to-generic + table + (org-combine-plists + '(:sep "\t" :fmt org-babel-gnuplot-quote-tsv-field) + params))))) data-file) (provide 'ob-gnuplot) diff --git a/elpa/org-20160215/ob-groovy.el b/elpa/org-20160215/ob-groovy.el new file mode 100644 index 00000000..14f644cd --- /dev/null +++ b/elpa/org-20160215/ob-groovy.el @@ -0,0 +1,118 @@ +;;; ob-groovy.el --- org-babel functions for Groovy evaluation + +;; Copyright (C) 2013-2016 Free Software Foundation, Inc. + +;; Author: Miro Bezjak +;; Keywords: literate programming, reproducible research +;; Homepage: http://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 . + +;;; Commentary: +;; Currently only supports the external execution. No session support yet. + +;;; Requirements: +;; - Groovy language :: http://groovy.codehaus.org +;; - Groovy major mode :: Can be installed from MELPA or +;; https://github.com/russel/Emacs-Groovy-Mode + +;;; Code: +(require 'ob) +(eval-when-compile (require 'cl)) + +(defvar org-babel-tangle-lang-exts) ;; Autoloaded +(add-to-list 'org-babel-tangle-lang-exts '("groovy" . "groovy")) +(defvar org-babel-default-header-args:groovy '()) +(defcustom org-babel-groovy-command "groovy" + "Name of the command to use for executing Groovy code. +May be either a command in the path, like groovy +or an absolute path name, like /usr/local/bin/groovy +parameters may be used, like groovy -v" + :group 'org-babel + :version "24.3" + :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'" + (message "executing Groovy source code block") + (let* ((processed-params (org-babel-process-params params)) + (session (org-babel-groovy-initiate-session (nth 0 processed-params))) + (vars (nth 1 processed-params)) + (result-params (nth 2 processed-params)) + (result-type (cdr (assoc :result-type params))) + (full-body (org-babel-expand-body:generic + body params)) + (result (org-babel-groovy-evaluate + session full-body result-type result-params))) + + (org-babel-reassemble-table + result + (org-babel-pick-name + (cdr (assoc :colname-names params)) (cdr (assoc :colnames params))) + (org-babel-pick-name + (cdr (assoc :rowname-names params)) (cdr (assoc :rownames params)))))) + +(defvar org-babel-groovy-wrapper-method + + "class Runner extends Script { + def out = new PrintWriter(new ByteArrayOutputStream()) + def run() { %s } +} + +println(new Runner().run()) +") + + +(defun org-babel-groovy-evaluate + (session body &optional result-type result-params) + "Evaluate BODY in external Groovy process. +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." + (when session (error "Sessions are not (yet) supported for Groovy")) + (case result-type + (output + (let ((src-file (org-babel-temp-file "groovy-"))) + (progn (with-temp-file src-file (insert body)) + (org-babel-eval + (concat org-babel-groovy-command " " src-file) "")))) + (value + (let* ((src-file (org-babel-temp-file "groovy-")) + (wrapper (format org-babel-groovy-wrapper-method body))) + (with-temp-file src-file (insert wrapper)) + (let ((raw (org-babel-eval + (concat org-babel-groovy-command " " src-file) ""))) + (org-babel-result-cond result-params + raw + (org-babel-script-escape raw))))))) + + +(defun org-babel-prep-session:groovy (session params) + "Prepare SESSION according to the header arguments specified in PARAMS." + (error "Sessions are not (yet) supported for Groovy")) + +(defun org-babel-groovy-initiate-session (&optional session) + "If there is not a current inferior-process-buffer in SESSION +then create. Return the initialized session. Sessions are not +supported in Groovy." + nil) + +(provide 'ob-groovy) + + + +;;; ob-groovy.el ends here diff --git a/elpa/org-20150629/ob-haskell.el b/elpa/org-20160215/ob-haskell.el similarity index 95% rename from elpa/org-20150629/ob-haskell.el rename to elpa/org-20160215/ob-haskell.el index 00066702..e9cb3ccc 100644 --- a/elpa/org-20150629/ob-haskell.el +++ b/elpa/org-20160215/ob-haskell.el @@ -1,6 +1,6 @@ ;;; ob-haskell.el --- org-babel functions for haskell evaluation -;; Copyright (C) 2009-2014 Free Software Foundation, Inc. +;; Copyright (C) 2009-2016 Free Software Foundation, Inc. ;; Author: Eric Schulte ;; Keywords: literate programming, reproducible research @@ -84,7 +84,7 @@ (output (mapconcat #'identity (reverse (cdr results)) "\n")) (value (car results))))) (org-babel-result-cond (cdr (assoc :result-params params)) - result (org-babel-haskell-table-or-string result))) + result (org-babel-script-escape result))) (org-babel-pick-name (cdr (assoc :colname-names params)) (cdr (assoc :colname-names params))) (org-babel-pick-name (cdr (assoc :rowname-names params)) @@ -133,12 +133,6 @@ then create one. Return the initialized session." (org-babel-haskell-var-to-haskell (cdr pair)))) (mapcar #'cdr (org-babel-get-header params :var)))) -(defun org-babel-haskell-table-or-string (results) - "Convert RESULTS to an Emacs-lisp table or string. -If RESULTS look like a table, then convert them into an -Emacs-lisp table, otherwise return the results as a string." - (org-babel-script-escape results)) - (defun org-babel-haskell-var-to-haskell (var) "Convert an elisp value VAR into a haskell variable. The elisp VAR is converted to a string of haskell source code diff --git a/elpa/org-20150629/ob-io.el b/elpa/org-20160215/ob-io.el similarity index 88% rename from elpa/org-20150629/ob-io.el rename to elpa/org-20160215/ob-io.el index 971b37fc..ec2cd02c 100644 --- a/elpa/org-20150629/ob-io.el +++ b/elpa/org-20160215/ob-io.el @@ -1,6 +1,6 @@ ;;; ob-io.el --- org-babel functions for Io evaluation -;; Copyright (C) 2012-2014 Free Software Foundation, Inc. +;; Copyright (C) 2012-2016 Free Software Foundation, Inc. ;; Author: Andrzej Lichnerowicz ;; Keywords: literate programming, reproducible research @@ -62,14 +62,6 @@ called by `org-babel-execute-src-block'" (org-babel-pick-name (cdr (assoc :rowname-names params)) (cdr (assoc :rownames params)))))) - -(defun org-babel-io-table-or-string (results) - "Convert RESULTS into an appropriate elisp value. -If RESULTS look like a table, then convert them into an -Emacs-lisp table, otherwise return the results as a string." - (org-babel-script-escape results)) - - (defvar org-babel-io-wrapper-method "( %s @@ -79,8 +71,8 @@ Emacs-lisp table, otherwise return the results as a string." (defun org-babel-io-evaluate (session body &optional result-type result-params) "Evaluate BODY in external Io process. -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 +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." (when session (error "Sessions are not (yet) supported for Io")) (case result-type @@ -98,7 +90,7 @@ in BODY as elisp." (concat org-babel-io-command " " src-file) ""))) (org-babel-result-cond result-params raw - (org-babel-io-table-or-string raw))))))) + (org-babel-script-escape raw))))))) (defun org-babel-prep-session:io (session params) diff --git a/elpa/org-20150629/ob-java.el b/elpa/org-20160215/ob-java.el similarity index 80% rename from elpa/org-20150629/ob-java.el rename to elpa/org-20160215/ob-java.el index 22f8785f..5856c65d 100644 --- a/elpa/org-20150629/ob-java.el +++ b/elpa/org-20160215/ob-java.el @@ -1,6 +1,6 @@ ;;; ob-java.el --- org-babel functions for java evaluation -;; Copyright (C) 2011-2014 Free Software Foundation, Inc. +;; Copyright (C) 2011-2016 Free Software Foundation, Inc. ;; Author: Eric Schulte ;; Keywords: literate programming, reproducible research @@ -32,11 +32,23 @@ (defvar org-babel-tangle-lang-exts) (add-to-list 'org-babel-tangle-lang-exts '("java" . "java")) -(defvar org-babel-java-command "java" - "Name of the java command.") - -(defvar org-babel-java-compiler "javac" - "Name of the java compiler.") +(defcustom org-babel-java-command "java" + "Name of the java command. +May be either a command in the path, like java +or an absolute path name, like /usr/local/bin/java +parameters may be used, like java -verbose" + :group 'org-babel + :version "24.3" + :type 'string) + +(defcustom org-babel-java-compiler "javac" + "Name of the java compiler. +May be either a command in the path, like javac +or an absolute path name, like /usr/local/bin/javac +parameters may be used, like javac -verbose" + :group 'org-babel + :version "24.3" + :type 'string) (defun org-babel-execute:java (body params) (let* ((classname (or (cdr (assoc :classname params)) diff --git a/elpa/org-20150629/ob-js.el b/elpa/org-20160215/ob-js.el similarity index 95% rename from elpa/org-20150629/ob-js.el rename to elpa/org-20160215/ob-js.el index ea51ed98..9440aa93 100644 --- a/elpa/org-20150629/ob-js.el +++ b/elpa/org-20160215/ob-js.el @@ -1,6 +1,6 @@ ;;; ob-js.el --- org-babel functions for Javascript -;; Copyright (C) 2010-2014 Free Software Foundation, Inc. +;; Copyright (C) 2010-2016 Free Software Foundation, Inc. ;; Author: Eric Schulte ;; Keywords: literate programming, reproducible research, js @@ -97,14 +97,15 @@ This function is called by `org-babel-execute-src-block'" If RESULTS look like a table, then convert them into an Emacs-lisp table, otherwise return the results as a string." (org-babel-read - (if (and (stringp results) (string-match "^\\[.+\\]$" results)) + (if (and (stringp results) (string-match "^\\[[^\000]+\\]$" results)) (org-babel-read (concat "'" (replace-regexp-in-string "\\[" "(" (replace-regexp-in-string "\\]" ")" (replace-regexp-in-string - ", " " " (replace-regexp-in-string - "'" "\"" results)))))) + ",[[:space:]]" " " + (replace-regexp-in-string + "'" "\"" results)))))) results))) (defun org-babel-js-var-to-js (var) diff --git a/elpa/org-20150629/ob-keys.el b/elpa/org-20160215/ob-keys.el similarity index 97% rename from elpa/org-20150629/ob-keys.el rename to elpa/org-20160215/ob-keys.el index 90b5196c..6a634564 100644 --- a/elpa/org-20150629/ob-keys.el +++ b/elpa/org-20160215/ob-keys.el @@ -1,6 +1,6 @@ ;;; ob-keys.el --- key bindings for org-babel -;; Copyright (C) 2009-2014 Free Software Foundation, Inc. +;; Copyright (C) 2009-2016 Free Software Foundation, Inc. ;; Author: Eric Schulte ;; Keywords: literate programming, reproducible research @@ -89,6 +89,7 @@ functions which are assigned key bindings, and see ("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 diff --git a/elpa/org-20150629/ob-latex.el b/elpa/org-20160215/ob-latex.el similarity index 86% rename from elpa/org-20150629/ob-latex.el rename to elpa/org-20160215/ob-latex.el index 35b66507..681e2296 100644 --- a/elpa/org-20150629/ob-latex.el +++ b/elpa/org-20160215/ob-latex.el @@ -1,6 +1,6 @@ ;;; ob-latex.el --- org-babel functions for latex "evaluation" -;; Copyright (C) 2009-2014 Free Software Foundation, Inc. +;; Copyright (C) 2009-2016 Free Software Foundation, Inc. ;; Author: Eric Schulte ;; Keywords: literate programming, reproducible research @@ -50,7 +50,18 @@ '((:results . "latex") (:exports . "results")) "Default arguments to use when evaluating a LaTeX source block.") -(defcustom org-babel-latex-htlatex "" +(defconst org-babel-header-args:latex + '((border . :any) + (fit . :any) + (iminoptions . :any) + (imoutoptions . :any) + (packages . :any) + (pdfheight . :any) + (pdfpng . :any) + (pdfwidth . :any)) + "LaTeX-specific header arguments.") + +(defcustom org-babel-latex-htlatex "htlatex" "The htlatex command to enable conversion of latex to SVG or HTML." :group 'org-babel :type 'string) @@ -99,6 +110,51 @@ This function is called by `org-babel-execute-src-block'." (when (file-exists-p out-file) (delete-file out-file)) (with-temp-file out-file (insert body))) + ((and (or (string-match "\\.svg$" out-file) + (string-match "\\.html$" out-file)) + (executable-find org-babel-latex-htlatex)) + ;; TODO: this is a very different way of generating the + ;; frame latex document than in the pdf case. Ideally, both + ;; would be unified. This would prevent bugs creeping in + ;; such as the one fixed on Aug 16 2014 whereby :headers was + ;; not included in the SVG/HTML case. + (with-temp-file tex-file + (insert (concat + "\\documentclass[preview]{standalone} +\\def\\pgfsysdriver{pgfsys-tex4ht.def} +" + (mapconcat (lambda (pkg) + (concat "\\usepackage" pkg)) + org-babel-latex-htlatex-packages + "\n") + (if headers + (concat "\n" + (if (listp headers) + (mapconcat #'identity headers "\n") + headers) "\n") + "") + "\\begin{document}" + body + "\\end{document}"))) + (when (file-exists-p out-file) (delete-file out-file)) + (let ((default-directory (file-name-directory tex-file))) + (shell-command (format "%s %s" org-babel-latex-htlatex tex-file))) + (cond + ((file-exists-p (concat (file-name-sans-extension tex-file) "-1.svg")) + (if (string-match "\\.svg$" out-file) + (progn + (shell-command "pwd") + (shell-command (format "mv %s %s" + (concat (file-name-sans-extension tex-file) "-1.svg") + out-file))) + (error "SVG file produced but HTML file requested"))) + ((file-exists-p (concat (file-name-sans-extension tex-file) ".html")) + (if (string-match "\\.html$" out-file) + (shell-command "mv %s %s" + (concat (file-name-sans-extension tex-file) + ".html") + out-file) + (error "HTML file produced but SVG file requested"))))) ((or (string-match "\\.pdf$" out-file) imagemagick) (with-temp-file tex-file (require 'ox-latex) @@ -135,55 +191,21 @@ This function is called by `org-babel-execute-src-block'." ((string-match "\\.pdf$" out-file) (rename-file transient-pdf-file out-file)) (imagemagick - (convert-pdf + (org-babel-latex-convert-pdf transient-pdf-file out-file im-in-options im-out-options) (when (file-exists-p transient-pdf-file) (delete-file transient-pdf-file)))))) - ((and (or (string-match "\\.svg$" out-file) - (string-match "\\.html$" out-file)) - (not (string= "" org-babel-latex-htlatex))) - (with-temp-file tex-file - (insert (concat - "\\documentclass[preview]{standalone} -\\def\\pgfsysdriver{pgfsys-tex4ht.def} -" - (mapconcat (lambda (pkg) - (concat "\\usepackage" pkg)) - org-babel-latex-htlatex-packages - "\n") - "\\begin{document}" - body - "\\end{document}"))) - (when (file-exists-p out-file) (delete-file out-file)) - (let ((default-directory (file-name-directory tex-file))) - (shell-command (format "%s %s" org-babel-latex-htlatex tex-file))) - (cond - ((file-exists-p (concat (file-name-sans-extension tex-file) "-1.svg")) - (if (string-match "\\.svg$" out-file) - (progn - (shell-command "pwd") - (shell-command (format "mv %s %s" - (concat (file-name-sans-extension tex-file) "-1.svg") - out-file))) - (error "SVG file produced but HTML file requested."))) - ((file-exists-p (concat (file-name-sans-extension tex-file) ".html")) - (if (string-match "\\.html$" out-file) - (shell-command "mv %s %s" - (concat (file-name-sans-extension tex-file) - ".html") - out-file) - (error "HTML file produced but SVG file requested."))))) ((string-match "\\.\\([^\\.]+\\)$" out-file) (error "Can not create %s files, please specify a .png or .pdf file or try the :imagemagick header argument" (match-string 1 out-file)))) nil) ;; signal that output has already been written to file body)) -(defun convert-pdf (pdffile out-file im-in-options im-out-options) +(defun org-babel-latex-convert-pdf (pdffile out-file im-in-options im-out-options) "Generate a file from a pdf file using imagemagick." (let ((cmd (concat "convert " im-in-options " " pdffile " " im-out-options " " out-file))) - (message (concat "Converting pdffile file " cmd "...")) + (message "Converting pdffile file %s..." cmd) (shell-command cmd))) (defun org-babel-latex-tex-to-pdf (file) diff --git a/elpa/org-20150629/ob-ledger.el b/elpa/org-20160215/ob-ledger.el similarity index 97% rename from elpa/org-20150629/ob-ledger.el rename to elpa/org-20160215/ob-ledger.el index 806fec61..d07f257a 100644 --- a/elpa/org-20150629/ob-ledger.el +++ b/elpa/org-20160215/ob-ledger.el @@ -1,6 +1,6 @@ ;;; ob-ledger.el --- org-babel functions for ledger evaluation -;; Copyright (C) 2010-2014 Free Software Foundation, Inc. +;; Copyright (C) 2010-2016 Free Software Foundation, Inc. ;; Author: Eric S Fraga ;; Keywords: literate programming, reproducible research, accounting diff --git a/elpa/org-20150629/ob-lilypond.el b/elpa/org-20160215/ob-lilypond.el similarity index 77% rename from elpa/org-20150629/ob-lilypond.el rename to elpa/org-20160215/ob-lilypond.el index 00a951d3..bfbace52 100644 --- a/elpa/org-20150629/ob-lilypond.el +++ b/elpa/org-20160215/ob-lilypond.el @@ -1,6 +1,6 @@ ;;; ob-lilypond.el --- org-babel functions for lilypond evaluation -;; Copyright (C) 2010-2014 Free Software Foundation, Inc. +;; Copyright (C) 2010-2016 Free Software Foundation, Inc. ;; Author: Martyn Jago ;; Keywords: babel language, literate programming @@ -28,6 +28,8 @@ ;; ;; Lilypond documentation can be found at ;; http://lilypond.org/manuals.html +;; +;; This depends on epstopdf --- See http://www.ctan.org/pkg/epstopdf. ;;; Code: (require 'ob) @@ -60,47 +62,64 @@ org-babel-lilypond-play-midi-post-tangle determines whether to automate the playing of the resultant midi file. If the value is nil, the midi file is not automatically played. Default value is t") -(defvar org-babel-lilypond-OSX-ly-path - "/Applications/lilypond.app/Contents/Resources/bin/lilypond") -(defvar org-babel-lilypond-OSX-pdf-path "open") -(defvar org-babel-lilypond-OSX-midi-path "open") - -(defvar org-babel-lilypond-nix-ly-path "/usr/bin/lilypond") -(defvar org-babel-lilypond-nix-pdf-path "evince") -(defvar org-babel-lilypond-nix-midi-path "timidity") - -(defvar org-babel-lilypond-w32-ly-path "lilypond") -(defvar org-babel-lilypond-w32-pdf-path "") -(defvar org-babel-lilypond-w32-midi-path "") +(defvar org-babel-lilypond-ly-command "" + "Command to execute lilypond on your system. +Do not set it directly. Customize `org-babel-lilypond-commands' instead.") +(defvar org-babel-lilypond-pdf-command "" + "Command to show a PDF file on your system. +Do not set it directly. Customize `org-babel-lilypond-commands' instead.") +(defvar org-babel-lilypond-midi-command "" + "Command to play a MIDI file on your system. +Do not set it directly. Customize `org-babel-lilypond-commands' instead.") +(defcustom org-babel-lilypond-commands + (cond + ((eq system-type 'darwin) + '("/Applications/lilypond.app/Contents/Resources/bin/lilypond" "open" "open")) + ((eq system-type 'windows-nt) + '("lilypond" "" "")) + (t + '("lilypond" "xdg-open" "xdg-open"))) + "Commands to run lilypond and view or play the results. +These should be executables that take a filename as an argument. +On some system it is possible to specify the filename directly +and the viewer or player will be determined from the file type; +you can leave the string empty on this case." + :group 'org-babel + :type '(list + (string :tag "Lilypond ") + (string :tag "PDF Viewer ") + (string :tag "MIDI Player")) + :version "24.3" + :package-version '(Org . "8.2.7") + :set + (lambda (symbol value) + (setq + org-babel-lilypond-ly-command (nth 0 value) + org-babel-lilypond-pdf-command (nth 1 value) + org-babel-lilypond-midi-command (nth 2 value)))) (defvar org-babel-lilypond-gen-png nil - "Image generation (png) can be turned on by default by setting -ORG-BABEL-LILYPOND-GEN-PNG to t") + "Non-nil means image generation (PNG) is turned on by default.") (defvar org-babel-lilypond-gen-svg nil - "Image generation (SVG) can be turned on by default by setting -ORG-BABEL-LILYPOND-GEN-SVG to t") + "Non-nil means image generation (SVG) is be turned on by default.") (defvar org-babel-lilypond-gen-html nil - "HTML generation can be turned on by default by setting -ORG-BABEL-LILYPOND-GEN-HTML to t") + "Non-nil means HTML generation is turned on by default.") (defvar org-babel-lilypond-gen-pdf nil - "PDF generation can be turned on by default by setting -ORG-BABEL-LILYPOND-GEN-PDF to t") + "Non-nil means PDF generation is be turned on by default.") (defvar org-babel-lilypond-use-eps nil - "You can force the compiler to use the EPS backend by setting -ORG-BABEL-LILYPOND-USE-EPS to t") + "Non-nil forces the compiler to use the EPS backend.") (defvar org-babel-lilypond-arrange-mode nil - "Arrange mode is turned on by setting ORG-BABEL-LILYPOND-ARRANGE-MODE -to t. In Arrange mode the following settings are altered -from default... + "Non-nil turns Arrange mode on. +In Arrange mode the following settings are altered from default: :tangle yes, :noweb yes :results silent :comments yes. In addition lilypond block execution causes tangling of all lilypond -blocks") +blocks.") (defun org-babel-expand-body:lilypond (body params) "Expand BODY according to PARAMS, return the expanded body." @@ -111,7 +130,7 @@ blocks") (value (cdr pair))) (setq body (replace-regexp-in-string - (concat "\$" (regexp-quote name)) + (concat "$" (regexp-quote name)) (if (stringp value) value (format "%S" value)) body)))) vars) @@ -148,7 +167,7 @@ specific arguments to =org-babel-tangle=" (insert (org-babel-expand-body:generic body params))) (org-babel-eval (concat - (org-babel-lilypond-determine-ly-path) + org-babel-lilypond-ly-command " -dbackend=eps " "-dno-gs-load-fonts " "-dinclude-eps-fonts " @@ -175,29 +194,27 @@ If error in compilation, attempt to mark the error in lilypond org file" (buffer-file-name) ".lilypond")) (org-babel-lilypond-temp-file (org-babel-lilypond-switch-extension (buffer-file-name) ".ly"))) - (if (file-exists-p org-babel-lilypond-tangled-file) - (progn - (when (file-exists-p org-babel-lilypond-temp-file) - (delete-file org-babel-lilypond-temp-file)) - (rename-file org-babel-lilypond-tangled-file - org-babel-lilypond-temp-file)) - (error "Error: Tangle Failed!") t) + (if (not (file-exists-p org-babel-lilypond-tangled-file)) + (error "Error: Tangle Failed!") + (when (file-exists-p org-babel-lilypond-temp-file) + (delete-file org-babel-lilypond-temp-file)) + (rename-file org-babel-lilypond-tangled-file + org-babel-lilypond-temp-file)) (switch-to-buffer-other-window "*lilypond*") (erase-buffer) (org-babel-lilypond-compile-lilyfile org-babel-lilypond-temp-file) (goto-char (point-min)) - (if (not (org-babel-lilypond-check-for-compile-error org-babel-lilypond-temp-file)) - (progn - (other-window -1) - (org-babel-lilypond-attempt-to-open-pdf org-babel-lilypond-temp-file) - (org-babel-lilypond-attempt-to-play-midi org-babel-lilypond-temp-file)) - (error "Error in Compilation!")))) nil) + (if (org-babel-lilypond-check-for-compile-error org-babel-lilypond-temp-file) + (error "Error in Compilation!") + (other-window -1) + (org-babel-lilypond-attempt-to-open-pdf org-babel-lilypond-temp-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" (message "Compiling LilyPond...") - (let ((arg-1 (org-babel-lilypond-determine-ly-path)) ;program + (let ((arg-1 org-babel-lilypond-ly-command) ;program (arg-2 nil) ;infile (arg-3 "*lilypond*") ;buffer (arg-4 t) ;display @@ -223,11 +240,10 @@ 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" (let ((is-error (search-forward "error:" nil t))) - (if (not test) - (if (not is-error) - nil - (org-babel-lilypond-process-compile-error file-name)) - is-error))) + (if test + is-error + (when is-error + (org-babel-lilypond-process-compile-error file-name))))) (defun org-babel-lilypond-process-compile-error (file-name) "Process the compilation error that has occurred. @@ -249,7 +265,7 @@ LINE is the erroneous line" (setq case-fold-search nil) (if (search-forward line nil t) (progn - (show-all) + (outline-show-all) (set-mark (point)) (goto-char (- (point) (length line)))) (goto-char temp)))) @@ -298,13 +314,13 @@ If TEST is non-nil, the shell command is returned and is not run" (let ((pdf-file (org-babel-lilypond-switch-extension file-name ".pdf"))) (if (file-exists-p pdf-file) (let ((cmd-string - (concat (org-babel-lilypond-determine-pdf-path) " " pdf-file))) + (concat org-babel-lilypond-pdf-command " " pdf-file))) (if test cmd-string (start-process "\"Audition pdf\"" "*lilypond*" - (org-babel-lilypond-determine-pdf-path) + org-babel-lilypond-pdf-command pdf-file))) (message "No pdf file generated so can't display!"))))) @@ -316,49 +332,16 @@ If TEST is non-nil, the shell command is returned and is not run" (let ((midi-file (org-babel-lilypond-switch-extension file-name ".midi"))) (if (file-exists-p midi-file) (let ((cmd-string - (concat (org-babel-lilypond-determine-midi-path) " " midi-file))) + (concat org-babel-lilypond-midi-command " " midi-file))) (if test cmd-string (start-process "\"Audition midi\"" "*lilypond*" - (org-babel-lilypond-determine-midi-path) + org-babel-lilypond-midi-command midi-file))) (message "No midi file generated so can't play!"))))) -(defun org-babel-lilypond-determine-ly-path (&optional test) - "Return correct path to ly binary depending on OS -If TEST is non-nil, it contains a simulation of the OS for test purposes" - (let ((sys-type - (or test system-type))) - (cond ((string= sys-type "darwin") - org-babel-lilypond-OSX-ly-path) - ((string= sys-type "windows-nt") - org-babel-lilypond-w32-ly-path) - (t org-babel-lilypond-nix-ly-path)))) - -(defun org-babel-lilypond-determine-pdf-path (&optional test) - "Return correct path to pdf viewer depending on OS -If TEST is non-nil, it contains a simulation of the OS for test purposes" - (let ((sys-type - (or test system-type))) - (cond ((string= sys-type "darwin") - org-babel-lilypond-OSX-pdf-path) - ((string= sys-type "windows-nt") - org-babel-lilypond-w32-pdf-path) - (t org-babel-lilypond-nix-pdf-path)))) - -(defun org-babel-lilypond-determine-midi-path (&optional test) - "Return correct path to midi player depending on OS -If TEST is non-nil, it contains a simulation of the OS for test purposes" - (let ((sys-type - (or test test system-type))) - (cond ((string= sys-type "darwin") - org-babel-lilypond-OSX-midi-path) - ((string= sys-type "windows-nt") - org-babel-lilypond-w32-midi-path) - (t org-babel-lilypond-nix-midi-path)))) - (defun org-babel-lilypond-toggle-midi-play () "Toggle whether midi will be played following a successful compilation." (interactive) diff --git a/elpa/org-20150629/ob-lisp.el b/elpa/org-20160215/ob-lisp.el similarity index 76% rename from elpa/org-20150629/ob-lisp.el rename to elpa/org-20160215/ob-lisp.el index 6bddd614..04df7fbd 100644 --- a/elpa/org-20150629/ob-lisp.el +++ b/elpa/org-20160215/ob-lisp.el @@ -1,6 +1,6 @@ ;;; ob-lisp.el --- org-babel functions for common lisp evaluation -;; Copyright (C) 2009-2014 Free Software Foundation, Inc. +;; Copyright (C) 2009-2016 Free Software Foundation, Inc. ;; Authors: Joel Boehland ;; Eric Schulte @@ -44,7 +44,7 @@ (defvar org-babel-header-args:lisp '((package . :any))) (defcustom org-babel-lisp-dir-fmt - "(let ((*default-pathname-defaults* #P%S)) %%s)" + "(let ((*default-pathname-defaults* #P%S\n)) %%s\n)" "Format string used to wrap code bodies to set the current directory. For example a value of \"(progn ;; %s\\n %%s)\" would ignore the current directory string." @@ -76,23 +76,25 @@ current directory string." (require 'slime) (org-babel-reassemble-table (let ((result - (with-temp-buffer - (insert (org-babel-expand-body:lisp body params)) - (slime-eval `(swank:eval-and-grab-output - ,(let ((dir (if (assoc :dir params) - (cdr (assoc :dir params)) - default-directory))) - (format - (if dir (format org-babel-lisp-dir-fmt dir) - "(progn %s)") - (buffer-substring-no-properties - (point-min) (point-max))))) - (cdr (assoc :package params)))))) + (funcall (if (member "output" (cdr (assoc :result-params params))) + #'car #'cadr) + (with-temp-buffer + (insert (org-babel-expand-body:lisp body params)) + (slime-eval `(swank:eval-and-grab-output + ,(let ((dir (if (assoc :dir params) + (cdr (assoc :dir params)) + default-directory))) + (format + (if dir (format org-babel-lisp-dir-fmt dir) + "(progn %s\n)") + (buffer-substring-no-properties + (point-min) (point-max))))) + (cdr (assoc :package params))))))) (org-babel-result-cond (cdr (assoc :result-params params)) - (car result) + result (condition-case nil - (read (org-babel-lisp-vector-to-list (cadr result))) - (error (cadr result))))) + (read (org-babel-lisp-vector-to-list result)) + (error result)))) (org-babel-pick-name (cdr (assoc :colname-names params)) (cdr (assoc :colnames params))) (org-babel-pick-name (cdr (assoc :rowname-names params)) diff --git a/elpa/org-20150629/ob-lob.el b/elpa/org-20160215/ob-lob.el similarity index 82% rename from elpa/org-20150629/ob-lob.el rename to elpa/org-20160215/ob-lob.el index 4e635da1..cf5cb4ed 100644 --- a/elpa/org-20150629/ob-lob.el +++ b/elpa/org-20160215/ob-lob.el @@ -1,6 +1,6 @@ ;;; ob-lob.el --- functions supporting the Library of Babel -;; Copyright (C) 2009-2014 Free Software Foundation, Inc. +;; Copyright (C) 2009-2016 Free Software Foundation, Inc. ;; Authors: Eric Schulte ;; Dan Davison @@ -64,14 +64,14 @@ To add files to this list use the `org-babel-lob-ingest' command." (defconst org-babel-block-lob-one-liner-regexp (concat - "^\\([ \t]*?\\)#\\+call:[ \t]+\\([^\(\)\n]+?\\)\\(\\[\\(.*\\)\\]\\|\\(\\)\\)" - "\(\\([^\n]*?\\)\)\\(\\[.+\\]\\|\\)[ \t]*\\(\\([^\n]*\\)\\)?") + "^\\([ \t]*?\\)#\\+call:[ \t]+\\([^()\n]+?\\)\\(\\[\\(.*\\)\\]\\|\\(\\)\\)" + "(\\([^\n]*?\\))\\(\\[.+\\]\\|\\)[ \t]*\\(\\([^\n]*\\)\\)?") "Regexp to match non-inline calls to predefined source block functions.") (defconst org-babel-inline-lob-one-liner-regexp (concat - "\\([^\n]*?\\)call_\\([^\(\)\n]+?\\)\\(\\[\\(.*?\\)\\]\\|\\(\\)\\)" - "\(\\([^\n]*?\\)\)\\(\\[\\(.*?\\)\\]\\)?") + "\\([^\n]*?\\)call_\\([^()[:space:]\n]+?\\)\\(\\[\\(.*?\\)\\]\\|\\(\\)\\)" + "(\\(.*?\\))\\(\\[\\(.*?\\)\\]\\)?") "Regexp to match inline calls to predefined source block functions.") (defconst org-babel-lob-one-liner-regexp @@ -116,9 +116,10 @@ if so then run the appropriate source block from the Library." (match-string 2) (match-string 11))) (save-excursion (forward-line -1) - (and (looking-at (concat org-babel-src-name-regexp - "\\([^\n]*\\)$")) - (org-no-properties (match-string 1)))))))))) + (save-match-data + (and (looking-at (concat org-babel-src-name-regexp + "\\([^\n]*\\)$")) + (org-no-properties (match-string 1))))))))))) (defvar org-babel-default-header-args:emacs-lisp) ; Defined in ob-emacs-lisp.el (defun org-babel-lob-execute (info) @@ -142,18 +143,32 @@ if so then run the appropriate source block from the Library." (pre-info (funcall mkinfo pre-params)) (cache-p (and (cdr (assoc :cache pre-params)) (string= "yes" (cdr (assoc :cache pre-params))))) - (new-hash (when cache-p (org-babel-sha1-hash pre-info))) - (old-hash (when cache-p (org-babel-current-result-hash))) + (new-hash (when cache-p + (org-babel-sha1-hash + ;; Do *not* pre-process params for call line + ;; hash evaluation, since for a call line :var + ;; extension *is* execution. + (let* ((params (nth 2 pre-info)) + (sha1-nth2 (list + (cons + (cons :c-var (cdr (assoc :var params))) + (assq-delete-all :var (copy-tree params))))) + (sha1-info (copy-tree pre-info))) + (prog1 sha1-info + (setcar (cddr sha1-info) sha1-nth2)))))) + (old-hash (when cache-p (org-babel-current-result-hash pre-info))) (org-babel-current-src-block-location (point-marker))) (if (and cache-p (equal new-hash old-hash)) - (save-excursion (goto-char (org-babel-where-is-src-block-result)) + (save-excursion (goto-char (org-babel-where-is-src-block-result + nil pre-info)) (forward-line 1) (message "%S" (org-babel-read-result))) (prog1 (let* ((proc-params (org-babel-process-params pre-params)) org-confirm-babel-evaluate) (org-babel-execute-src-block nil (funcall mkinfo proc-params))) ;; update the hash - (when new-hash (org-babel-set-current-result-hash new-hash)))))) + (when new-hash + (org-babel-set-current-result-hash new-hash pre-info)))))) (provide 'ob-lob) diff --git a/elpa/org-20150629/ob-makefile.el b/elpa/org-20160215/ob-makefile.el similarity index 96% rename from elpa/org-20150629/ob-makefile.el rename to elpa/org-20160215/ob-makefile.el index af7e66e5..8f33773c 100644 --- a/elpa/org-20150629/ob-makefile.el +++ b/elpa/org-20160215/ob-makefile.el @@ -1,6 +1,6 @@ ;;; ob-makefile.el --- org-babel functions for makefile evaluation -;; Copyright (C) 2009-2014 Free Software Foundation, Inc. +;; Copyright (C) 2009-2016 Free Software Foundation, Inc. ;; Author: Eric Schulte ;; Thomas S. Dye diff --git a/elpa/org-20150629/ob-matlab.el b/elpa/org-20160215/ob-matlab.el similarity index 95% rename from elpa/org-20150629/ob-matlab.el rename to elpa/org-20160215/ob-matlab.el index ef77de30..69b4c458 100644 --- a/elpa/org-20150629/ob-matlab.el +++ b/elpa/org-20160215/ob-matlab.el @@ -1,6 +1,6 @@ ;;; ob-matlab.el --- org-babel support for matlab evaluation -;; Copyright (C) 2010-2014 Free Software Foundation, Inc. +;; Copyright (C) 2010-2016 Free Software Foundation, Inc. ;; Author: Dan Davison ;; Keywords: literate programming, reproducible research diff --git a/elpa/org-20150629/ob-maxima.el b/elpa/org-20160215/ob-maxima.el similarity index 91% rename from elpa/org-20150629/ob-maxima.el rename to elpa/org-20160215/ob-maxima.el index 7435f1d3..9b6cee67 100644 --- a/elpa/org-20150629/ob-maxima.el +++ b/elpa/org-20160215/ob-maxima.el @@ -1,6 +1,6 @@ ;;; ob-maxima.el --- org-babel functions for maxima evaluation -;; Copyright (C) 2009-2014 Free Software Foundation, Inc. +;; Copyright (C) 2009-2016 Free Software Foundation, Inc. ;; Author: Eric S Fraga ;; Eric Schulte @@ -52,7 +52,7 @@ (mapconcat 'identity (list ;; graphic output - (let ((graphic-file (org-babel-maxima-graphical-output-file params))) + (let ((graphic-file (ignore-errors (org-babel-graphical-output-file params)))) (if graphic-file (format "set_plot_option ([gnuplot_term, png]); set_plot_option ([gnuplot_out_file, %S]);" @@ -89,7 +89,7 @@ This function is called by `org-babel-execute-src-block'." (= 0 (length line))) line)) (split-string raw "[\r\n]"))) "\n"))))) - (if (org-babel-maxima-graphical-output-file params) + (if (ignore-errors (org-babel-graphical-output-file params)) nil (org-babel-result-cond result-params result @@ -113,11 +113,6 @@ of the same value." (format "%S: %s$" var (org-babel-maxima-elisp-to-maxima val)))) -(defun org-babel-maxima-graphical-output-file (params) - "Name of file to which maxima should send graphical output." - (and (member "graphics" (cdr (assq :result-params params))) - (cdr (assq :file params)))) - (defun org-babel-maxima-elisp-to-maxima (val) "Return a string of maxima code which evaluates to VAL." (if (listp val) diff --git a/elpa/org-20150629/ob-mscgen.el b/elpa/org-20160215/ob-mscgen.el similarity index 97% rename from elpa/org-20150629/ob-mscgen.el rename to elpa/org-20160215/ob-mscgen.el index 4a4dc052..dae4c657 100644 --- a/elpa/org-20150629/ob-mscgen.el +++ b/elpa/org-20160215/ob-mscgen.el @@ -1,6 +1,6 @@ ;;; ob-msc.el --- org-babel functions for mscgen evaluation -;; Copyright (C) 2010-2014 Free Software Foundation, Inc. +;; Copyright (C) 2010-2016 Free Software Foundation, Inc. ;; Author: Juan Pechiar ;; Keywords: literate programming, reproducible research diff --git a/elpa/org-20150629/ob-ocaml.el b/elpa/org-20160215/ob-ocaml.el similarity index 78% rename from elpa/org-20150629/ob-ocaml.el rename to elpa/org-20160215/ob-ocaml.el index 1f29a25c..eadc388e 100644 --- a/elpa/org-20150629/ob-ocaml.el +++ b/elpa/org-20160215/ob-ocaml.el @@ -1,6 +1,6 @@ ;;; ob-ocaml.el --- org-babel functions for ocaml evaluation -;; Copyright (C) 2009-2014 Free Software Foundation, Inc. +;; Copyright (C) 2009-2016 Free Software Foundation, Inc. ;; Author: Eric Schulte ;; Keywords: literate programming, reproducible research @@ -70,7 +70,8 @@ (session org-babel-ocaml-eoe-output t full-body) (insert (concat - (org-babel-chomp full-body)";;\n"org-babel-ocaml-eoe-indicator)) + (org-babel-chomp full-body) ";;\n" + org-babel-ocaml-eoe-indicator)) (tuareg-interactive-send-input))) (clean (car (let ((re (regexp-quote org-babel-ocaml-eoe-output)) out) @@ -79,16 +80,25 @@ (progn (setq out nil) line) (when (string-match re line) (progn (setq out t) nil)))) - (mapcar #'org-babel-trim (reverse raw)))))))) + (mapcar #'org-babel-trim (reverse raw))))))) + (raw (org-babel-trim clean)) + (result-params (cdr (assoc :result-params params))) + (parsed + (string-match + "\\(\\(.*\n\\)*\\)[^:\n]+ : \\([^=\n]+\\) =\\(\n\\| \\)\\(.+\\)$" + raw)) + (output (match-string 1 raw)) + (type (match-string 3 raw)) + (value (match-string 5 raw))) (org-babel-reassemble-table - (let ((raw (org-babel-trim clean)) - (result-params (cdr (assoc :result-params params)))) - (org-babel-result-cond result-params - ;; strip type information from output unless verbatim is specified - (if (and (not (member "verbatim" result-params)) - (string-match "= \\(.+\\)$" raw)) - (match-string 1 raw) raw) - (org-babel-ocaml-parse-output raw))) + (org-babel-result-cond result-params + (cond + ((member "verbatim" result-params) raw) + ((member "output" result-params) output) + (t raw)) + (if (and value type) + (org-babel-ocaml-parse-output value type) + raw)) (org-babel-pick-name (cdr (assoc :colname-names params)) (cdr (assoc :colnames params))) (org-babel-pick-name @@ -121,26 +131,29 @@ (concat "[|" (mapconcat #'org-babel-ocaml-elisp-to-ocaml val "; ") "|]") (format "%S" val))) -(defun org-babel-ocaml-parse-output (output) - "Parse OUTPUT. -OUTPUT is string output from an ocaml process." - (let ((regexp "[^:]+ : %s = \\(.+\\)$")) - (cond - ((string-match (format regexp "string") output) - (org-babel-read (match-string 1 output))) - ((or (string-match (format regexp "int") output) - (string-match (format regexp "float") output)) - (string-to-number (match-string 1 output))) - ((string-match (format regexp "list") output) - (org-babel-ocaml-read-list (match-string 1 output))) - ((string-match (format regexp "array") output) - (org-babel-ocaml-read-array (match-string 1 output))) - (t (message "don't recognize type of %s" output) output)))) +(defun org-babel-ocaml-parse-output (value type) + "Parse VALUE of type TYPE. +VALUE and TYPE are string output from an ocaml process." + (cond + ((string= "string" type) + (org-babel-read value)) + ((or (string= "int" type) + (string= "float" type)) + (string-to-number value)) + ((string-match "list" type) + (org-babel-ocaml-read-list value)) + ((string-match "array" type) + (org-babel-ocaml-read-array value)) + (t (message "don't recognize type %s" type) value))) (defun org-babel-ocaml-read-list (results) "Convert RESULTS into an elisp table or string. If the results look like a table, then convert them into an Emacs-lisp table, otherwise return the results as a string." + ;; XXX: This probably does not behave as expected when a semicolon + ;; is in a string in a list. The same comment applies to + ;; `org-babel-ocaml-read-array' below (with even more failure + ;; modes). (org-babel-script-escape (replace-regexp-in-string ";" "," results))) (defun org-babel-ocaml-read-array (results) diff --git a/elpa/org-20150629/ob-octave.el b/elpa/org-20160215/ob-octave.el similarity index 93% rename from elpa/org-20150629/ob-octave.el rename to elpa/org-20160215/ob-octave.el index 8cc66b6f..fba5a012 100644 --- a/elpa/org-20150629/ob-octave.el +++ b/elpa/org-20160215/ob-octave.el @@ -1,6 +1,6 @@ ;;; ob-octave.el --- org-babel functions for octave and matlab evaluation -;; Copyright (C) 2010-2014 Free Software Foundation, Inc. +;; Copyright (C) 2010-2016 Free Software Foundation, Inc. ;; Author: Dan Davison ;; Keywords: literate programming, reproducible research @@ -61,7 +61,7 @@ if ischar(ans), fid = fopen('%s', 'w'); fprintf(fid, '%%s\\n', ans); fclose(fid) else, dlmwrite('%s', ans, '\\t') end") -(defvar org-babel-octave-eoe-indicator "\'org_babel_eoe\'") +(defvar org-babel-octave-eoe-indicator "'org_babel_eoe'") (defvar org-babel-octave-eoe-output "ans = org_babel_eoe") @@ -82,18 +82,19 @@ end") (full-body (org-babel-expand-body:generic body params (org-babel-variable-assignments:octave params))) + (gfx-file (ignore-errors (org-babel-graphical-output-file params))) (result (org-babel-octave-evaluate session - (if (org-babel-octave-graphical-output-file params) + (if gfx-file (mapconcat 'identity (list "set (0, \"defaultfigurevisible\", \"off\");" full-body - (format "print -dpng %s" (org-babel-octave-graphical-output-file params))) + (format "print -dpng %s" gfx-file)) "\n") full-body) result-type matlabp))) - (if (org-babel-octave-graphical-output-file params) + (if gfx-file nil (org-babel-reassemble-table result @@ -127,7 +128,7 @@ specifying a variable of the same value." (if (listp (car var)) "; " ",")) "]") (cond ((stringp var) - (format "\'%s\'" var)) + (format "'%s'" var)) (t (format "%s" var))))) @@ -167,8 +168,8 @@ create. Return the initialized session." (defun org-babel-octave-evaluate (session body result-type &optional matlabp) "Pass BODY to the octave process in SESSION. -If RESULT-TYPE equals 'output then return the outputs of the -statements in BODY, if RESULT-TYPE equals 'value then return the +If RESULT-TYPE equals `output' then return the outputs of the +statements in BODY, if RESULT-TYPE equals `value' then return the value of the last statement in BODY, as elisp." (if session (org-babel-octave-evaluate-session session body result-type matlabp) @@ -268,11 +269,6 @@ This removes initial blank and comment lines and then calls (match-string 1 string) string)) -(defun org-babel-octave-graphical-output-file (params) - "Name of file to which maxima should send graphical output." - (and (member "graphics" (cdr (assq :result-params params))) - (cdr (assq :file params)))) - (provide 'ob-octave) diff --git a/elpa/org-20150629/ob-org.el b/elpa/org-20160215/ob-org.el similarity index 97% rename from elpa/org-20150629/ob-org.el rename to elpa/org-20160215/ob-org.el index bc02f23f..af5b5486 100644 --- a/elpa/org-20150629/ob-org.el +++ b/elpa/org-20160215/ob-org.el @@ -1,6 +1,6 @@ ;;; ob-org.el --- org-babel functions for org code block evaluation -;; Copyright (C) 2010-2014 Free Software Foundation, Inc. +;; Copyright (C) 2010-2016 Free Software Foundation, Inc. ;; Author: Eric Schulte ;; Keywords: literate programming, reproducible research diff --git a/elpa/org-20150629/ob-perl.el b/elpa/org-20160215/ob-perl.el similarity index 96% rename from elpa/org-20150629/ob-perl.el rename to elpa/org-20160215/ob-perl.el index ff4cbea9..3a63837b 100644 --- a/elpa/org-20150629/ob-perl.el +++ b/elpa/org-20160215/ob-perl.el @@ -1,6 +1,6 @@ ;;; ob-perl.el --- org-babel functions for perl evaluation -;; Copyright (C) 2009-2014 Free Software Foundation, Inc. +;; Copyright (C) 2009-2016 Free Software Foundation, Inc. ;; Authors: Dan Davison ;; Eric Schulte @@ -127,8 +127,8 @@ specifying a var of the same value." (defun org-babel-perl-evaluate (session ibody &optional result-type result-params) "Pass BODY to the Perl process in SESSION. -If RESULT-TYPE equals 'output then return a list of the outputs -of the statements in BODY, if RESULT-TYPE equals 'value then +If RESULT-TYPE equals `output' then return a list of the outputs +of the statements in BODY, if RESULT-TYPE equals `value' then return the value of the last statement in BODY, as elisp." (when session (error "Sessions are not supported for Perl")) (let* ((body (concat org-babel-perl-preface ibody)) diff --git a/elpa/org-20150629/ob-picolisp.el b/elpa/org-20160215/ob-picolisp.el similarity index 99% rename from elpa/org-20150629/ob-picolisp.el rename to elpa/org-20160215/ob-picolisp.el index b240138f..2a4ddc01 100644 --- a/elpa/org-20150629/ob-picolisp.el +++ b/elpa/org-20160215/ob-picolisp.el @@ -1,6 +1,6 @@ ;;; ob-picolisp.el --- org-babel functions for picolisp evaluation -;; Copyright (C) 2010-2014 Free Software Foundation, Inc. +;; Copyright (C) 2010-2016 Free Software Foundation, Inc. ;; Authors: Thorsten Jolitz ;; Eric Schulte diff --git a/elpa/org-20150629/ob-plantuml.el b/elpa/org-20160215/ob-plantuml.el similarity index 98% rename from elpa/org-20150629/ob-plantuml.el rename to elpa/org-20160215/ob-plantuml.el index ebc5a10e..9a0604c6 100644 --- a/elpa/org-20150629/ob-plantuml.el +++ b/elpa/org-20160215/ob-plantuml.el @@ -1,6 +1,6 @@ ;;; ob-plantuml.el --- org-babel functions for plantuml evaluation -;; Copyright (C) 2010-2014 Free Software Foundation, Inc. +;; Copyright (C) 2010-2016 Free Software Foundation, Inc. ;; Author: Zhang Weize ;; Keywords: literate programming, reproducible research diff --git a/elpa/org-20160215/ob-processing.el b/elpa/org-20160215/ob-processing.el new file mode 100644 index 00000000..2410402b --- /dev/null +++ b/elpa/org-20160215/ob-processing.el @@ -0,0 +1,197 @@ +;;; ob-processing.el --- Babel functions for evaluation of processing + +;; Copyright (C) 2015-2016 Free Software Foundation, Inc. + +;; Author: Jarmo Hurri (adapted from ob-asymptote.el written by Eric Schulte) +;; Keywords: literate programming, reproducible research +;; Homepage: http://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 . + +;;; Commentary: + +;; Babel support for evaluating processing source code. +;; +;; This differs from most standard languages in that +;; +;; 1) there is no such thing as a "session" in processing +;; +;; 2) results can only be exported as html; in this case, the +;; processing code is embedded via a file into a javascript block +;; using the processing.js module; the script then draws the +;; resulting output when the web page is viewed in a browser; note +;; that the user is responsible for making sure that processing.js +;; is available on the website +;; +;; 3) it is possible to interactively view the sketch of the +;; Processing code block via Processing 2.0 Emacs mode, using +;; `org-babel-processing-view-sketch'. You can bind this command +;; to, e.g., C-c C-v C-k with +;; +;; (define-key org-babel-map (kbd "C-k") 'org-babel-processing-view-sketch) + + +;;; Requirements: + +;; - processing2-emacs mode :: https://github.com/ptrv/processing2-emacs +;; - Processing.js module :: http://processingjs.org/ + +;;; Code: +(require 'ob) +(require 'sha1) +(eval-when-compile (require 'cl)) + +(declare-function processing-sketch-run "ext:processing-mode" ()) + +(defvar org-babel-temporary-directory) + +(defvar org-babel-tangle-lang-exts) +(add-to-list 'org-babel-tangle-lang-exts '("processing" . "pde")) + +;; Default header tags depend on whether exporting html or not; if not +;; exporting html, then no results are produced; otherwise results are +;; HTML. +(defvar org-babel-default-header-args:processing + '((:results . "html") (:exports . "results")) + "Default arguments when evaluating a Processing source block.") + +(defvar org-babel-processing-processing-js-filename "processing.js" + "Filename of the processing.js file.") + +(defun org-babel-processing-view-sketch () + "Show the sketch of the Processing block under point in an external viewer." + (interactive) + (require 'processing-mode) + (let ((info (org-babel-get-src-block-info))) + (if (string= (nth 0 info) "processing") + (let* ((body (nth 1 info)) + (params (org-babel-process-params (nth 2 info))) + (sketch-code + (org-babel-expand-body:generic + body + params + (org-babel-variable-assignments:processing params)))) + ;; Note: sketch filename can not contain a hyphen, since it + ;; has to be a valid java class name; for this reason + ;; make-temp-file is repeated until no hyphen is in the + ;; name; also sketch dir name must be the same as the + ;; basename of the sketch file. + (let* ((temporary-file-directory org-babel-temporary-directory) + (sketch-dir + (let (sketch-dir-candidate) + (while + (progn + (setq sketch-dir-candidate + (make-temp-file "processing" t)) + (when (org-string-match-p + "-" + (file-name-nondirectory sketch-dir-candidate)) + (delete-directory sketch-dir-candidate) + t))) + sketch-dir-candidate)) + (sketch-filename + (concat sketch-dir + "/" + (file-name-nondirectory sketch-dir) + ".pde"))) + (with-temp-file sketch-filename (insert sketch-code)) + (find-file sketch-filename) + (processing-sketch-run) + (kill-buffer))) + (message "Not inside a Processing source block.")))) + +(defun org-babel-execute:processing (body params) + "Execute a block of Processing code. +This function is called by `org-babel-execute-src-block'." + (let ((sketch-code + (org-babel-expand-body:generic + body + params + (org-babel-variable-assignments:processing params)))) + ;; Results are HTML. + (let ((sketch-canvas-id (concat "ob-" (sha1 sketch-code)))) + (concat "\n ")))) + +(defun org-babel-prep-session:processing (session params) + "Return an error if the :session header argument is set. +Processing does not support sessions" + (error "Processing does not support sessions")) + +(defun org-babel-variable-assignments:processing (params) + "Return list of processing statements assigning the block's variables." + (mapcar #'org-babel-processing-var-to-processing + (mapcar #'cdr (org-babel-get-header params :var)))) + +(defun org-babel-processing-var-to-processing (pair) + "Convert an elisp value into a Processing variable. +The elisp value PAIR is converted into Processing code specifying +a variable of the same value." + (let ((var (car pair)) + (val (let ((v (cdr pair))) + (if (symbolp v) (symbol-name v) v)))) + (cond + ((integerp val) + (format "int %S=%S;" var val)) + ((floatp val) + (format "float %S=%S;" var val)) + ((stringp val) + (format "String %S=\"%s\";" var val)) + ((and (listp val) (not (listp (car val)))) + (let* ((type (org-babel-processing-define-type val)) + (fmt (if (eq 'String type) "\"%s\"" "%s")) + (vect (mapconcat (lambda (e) (format fmt e)) val ", "))) + (format "%s[] %S={%s};" type var vect))) + ((listp val) + (let* ((type (org-babel-processing-define-type val)) + (fmt (if (eq 'String type) "\"%s\"" "%s")) + (array (mapconcat (lambda (row) + (concat "{" + (mapconcat (lambda (e) (format fmt e)) + row ", ") + "}")) + val ","))) + (format "%S[][] %S={%s};" type var array)))))) + +(defun org-babel-processing-define-type (data) + "Determine type of DATA. + +DATA is a list. Return type as a symbol. + +The type is `String' if any element in DATA is +a string. Otherwise, it is either `float', if some elements are +floats, or `int'." + (let* ((type 'int) + find-type ; For byte-compiler. + (find-type + (lambda (row) + (dolist (e row type) + (cond ((listp e) (setq type (funcall find-type e))) + ((stringp e) (throw 'exit 'String)) + ((floatp e) (setq type 'float))))))) + (catch 'exit (funcall find-type data)))) + +(provide 'ob-processing) + +;;; ob-processing.el ends here diff --git a/elpa/org-20150629/ob-python.el b/elpa/org-20160215/ob-python.el similarity index 95% rename from elpa/org-20150629/ob-python.el rename to elpa/org-20160215/ob-python.el index 7cee1046..1932e619 100644 --- a/elpa/org-20150629/ob-python.el +++ b/elpa/org-20160215/ob-python.el @@ -1,6 +1,6 @@ ;;; ob-python.el --- org-babel functions for python evaluation -;; Copyright (C) 2009-2014 Free Software Foundation, Inc. +;; Copyright (C) 2009-2016 Free Software Foundation, Inc. ;; Authors: Eric Schulte ;; Dan Davison @@ -50,7 +50,7 @@ (defcustom org-babel-python-mode (if (or (featurep 'xemacs) (featurep 'python-mode)) 'python-mode 'python) "Preferred python mode for use in running python interactively. -This will typically be either 'python or 'python-mode." +This will typically be either `python' or `python-mode'." :group 'org-babel :version "24.4" :package-version '(Org . "8.0") @@ -64,7 +64,7 @@ This will typically be either 'python or 'python-mode." :type 'string) (defcustom org-babel-python-None-to 'hline - "Replace 'None' in python tables with this before returning." + "Replace `None' in python tables with this before returning." :group 'org-babel :version "24.4" :package-version '(Org . "8.0") @@ -80,6 +80,8 @@ This function is called by `org-babel-execute-src-block'." (return-val (when (and (eq result-type 'value) (not session)) (cdr (assoc :return params)))) (preamble (cdr (assoc :preamble params))) + (org-babel-python-command + (or (cdr (assoc :python params)) org-babel-python-command)) (full-body (org-babel-expand-body:generic (concat body (if return-val (format "\nreturn %s" return-val) "")) @@ -222,13 +224,13 @@ then create. Return the initialized session." (defvar org-babel-python-eoe-indicator "'org_babel_python_eoe'" "A string to indicate that evaluation has completed.") -(defvar org-babel-python-wrapper-method +(defconst org-babel-python-wrapper-method " def main(): %s open('%s', 'w').write( str(main()) )") -(defvar org-babel-python-pp-wrapper-method +(defconst org-babel-python-pp-wrapper-method " import pprint def main(): @@ -248,8 +250,8 @@ open('%s', 'w').write( pprint.pformat(main()) )") (defun org-babel-python-evaluate-external-process (body &optional result-type result-params preamble) "Evaluate BODY in external python 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 (case result-type @@ -280,8 +282,8 @@ last statement in BODY, as elisp." (defun org-babel-python-evaluate-session (session body &optional result-type result-params) "Pass BODY to the Python 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 @@ -332,7 +334,7 @@ last statement in BODY, as elisp." (org-babel-python-table-or-string results))))) (defun org-babel-python-read-string (string) - "Strip 's from around Python string." + "Strip \\='s from around Python string." (if (string-match "^'\\([^\000]+\\)'$" string) (match-string 1 string) string)) diff --git a/elpa/org-20150629/ob-ref.el b/elpa/org-20160215/ob-ref.el similarity index 57% rename from elpa/org-20150629/ob-ref.el rename to elpa/org-20160215/ob-ref.el index 152af86a..95eb1144 100644 --- a/elpa/org-20150629/ob-ref.el +++ b/elpa/org-20160215/ob-ref.el @@ -1,6 +1,6 @@ ;;; ob-ref.el --- org-babel functions for referencing external data -;; Copyright (C) 2009-2014 Free Software Foundation, Inc. +;; Copyright (C) 2009-2016 Free Software Foundation, Inc. ;; Authors: Eric Schulte ;; Dan Davison @@ -53,6 +53,8 @@ (eval-when-compile (require 'cl)) +(declare-function org-end-of-meta-data "org" (&optional full)) +(declare-function org-find-property "org" (property &optional value)) (declare-function org-remove-if-not "org" (predicate seq)) (declare-function org-at-table-p "org" (&optional table-type)) (declare-function org-count "org" (CL-ITEM CL-SEQ)) @@ -63,6 +65,8 @@ (declare-function org-show-context "org" (&optional key)) (declare-function org-pop-to-buffer-same-window "org-compat" (&optional buffer-or-name norecord label)) +(declare-function org-babel-lob-execute "ob-lob" (info)) +(declare-function org-babel-lob-get-info "ob-lob" nil) (defvar org-babel-ref-split-regexp "[ \f\t\n\r\v]*\\(.+?\\)[ \f\t\n\r\v]*=[ \f\t\n\r\v]*\\(.+\\)[ \f\t\n\r\v]*") @@ -96,119 +100,125 @@ the variable." out)))))) (defun org-babel-ref-goto-headline-id (id) - (goto-char (point-min)) - (let ((rx (regexp-quote id))) - (or (re-search-forward - (concat "^[ \t]*:CUSTOM_ID:[ \t]+" rx "[ \t]*$") nil t) - (let* ((file (org-id-find-id-file id)) - (m (when file (org-id-find-id-in-file id file 'marker)))) - (when (and file m) - (message "file:%S" file) - (org-pop-to-buffer-same-window (marker-buffer m)) - (goto-char m) - (move-marker m nil) - (org-show-context) - t))))) + (or (let ((h (org-find-property "CUSTOM_ID" id))) + (when h (goto-char h))) + (let* ((file (org-id-find-id-file id)) + (m (when file (org-id-find-id-in-file id file 'marker)))) + (when (and file m) + (message "file:%S" file) + (org-pop-to-buffer-same-window (marker-buffer m)) + (goto-char m) + (move-marker m nil) + (org-show-context) + t)))) (defun org-babel-ref-headline-body () (save-restriction (org-narrow-to-subtree) (buffer-substring (save-excursion (goto-char (point-min)) - (forward-line 1) - (when (looking-at "[ \t]*:PROPERTIES:") - (re-search-forward ":END:" nil) - (forward-char)) + (org-end-of-meta-data) (point)) (point-max)))) +(defvar org-babel-lob-one-liner-regexp) (defvar org-babel-library-of-babel) (defun org-babel-ref-resolve (ref) "Resolve the reference REF and return its value." (save-window-excursion - (save-excursion - (let ((case-fold-search t) - type args new-refere new-header-args new-referent result - lob-info split-file split-ref index index-row index-col id) - ;; if ref is indexed grab the indices -- beware nested indices - (when (and (string-match "\\[\\([^\\[]+\\)\\]$" ref) - (let ((str (substring ref 0 (match-beginning 0)))) - (= (org-count ?( str) (org-count ?) str)))) - (setq index (match-string 1 ref)) - (setq ref (substring ref 0 (match-beginning 0)))) - ;; assign any arguments to pass to source block - (when (string-match - "^\\(.+?\\)\\(\\[\\(.*\\)\\]\\|\\(\\)\\)\(\\(.*\\)\)$" ref) - (setq new-refere (match-string 1 ref)) - (setq new-header-args (match-string 3 ref)) - (setq new-referent (match-string 5 ref)) - (when (> (length new-refere) 0) - (when (> (length new-referent) 0) - (setq args (mapcar (lambda (ref) (cons :var ref)) - (org-babel-ref-split-args new-referent)))) - (when (> (length new-header-args) 0) - (setq args (append (org-babel-parse-header-arguments - new-header-args) args))) - (setq ref new-refere))) - (when (string-match "^\\(.+\\):\\(.+\\)$" ref) - (setq split-file (match-string 1 ref)) - (setq split-ref (match-string 2 ref)) - (find-file split-file) (setq ref split-ref)) - (save-restriction - (widen) - (goto-char (point-min)) - (if (let ((src-rx (org-babel-named-src-block-regexp-for-name ref)) - (res-rx (org-babel-named-data-regexp-for-name ref))) - ;; goto ref in the current buffer - (or - ;; check for code blocks - (re-search-forward src-rx nil t) - ;; check for named data - (re-search-forward res-rx nil t) - ;; check for local or global headlines by id - (setq id (org-babel-ref-goto-headline-id ref)) - ;; check the Library of Babel - (setq lob-info (cdr (assoc (intern ref) - org-babel-library-of-babel))))) - (unless (or lob-info id) (goto-char (match-beginning 0))) - ;; ;; TODO: allow searching for names in other buffers - ;; (setq id-loc (org-id-find ref 'marker) - ;; buffer (marker-buffer id-loc) - ;; loc (marker-position id-loc)) - ;; (move-marker id-loc nil) - (error "Reference '%s' not found in this buffer" ref)) - (cond - (lob-info (setq type 'lob)) - (id (setq type 'id)) - ((and (looking-at org-babel-src-name-regexp) - (save-excursion - (forward-line 1) - (or (looking-at org-babel-src-block-regexp) - (looking-at org-babel-multi-line-header-regexp)))) - (setq type 'source-block)) - (t (while (not (setq type (org-babel-ref-at-ref-p))) - (forward-line 1) - (beginning-of-line) - (if (or (= (point) (point-min)) (= (point) (point-max))) - (error "Reference not found"))))) - (let ((params (append args '((:results . "silent"))))) - (setq result - (case type - (results-line (org-babel-read-result)) - (table (org-babel-read-table)) - (list (org-babel-read-list)) - (file (org-babel-read-link)) - (source-block (org-babel-execute-src-block - nil nil (if org-babel-update-intermediate - nil params))) - (lob (org-babel-execute-src-block - nil lob-info params)) - (id (org-babel-ref-headline-body))))) - (if (symbolp result) - (format "%S" result) - (if (and index (listp result)) - (org-babel-ref-index-list index result) - result))))))) + (with-current-buffer (or org-babel-exp-reference-buffer (current-buffer)) + (save-excursion + (let ((case-fold-search t) + type args new-refere new-header-args new-referent result + lob-info split-file split-ref index index-row index-col id) + ;; if ref is indexed grab the indices -- beware nested indices + (when (and (string-match "\\[\\([^\\[]+\\)\\]$" ref) + (let ((str (substring ref 0 (match-beginning 0)))) + (= (org-count ?( str) (org-count ?) str)))) + (setq index (match-string 1 ref)) + (setq ref (substring ref 0 (match-beginning 0)))) + ;; assign any arguments to pass to source block + (when (string-match + "^\\(.+?\\)\\(\\[\\(.*\\)\\]\\|\\(\\)\\)(\\(.*\\))$" ref) + (setq new-refere (match-string 1 ref)) + (setq new-header-args (match-string 3 ref)) + (setq new-referent (match-string 5 ref)) + (when (> (length new-refere) 0) + (when (> (length new-referent) 0) + (setq args (mapcar (lambda (ref) (cons :var ref)) + (org-babel-ref-split-args new-referent)))) + (when (> (length new-header-args) 0) + (setq args (append (org-babel-parse-header-arguments + new-header-args) args))) + (setq ref new-refere))) + (when (string-match "^\\(.+\\):\\(.+\\)$" ref) + (setq split-file (match-string 1 ref)) + (setq split-ref (match-string 2 ref)) + (find-file split-file) (setq ref split-ref)) + (save-restriction + (widen) + (goto-char (point-min)) + (if (let ((src-rx (org-babel-named-src-block-regexp-for-name ref)) + (res-rx (org-babel-named-data-regexp-for-name ref))) + ;; goto ref in the current buffer + (or + ;; check for code blocks + (re-search-forward src-rx nil t) + ;; check for named data + (re-search-forward res-rx nil t) + ;; check for local or global headlines by id + (setq id (org-babel-ref-goto-headline-id ref)) + ;; check the Library of Babel + (setq lob-info (cdr (assoc (intern ref) + org-babel-library-of-babel))))) + (unless (or lob-info id) (goto-char (match-beginning 0))) + ;; ;; TODO: allow searching for names in other buffers + ;; (setq id-loc (org-id-find ref 'marker) + ;; buffer (marker-buffer id-loc) + ;; loc (marker-position id-loc)) + ;; (move-marker id-loc nil) + (error "Reference `%s' not found in this buffer" ref)) + (cond + (lob-info (setq type 'lob)) + (id (setq type 'id)) + ((and (looking-at org-babel-src-name-regexp) + (save-excursion + (forward-line 1) + (or (looking-at org-babel-src-block-regexp) + (looking-at org-babel-multi-line-header-regexp)))) + (setq type 'source-block)) + ((and (looking-at org-babel-src-name-regexp) + (save-excursion + (forward-line 1) + (looking-at org-babel-lob-one-liner-regexp))) + (setq type 'call-line)) + (t (while (not (setq type (org-babel-ref-at-ref-p))) + (forward-line 1) + (beginning-of-line) + (if (or (= (point) (point-min)) (= (point) (point-max))) + (error "Reference not found"))))) + (let ((params (append args '((:results . "silent"))))) + (setq result + (case type + (results-line (org-babel-read-result)) + (table (org-babel-read-table)) + (list (org-babel-read-list)) + (file (org-babel-read-link)) + (source-block (org-babel-execute-src-block + nil nil (if org-babel-update-intermediate + nil params))) + (call-line (save-excursion + (forward-line 1) + (org-babel-lob-execute + (org-babel-lob-get-info)))) + (lob (org-babel-execute-src-block + nil lob-info params)) + (id (org-babel-ref-headline-body))))) + (if (symbolp result) + (format "%S" result) + (if (and index (listp result)) + (org-babel-ref-index-list index result) + result)))))))) (defun org-babel-ref-index-list (index lis) "Return the subset of LIS indexed by INDEX. @@ -224,7 +234,7 @@ returned, or an empty string or \"*\" both of which are interpreted to mean the entire range and as such are equivalent to \"0:-1\"." (if (and (> (length index) 0) (string-match "^\\([^,]*\\),?" index)) - (let* ((ind-re "\\(\\([-[:digit:]]+\\):\\([-[:digit:]]+\\)\\|\*\\)") + (let* ((ind-re "\\(\\([-[:digit:]]+\\):\\([-[:digit:]]+\\)\\|\\*\\)") (lgth (length lis)) (portion (match-string 1 index)) (remainder (substring index (match-end 0))) diff --git a/elpa/org-20150629/ob-ruby.el b/elpa/org-20160215/ob-ruby.el similarity index 86% rename from elpa/org-20150629/ob-ruby.el rename to elpa/org-20160215/ob-ruby.el index 5b31247b..0cc665dc 100644 --- a/elpa/org-20150629/ob-ruby.el +++ b/elpa/org-20160215/ob-ruby.el @@ -1,6 +1,6 @@ ;;; ob-ruby.el --- org-babel functions for ruby evaluation -;; Copyright (C) 2009-2014 Free Software Foundation, Inc. +;; Copyright (C) 2009-2016 Free Software Foundation, Inc. ;; Author: Eric Schulte ;; Keywords: literate programming, reproducible research @@ -58,7 +58,7 @@ :type 'string) (defcustom org-babel-ruby-nil-to 'hline - "Replace 'nil' in ruby tables with this before returning." + "Replace nil in ruby tables with this before returning." :group 'org-babel :version "24.4" :package-version '(Org . "8.0") @@ -187,8 +187,8 @@ end (defun org-babel-ruby-evaluate (buffer body &optional result-type result-params) "Pass BODY to the Ruby process in BUFFER. -If RESULT-TYPE equals 'output then return a list of the outputs -of the statements in BODY, if RESULT-TYPE equals 'value then +If RESULT-TYPE equals `output' then return a list of the outputs +of the statements in BODY, if RESULT-TYPE equals `value' then return the value of the last statement in BODY, as elisp." (if (not buffer) ;; external process evaluation @@ -201,29 +201,36 @@ return the value of the last statement in BODY, as elisp." org-babel-ruby-pp-wrapper-method org-babel-ruby-wrapper-method) body (org-babel-process-file-name tmp-file 'noquote))) - (let ((raw (org-babel-eval-read-file tmp-file))) - (if (or (member "code" result-params) - (member "pp" result-params)) - raw - (org-babel-ruby-table-or-string raw)))))) + (org-babel-eval-read-file tmp-file)))) ;; comint session evaluation (case result-type (output - (mapconcat - #'identity - (butlast - (split-string - (mapconcat - #'org-babel-trim - (butlast - (org-babel-comint-with-output - (buffer org-babel-ruby-eoe-indicator t body) - (mapc - (lambda (line) - (insert (org-babel-chomp line)) (comint-send-input nil t)) - (list body org-babel-ruby-eoe-indicator)) - (comint-send-input nil t)) 2) - "\n") "[\r\n]")) "\n")) + (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 + ;; been inserted and that throws off the extraction of the + ;; result for Babel. + (org-babel-comint-with-output + (buffer org-babel-ruby-eoe-indicator t eoe-string) + (insert eoe-string) (comint-send-input nil t)) + ;; Now we can start the evaluation. + (mapconcat + #'identity + (butlast + (split-string + (mapconcat + #'org-babel-trim + (org-babel-comint-with-output + (buffer org-babel-ruby-eoe-indicator t body) + (mapc + (lambda (line) + (insert (org-babel-chomp line)) (comint-send-input nil t)) + (list "conf.echo=false;_org_prompt_mode=conf.prompt_mode;conf.prompt_mode=:NULL" + body + "conf.prompt_mode=_org_prompt_mode;conf.echo=true" + eoe-string))) + "\n") "[\r\n]") 4) "\n"))) (value (let* ((tmp-file (org-babel-temp-file "ruby-")) (ppp (or (member "code" result-params) diff --git a/elpa/org-20150629/ob-sass.el b/elpa/org-20160215/ob-sass.el similarity index 97% rename from elpa/org-20150629/ob-sass.el rename to elpa/org-20160215/ob-sass.el index 78c0c958..f675914c 100644 --- a/elpa/org-20150629/ob-sass.el +++ b/elpa/org-20160215/ob-sass.el @@ -1,6 +1,6 @@ ;;; ob-sass.el --- org-babel functions for the sass css generation language -;; Copyright (C) 2009-2014 Free Software Foundation, Inc. +;; Copyright (C) 2009-2016 Free Software Foundation, Inc. ;; Author: Eric Schulte ;; Keywords: literate programming, reproducible research diff --git a/elpa/org-20150629/ob-scala.el b/elpa/org-20160215/ob-scala.el similarity index 88% rename from elpa/org-20150629/ob-scala.el rename to elpa/org-20160215/ob-scala.el index 0584342f..7df8da82 100644 --- a/elpa/org-20150629/ob-scala.el +++ b/elpa/org-20160215/ob-scala.el @@ -1,6 +1,6 @@ ;;; ob-scala.el --- org-babel functions for Scala evaluation -;; Copyright (C) 2012-2014 Free Software Foundation, Inc. +;; Copyright (C) 2012-2016 Free Software Foundation, Inc. ;; Author: Andrzej Lichnerowicz ;; Keywords: literate programming, reproducible research @@ -60,14 +60,6 @@ called by `org-babel-execute-src-block'" (org-babel-pick-name (cdr (assoc :rowname-names params)) (cdr (assoc :rownames params)))))) - -(defun org-babel-scala-table-or-string (results) - "Convert RESULTS into an appropriate elisp value. -If RESULTS look like a table, then convert them into an -Emacs-lisp table, otherwise return the results as a string." - (org-babel-script-escape results)) - - (defvar org-babel-scala-wrapper-method "var str_result :String = null; @@ -86,8 +78,8 @@ print(str_result) (defun org-babel-scala-evaluate (session body &optional result-type result-params) "Evaluate BODY in external Scala process. -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 +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." (when session (error "Sessions are not (yet) supported for Scala")) (case result-type @@ -104,7 +96,7 @@ in BODY as elisp." (concat org-babel-scala-command " " src-file) ""))) (org-babel-result-cond result-params raw - (org-babel-scala-table-or-string raw))))))) + (org-babel-script-escape raw))))))) (defun org-babel-prep-session:scala (session params) diff --git a/elpa/org-20150629/ob-scheme.el b/elpa/org-20160215/ob-scheme.el similarity index 88% rename from elpa/org-20150629/ob-scheme.el rename to elpa/org-20160215/ob-scheme.el index b7117e9a..04731386 100644 --- a/elpa/org-20150629/ob-scheme.el +++ b/elpa/org-20160215/ob-scheme.el @@ -1,6 +1,6 @@ ;;; ob-scheme.el --- org-babel functions for Scheme -;; Copyright (C) 2010-2014 Free Software Foundation, Inc. +;; Copyright (C) 2010-2016 Free Software Foundation, Inc. ;; Authors: Eric Schulte ;; Michael Gauland @@ -109,7 +109,7 @@ For a named session, the buffer name will be the session name. If the session is unnamed (nil), generate a name. -If the session is 'none', use nil for the session name, and +If the session is `none', use nil for the session name, and org-babel-scheme-execute-with-geiser will use a temporary session." (let ((result (cond ((not name) @@ -118,6 +118,22 @@ org-babel-scheme-execute-with-geiser will use a temporary session." (name)))) result)) +(defmacro org-babel-scheme-capture-current-message (&rest body) + "Capture current message in both interactive and noninteractive mode" + `(if noninteractive + (let ((original-message (symbol-function 'message)) + (current-message nil)) + (unwind-protect + (progn + (defun message (&rest args) + (setq current-message (apply original-message args))) + ,@body + current-message) + (fset 'message original-message))) + (progn + ,@body + (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. @@ -142,10 +158,11 @@ is true; otherwise returns the last value." (current-buffer))))) (setq geiser-repl--repl repl-buffer) (setq geiser-impl--implementation nil) - (geiser-eval-region (point-min) (point-max)) + (setq result (org-babel-scheme-capture-current-message + (geiser-eval-region (point-min) (point-max)))) (setq result - (if (equal (substring (current-message) 0 3) "=> ") - (replace-regexp-in-string "^=> " "" (current-message)) + (if (and (stringp result) (equal (substring result 0 3) "=> ")) + (replace-regexp-in-string "^=> " "" result) "\"An error occurred.\"")) (when (not repl) (save-current-buffer (set-buffer repl-buffer) diff --git a/elpa/org-20150629/ob-screen.el b/elpa/org-20160215/ob-screen.el similarity index 98% rename from elpa/org-20150629/ob-screen.el rename to elpa/org-20160215/ob-screen.el index 1d4ccddd..db89733a 100644 --- a/elpa/org-20150629/ob-screen.el +++ b/elpa/org-20160215/ob-screen.el @@ -1,6 +1,6 @@ ;;; ob-screen.el --- org-babel support for interactive terminal -;; Copyright (C) 2009-2014 Free Software Foundation, Inc. +;; Copyright (C) 2009-2016 Free Software Foundation, Inc. ;; Author: Benjamin Andresen ;; Keywords: literate programming, interactive shell diff --git a/elpa/org-20160215/ob-sed.el b/elpa/org-20160215/ob-sed.el new file mode 100644 index 00000000..f68bb141 --- /dev/null +++ b/elpa/org-20160215/ob-sed.el @@ -0,0 +1,107 @@ +;;; ob-sed.el --- org-babel functions for sed scripts + +;; Copyright (C) 2015-2016 Free Software Foundation, Inc. + +;; Author: Bjarte Johansen +;; Keywords: literate programming, reproducible research +;; Version: 0.1.0 + +;; This file is part of GNU Emacs. + +;;; License: + +;; 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, 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 GNU Emacs. If not, see . + +;;; Commentary: + +;; Provides a way to evaluate sed scripts in Org mode. + +;;; Usage: + +;; Add to your Emacs config: + +;; (org-babel-do-load-languages +;; 'org-babel-load-languages +;; '((sed . t))) + +;; In addition to the normal header arguments, ob-sed also provides +;; :cmd-line and :in-file. :cmd-line allows one to pass other flags to +;; the sed command like the "--in-place" flag which makes sed edit the +;; file pass to it instead of outputting to standard out or to a +;; different file. :in-file is a header arguments that allows one to +;; tell Org Babel which file the sed script to act on. + +;;; Code: +(require 'ob) + +(defvar org-babel-sed-command "sed" + "Name of the sed executable command.") + +(defvar org-babel-tangle-lang-exts) +(add-to-list 'org-babel-tangle-lang-exts '("sed" . "sed")) + +(defconst org-babel-header-args:sed + '((:cmd-line . :any) + (:in-file . :any)) + "Sed specific header arguments.") + +(defvar org-babel-default-header-args:sed '() + "Default arguments for evaluating a sed source block.") + +(defun org-babel-execute:sed (body params) + "Execute a block of sed code with Org Babel. +BODY is the source inside a sed source block and PARAMS is an +association list over the source block configurations. This +function is called by `org-babel-execute-src-block'." + (message "executing sed source code block") + (let* ((result-params (cdr (assq :result-params params))) + (cmd-line (cdr (assq :cmd-line params))) + (in-file (cdr (assq :in-file params))) + (code-file (let ((file (org-babel-temp-file "sed-"))) + (with-temp-file file + (insert body)) file)) + (stdin (let ((stdin (cdr (assq :stdin params)))) + (when stdin + (let ((tmp (org-babel-temp-file "sed-stdin-")) + (res (org-babel-ref-resolve stdin))) + (with-temp-file tmp + (insert res)) + tmp)))) + (cmd (mapconcat #'identity + (remq nil + (list org-babel-sed-command + (format "--file=\"%s\"" code-file) + cmd-line + in-file)) + " "))) + (org-babel-reassemble-table + (let ((results + (cond + (stdin (with-temp-buffer + (call-process-shell-command cmd stdin (current-buffer)) + (buffer-string))) + (t (org-babel-eval cmd ""))))) + (when results + (org-babel-result-cond result-params + results + (let ((tmp (org-babel-temp-file "sed-results-"))) + (with-temp-file tmp (insert results)) + (org-babel-import-elisp-from-file tmp))))) + (org-babel-pick-name + (cdr (assq :colname-names params)) (cdr (assq :colnames params))) + (org-babel-pick-name + (cdr (assq :rowname-names params)) (cdr (assq :rownames params)))))) + +(provide 'ob-sed) +;;; ob-sed.el ends here diff --git a/elpa/org-20150629/ob-sh.el b/elpa/org-20160215/ob-shell.el similarity index 64% rename from elpa/org-20150629/ob-sh.el rename to elpa/org-20160215/ob-shell.el index 856c7a01..527e6f55 100644 --- a/elpa/org-20150629/ob-sh.el +++ b/elpa/org-20160215/ob-shell.el @@ -1,6 +1,6 @@ -;;; ob-sh.el --- org-babel functions for shell evaluation +;;; ob-shell.el --- org-babel functions for shell evaluation -;; Copyright (C) 2009-2014 Free Software Foundation, Inc. +;; Copyright (C) 2009-2016 Free Software Foundation, Inc. ;; Author: Eric Schulte ;; Keywords: literate programming, reproducible research @@ -36,19 +36,25 @@ (declare-function org-babel-comint-with-output "ob-comint" (meta &rest body)) (declare-function orgtbl-to-generic "org-table" (table params)) -(defvar org-babel-default-header-args:sh '()) +(defvar org-babel-default-header-args:shell '()) -(defvar org-babel-sh-command "sh" - "Command used to invoke a shell. -This will be passed to `shell-command-on-region'") - -(defcustom org-babel-sh-var-quote-fmt - "$(cat <<'BABEL_TABLE'\n%s\nBABEL_TABLE\n)" - "Format string used to escape variables when passed to shell scripts." +(defcustom org-babel-shell-names + '("sh" "bash" "csh" "ash" "dash" "ksh" "mksh" "posh") + "List of names of shell supported by babel shell code blocks." :group 'org-babel - :type 'string) + :type 'string + :initialize + (lambda (symbol value) + (set-default symbol (second value)) + (mapc + (lambda (name) + (eval `(defun ,(intern (concat "org-babel-execute:" name)) (body params) + ,(format "Execute a block of %s commands with Babel." name) + (let ((shell-file-name ,name)) + (org-babel-execute:shell body params))))) + (second value)))) -(defun org-babel-execute:sh (body params) +(defun org-babel-execute:shell (body params) "Execute a block of Shell commands with Babel. This function is called by `org-babel-execute-src-block'." (let* ((session (org-babel-sh-initiate-session @@ -56,68 +62,108 @@ This function is called by `org-babel-execute-src-block'." (stdin (let ((stdin (cdr (assoc :stdin params)))) (when stdin (org-babel-sh-var-to-string (org-babel-ref-resolve stdin))))) + (cmdline (cdr (assoc :cmdline params))) (full-body (org-babel-expand-body:generic - body params (org-babel-variable-assignments:sh params)))) + body params (org-babel-variable-assignments:shell params)))) (org-babel-reassemble-table - (org-babel-sh-evaluate session full-body params stdin) + (org-babel-sh-evaluate session full-body params stdin cmdline) (org-babel-pick-name (cdr (assoc :colname-names params)) (cdr (assoc :colnames params))) (org-babel-pick-name (cdr (assoc :rowname-names params)) (cdr (assoc :rownames params)))))) -(defun org-babel-prep-session:sh (session params) +(defun org-babel-prep-session:shell (session params) "Prepare SESSION according to the header arguments specified in PARAMS." (let* ((session (org-babel-sh-initiate-session session)) - (var-lines (org-babel-variable-assignments:sh params))) + (var-lines (org-babel-variable-assignments:shell params))) (org-babel-comint-in-buffer session (mapc (lambda (var) (insert var) (comint-send-input nil t) (org-babel-comint-wait-for-output session)) var-lines)) session)) -(defun org-babel-load-session:sh (session body params) +(defun org-babel-load-session:shell (session body params) "Load BODY into SESSION." (save-window-excursion - (let ((buffer (org-babel-prep-session:sh session params))) + (let ((buffer (org-babel-prep-session:shell session params))) (with-current-buffer buffer (goto-char (process-mark (get-buffer-process (current-buffer)))) (insert (org-babel-chomp body))) buffer))) ;; 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." + (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." + (format "unset %s\ndeclare -a %s=( %s )" + varname varname + (mapconcat + (lambda (value) (org-babel-sh-var-to-sh value sep hline)) + values + " "))) + +(defun org-babel-variable-assignments:bash_assoc + (varname values &optional sep hline) + "Returns a list of statements declaring the values as bash associative array." + (format "unset %s\ndeclare -A %s\n%s" + varname varname + (mapconcat + (lambda (items) + (format "%s[%s]=%s" + varname + (org-babel-sh-var-to-sh (car items) sep hline) + (org-babel-sh-var-to-sh (cdr items) sep hline))) + values + "\n"))) -(defun org-babel-variable-assignments:sh (params) +(defun org-babel-variable-assignments:bash (varname values &optional sep hline) + "Represents the parameters as useful Bash shell variables." + (if (listp values) + (if (and (listp (car values)) (= 1 (length (car values)))) + (org-babel-variable-assignments:bash_array varname values sep hline) + (org-babel-variable-assignments:bash_assoc varname values sep hline)) + (org-babel-variable-assignments:sh-generic varname values sep hline))) + +(defun org-babel-variable-assignments:shell (params) "Return list of shell statements assigning the block's variables." - (let ((sep (cdr (assoc :separator params)))) + (let ((sep (cdr (assoc :separator params))) + (hline (when (string= "yes" (cdr (assoc :hlines params))) + (or (cdr (assoc :hline-string params)) + "hline")))) (mapcar (lambda (pair) - (format "%s=%s" - (car pair) - (org-babel-sh-var-to-sh (cdr pair) sep))) + (if (string-match "bash$" shell-file-name) + (org-babel-variable-assignments:bash + (car pair) (cdr pair) sep hline) + (org-babel-variable-assignments:sh-generic + (car pair) (cdr pair) sep hline))) (mapcar #'cdr (org-babel-get-header params :var))))) -(defun org-babel-sh-var-to-sh (var &optional sep) +(defun org-babel-sh-var-to-sh (var &optional sep hline) "Convert an elisp value to a shell variable. Convert an elisp var into a string of shell commands specifying a var of the same value." - (format org-babel-sh-var-quote-fmt (org-babel-sh-var-to-string var sep))) + (concat "'" (replace-regexp-in-string + "'" "'\"'\"'" + (org-babel-sh-var-to-string var sep hline)) + "'")) -(defun org-babel-sh-var-to-string (var &optional sep) +(defun org-babel-sh-var-to-string (var &optional sep hline) "Convert an elisp value to a string." (let ((echo-var (lambda (v) (if (stringp v) v (format "%S" v))))) (cond ((and (listp var) (or (listp (car var)) (equal (car var) 'hline))) - (orgtbl-to-generic var (list :sep (or sep "\t") :fmt echo-var))) + (orgtbl-to-generic var (list :sep (or sep "\t") :fmt echo-var + :hline hline))) ((listp var) (mapconcat echo-var var "\n")) (t (funcall echo-var var))))) -(defun org-babel-sh-table-or-results (results) - "Convert RESULTS to an appropriate elisp value. -If the results look like a table, then convert them into an -Emacs-lisp table, otherwise return the results as a string." - (org-babel-script-escape results)) - (defun org-babel-sh-initiate-session (&optional session params) "Initiate a session named SESSION according to PARAMS." (when (and session (not (string= session "none"))) @@ -136,14 +182,14 @@ Emacs-lisp table, otherwise return the results as a string." (defvar org-babel-sh-eoe-output "org_babel_sh_eoe" "String to indicate that evaluation has completed.") -(defun org-babel-sh-evaluate (session body &optional params stdin) +(defun org-babel-sh-evaluate (session body &optional params stdin cmdline) "Pass BODY to the Shell process in BUFFER. -If RESULT-TYPE equals 'output then return a list of the outputs -of the statements in BODY, if RESULT-TYPE equals 'value then +If RESULT-TYPE equals `output' then return a list of the outputs +of the statements in BODY, if RESULT-TYPE equals `value' then return the value of the last statement in BODY." (let ((results (cond - (stdin ; external shell script w/STDIN + ((or stdin cmdline) ; external shell script w/STDIN (let ((script-file (org-babel-temp-file "sh-script-")) (stdin-file (org-babel-temp-file "sh-stdin-")) (shebang (cdr (assoc :shebang params))) @@ -153,14 +199,14 @@ return the value of the last statement in BODY." (when padline (insert "\n")) (insert body)) (set-file-modes script-file #o755) - (with-temp-file stdin-file (insert stdin)) + (with-temp-file stdin-file (insert (or stdin ""))) (with-temp-buffer (call-process-shell-command - (if shebang - script-file - (format "%s %s" org-babel-sh-command script-file)) + (concat (if shebang script-file + (format "%s %s" shell-file-name script-file)) + (and cmdline (concat " " cmdline))) stdin-file - (current-buffer)) + (current-buffer)) (buffer-string)))) (session ; session evaluation (mapconcat @@ -196,7 +242,7 @@ return the value of the last statement in BODY." (insert body)) (set-file-modes script-file #o755) (org-babel-eval script-file "")) - (org-babel-eval org-babel-sh-command (org-babel-trim body))))))) + (org-babel-eval shell-file-name (org-babel-trim body))))))) (when results (let ((result-params (cdr (assoc :result-params params)))) (org-babel-result-cond result-params @@ -211,8 +257,8 @@ return the value of the last statement in BODY." (setq string (substring string (match-end 0)))) string) -(provide 'ob-sh) +(provide 'ob-shell) -;;; ob-sh.el ends here +;;; ob-shell.el ends here diff --git a/elpa/org-20150629/ob-shen.el b/elpa/org-20160215/ob-shen.el similarity index 97% rename from elpa/org-20150629/ob-shen.el rename to elpa/org-20160215/ob-shen.el index e40e45cc..413fe0d4 100644 --- a/elpa/org-20150629/ob-shen.el +++ b/elpa/org-20160215/ob-shen.el @@ -1,6 +1,6 @@ ;;; ob-shen.el --- org-babel functions for Shen -;; Copyright (C) 2010-2014 Free Software Foundation, Inc. +;; Copyright (C) 2010-2016 Free Software Foundation, Inc. ;; Author: Eric Schulte ;; Keywords: literate programming, reproducible research, shen diff --git a/elpa/org-20150629/ob-sql.el b/elpa/org-20160215/ob-sql.el similarity index 88% rename from elpa/org-20150629/ob-sql.el rename to elpa/org-20160215/ob-sql.el index 08d44191..f096572e 100644 --- a/elpa/org-20150629/ob-sql.el +++ b/elpa/org-20160215/ob-sql.el @@ -1,6 +1,6 @@ ;;; ob-sql.el --- org-babel functions for sql evaluation -;; Copyright (C) 2009-2014 Free Software Foundation, Inc. +;; Copyright (C) 2009-2016 Free Software Foundation, Inc. ;; Author: Eric Schulte ;; Keywords: literate programming, reproducible research @@ -36,6 +36,7 @@ ;; - engine ;; - cmdline ;; - dbhost +;; - dbport ;; - dbuser ;; - dbpassword ;; - database @@ -68,6 +69,7 @@ '((engine . :any) (out-file . :any) (dbhost . :any) + (dbport . :any) (dbuser . :any) (dbpassword . :any) (database . :any)) @@ -78,21 +80,32 @@ (org-babel-sql-expand-vars body (mapcar #'cdr (org-babel-get-header params :var)))) -(defun dbstring-mysql (host user password database) +(defun org-babel-sql-dbstring-mysql (host port user password database) "Make MySQL cmd line args for database connection. Pass nil to omit that arg." (combine-and-quote-strings - (remq nil + (delq nil (list (when host (concat "-h" host)) + (when port (format "-P%d" port)) (when user (concat "-u" user)) (when password (concat "-p" password)) (when database (concat "-D" database)))))) +(defun org-babel-sql-dbstring-postgresql (host user database) + "Make PostgreSQL command line args for database connection. +Pass nil to omit that arg." + (combine-and-quote-strings + (delq nil + (list (when host (concat "-h" host)) + (when user (concat "-U" user)) + (when database (concat "-d" database)))))) + (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 (assoc :result-params params))) (cmdline (cdr (assoc :cmdline params))) (dbhost (cdr (assoc :dbhost params))) + (dbport (cdr (assq :dbport params))) (dbuser (cdr (assoc :dbuser params))) (dbpassword (cdr (assoc :dbpassword params))) (database (cdr (assoc :database params))) @@ -106,7 +119,7 @@ This function is called by `org-babel-execute-src-block'." ('dbi (format "dbish --batch %s < %s | sed '%s' > %s" (or cmdline "") (org-babel-process-file-name in-file) - "/^+/d;s/^\|//;s/(NULL)/ /g;$d" + "/^+/d;s/^|//;s/(NULL)/ /g;$d" (org-babel-process-file-name out-file))) ('monetdb (format "mclient -f tab %s < %s > %s" (or cmdline "") @@ -117,13 +130,16 @@ This function is called by `org-babel-execute-src-block'." (org-babel-process-file-name in-file) (org-babel-process-file-name out-file))) ('mysql (format "mysql %s %s %s < %s > %s" - (dbstring-mysql dbhost dbuser dbpassword database) + (org-babel-sql-dbstring-mysql + dbhost dbport dbuser dbpassword database) (if colnames-p "" "-N") (or cmdline "") (org-babel-process-file-name in-file) (org-babel-process-file-name out-file))) ('postgresql (format - "psql -A -P footer=off -F \"\t\" -f %s -o %s %s" + "psql --set=\"ON_ERROR_STOP=1\" %s -A -P footer=off -F \"\t\" %s -f %s -o %s %s" + (if colnames-p "" "-t") + (org-babel-sql-dbstring-postgresql dbhost dbuser database) (org-babel-process-file-name in-file) (org-babel-process-file-name out-file) (or cmdline ""))) @@ -186,7 +202,7 @@ This function is called by `org-babel-execute-src-block'." (lambda (pair) (setq body (replace-regexp-in-string - (format "\$%s" (car pair)) ;FIXME: "\$" == "$"! + (format "$%s" (car pair)) (let ((val (cdr pair))) (if (listp val) (let ((data-file (org-babel-temp-file "sql-data-"))) diff --git a/elpa/org-20150629/ob-sqlite.el b/elpa/org-20160215/ob-sqlite.el similarity index 97% rename from elpa/org-20150629/ob-sqlite.el rename to elpa/org-20160215/ob-sqlite.el index 098626fe..705d7cee 100644 --- a/elpa/org-20150629/ob-sqlite.el +++ b/elpa/org-20160215/ob-sqlite.el @@ -1,6 +1,6 @@ ;;; ob-sqlite.el --- org-babel functions for sqlite database interaction -;; Copyright (C) 2010-2014 Free Software Foundation, Inc. +;; Copyright (C) 2010-2016 Free Software Foundation, Inc. ;; Author: Eric Schulte ;; Keywords: literate programming, reproducible research @@ -119,7 +119,7 @@ This function is called by `org-babel-execute-src-block'." (lambda (pair) (setq body (replace-regexp-in-string - (format "\$%s" (car pair)) ;FIXME: "\$" == "$"! + (format "$%s" (car pair)) (let ((val (cdr pair))) (if (listp val) (let ((data-file (org-babel-temp-file "sqlite-data-"))) diff --git a/elpa/org-20160215/ob-stan.el b/elpa/org-20160215/ob-stan.el new file mode 100644 index 00000000..e69de29b diff --git a/elpa/org-20150629/ob-table.el b/elpa/org-20160215/ob-table.el similarity index 84% rename from elpa/org-20150629/ob-table.el rename to elpa/org-20160215/ob-table.el index 831e3521..6e6d7ac1 100644 --- a/elpa/org-20150629/ob-table.el +++ b/elpa/org-20160215/ob-table.el @@ -1,6 +1,6 @@ ;;; ob-table.el --- support for calling org-babel functions from tables -;; Copyright (C) 2009-2014 Free Software Foundation, Inc. +;; Copyright (C) 2009-2016 Free Software Foundation, Inc. ;; Author: Eric Schulte ;; Keywords: literate programming, reproducible research @@ -47,7 +47,10 @@ ;; | 7 | | ;; | 8 | | ;; | 9 | | -;; #+TBLFM: $2='(org-sbe 'fibbd (n $1)) +;; #+TBLFM: $2='(org-sbe "fibbd" (n $1)) + +;; NOTE: The quotation marks around the function name, 'fibbd' here, +;; are optional. ;;; Code: (require 'ob-core) @@ -62,29 +65,36 @@ character and replace it with ellipses." (defmacro org-sbe (source-block &rest variables) "Return the results of calling SOURCE-BLOCK with VARIABLES. -Each element of VARIABLES should be a two -element list, whose first element is the name of the variable and -second element is a string of its value. The following call to -`org-sbe' would be equivalent to the following source code block. - (org-sbe 'source-block (n $2) (m 3)) +Each element of VARIABLES should be a list of two elements: the +first element is the name of the variable and second element is a +string of its value. + +So this `org-sbe' construct + + (org-sbe \"source-block\" (n $2) (m 3)) + +is the equivalent of the following source code block: + + #+begin_src emacs-lisp :var results=source-block(n=val_at_col_2, m=3) :results silent + results + #+end_src -#+begin_src emacs-lisp :var results=source-block(n=val_at_col_2, m=3) :results silent -results -#+end_src +NOTE: The quotation marks around the function name, +'source-block', are optional. -NOTE: by default string variable names are interpreted as +NOTE: By default, string variable names are interpreted as references to source-code blocks, to force interpretation of a cell's value as a string, prefix the identifier a \"$\" (e.g., \"$$2\" instead of \"$2\" or \"$@2$2\" instead of \"@2$2\"). -NOTE: it is also possible to pass header arguments to the code +NOTE: It is also possible to pass header arguments to the code block. In this case a table cell should hold the string value of the header argument which can then be passed before all variables as shown in the example below. | 1 | 2 | :file nothing.png | nothing.png | -#+TBLFM: @1$4='(org-sbe test-sbe $3 (x $1) (y $2))" +#+TBLFM: @1$4=\\='(org-sbe test-sbe $3 (x $1) (y $2))" (declare (debug (form form))) (let* ((header-args (if (stringp (car variables)) (car variables) "")) (variables (if (stringp (car variables)) (cdr variables) variables))) diff --git a/elpa/org-20150629/ob-tangle.el b/elpa/org-20160215/ob-tangle.el similarity index 78% rename from elpa/org-20150629/ob-tangle.el rename to elpa/org-20160215/ob-tangle.el index 3a43b42e..a42dd1d0 100644 --- a/elpa/org-20150629/ob-tangle.el +++ b/elpa/org-20160215/ob-tangle.el @@ -1,6 +1,6 @@ ;;; ob-tangle.el --- extract source code from org-mode files -;; Copyright (C) 2009-2014 Free Software Foundation, Inc. +;; Copyright (C) 2009-2016 Free Software Foundation, Inc. ;; Author: Eric Schulte ;; Keywords: literate programming, reproducible research @@ -27,21 +27,29 @@ ;;; Code: (require 'org-src) -(eval-when-compile - (require 'cl)) +(declare-function make-directory "files" (dir &optional parents)) +(declare-function org-at-heading-p "org" (&optional ignored)) +(declare-function org-babel-update-block-body "org" (new-body)) +(declare-function org-back-to-heading "org" (invisible-ok)) +(declare-function org-before-first-heading-p "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-fill-template "org" (template alist)) +(declare-function org-heading-components "org" ()) +(declare-function org-in-commented-heading-p "org" (&optional no-inheritance)) (declare-function org-link-escape "org" (text &optional table)) -(declare-function org-store-link "org" (arg)) (declare-function org-open-link-from-string "org" (s &optional arg reference-buffer)) -(declare-function org-heading-components "org" ()) -(declare-function org-back-to-heading "org" (invisible-ok)) -(declare-function org-fill-template "org" (template alist)) -(declare-function org-babel-update-block-body "org" (new-body)) -(declare-function make-directory "files" (dir &optional parents)) +(declare-function org-store-link "org" (arg)) +(declare-function org-string-nw-p "org" (s)) +(declare-function outline-previous-heading "outline" ()) + +(defvar org-link-types-re) (defcustom org-babel-tangle-lang-exts - '(("emacs-lisp" . "el")) + '(("emacs-lisp" . "el") + ("elisp" . "el")) "Alist mapping languages to their file extensions. The key is the language name, the value is the string that should be inserted as the extension commonly used to identify files @@ -54,6 +62,11 @@ then the name of the language is used." (string "Language name") (string "File Extension")))) +(defcustom org-babel-tangle-use-relative-file-links t + "Use relative path names in links from tangled source back the Org-mode file." + :group 'org-babel-tangle + :type 'boolean) + (defcustom org-babel-post-tangle-hook nil "Hook run in code files tangled by `org-babel-tangle'." :group 'org-babel @@ -81,6 +94,11 @@ information into the output using `org-fill-template'. %link --------- Org-mode style link to the code block %source-name -- name of the code block +Upon insertion the formatted comment will be commented out, and +followed by a newline. To inhibit this post-insertion processing +set the `org-babel-tangle-uncomment-comments' variable to a +non-nil value. + Whether or not comments are inserted during tangling is controlled by the :comments header argument." :group 'org-babel @@ -96,17 +114,30 @@ information into the output using `org-fill-template'. %link --------- Org-mode style link to the code block %source-name -- name of the code block +Upon insertion the formatted comment will be commented out, and +followed by a newline. To inhibit this post-insertion processing +set the `org-babel-tangle-uncomment-comments' variable to a +non-nil value. + Whether or not comments are inserted during tangling is controlled by the :comments header argument." :group 'org-babel :version "24.1" :type 'string) -(defcustom org-babel-process-comment-text #'org-babel-trim +(defcustom org-babel-tangle-uncomment-comments nil + "Inhibits automatic commenting and addition of trailing newline +of tangle comments. Use `org-babel-tangle-comment-format-beg' +and `org-babel-tangle-comment-format-end' to customize the format +of tangled comments." + :group 'org-babel + :type 'boolean) + +(defcustom org-babel-process-comment-text #'org-remove-indentation "Function called to process raw Org-mode text collected to be inserted as comments in tangled source-code files. The function should take a single string argument and return a string -result. The default value is `org-babel-trim'." +result. The default value is `org-remove-indentation'." :group 'org-babel :version "24.1" :type 'function) @@ -153,12 +184,14 @@ Return a list whose CAR is the tangled file name." (save-window-excursion (find-file file) (setq to-be-removed (current-buffer)) - (org-babel-tangle nil target-file lang)) + (mapcar #'expand-file-name (org-babel-tangle nil target-file lang))) (unless visited-p (kill-buffer to-be-removed))))) (defun org-babel-tangle-publish (_ filename pub-dir) "Tangle FILENAME and place the results in PUB-DIR." + (unless (file-exists-p pub-dir) + (make-directory pub-dir t)) (mapc (lambda (el) (copy-file el pub-dir t)) (org-babel-tangle-file filename))) ;;;###autoload @@ -176,12 +209,12 @@ used to limit the exported source code blocks by language." (run-hooks 'org-babel-pre-tangle-hook) ;; Possibly Restrict the buffer to the current code block (save-restriction - (when (equal arg '(4)) - (let ((head (org-babel-where-is-src-block-head))) + (save-excursion + (when (equal arg '(4)) + (let ((head (org-babel-where-is-src-block-head))) (if head (goto-char head) (user-error "Point is not in a source code block")))) - (save-excursion (let ((block-counter 0) (org-babel-default-header-args (if target-file @@ -216,7 +249,7 @@ used to limit the exported source code blocks by language." (base-name (cond ((string= "yes" tangle) (file-name-sans-extension - (buffer-file-name))) + (nth 1 spec))) ((string= "no" tangle) nil) ((> (length tangle) 0) tangle))) (file-name (when base-name @@ -246,6 +279,10 @@ used to limit the exported source code blocks by language." (if (file-exists-p file-name) (insert-file-contents file-name)) (goto-char (point-max)) + ;; Handle :padlines unless first line in file + (unless (or (string= "no" (cdr (assoc :padline (nth 4 spec)))) + (= (point) (point-min))) + (insert "\n")) (insert content) (write-region nil nil file-name)))) ;; if files contain she-bangs, then make the executable @@ -302,15 +339,27 @@ Insert the source-code specified by SPEC into the current source code file. This function uses `comment-region' which assumes that the appropriate major-mode is set. SPEC has the form: - \(start-line file link source-name params body comment)" + (start-line file link source-name params body comment)" (let* ((start-line (nth 0 spec)) - (file (nth 1 spec)) - (link (nth 2 spec)) + (info (nth 4 spec)) + (file (if org-babel-tangle-use-relative-file-links + (file-relative-name (nth 1 spec)) + (nth 1 spec))) + (link (let ((link (nth 2 spec))) + (if org-babel-tangle-use-relative-file-links + (when (string-match org-link-types-re link) + (let ((type (match-string 0 link)) + (link (substring link (match-end 0)))) + (concat + type + (file-relative-name + link + (file-name-directory (cdr (assq :tangle info))))))) + link))) (source-name (nth 3 spec)) (body (nth 5 spec)) (comment (nth 6 spec)) - (comments (cdr (assoc :comments (nth 4 spec)))) - (padline (not (string= "no" (cdr (assoc :padline (nth 4 spec)))))) + (comments (cdr (assq :comments info))) (link-p (or (string= comments "both") (string= comments "link") (string= comments "yes") (string= comments "noweb"))) (link-data (mapcar (lambda (el) @@ -319,17 +368,27 @@ that the appropriate major-mode is set. SPEC has the form: (if (stringp le) le (format "%S" le))))) '(start-line file link source-name))) (insert-comment (lambda (text) - (when (and comments (not (string= comments "no")) - (> (length text) 0)) - (when padline (insert "\n")) - (comment-region (point) (progn (insert text) (point))) - (end-of-line nil) (insert "\n"))))) + (when (and comments + (not (string= comments "no")) + (org-string-nw-p text)) + (if org-babel-tangle-uncomment-comments + ;; Plain comments: no processing. + (insert text) + ;; Ensure comments are made to be + ;; comments, and add a trailing + ;; newline. Also ignore invisible + ;; characters when commenting. + (comment-region + (point) + (progn (insert (org-no-properties text)) + (point))) + (end-of-line) + (insert "\n")))))) (when comment (funcall insert-comment comment)) (when link-p (funcall insert-comment (org-fill-template org-babel-tangle-comment-format-beg link-data))) - (when padline (insert "\n")) (insert (format "%s\n" @@ -340,49 +399,36 @@ that the appropriate major-mode is set. SPEC has the form: insert-comment (org-fill-template org-babel-tangle-comment-format-end link-data))))) -(defvar org-comment-string) ;; Defined in org.el (defun org-babel-tangle-collect-blocks (&optional language tangle-file) - "Collect source blocks in the current Org-mode file. + "Collect source blocks in the current Org file. Return an association list of source-code block specifications of the form used by `org-babel-spec-to-string' grouped by language. Optional argument LANGUAGE can be used to limit the collected source code blocks by language. Optional argument TANGLE-FILE can be used to limit the collected code blocks by target file." - (let ((block-counter 1) (current-heading "") blocks by-lang) + (let ((counter 0) last-heading-pos blocks) (org-babel-map-src-blocks (buffer-file-name) - (lambda (new-heading) - (if (not (string= new-heading current-heading)) - (progn - (setq block-counter 1) - (setq current-heading new-heading)) - (setq block-counter (+ 1 block-counter)))) - (replace-regexp-in-string "[ \t]" "-" - (condition-case nil - (or (nth 4 (org-heading-components)) - "(dummy for heading without text)") - (error (buffer-file-name)))) - (let* ((info (org-babel-get-src-block-info 'light)) - (src-lang (nth 0 info)) - (src-tfile (cdr (assoc :tangle (nth 2 info))))) - (unless (or (string-match (concat "^" org-comment-string) current-heading) - (string= (cdr (assoc :tangle (nth 2 info))) "no") - (and tangle-file (not (equal tangle-file src-tfile)))) - (unless (and language (not (string= language src-lang))) - ;; Add the spec for this block to blocks under it's language - (setq by-lang (cdr (assoc src-lang blocks))) - (setq blocks (delq (assoc src-lang blocks) blocks)) - (setq blocks (cons - (cons src-lang - (cons - (org-babel-tangle-single-block - block-counter) - by-lang)) blocks)))))) - ;; Ensure blocks are in the correct order - (setq blocks - (mapcar - (lambda (by-lang) (cons (car by-lang) (reverse (cdr by-lang)))) - blocks)) - blocks)) + (let ((current-heading-pos + (org-with-wide-buffer + (org-with-limited-levels (outline-previous-heading))))) + (if (eq last-heading-pos current-heading-pos) (incf counter) + (setq counter 1) + (setq last-heading-pos current-heading-pos))) + (unless (org-in-commented-heading-p) + (let* ((info (org-babel-get-src-block-info 'light)) + (src-lang (nth 0 info)) + (src-tfile (cdr (assq :tangle (nth 2 info))))) + (unless (or (string= src-tfile "no") + (and tangle-file (not (equal tangle-file src-tfile))) + (and language (not (string= language src-lang)))) + ;; Add the spec for this block to blocks under its + ;; language. + (let ((by-lang (assoc src-lang blocks)) + (block (org-babel-tangle-single-block counter))) + (if by-lang (setcdr by-lang (cons block (cdr by-lang))) + (push (cons src-lang (list block)) blocks))))))) + ;; Ensure blocks are in the correct order. + (mapcar (lambda (b) (cons (car b) (nreverse (cdr b)))) blocks))) (defun org-babel-tangle-single-block (block-counter &optional only-this-block) @@ -395,7 +441,7 @@ list to be used by `org-babel-tangle' directly." (start-line (save-restriction (widen) (+ 1 (line-number-at-pos (point))))) - (file (buffer-file-name)) + (file (buffer-file-name (buffer-base-buffer))) (src-lang (nth 0 info)) (params (nth 2 info)) (extra (nth 3 info)) @@ -504,7 +550,7 @@ which enable the original code blocks to be found." (prog1 counter (message "Detangled %d code blocks" counter))))) (defun org-babel-tangle-jump-to-org () - "Jump from a tangled code file to the related Org-mode file." + "Jump from a tangled code file to the related Org mode file." (interactive) (let ((mid (point)) start body-start end done @@ -513,9 +559,8 @@ which enable the original code blocks to be found." (save-excursion (while (and (re-search-backward org-bracket-link-analytic-regexp nil t) (not ; ever wider searches until matching block comments - (and (setq start (point-at-eol)) - (setq body-start (save-excursion - (forward-line 2) (point-at-bol))) + (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)) @@ -524,29 +569,33 @@ which enable the original code blocks to be found." (re-search-forward (concat " " (regexp-quote block-name) " ends here") nil t) - (setq end (point-at-bol)))))))) + (setq end (line-beginning-position)))))))) (unless (and start (< start mid) (< mid end)) (error "Not in tangled code")) - (setq body (org-babel-trim (buffer-substring start end)))) + (setq body (buffer-substring body-start end))) (when (string-match "::" path) (setq path (substring path 0 (match-beginning 0)))) - (find-file path) (setq target-buffer (current-buffer)) - (goto-char start) (org-open-link-from-string link) + (find-file path) + (setq target-buffer (current-buffer)) + ;; Go to the beginning of the relative block in Org file. + (org-open-link-from-string link) (if (string-match "[^ \t\n\r]:\\([[:digit:]]+\\)" block-name) - (org-babel-next-src-block - (string-to-number (match-string 1 block-name))) + (let ((n (string-to-number (match-string 1 block-name)))) + (if (org-before-first-heading-p) (goto-char (point-min)) + (org-back-to-heading t)) + ;; Do not skip the first block if it begins at point min. + (cond ((or (org-at-heading-p) + (not (eq (org-element-type (org-element-at-point)) + 'src-block))) + (org-babel-next-src-block n)) + ((= n 1)) + (t (org-babel-next-src-block (1- n))))) (org-babel-goto-named-src-block block-name)) - ;; position at the beginning of the code block body (goto-char (org-babel-where-is-src-block-head)) + ;; Preserve location of point within the source code in tangled + ;; code file. (forward-line 1) - ;; Use org-edit-special to isolate the code. - (org-edit-special) - ;; Then move forward the correct number of characters in the - ;; code buffer. (forward-char (- mid body-start)) - ;; And return to the Org-mode buffer with the point in the right - ;; place. - (org-edit-src-exit) (setq target-char (point))) (org-src-switch-to-buffer target-buffer t) (prog1 body (goto-char target-char)))) diff --git a/elpa/org-20150629/ob.el b/elpa/org-20160215/ob.el similarity index 95% rename from elpa/org-20150629/ob.el rename to elpa/org-20160215/ob.el index 87657fef..cc46693c 100644 --- a/elpa/org-20150629/ob.el +++ b/elpa/org-20160215/ob.el @@ -1,6 +1,6 @@ ;;; ob.el --- working with code blocks in org-mode -;; Copyright (C) 2009-2014 Free Software Foundation, Inc. +;; Copyright (C) 2009-2016 Free Software Foundation, Inc. ;; Authors: Eric Schulte ;; Keywords: literate programming, reproducible research diff --git a/elpa/org-20150629/org b/elpa/org-20160215/org similarity index 87% rename from elpa/org-20150629/org rename to elpa/org-20160215/org index a18d92b7..ec231e34 100644 --- a/elpa/org-20150629/org +++ b/elpa/org-20160215/org @@ -1,8 +1,8 @@ This is org, produced by makeinfo version 4.13 from org.texi. -This manual is for Org version 8.2.10 (release_8.2.10-41-g42228a). +This manual is for Org version 8.3.3 (release_8.3.3-55-g9f737b). - Copyright (C) 2004-2014 Free Software Foundation, Inc. + Copyright (C) 2004-2016 Free Software Foundation, Inc. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, @@ -26,9 +26,9 @@ File: org, Node: Top, Next: Introduction, Prev: (dir), Up: (dir) Org Mode Manual *************** -This manual is for Org version 8.2.10 (release_8.2.10-41-g42228a). +This manual is for Org version 8.3.3 (release_8.3.3-55-g9f737b). - Copyright (C) 2004-2014 Free Software Foundation, Inc. + Copyright (C) 2004-2016 Free Software Foundation, Inc. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, @@ -44,23 +44,23 @@ This manual is for Org version 8.2.10 (release_8.2.10-41-g42228a). * Menu: * Introduction:: Getting started -* Document Structure:: A tree works like your brain +* 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 +* TODO items:: Every tree branch can be a TODO item * Tags:: Tagging headlines and matching sets of tags -* Properties and Columns:: Storing information about an entry -* Dates and Times:: Making items useful for planning +* Properties and columns:: Storing information about an entry +* Dates and times:: Making items useful for planning * Capture - Refile - Archive:: The ins and outs for projects -* Agenda Views:: Collecting information into views +* Agenda views:: Collecting information into views * Markup:: Prepare text for rich export * Exporting:: Sharing and publishing notes * Publishing:: Create a web site of linked Org files -* Working With Source Code:: Export, evaluate, and tangle code blocks +* Working with source code:: Export, evaluate, and tangle code blocks * Miscellaneous:: All the rest which did not fit elsewhere * Hacking:: How to hack your way around * MobileOrg:: Viewing and capture on a mobile device -* History and Acknowledgments:: How Org came into being +* History and acknowledgments:: How Org came into being * GNU Free Documentation License:: The license for this documentation. * Main Index:: An index of Org's concepts and features * Key Index:: Key bindings and where they are described @@ -98,11 +98,6 @@ Visibility cycling * Initial visibility:: Setting the initial visibility state * Catching invisible edits:: Preventing mistakes when editing invisible parts -Global and local cycling - -* Initial visibility:: Setting the initial visibility state -* Catching invisible edits:: Preventing mistakes when editing invisible parts - Tables * Built-in table editor:: Simple tables @@ -169,7 +164,7 @@ 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 hierarchy:: Create a hierarchy of tags * Tag searches:: Searching for combinations of tags Properties and columns @@ -199,8 +194,7 @@ Dates and times * Deadlines and scheduling:: Planning your work * Clocking work time:: Tracking how long you spend on a task * Effort estimates:: Planning work effort in advance -* Relative timer:: Notes with a running timer -* Countdown timer:: Starting a countdown timer for a task +* Timers:: Notes with a running timer Creating timestamps @@ -222,7 +216,7 @@ Capture - Refile - Archive * Capture:: Capturing new stuff * Attachments:: Add files to tasks -* RSS Feeds:: Getting input from RSS feeds +* RSS feeds:: Getting input from RSS feeds * Protocols:: External (e.g., Browser) access to Emacs and Org * Refile and copy:: Moving/copying a tree from one place to another * Archiving:: What to do with finished projects @@ -252,7 +246,7 @@ Agenda views * Presentation and sorting:: How agenda items are prepared for display * Agenda commands:: Remote editing of Org trees * Custom agenda views:: Defining special searches and views -* Exporting Agenda Views:: Writing a view to a file +* Exporting agenda views:: Writing a view to a file * Agenda column view:: Using column view for collected entries The built-in agenda views @@ -275,7 +269,7 @@ Custom agenda views * Storing searches:: Type once, use often * Block agenda:: All the stuff you need in a single buffer -* Setting Options:: Changing the rules +* Setting options:: Changing the rules Markup for rich export @@ -310,7 +304,7 @@ Embedded LaTeX Exporting -* The Export Dispatcher:: The main exporter interface +* The export dispatcher:: The main exporter interface * Export back-ends:: Built-in export formats * Export settings:: Generic export settings * ASCII/Latin-1/UTF-8 export:: Exporting to flat files with encoding @@ -347,7 +341,7 @@ LaTeX and PDF export * Quoting LaTeX code:: Incorporating literal LaTeX code * LaTeX specific attributes:: Controlling LaTeX output -OpenDocument Text export +OpenDocument text export * Pre-requisites for ODT export:: What packages ODT exporter relies on * ODT export commands:: How to invoke ODT export @@ -475,7 +469,7 @@ Specific header arguments Miscellaneous * Completion:: M-TAB knows what you need -* Easy Templates:: Quick insertion of structural elements +* Easy templates:: Quick insertion of structural elements * Speed keys:: Electric commands at the beginning of a headline * Code evaluation security:: Org mode files evaluate inline code * Customization:: Adapting Org to your taste @@ -520,7 +514,7 @@ MobileOrg * Pulling from MobileOrg:: Integrating captured and flagged items  -File: org, Node: Introduction, Next: Document Structure, Prev: Top, Up: Top +File: org, Node: Introduction, Next: Document structure, Prev: Top, Up: Top 1 Introduction ************** @@ -534,65 +528,62 @@ File: org, Node: Introduction, Next: Document Structure, Prev: Top, Up: Top * Conventions:: Typesetting conventions in the manual  -File: org, Node: Summary, Next: Installation, Prev: Introduction, Up: Introduction +File: org, Node: Summary, Next: Installation, Up: Introduction 1.1 Summary =========== -Org is a mode for keeping notes, maintaining TODO lists, and doing -project planning with a fast and effective plain-text system. - - Org develops organizational tasks around NOTES files that contain -lists or information about projects as plain text. Org is implemented -on top of Outline mode, which makes it possible to keep the content of -large files well structured. Visibility cycling and structure editing -help to work with the tree. Tables are easily created with a built-in -table editor. Org supports TODO items, deadlines, timestamps, and -scheduling. It dynamically compiles entries into an agenda that -utilizes and smoothly integrates much of the Emacs calendar and diary. -Plain text URL-like links connect to websites, emails, Usenet messages, -BBDB entries, and any files related to the projects. For printing and -sharing notes, an Org file can be exported as a structured ASCII file, -as HTML, or (TODO and agenda items only) as an iCalendar file. It can -also serve as a publishing tool for a set of linked web pages. - - As a project planning environment, Org works by adding metadata to -outline nodes. Based on this data, specific entries can be extracted -in queries and create dynamic agenda views. - - Org mode contains the Org Babel environment which allows you to work -with embedded source code blocks in a file, to facilitate code -evaluation, documentation, and literate programming techniques. - - Org's automatic, context-sensitive table editor with spreadsheet -capabilities can be integrated into any major mode by activating the -minor Orgtbl mode. Using a translation step, it can be used to maintain -tables in arbitrary file types, for example in LaTeX. The structure -editing and list creation capabilities can be used outside Org with the -minor Orgstruct mode. +Org is a mode for keeping notes, maintaining TODO lists, and project +planning with a fast and effective plain-text system. It also is an +authoring system with unique support for literate programming and +reproducible research. + + Org is implemented on top of Outline mode, which makes it possible +to keep the content of large files well structured. Visibility cycling +and structure editing help to work with the tree. Tables are easily +created with a built-in table editor. Plain text URL-like links +connect to websites, emails, Usenet messages, BBDB entries, and any +files related to the projects. + + Org develops organizational tasks around notes files that contain +lists or information about projects as plain text. Project planning +and task management makes use of metadata which is part of an outline +node. Based on this data, specific entries can be extracted in queries +and create dynamic agenda views that also integrate the Emacs calendar +and diary. Org can be used to implement many different project +planning schemes, such as David Allen's GTD system. + + Org files can serve as a single source authoring system with export +to many different formats such as HTML, LaTeX, Open Document, and +Markdown. New export backends can be derived from existing ones, or +defined from scratch. + + Org files can include source code blocks, which makes Org uniquely +suited for authoring technical documents with code examples. Org source +code blocks are fully functional; they can be evaluated in place and +their results can be captured in the file. This makes it possible to +create a single file reproducible research compendium. Org keeps simple things simple. When first fired up, it should feel like a straightforward, easy to use outliner. Complexity is not -imposed, but a large amount of functionality is available when you need -it. Org is a toolbox and can be used in different ways and for -different ends, for example: - - * an outline extension with visibility cycling and structure editing - * an ASCII system and table editor for taking structured notes - * a TODO list editor - * a full agenda and planner with deadlines and work scheduling - * an environment in which to implement David Allen's GTD system - * a simple hypertext system, with HTML and LaTeX export - * a publishing tool to create a set of interlinked web pages - * an environment for literate programming +imposed, but a large amount of functionality is available when needed. +Org is a toolbox. Many users actually run only a (very personal) +fraction of Org's capabilities, and know that there is more whenever +they need it. + + All of this is achieved with strictly plain text files, the most +portable and future-proof file format. Org runs in Emacs. Emacs is +one of the most widely ported programs, so that Org mode is available +on every major platform. There is a website for Org which provides links to the newest version of Org, as well as additional information, frequently asked questions (FAQ), links to tutorials, etc. This page is located at -`http://orgmode.org'. +`http://orgmode.org'. - The version 7.3 of this manual is available as a paperback book from -Network Theory Ltd. (http://www.network-theory.co.uk/org/manual/) + An earlier version (7.3) of this manual is available as a paperback +book from Network Theory Ltd. +(http://www.network-theory.co.uk/org/manual/)  File: org, Node: Installation, Next: Activation, Prev: Summary, Up: Introduction @@ -620,7 +611,7 @@ install Elisp libraries. You can install Org with `M-x package-install RET org'. Important: you need to do this in a session where no `.org' file has -been visited, i.e. where no Org built-in function have been loaded. +been visited, i.e., where no Org built-in function have been loaded. Otherwise autoload Org functions will mess up the installation. Then, to make sure your Org configuration is taken into account, @@ -695,13 +686,12 @@ and `org-iswitchb' should be accessible through global keys (i.e., anywhere in Emacs, not just in Org buffers). Here are suggested bindings for these keys, please modify the keys to your own liking. (global-set-key "\C-cl" 'org-store-link) - (global-set-key "\C-cc" 'org-capture) (global-set-key "\C-ca" 'org-agenda) + (global-set-key "\C-cc" 'org-capture) (global-set-key "\C-cb" 'org-iswitchb) - With this setup, all files with extension `.org' will be put into -Org mode. As an alternative, make the first line of a file look like -this: + To turn on Org mode in a file that does not have the extension +`.org', make the first line of a file look like this: MY PROJECTS -*- mode: org; -*- @@ -730,9 +720,10 @@ File: org, Node: Feedback, Next: Conventions, Prev: Activation, Up: Introduc If you find problems with Org, or if you have questions, remarks, or ideas about it, please mail to the Org mailing list -. If you are not a member of the mailing list, -your mail will be passed to the list after a moderator has approved -it(1). +. You can subscribe to the list on this web +page (https://lists.gnu.org/mailman/listinfo/emacs-orgmode). If you +are not a member of the mailing list, your mail will be passed to the +list after a moderator has approved it(1). For bug reports, please first try to reproduce the bug with the latest version of Org available--if you are running an outdated @@ -744,7 +735,7 @@ Org related setup in `.emacs'. The easiest way to do this is to use the command M-x org-submit-bug-report RET which will put all this information into an Emacs mail buffer so -that you only need to add your description. If you re not sending the +that you only need to add your description. If you are not sending the Email from within Emacs, please copy and paste the content into your Email program. @@ -762,7 +753,7 @@ minimal setup is not necessary. In that case it is sufficient to start Emacs as `emacs -Q'. The `minimal-org.el' setup file can have contents as shown below. - ;;; Minimal setup to load latest `org-mode' + ;;; Minimal setup to load latest 'org-mode' ;; activate debugging (setq debug-on-error t @@ -850,9 +841,10 @@ its readability, but you can use lowercase in your Org files(1). Keybindings and commands ........................ -The manual suggests two global keybindings: `C-c a' for `org-agenda' -and `C-c c' for `org-capture'. These are only suggestions, but the -rest of the manual assumes that you are using these keybindings. +The manual suggests a few global keybindings, in particular `C-c a' for +`org-agenda' and `C-c c' for `org-capture'. These are only +suggestions, but the rest of the manual assumes that these keybindings +are in place in order to list commands by key access. Also, the manual lists both the keys and the corresponding commands for accessing a functionality. Org mode often uses the same key for @@ -872,7 +864,7 @@ manual without the command names by unsetting the flag `cmdnames' in inserts `#+results'.  -File: org, Node: Document Structure, Next: Tables, Prev: Introduction, Up: Top +File: org, Node: Document structure, Next: Tables, Prev: Introduction, Up: Top 2 Document structure ******************** @@ -896,7 +888,7 @@ structure of the document. * Org syntax:: Formal description of Org's syntax  -File: org, Node: Outlines, Next: Headlines, Prev: Document Structure, Up: Document Structure +File: org, Node: Outlines, Next: Headlines, Up: Document structure 2.1 Outlines ============ @@ -911,7 +903,7 @@ compressing the entire show/hide functionality into a single command, `org-cycle', which is bound to the key.  -File: org, Node: Headlines, Next: Visibility cycling, Prev: Outlines, Up: Document Structure +File: org, Node: Headlines, Next: Visibility cycling, Prev: Outlines, Up: Document structure 2.2 Headlines ============= @@ -928,9 +920,13 @@ start with one or more stars, on the left margin(1) (2). For example: * Another top level headline -Some people find the many stars too noisy and would prefer an outline -that has whitespace followed by a single star as headline starters. -*note Clean view::, describes a setup to realize this. +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. *note Clean view::, describes a setup to realize this. An empty line after the end of a subtree is considered part of it and will be hidden when the subtree is folded. However, if you leave at @@ -944,10 +940,10 @@ variable `org-cycle-separator-lines' to modify this behavior. and `org-ctrl-k-protect-subtree' to configure special behavior of `C-a', `C-e', and `C-k' in headlines. - (2) Clocking only works with headings indented less then 30 stars. + (2) Clocking only works with headings indented less than 30 stars.  -File: org, Node: Visibility cycling, Next: Motion, Prev: Headlines, Up: Document Structure +File: org, Node: Visibility cycling, Next: Motion, Prev: Headlines, Up: Document structure 2.3 Visibility cycling ====================== @@ -959,7 +955,7 @@ File: org, Node: Visibility cycling, Next: Motion, Prev: Headlines, Up: Docu * Catching invisible edits:: Preventing mistakes when editing invisible parts  -File: org, Node: Global and local cycling, Next: Initial visibility, Prev: Visibility cycling, Up: Visibility cycling +File: org, Node: Global and local cycling, Next: Initial visibility, Up: Visibility cycling 2.3.1 Global and local cycling ------------------------------ @@ -1024,11 +1020,6 @@ C-u `C-c C-x v' (`org-copy-visible') Copy the visible text in the region into the kill ring. -* Menu: - -* Initial visibility:: Setting the initial visibility state -* Catching invisible edits:: Preventing mistakes when editing invisible parts - ---------- Footnotes ---------- (1) see, however, the option `org-cycle-emulate-tab'. @@ -1036,7 +1027,7 @@ C-u (2) see the option `org-cycle-global-at-bob'. (3) The indirect buffer (*note Indirect Buffers: (emacs)Indirect -Buffers.) will contain the entire buffer, but will be narrowed to the +Buffers.) will contain the entire buffer, but will be narrowed to the current tree. Editing the indirect buffer will also change the original buffer, but without affecting visibility in that buffer. @@ -1062,7 +1053,7 @@ the first time during the agenda generation: if you want the agenda to honor the startup visibility, set `org-agenda-inhibit-startup' to `nil'. Furthermore, any entries with a `VISIBILITY' property (*note Properties -and Columns::) will get their visibility adapted accordingly. Allowed +and columns::) will get their visibility adapted accordingly. Allowed values for this property are `folded', `children', `content', and `all'. `C-u C-u ' (`org-set-startup-visibility') @@ -1089,7 +1080,7 @@ this. See the docstring of this option on how Org should catch invisible edits and process them.  -File: org, Node: Motion, Next: Structure editing, Prev: Visibility cycling, Up: Document Structure +File: org, Node: Motion, Next: Structure editing, Prev: Visibility cycling, Up: Document structure 2.4 Motion ========== @@ -1128,25 +1119,34 @@ The following commands jump to other headlines in the buffer. See also the option `org-goto-interface'.  -File: org, Node: Structure editing, Next: Sparse trees, Prev: Motion, Up: Document Structure +File: org, Node: Structure editing, Next: Sparse trees, Prev: Motion, Up: Document structure 2.5 Structure editing ===================== `M-' (`org-insert-heading') - Insert a new heading/item with the same level than the one at - point. If the cursor is in a plain list item, a new item is - created (*note Plain lists::). To prevent this behavior in lists, - call the command with a prefix argument. 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(1). If the command is - used at the _beginning_ of a headline, the new headline is created - before the current line. If the command is used at the _end_ of a - folded subtree (i.e., behind the ellipses at the end of a + Insert a new heading/item with the same level as the one at point. + + If the cursor is in a plain list item, a new item is created + (*note Plain lists::). To prevent this behavior in lists, call + the command with one prefix argument. 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'. + + If the command is used at the _beginning_ of a line, and if there + is a heading or an item at point, the new heading/item is created + _before_ the current line. If the command is used at the _end_ of + a folded subtree (i.e., behind the ellipses at the end of a headline), then a headline will be inserted after the end of the - subtree. Calling this command with `C-u C-u' will unconditionally - respect the headline's content and create a new item at the end of - the parent subtree. + subtree. + + Calling this command with `C-u C-u' will unconditionally respect + the headline's content and create a new item at the end of the + parent subtree. + + If point is at the beginning of a normal line, turn this line into + a heading. `C-' (`org-insert-heading-respect-content') Just like `M-', except when adding a new heading below the @@ -1272,13 +1272,8 @@ just after the last headline to change. Note that when the cursor is inside a table (*note Tables::), the Meta-Cursor keys have different functionality. - ---------- Footnotes ---------- - - (1) If you do not want the line to be split, customize the variable -`org-M-RET-may-split-line'. -  -File: org, Node: Sparse trees, Next: Plain lists, Prev: Structure editing, Up: Document Structure +File: org, Node: Sparse trees, Next: Plain lists, Prev: Structure editing, Up: Document structure 2.6 Sparse trees ================ @@ -1289,7 +1284,7 @@ document is folded as much as possible, but the selected information is made visible along with the headline structure above it(1). Just try it out and you will see immediately how it works. - Org mode contains several commands creating such trees, all these + Org mode contains several commands for creating such trees, all these commands can be accessed through a dispatcher: `C-c /' (`org-sparse-tree') @@ -1337,10 +1332,8 @@ visible part of the document and print the resulting file. ---------- Footnotes ---------- - (1) See also the variables `org-show-hierarchy-above', -`org-show-following-heading', `org-show-siblings', and -`org-show-entry-below' for detailed control on how much context is -shown around each match. + (1) See also the variable `org-show-context-detail' to decide how +much context is shown around each match. (2) This depends on the option `org-remove-highlights-with-change' @@ -1348,7 +1341,7 @@ shown around each match. display for outlining, not text properties.  -File: org, Node: Plain lists, Next: Drawers, Prev: Sparse trees, Up: Document Structure +File: org, Node: Plain lists, Next: Drawers, Prev: Sparse trees, Up: Document structure 2.7 Plain lists =============== @@ -1394,7 +1387,7 @@ is an example: But in the end, no individual scenes matter but the film as a whole. Important actors in this film are: - Elijah Wood :: He plays Frodo - - Sean Austin :: He plays Sam, Frodo's friend. I still remember + - Sean Astin :: He plays Sam, Frodo's friend. I still remember him very well from his role as Mikey Walsh in The Goonies. Org supports these lists by tuning filling and wrapping commands to @@ -1406,7 +1399,7 @@ indented to signal that they belong to a particular item. If you find that using a different bullet for a sub-list (than that used for the current list-level) improves readability, customize the variable `org-list-demote-modify-bullet'. To get a greater difference -of indentation between items and theirs sub-items, customize +of indentation between items and their sub-items, customize `org-list-indent-offset'. The following commands act on items when the cursor is in the first @@ -1544,15 +1537,15 @@ into `.emacs': `(require 'filladapt)' (9) See `org-list-use-circular-motion' for a cyclic behavior.  -File: org, Node: Drawers, Next: Blocks, Prev: Plain lists, Up: Document Structure +File: org, Node: Drawers, Next: Blocks, Prev: Plain lists, Up: Document structure 2.8 Drawers =========== Sometimes you want to keep information associated with an entry, but you -normally don't want to see it. For this, Org mode has _drawers_. -Drawers need to be configured with the option `org-drawers'(1). -Drawers look like this: +normally don't want to see it. For this, Org mode has _drawers_. They +can contain anything but a headline and another drawer. Drawers look +like this: ** This is a headline Still outside the drawer @@ -1573,7 +1566,7 @@ hide and show the entry, but keep the drawer collapsed to a single line. In order to look inside the drawer, you need to move the cursor to the drawer line and press there. Org mode uses the `PROPERTIES' drawer for storing properties (*note Properties and -Columns::), and you can also arrange for state change notes (*note +columns::), and you can also arrange for state change notes (*note Tracking TODO state changes::) and clock times (*note Clocking work time::) to be stored in a drawer `LOGBOOK'. If you want to store a quick note in the LOGBOOK drawer, in a similar way to state changes, use @@ -1583,16 +1576,11 @@ quick note in the LOGBOOK drawer, in a similar way to state changes, use You can select the name of the drawers which should be exported with `org-export-with-drawers'. In that case, drawer contents will appear in -export output. Property drawers are not affected by this variable and -are never exported. - - ---------- Footnotes ---------- - - (1) You can define additional drawers on a per-file basis with a -line like `#+DRAWERS: HIDDEN STATE' +export output. Property drawers are not affected by this variable: +configure `org-export-with-properties' instead.  -File: org, Node: Blocks, Next: Footnotes, Prev: Drawers, Up: Document Structure +File: org, Node: Blocks, Next: Footnotes, Prev: Drawers, Up: Document structure 2.9 Blocks ========== @@ -1608,7 +1596,7 @@ get all blocks folded at startup by configuring the option #+STARTUP: nohideblocks  -File: org, Node: Footnotes, Next: Orgstruct mode, Prev: Blocks, Up: Document Structure +File: org, Node: Footnotes, Next: Orgstruct mode, Prev: Blocks, Up: Document structure 2.10 Footnotes ============== @@ -1704,6 +1692,15 @@ The following command handles footnotes: definition/reference, and you can use the usual commands to follow these links. +`C-c '' + +`C-c '' + Edit the footnote definition corresponding to the reference at + point in a seperate window. This may be useful if editing + footnotes in a narrowed buffer. The window can be closed by + pressing `C-c ''. + + ---------- Footnotes ---------- (1) The corresponding in-buffer setting is: `#+STARTUP: fninline' or @@ -1713,7 +1710,7 @@ The following command handles footnotes: `nofnadjust'.  -File: org, Node: Orgstruct mode, Next: Org syntax, Prev: Footnotes, Up: Document Structure +File: org, Node: Orgstruct mode, Next: Org syntax, Prev: Footnotes, Up: Document structure 2.11 The Orgstruct minor mode ============================= @@ -1747,7 +1744,7 @@ commented lines. Some commands like `org-demote' are disabled when the prefix is set, but folding/unfolding will work correctly.  -File: org, Node: Org syntax, Prev: Orgstruct mode, Up: Document Structure +File: org, Node: Org syntax, Prev: Orgstruct mode, Up: Document structure 2.12 Org syntax =============== @@ -1771,7 +1768,7 @@ stored in this list. Most interactive commands (e.g., for structure editing) also rely on the syntactic meaning of the surrounding context.  -File: org, Node: Tables, Next: Hyperlinks, Prev: Document Structure, Up: Top +File: org, Node: Tables, Next: Hyperlinks, Prev: Document structure, Up: Top 3 Tables ******** @@ -1790,7 +1787,7 @@ calculations are supported using the Emacs `calc' package (*note Calc: * Org-Plot:: Plotting from org tables  -File: org, Node: Built-in table editor, Next: Column width and alignment, Prev: Tables, Up: Tables +File: org, Node: Built-in table editor, Next: Column width and alignment, Up: Tables 3.1 The built-in table editor ============================= @@ -1831,14 +1828,15 @@ Creation and conversion ....................... `C-c | (`org-table-create-or-convert-from-region')' - Convert the active region to table. If every line contains at + Convert the active region to a 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. You can use a prefix argument to force a specific - separator: `C-u' forces CSV, `C-u C-u' forces TAB, and a numeric - argument N indicates that at least N consecutive spaces, or - alternatively a TAB will be the separator. + separator: `C-u' forces CSV, `C-u C-u' forces TAB, `C-u C-u C-u' + will prompt for a regular expression to match the separator, and a + numeric argument N indicates that at least N consecutive spaces, + or alternatively a 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 `|Name|Phone|Age |- '. @@ -1849,6 +1847,9 @@ Re-aligning and field motion `C-c C-c (`org-table-align')' Re-align the table and don't move to another field. +`C-c SPC (`org-table-blank-field')' + Blank the field at point. + ` (`org-table-next-field')' Re-align the table, move to the next field. Creates a new row if necessary. @@ -1909,8 +1910,10 @@ Column and row editing 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). When called with a - prefix argument, alphabetic sorting will be case-sensitive. + (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 will be case-sensitive. Regions ....... @@ -2042,8 +2045,8 @@ Fields that are wider become clipped and end in the string `=>'. Note that the full text is still in the buffer but is hidden. To see the full text, hold the mouse over the field--a tool-tip window will show the full content. To edit such a field, use the command `C-c `' (that -is `C-c' followed by the backquote). This will open a new window with -the full field. Edit it and finish with `C-c C-c'. +is `C-c' followed by the grave accent). This will open a new window +with the full field. Edit it and finish with `C-c C-c'. When visiting a file containing a table with narrowed columns, the necessary character hiding has not yet happened, and the table needs to @@ -2087,13 +2090,13 @@ the end of a column, or `<>' (no space between `<' and `>') to make a column a group of its own. Boundaries between column groups will upon export be marked with vertical lines. Here is an example: - | N | N^2 | N^3 | N^4 | sqrt(n) | sqrt[4](N) | - |---+-----+-----+-----+---------+------------| - | / | < | | > | < | > | - | 1 | 1 | 1 | 1 | 1 | 1 | - | 2 | 4 | 8 | 16 | 1.4142 | 1.1892 | - | 3 | 9 | 27 | 81 | 1.7321 | 1.3161 | - |---+-----+-----+-----+---------+------------| + | N | N^2 | N^3 | N^4 | ~sqrt(n)~ | ~sqrt[4](N)~ | + |---+-----+-----+-----+-----------+--------------| + | / | < | | > | < | > | + | 1 | 1 | 1 | 1 | 1 | 1 | + | 2 | 4 | 8 | 16 | 1.4142 | 1.1892 | + | 3 | 9 | 27 | 81 | 1.7321 | 1.3161 | + |---+-----+-----+-----+-----------+--------------| #+TBLFM: $2=$1^2::$3=$1^3::$4=$1^4::$5=sqrt($1)::$6=sqrt(sqrt(($1))) It is also sufficient to just insert the column group starters after @@ -2154,7 +2157,7 @@ by arrow keys * Advanced features:: Field and column names, parameters and automatic recalc  -File: org, Node: References, Next: Formula syntax for Calc, Prev: The spreadsheet, Up: The spreadsheet +File: org, Node: References, Next: Formula syntax for Calc, Up: The spreadsheet 3.5.1 References ---------------- @@ -2225,7 +2228,7 @@ order to be interpreted correctly). Examples: $1..$3 first three fields in the current row $P..$Q range, using column names (see under Advanced) - $<<<..$>> start in third column, continue to the one but last + $<<<..$>> start in third column, continue to the last but one @2$1..@4$3 6 fields between these two fields (same as `A2..C4') @-1$-2..@-1 3 fields in the row above, starting from 2 columns on the left @I..II between first and second hline, short for `@I..@II' @@ -2239,18 +2242,26 @@ Calc::. Field coordinates in formulas ............................. -For Calc formulas and Lisp formulas `@#' and `$#' can be used to get -the row or column number of the field where the formula result goes. +One of the very first actions during evaluation of Calc formulas and +Lisp formulas is to substitute `@#' and `$#' in the formula with the +row or column number of the field where the current result will go to. The traditional Lisp formula equivalents are `org-table-current-dline' and `org-table-current-column'. Examples: - if(@# % 2, $#, string("")) column number on odd lines only - $3 = remote(FOO, @@#$2) copy column 2 from table FOO into - column 3 of the current table +`if(@# % 2, $#, string(""))' + 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 + `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 + `FOO' into row 3 of the current table. -For the second example, table FOO must have at least as many rows as -the current table. Note that this is inefficient(3) for large number -of rows. +For the second/third example, the table named `FOO' must have at least +as many rows/columns as the current table. Note that this is +inefficient(3) for large number of rows/columns. Named references ................ @@ -2262,7 +2273,7 @@ line like #+CONSTANTS: c=299792458. pi=3.14 eps=2.4e-6 -Also properties (*note Properties and Columns::) can be used as +Also properties (*note Properties and columns::) can be used as constants in table formulas: for a property `:Xyz:' use the name `$PROP_Xyz', and the property will be searched in the current outline entry and in the hierarchy above it. If you have the `constants.el' @@ -2289,6 +2300,12 @@ first table in that entry. REF is an absolute field or range reference as described above for example `@3$3' or `$somename', valid in the referenced table. + Indirection of NAME-OR-ID: When NAME-OR-ID has the format +`@ROW$COLUMN' it will be substituted with the name or ID found in this +field of the current table. For example `remote($1, @>$2)' => +`remote(year_2013, @>$1)'. The format `B3' is not supported because it +can not be distinguished from a plain table name or ID. + ---------- Footnotes ---------- (1) Org will understand references typed by the user as `B4', but it @@ -2301,8 +2318,8 @@ customize this behavior using the option in the last row of the table. However, this syntax is deprecated, it should not be used for new documents. Use `@>$' instead. - (3) The computation time scales as O(N^2) because table FOO is -parsed for each field to be copied. + (3) The computation time scales as O(N^2) because the table named +`FOO' is parsed for each field to be read. (4) `constants.el' can supply the values of constants in two different unit systems, `SI' and `cgs'. Which one is used depends on @@ -2442,7 +2459,7 @@ It is also possible to write a formula in Emacs Lisp. This can be useful for string manipulation and control structures, if Calc's functionality is not enough. - If a formula starts with a single-quote followed by an opening + If a formula starts with an apostrophe followed by an opening parenthesis, then it is evaluated as a Lisp form. The evaluation should return either a string or a number. Just as with `calc' formulas, you can specify modes and a printf format after a semicolon. @@ -2486,13 +2503,13 @@ formulas or Elisp formulas: | 3:02:20 | -2:07:00 | 0.92 | #+TBLFM: @2$3=$1+$2;T::@3$3=$1+$2;t - Input duration values must be of the form `[HH:MM[:SS]', where -seconds are optional. With the `T' flag, computed durations will be -displayed as `HH:MM:SS' (see the first formula above). With the `t' -flag, computed durations will be displayed according to the value of -the option `org-table-duration-custom-format', which defaults to -`'hours' and will display the result as a fraction of hours (see the -second formula in the example above). + Input duration values must be of the form `HH:MM[:SS]', where seconds +are optional. With the `T' flag, computed durations will be displayed +as `HH:MM:SS' (see the first formula above). With the `t' flag, +computed durations will be displayed according to the value of the +option `org-table-duration-custom-format', which defaults to `'hours' +and will display the result as a fraction of hours (see the second +formula in the example above). Negative duration values can be manipulated as well, and integers will be considered as seconds in addition and subtraction. @@ -2512,15 +2529,14 @@ current field will be replaced with the result. Formulas are stored in a special line starting with `#+TBLFM:' directly below the table. If you type the equation in the 4th field of the 3rd data line in the table, the formula will look like -`@3$4=$1+$2'. When inserting/deleting/swapping column and rows with +`@3$4=$1+$2'. When inserting/deleting/swapping columns and rows with the appropriate commands, absolute references (but not relative ones) in stored formulas are modified in order to still reference the same -field. To avoid this from happening, in particular in range -references, anchor ranges at the table borders (using `@<', `@>', `$<', -`$>'), or at hlines using the `@I' notation. Automatic adaptation of -field references does of course not happen if you edit the table -structure with normal editing commands--then you must fix the equations -yourself. +field. To avoid this, in particular in range references, anchor ranges +at the table borders (using `@<', `@>', `$<', `$>'), or at hlines using +the `@I' notation. Automatic adaptation of field references does of +course not happen if you edit the table structure with normal editing +commands--then you must fix the equations yourself. Instead of typing an equation into the field, you may also use the following command @@ -2579,7 +2595,7 @@ and the current field replaced with the result. If the field contains only `=', the previously stored formula for this column is used. For each column, Org will only remember the most recently used formula. In the `#+TBLFM:' line, column formulas will look like `$4=$1+$2'. The -left-hand side of a column formula can not be the name of column, it +left-hand side of a column formula cannot be the name of column, it must be the numeric column reference or `$>'. Instead of typing an equation into the field, you may also use the @@ -2916,11 +2932,18 @@ File: org, Node: Org-Plot, Prev: The spreadsheet, Up: Tables 3.6 Org-Plot ============ -Org-Plot can produce 2D and 3D graphs of information stored in org -tables using `Gnuplot' `http://www.gnuplot.info/' and `gnuplot-mode' +Org-Plot can produce graphs of information stored in org tables, either +graphically or in ASCII-art. + +Graphical plots using `Gnuplot' +------------------------------- + +Org-Plot produces 2D and 3D graphs using `Gnuplot' +`http://www.gnuplot.info/' and `gnuplot-mode' `http://xafs.org/BruceRavel/GnuplotMode'. To see this in action, ensure that you have both Gnuplot and Gnuplot mode installed on your system, -then call `org-plot/gnuplot' on the following table. +then call `C-c " g' or `M-x org-plot/gnuplot ' on the following +table. #+PLOT: title:"Citas" ind:1 deps:(3) type:2d with:histograms set:"yrange [0:]" | Sede | Max cites | H-index | @@ -2934,8 +2957,9 @@ then call `org-plot/gnuplot' on the following table. Notice that Org Plot is smart enough to apply the table's headers as labels. Further control over the labels, type, content, and appearance of plots can be exercised through the `#+PLOT:' lines preceding a -table. See below for a complete list of Org-plot options. For more -information and examples see the Org-plot tutorial at +table. See below for a complete list of Org-plot options. The +`#+PLOT:' lines are optional. For more information and examples see +the Org-plot tutorial at `http://orgmode.org/worg/org-tutorials/org-plot.html'. Plot Options @@ -2991,8 +3015,41 @@ Plot Options 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 +--------------- + +While the cursor is on a column, typing `C-c " a' or `M-x +orgtbl-ascii-plot ' create a new column containing an ASCII-art +bars plot. The plot is implemented through a regular column formula. +When the source column changes, the bar plot may be updated by +refreshing the table, for example typing `C-u C-c *'. + + | Sede | Max cites | | + |---------------+-----------+--------------| + | Chile | 257.72 | WWWWWWWWWWWW | + | Leeds | 165.77 | WWWWWWWh | + | Sao Paolo | 71.00 | WWW; | + | Stockholm | 134.19 | WWWWWW: | + | Morelia | 257.56 | WWWWWWWWWWWH | + | Rochefourchat | 0.00 | | + #+TBLFM: $3='(orgtbl-ascii-draw $2 0.0 257.72 12) + + The formula is an elisp call: + (orgtbl-ascii-draw COLUMN MIN MAX WIDTH) + +`COLUMN' + is a reference to the source column. + +`MIN MAX' + are the minimal and maximal values displayed. Sources values + outside this range are displayed as `too small' or `too large'. + +`WIDTH' + is the width in characters of the bar-plot. It defaults to `12'. + +  -File: org, Node: Hyperlinks, Next: TODO Items, Prev: Tables, Up: Top +File: org, Node: Hyperlinks, Next: TODO items, Prev: Tables, Up: Top 4 Hyperlinks ************ @@ -3012,7 +3069,7 @@ files, Usenet articles, emails, and much more. * Custom searches:: When the default search is not enough  -File: org, Node: Link format, Next: Internal links, Prev: Hyperlinks, Up: Hyperlinks +File: org, Node: Link format, Next: Internal links, Up: Hyperlinks 4.1 Link format =============== @@ -3062,7 +3119,7 @@ brackets, like `<>'. If no dedicated target exists, the link will then try to match the exact name of an element within the buffer. Naming is done with the -`#+NAME' keyword, which has to be put the line before the element it +`#+NAME' keyword, which has to be put in the line before the element it refers to, as in the following example #+NAME: My Target @@ -3110,7 +3167,7 @@ be offered as completions. mandatory in order to get proper numbering (*note Images and tables::).  -File: org, Node: Radio targets, Prev: Internal links, Up: Internal links +File: org, Node: Radio targets, Up: Internal links 4.2.1 Radio targets ------------------- @@ -3148,7 +3205,8 @@ the colon. The following list shows examples for each link type. file:sometextfile::NNN file, jump to line number file:projects.org another Org file file:projects.org::some words text search in Org file(1) - file:projects.org::*task title heading search in Org file + file:projects.org::*task title heading search in Org + file(2) 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 @@ -3163,7 +3221,7 @@ the colon. The following list shows examples for each link type. 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 + info:org#External links Info node or index link shell:ls *.org A shell command elisp:org-agenda Interactive Elisp command elisp:(find-file-other-frame "Elisp.org") Elisp form to evaluate @@ -3205,9 +3263,15 @@ the end of the link, enclose them in square brackets. (1) The actual behavior of the search will depend on the value of the option `org-link-search-must-match-exact-headline'. If its value is `nil', then a fuzzy text search will be done. If it is t, then only -the exact headline will be matched. If the value is `'query-to-create', -then an exact headline will be searched; if it is not found, then the -user will be queried to create it. +the exact headline will be matched, ignoring spaces and cookies. If +the value is `query-to-create', then an exact headline will be +searched; if it is not found, then the user will be queried to create +it. + + (2) Headline searches always match the exact headline, ignoring +spaces and cookies. If the headline is not found and the value of the +option `org-link-search-must-match-exact-headline' is `query-to-create', +then the user will be queried to create it.  File: org, Node: Handling links, Next: Using links outside Org, Prev: External links, Up: Hyperlinks @@ -3384,7 +3448,7 @@ in the headline. `org-customize' by enabling `org-id' in `org-modules', or by adding `(require 'org-id)' in your `.emacs'. - (3) Note that you don't have to use this command to insert a link. + (3) Note that you don't 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 @@ -3448,7 +3512,7 @@ tag (see the example above, where we need to encode the URL parameter.) Using `%(my-function)' will pass the tag to a custom function, and replace it by the resulting string. - If the replacement text don't contain any specifier, it will simply + If the replacement text doesn't contain any specifier, it will simply be appended to the string in order to create the link. Instead of a string, you may also specify a function that will be @@ -3551,7 +3615,7 @@ BibTeX database files, and you can use the corresponding code as an implementation example. See the file `org-bibtex.el'.  -File: org, Node: TODO Items, Next: Tags, Prev: Hyperlinks, Up: Top +File: org, Node: TODO items, Next: Tags, Prev: Hyperlinks, Up: Top 5 TODO items ************ @@ -3582,7 +3646,7 @@ methods to give you an overview of all the things that you have to do. of TODO items, but this is not required.  -File: org, Node: TODO basics, Next: TODO extensions, Prev: TODO Items, Up: TODO Items +File: org, Node: TODO basics, Next: TODO extensions, Up: TODO items 5.1 Basic TODO functionality ============================ @@ -3635,7 +3699,7 @@ The most important commands to work with TODO entries are: `C-c a t (`org-todo-list')' Show the global TODO list. Collects the TODO items (with not-DONE - states) from all agenda files (*note Agenda Views::) into a single + states) from all agenda files (*note Agenda views::) into a single buffer. The new buffer will be in `agenda-mode', which provides commands to examine and manipulate the TODO entries from the new buffer (*note Agenda commands::). *Note Global TODO list::, for @@ -3648,7 +3712,7 @@ Changing a TODO state can also trigger tag changes. See the docstring of the option `org-todo-state-tags-triggers' for details.  -File: org, Node: TODO extensions, Next: Progress logging, Prev: TODO basics, Up: TODO Items +File: org, Node: TODO extensions, Next: Progress logging, Prev: TODO basics, Up: TODO items 5.2 Extended use of TODO keywords ================================= @@ -3672,7 +3736,7 @@ TODO items in particular (*note Tags::). * TODO dependencies:: When one task needs to wait for others  -File: org, Node: Workflow states, Next: TODO types, Prev: TODO extensions, Up: TODO extensions +File: org, Node: Workflow states, Next: TODO types, Up: TODO extensions 5.2.1 TODO keywords as workflow states -------------------------------------- @@ -3773,11 +3837,10 @@ using completion, you may also apply the following commands: `S-' `S-' - `S-<>' and `S-<>' and walk through _all_ keywords - from all sets, so for example `S-<>' would switch from - `DONE' to `REPORT' in the example above. See also *note - Conflicts::, for a discussion of the interaction with - `shift-selection-mode'. + `S-' and `S-' and walk through _all_ keywords from + all sets, so for example `S-' would switch from `DONE' to + `REPORT' in the example above. See also *note Conflicts::, for a + discussion of the interaction with `shift-selection-mode'.  File: org, Node: Fast access to TODO states, Next: Per-file keywords, Prev: Multiple sets in one file, Up: TODO extensions @@ -3817,11 +3880,10 @@ File: org, Node: Per-file keywords, Next: Faces for TODO keywords, Prev: Fast ---------------------------------------------- It can be very useful to use different aspects of the TODO mechanism in -different files. For file-local settings, you need to add special lines -to the file which set the keywords and interpretation for that file -only. For example, to set one of the two examples discussed above, you -need one of the following lines, starting in column zero anywhere in the -file: +different files. For file-local settings, you need to add special +lines to the file which set the keywords and interpretation for that +file only. For example, to set one of the two examples discussed +above, you need one of the following lines anywhere in the file: #+TODO: TODO FEEDBACK VERIFY | DONE CANCELED (you may also write `#+SEQ_TODO' to be explicit about the @@ -3901,6 +3963,14 @@ blocked until all earlier siblings are marked DONE. Here is an example: ** TODO b, needs to wait for (a) ** TODO c, needs to wait for (a) and (b) + You can ensure an entry is never blocked by using the `NOBLOCKING' +property: + + * This entry is never blocked + :PROPERTIES: + :NOBLOCKING: t + :END: + `C-c C-x o (`org-toggle-ordered-property')' Toggle the `ORDERED' property of the current entry. A property is used for this behavior because this should be local to the current @@ -3914,7 +3984,7 @@ blocked until all earlier siblings are marked DONE. Here is an example: If you set the option `org-agenda-dim-blocked-tasks', TODO entries that cannot be closed because of such dependencies will be shown in a dimmed font or even made invisible in agenda views (*note Agenda -Views::). +views::). You can also block changes of TODO states by looking at checkboxes (*note Checkboxes::). If you set the option @@ -3926,7 +3996,7 @@ dependencies between entries in different trees or files, check out the contributed module `org-depend.el'.  -File: org, Node: Progress logging, Next: Priorities, Prev: TODO extensions, Up: TODO Items +File: org, Node: Progress logging, Next: Priorities, Prev: TODO extensions, Up: TODO items 5.3 Progress logging ==================== @@ -3945,7 +4015,7 @@ work time::. * Tracking your habits:: How consistent have you been?  -File: org, Node: Closing items, Next: Tracking TODO state changes, Prev: Progress logging, Up: Progress logging +File: org, Node: Closing items, Next: Tracking TODO state changes, Up: Progress logging 5.3.1 Closing items ------------------- @@ -4094,6 +4164,10 @@ here's an actual habit with some history: ** TODO Shave SCHEDULED: <2009-10-17 Sat .+2d/4d> + :PROPERTIES: + :STYLE: habit + :LAST_REPEAT: [2009-10-19 Mon 00:36] + :END: - State "DONE" from "TODO" [2009-10-15 Thu] - State "DONE" from "TODO" [2009-10-12 Mon] - State "DONE" from "TODO" [2009-10-10 Sat] @@ -4104,10 +4178,6 @@ here's an actual habit with some history: - State "DONE" from "TODO" [2009-09-19 Sat] - State "DONE" from "TODO" [2009-09-16 Wed] - State "DONE" from "TODO" [2009-09-12 Sat] - :PROPERTIES: - :STYLE: habit - :LAST_REPEAT: [2009-10-19 Mon 00:36] - :END: What this habit says is: I want to shave at most every 2 days (given by the `SCHEDULED' date and repeat interval) and at least every 4 days. @@ -4163,7 +4233,7 @@ to bring them back. They are also subject to tag filtering, if you have habits which should only be done in certain contexts, for example.  -File: org, Node: Priorities, Next: Breaking down tasks, Prev: Progress logging, Up: TODO Items +File: org, Node: Priorities, Next: Breaking down tasks, Prev: Progress logging, Up: TODO items 5.4 Priorities ============== @@ -4213,7 +4283,7 @@ highest priority is earlier in the alphabet than the lowest priority): (1) See also the option `org-priority-start-cycle-with-default'.  -File: org, Node: Breaking down tasks, Next: Checkboxes, Prev: Priorities, Up: TODO Items +File: org, Node: Breaking down tasks, Next: Checkboxes, Prev: Priorities, Up: TODO items 5.5 Breaking tasks down into subtasks ===================================== @@ -4267,14 +4337,14 @@ hierarchy of) a large number of subtasks (*note Checkboxes::). `org-agenda-todo-list-sublevels'.  -File: org, Node: Checkboxes, Prev: Breaking down tasks, Up: TODO Items +File: org, Node: Checkboxes, Prev: Breaking down tasks, Up: TODO items 5.6 Checkboxes ============== Every item in a plain list(1) (*note Plain lists::) can be made into a checkbox by starting it with the string `[ ]'. This feature is similar -to TODO items (*note TODO Items::), but is more lightweight. +to TODO items (*note TODO items::), but is more lightweight. Checkboxes are not included in 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 `C-c C-c', or use @@ -4374,7 +4444,7 @@ those belonging to direct children. will add checkboxes to the rest of the list.  -File: org, Node: Tags, Next: Properties and Columns, Prev: TODO Items, Up: Top +File: org, Node: Tags, Next: Properties and columns, Prev: TODO items, Up: Top 6 Tags ****** @@ -4396,11 +4466,11 @@ You may specify special faces for specific tags using the option * 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 hierarchy:: Create a hierarchy of tags * Tag searches:: Searching for combinations of tags  -File: org, Node: Tag inheritance, Next: Setting tags, Prev: Tags, Up: Tags +File: org, Node: Tag inheritance, Next: Setting tags, Up: Tags 6.1 Tag inheritance =================== @@ -4448,7 +4518,7 @@ activates any changes in the line. tests including properties (*note Property searches::).  -File: org, Node: Setting tags, Next: Tag groups, Prev: Tag inheritance, Up: Tags +File: org, Node: Setting tags, Next: Tag hierarchy, Prev: Tag inheritance, Up: Tags 6.2 Setting tags ================ @@ -4607,45 +4677,98 @@ comes up only when you press an extra `C-c'. configured keys.  -File: org, Node: Tag groups, Next: Tag searches, Prev: Setting tags, Up: Tags - -6.3 Tag groups -============== - -In a set of mutually exclusive tags, the first tag can be defined as a -_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. +File: org, Node: Tag hierarchy, Next: Tag searches, Prev: Setting tags, Up: Tags - You can set group tags by inserting a colon between the group tag -and other tags--beware that all whitespaces are mandatory so that Org -can parse this line correctly: - - #+TAGS: { @read : @read_book @read_ebook } - - In this example, `@read' is a _group tag_ for a set of three tags: -`@read', `@read_book' and `@read_ebook'. - - You can also use the `:grouptags' keyword directly when setting -`org-tag-alist': - - (setq org-tag-alist '((:startgroup . nil) - ("@read" . nil) - (:grouptags . nil) - ("@read_book" . nil) - ("@read_ebook" . nil) - (:endgroup . nil))) +6.3 Tag hierarchy +================= - You cannot nest group tags or use a group tag as a tag in another -group. +Tags can be defined in hierarchies. 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. Defining multiple _group tags_ and nesting +them creates a tag hierarchy. + + One use-case is to create a taxonomy of terms (tags) that can be +used to classify nodes in a document or set of documents. + + When you search for a group tag, it will return matches for all +members in the group and its subgroup. In an agenda view, filtering by +a group tag will display or hide headlines tagged with at least one of +the members of the group or any of its subgroups. This makes tag +searches and filters even more flexible. + + You can set group tags by using brackets and inserting a colon +between the group tag and its related tags--beware that all whitespaces +are mandatory so that Org can parse this line correctly: + + #+TAGS: [ GTD : Control Persp ] + + In this example, `GTD' is the _group tag_ and it is related to two +other tags: `Control', `Persp'. Defining `Control' and `Persp' as +group tags creates an hierarchy of tags: + + #+TAGS: [ Control : Context Task ] + #+TAGS: [ Persp : Vision Goal AOF Project ] + + That can conceptually be seen as a hierarchy of tags: + + - GTD + - Persp + - Vision + - Goal + - AOF + - Project + - Control + - Context + - Task + + You can use the `:startgrouptag', `:grouptags' and `:endgrouptag' +keyword directly when setting `org-tag-alist' directly: + + (setq org-tag-alist '((:startgrouptag) + ("GTD") + (:grouptags) + ("Control") + ("Persp") + (:endgrouptag) + (:startgrouptag) + ("Control") + (:grouptags) + ("Context") + ("Task") + (:endgrouptag))) + + The tags in a group can be mutually exclusive if using the same +group syntax as is used for grouping mutually exclusive tags together; +using curly brackets. + + #+TAGS: { Context : @Home @Work @Call } + + When setting `org-tag-alist' you can use `:startgroup' & `:endgroup' +instead of `:startgrouptag' & `:endgrouptag' to make the tags mutually +exclusive. + + Furthermore; The members of a _group tag_ can also be regular +expression, creating the possibility of more dynamic and rule-based +tag-structure. The regular expressions in the group must be marked up +within { }. Example use, to expand on the example given above: + + #+TAGS: [ Vision : {V.+} ] + #+TAGS: [ Goal : {G.+} ] + #+TAGS: [ AOF : {AOF.+} ] + #+TAGS: [ Project : {P.+} ] + + Searching for the tag `Project' will now list all tags also including +regular expression matches for `P@.+'. Similar for tag-searches on +`Vision', `Goal' and `AOF'. This can be good for example if tags for a +certain project is tagged with a common project-identifier, i.e. +`P@2014_OrgTags'. If you want to ignore group tags temporarily, toggle group tags support with `org-toggle-tags-groups', bound to `C-c C-x q'. If you want to disable tag groups completely, set `org-group-tags' to `nil'.  -File: org, Node: Tag searches, Prev: Tag groups, Up: Tags +File: org, Node: Tag searches, Prev: Tag hierarchy, Up: Tags 6.4 Tag searches ================ @@ -4677,7 +4800,7 @@ keywords, entry levels and properties. For a complete description with many examples, see *note Matching tags and properties::.  -File: org, Node: Properties and Columns, Next: Dates and Times, Prev: Tags, Up: Top +File: org, Node: Properties and columns, Next: Dates and times, Prev: Tags, Up: Top 7 Properties and columns ************************ @@ -4709,16 +4832,18 @@ as the album, artist, date of release, number of tracks, and so on. * Property API:: Properties for Lisp programmers  -File: org, Node: Property syntax, Next: Special properties, Prev: Properties and Columns, Up: Properties and Columns +File: org, Node: Property syntax, Next: Special properties, Up: Properties and columns 7.1 Property syntax =================== Properties are key-value pairs. When they are associated with a single entry or with a tree they need to be inserted into a special drawer -(*note Drawers::) with the name `PROPERTIES'. Each property is -specified on a single line, with the key (surrounded by colons) first, -and the value after it. Here is an example: +(*note Drawers::) with the name `PROPERTIES', which has to be located +right below a headline, and its planning line (*note Deadlines and +scheduling::) when applicable. Each property is specified on a single +line, with the key (surrounded by colons) first, and the value after +it. Keys are case-insensitives. Here is an example: * CD collection ** Classic @@ -4733,7 +4858,7 @@ and the value after it. Here is an example: Depending on the value of `org-use-property-inheritance', a property set this way will either be associated with a single entry, or the -sub-tree defined by the entry, see *note Property inheritance::. +subtree defined by the entry, see *note Property inheritance::. You may define the allowed values for a particular property `:Xyz:' by setting a property `:Xyz_ALL:'. This special property is @@ -4754,7 +4879,7 @@ file, use a line like #+PROPERTY: NDisks_ALL 1 2 3 4 Contrary to properties set from a special drawer, you have to -refresh the buffer with `C-c C-c' to activate this changes. +refresh the buffer with `C-c C-c' to activate this change. If you want to add to the value of an existing property, append a `+' to the property name. The following results in the property `var' @@ -4823,7 +4948,7 @@ The following commands help to work with properties: the nearest column format definition.  -File: org, Node: Special properties, Next: Property searches, Prev: Property syntax, Up: Properties and Columns +File: org, Node: Special properties, Next: Property searches, Prev: Property syntax, Up: Properties and columns 7.2 Special properties ====================== @@ -4832,32 +4957,29 @@ Special properties provide an alternative access method to Org mode features, like the TODO state or the priority of an entry, discussed in the previous chapters. This interface exists so that you can include these states in a column view (*note Column view::), or to use them in -queries. The following property names are special and (except for -`:CATEGORY:') should not be used as keys in the properties drawer: +queries. The following property names are special and should not be +used as keys in the properties drawer: - ID A globally unique ID used for synchronization during - iCalendar or MobileOrg export. - TODO The TODO keyword of the entry. - TAGS The tags defined directly in the headline. ALLTAGS All tags, including inherited ones. - CATEGORY The category of an entry. - PRIORITY The priority of the entry, a string with a single letter. - DEADLINE The deadline time string, without the angular brackets. - SCHEDULED The scheduling timestamp, without the angular brackets. - CLOSED When was this entry closed? - TIMESTAMP The first keyword-less timestamp in the entry. - TIMESTAMP_IA The first inactive timestamp in the entry. + BLOCKED "t" if task is currently blocked by children or siblings. CLOCKSUM The sum of CLOCK intervals in the subtree. `org-clock-sum' must be run first to compute the values in the current buffer. CLOCKSUM_T The sum of CLOCK intervals in the subtree for today. `org-clock-sum-today' must be run first to compute the values in the current buffer. - BLOCKED "t" if task is currently blocked by children or siblings - ITEM The headline of the entry. + CLOSED When was this entry closed? + DEADLINE The deadline time string, without the angular brackets. FILE The filename the entry is located in. + ITEM The headline of the entry, with stars. + PRIORITY The priority of the entry, a string with a single letter. + SCHEDULED The scheduling timestamp, without the angular brackets. + TAGS The tags defined directly in the headline. + TIMESTAMP The first keyword-less timestamp in the entry. + TIMESTAMP_IA The first inactive timestamp in the entry. + TODO The TODO keyword of the entry.  -File: org, Node: Property searches, Next: Property inheritance, Prev: Special properties, Up: Properties and Columns +File: org, Node: Property searches, Next: Property inheritance, Prev: Special properties, Up: Properties and columns 7.3 Property searches ===================== @@ -4894,7 +5016,7 @@ single property: property values.  -File: org, Node: Property inheritance, Next: Column view, Prev: Property searches, Up: Properties and Columns +File: org, Node: Property inheritance, Next: Column view, Prev: Property searches, Up: Properties and columns 7.4 Property Inheritance ======================== @@ -4935,7 +5057,7 @@ least for the special applications for which they are used: subtree (*note Tracking TODO state changes::).  -File: org, Node: Column view, Next: Property API, Prev: Property inheritance, Up: Properties and Columns +File: org, Node: Column view, Next: Property API, Prev: Property inheritance, Up: Properties and columns 7.5 Column view =============== @@ -4951,7 +5073,7 @@ For example, you get a compact table by switching to CONTENTS view can still open, read, and edit the entry below each headline. Or, you can switch to column view after executing a sparse tree command and in this way get a table only for the selected items. Column view also -works in agenda buffers (*note Agenda Views::) where queries have +works in agenda buffers (*note Agenda views::) where queries have collected selected items, possibly from a number of files. * Menu: @@ -4961,7 +5083,7 @@ collected selected items, possibly from a number of files. * Capturing column view:: A dynamic block for column view  -File: org, Node: Defining columns, Next: Using column view, Prev: Column view, Up: Column view +File: org, Node: Defining columns, Next: Using column view, Up: Column view 7.5.1 Defining columns ---------------------- @@ -4975,7 +5097,7 @@ done by defining a column format line. * Column attributes:: Appearance and content of a column  -File: org, Node: Scope of column definitions, Next: Column attributes, Prev: Defining columns, Up: Defining columns +File: org, Node: Scope of column definitions, Next: Column attributes, Up: Defining columns 7.5.1.1 Scope of column definitions ................................... @@ -5039,19 +5161,19 @@ optional. The individual parts have the following meaning: {@min} Minimum age (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. + {est+} Add `low-high' estimates. Be aware that you can only have one summary type for any property you include. Subsequent columns referencing the same property will all display the same summary information. The `est+' summary type requires further explanation. It is used for -combining estimates, expressed as low-high ranges. For example, instead -of estimating a particular task will take 5 days, you might estimate it -as 5-6 days if you're fairly confident you know how much work is -required, or 1-10 days if you don't really know what needs to be done. -Both ranges average at 5.5 days, but the first represents a more -predictable delivery. +combining estimates, expressed as `low-high' ranges or plain numbers. +For example, instead of estimating a particular task will take 5 days, +you might estimate it as 5-6 days if you're fairly confident you know +how much work is required, or 1-10 days if you don't really know what +needs to be done. Both ranges average at 5.5 days, but the first +represents a more predictable delivery. When combining a set of such estimates, simply adding the lows and highs produces an unrealistically wide result. Instead, `est+' adds the @@ -5158,9 +5280,9 @@ Editing values `a (`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. + found in the hierarchy, the modified value 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 the table structure ............................. @@ -5255,7 +5377,7 @@ or a dynamic block. with the main distribution of Org (visit `http://orgmode.org').  -File: org, Node: Property API, Prev: Column view, Up: Properties and Columns +File: org, Node: Property API, Prev: Column view, Up: Properties and columns 7.6 The Property API ==================== @@ -5266,7 +5388,7 @@ features based on them. For more information see *note Using the property API::.  -File: org, Node: Dates and Times, Next: Capture - Refile - Archive, Prev: Properties and Columns, Up: Top +File: org, Node: Dates and times, Next: Capture - Refile - Archive, Prev: Properties and columns, Up: Top 8 Dates and times ***************** @@ -5274,7 +5396,7 @@ File: org, Node: Dates and Times, Next: Capture - Refile - Archive, Prev: Pro 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. This may be a little -confusing because timestamp is often used as indicating when something +confusing because timestamp is often used to indicate when something was created or last changed. However, in Org mode this term is used in a much wider sense. @@ -5285,11 +5407,10 @@ a much wider sense. * Deadlines and scheduling:: Planning your work * Clocking work time:: Tracking how long you spend on a task * Effort estimates:: Planning work effort in advance -* Relative timer:: Notes with a running timer -* Countdown timer:: Starting a countdown timer for a task +* Timers:: Notes with a running timer  -File: org, Node: Timestamps, Next: Creating timestamps, Prev: Dates and Times, Up: Dates and Times +File: org, Node: Timestamps, Next: Creating timestamps, Up: Dates and times 8.1 Timestamps, deadlines, and scheduling ========================================= @@ -5358,10 +5479,10 @@ add that day name, for reading convenience. use an alternative format, see *note Custom time format::. (3) When working with the standard diary sexp functions, you need to -be very careful with the order of the arguments. That order depend +be very careful with the order of the arguments. That order depends evilly on the variable `calendar-date-style' (or, for older Emacs versions, `european-calendar-style'). For example, to specify a date -December 12, 2005, the call might look like `(diary-date 12 1 2005)' or +December 1, 2005, the call might look like `(diary-date 12 1 2005)' or `(diary-date 1 12 2005)' or `(diary-date 2005 12 1)', depending on the settings. This has been the source of much confusion. Org mode users can resort to special versions of these functions like `org-date' or @@ -5370,7 +5491,7 @@ functions, but with stable ISO order of arguments (year, month, day) wherever applicable, independent of the value of `calendar-date-style'.  -File: org, Node: Creating timestamps, Next: Deadlines and scheduling, Prev: Timestamps, Up: Dates and Times +File: org, Node: Creating timestamps, Next: Deadlines and scheduling, Prev: Timestamps, Up: Dates and times 8.2 Creating timestamps ======================= @@ -5441,7 +5562,7 @@ format. * Custom time format:: Making dates look different  -File: org, Node: The date/time prompt, Next: Custom time format, Prev: Creating timestamps, Up: Creating timestamps +File: org, Node: The date/time prompt, Next: Custom time format, Up: Creating timestamps 8.2.1 The date/time prompt -------------------------- @@ -5475,7 +5596,7 @@ in bold. feb 15 => 2007-02-15 sep 12 9 => 2009-09-12 12:45 => 2006-06-13 12:45 - 22 sept 0:34 => 2006-09-22 0:34 + 22 sept 0:34 => 2006-09-22 00:34 w4 => ISO week for of the current year 2006 2012 w4 fri => Friday of ISO week 4 in 2012 2012-w04-5 => Same as above @@ -5522,13 +5643,14 @@ or by pressing , the date selected in the calendar will be combined with the information entered at the prompt. You can control the calendar fully from the minibuffer: - Choose date at cursor in calendar. - mouse-1 Select date by clicking on it. - S-/ One day forward/backward. - S-/ One week forward/backward. - M-S-/ One month forward/backward. - > / < Scroll calendar forward/backward by one month. - M-v / C-v Scroll calendar forward/backward by 3 months. + Choose date at cursor in calendar. + mouse-1 Select date by clicking on it. + S-/ One day forward/backward. + S-/ One week forward/backward. + M-S-/ One month forward/backward. + > / < Scroll calendar forward/backward by one month. + M-v / C-v Scroll calendar forward/backward by 3 months. + M-S-/ Scroll calendar forward/backward by one year. 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 @@ -5588,7 +5710,7 @@ consequences: the custom format is shorter, things do work as expected.  -File: org, Node: Deadlines and scheduling, Next: Clocking work time, Prev: Creating timestamps, Up: Dates and Times +File: org, Node: Deadlines and scheduling, Next: Clocking work time, Prev: Creating timestamps, Up: Dates and times 8.3 Deadlines and scheduling ============================ @@ -5610,9 +5732,9 @@ DEADLINE The editor in charge is [[bbdb:Ford Prefect]] You can specify a different lead time for warnings for a specific - deadlines using the following syntax. Here is an example with a + deadline 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 get scheduled and you set + warning is deactivated if the task gets scheduled and you set `org-agenda-skip-deadline-prewarning-if-scheduled' to `t'. SCHEDULED @@ -5666,7 +5788,7 @@ DONE. If you don't like this, set the variable `org-agenda-skip-scheduled-if-done'.  -File: org, Node: Inserting deadline/schedule, Next: Repeated tasks, Prev: Deadlines and scheduling, Up: Deadlines and scheduling +File: org, Node: Inserting deadline/schedule, Next: Repeated tasks, Up: Deadlines and scheduling 8.3.1 Inserting deadlines or schedules -------------------------------------- @@ -5690,12 +5812,6 @@ schedule an item: variable `org-log-reschedule'(3), a note will be taken when changing an existing scheduling time. -`C-c C-x C-k (`org-mark-entry-for-agenda-action')' - Mark the current entry for agenda action. After you have marked - the entry like this, you can open the agenda or the calendar to - find an appropriate date. With the cursor on the selected date, - press `k s' or `k d' to schedule the marked item. - `C-c / d (`org-check-deadlines')' Create a sparse tree with all deadlines that are either past-due, or which will become due within `org-deadline-warning-days'. With @@ -5760,6 +5876,9 @@ to DONE would actually switch the date like this: ** TODO Pay the rent DEADLINE: <2005-11-01 Tue +1m> + To mark a task with a repeater as `DONE', use `C-- 1 C-c C-t' (i.e., +`org-todo' with a numeric prefix argument of -1.) + A timestamp(2) will be added under the deadline, to keep a record that you actually acted on the previous instance of this deadline. @@ -5813,7 +5932,7 @@ first state of the TODO state sequence. With `lognoterepeat', you will also be prompted for a note.  -File: org, Node: Clocking work time, Next: Effort estimates, Prev: Deadlines and scheduling, Up: Dates and Times +File: org, Node: Clocking work time, Next: Effort estimates, Prev: Deadlines and scheduling, Up: Dates and times 8.4 Clocking work time ====================== @@ -5823,7 +5942,7 @@ 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(1) of a project. -And it remembers a history or tasks recently clocked, to that you can +And it remembers a history or tasks recently clocked, so that you can jump quickly between a number of tasks absorbing your time. To save the clock history across Emacs sessions, use @@ -5848,7 +5967,7 @@ prompted about what to do with it. this task while outside Emacs, use `(setq org-clock-persist t)'.  -File: org, Node: Clocking commands, Next: The clock table, Prev: Clocking work time, Up: Clocking work time +File: org, Node: Clocking commands, Next: The clock table, Up: Clocking work time 8.4.1 Clocking commands ----------------------- @@ -5877,7 +5996,7 @@ File: org, Node: Clocking commands, Next: The clock table, Prev: Clocking wor be shown. More control over what time is shown can be exercised 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 + show all time clocked on this task today (see also the variable `org-extend-today-until'), `all' to include all time, or `auto' which is the default(3). Clicking with `mouse-1' onto the mode line entry will pop up a @@ -5886,7 +6005,7 @@ File: org, Node: Clocking commands, Next: The clock table, Prev: Clocking wor `C-c C-x C-o (`org-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 + computes the resulting time and 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(4). @@ -5994,7 +6113,7 @@ into the buffer with the `C-c C-x C-r' command: #+BEGIN: clocktable :maxlevel 2 :emphasize nil :scope file #+END: clocktable - The `BEGIN' line and specify a number of options to define the scope, + The `BEGIN' line specifies a number of options to define the scope, structure, and formatting of the report. Defaults for all these options can be configured in the variable `org-clocktable-defaults'. @@ -6013,7 +6132,7 @@ selected: 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 - absolute, or relative to the current time and may be any of + 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 @@ -6024,6 +6143,7 @@ selected: thisweek, lastweek, thisweek-N a relative week thismonth, lastmonth, thismonth-N a relative month thisyear, lastyear, thisyear-N a relative year + untilnow Use `S-/' keys to shift the time interval. :tstart A time string specifying when to start considering times. Relative times like `"<-2w>"' can also be used. See @@ -6042,7 +6162,7 @@ selected: *note Matching tags and properties:: for the match syntax. Then there are options which determine the formatting of the table. -There options are interpreted by the function +These options are interpreted by the function `org-clocktable-write-default', but you can specify your own function using the `:formatter' parameter. :emphasize When `t', emphasize level one and level two items. @@ -6055,6 +6175,8 @@ using the `:formatter' parameter. :tcolumns Number of columns to be used for times. If this is smaller than `:maxlevel', lower levels will be lumped into one column. :level Should a level number column be included? + :sort A cons cell like 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' :timestamp A timestamp for the entry, when available. Look for SCHEDULED, @@ -6193,7 +6315,7 @@ you are running Debian, to get the same general treatment of idleness. On other systems, idle time refers to Emacs idle time only.  -File: org, Node: Effort estimates, Next: Relative timer, Prev: Clocking work time, Up: Dates and Times +File: org, Node: Effort estimates, Next: Timers, Prev: Clocking work time, Up: Dates and times 8.5 Effort estimates ==================== @@ -6253,64 +6375,61 @@ slot. list (*note Agenda column view::).  -File: org, Node: Relative timer, Next: Countdown timer, Prev: Effort estimates, Up: Dates and Times +File: org, Node: Timers, Prev: Effort estimates, Up: Dates and times -8.6 Taking notes with a relative timer -====================================== +8.6 Taking notes with a timer +============================= + +Org provides provides two types of timers. There is a relative timer +that counts up, which can be useful when taking notes during, for +example, a meeting or a video viewing. There is also a countdown timer. -When taking notes during, for example, a meeting or a video viewing, it -can be useful to have access to times relative to a starting time. Org -provides such a relative timer and make it easy to create timed notes. + The relative and countdown are started with separate commands. + +`C-c C-x 0 (`org-timer-start')' + Start or reset the relative timer. By default, the timer is set + to 0. When called with a `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 `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. + +`C-c C-x ; (`org-timer-set-timer')' + Start a countdown timer. The user is prompted for a duration. + `org-timer-default-timer' sets the default countdown value. + Giving a prefix numeric argument overrides this default value. + This command is available as `;' in agenda buffers. + + Once started, relative and countdown timers are controlled with the +same commands. `C-c C-x . (`org-timer')' - Insert a relative time into the buffer. The first time you use - this, the timer will be started. When called with a prefix - argument, the timer is restarted. + Insert the value of the current relative or countdown timer into + the buffer. If no timer is running, the relative timer will be + started. When called with a prefix argument, the relative timer + is restarted. `C-c C-x - (`org-timer-item')' - Insert a description list item with the current relative time. - With a prefix argument, first reset the timer to 0. + Insert a description list item with the value of the current + relative or countdown timer. With a prefix argument, first reset + the relative timer to 0. `M- (`org-insert-heading')' Once the timer list is started, you can also use `M-' to insert new timer items. -`C-c C-x ,' - Pause the timer, or continue it if it is already paused - (`org-timer-pause-or-continue'). +`C-c C-x \ (`org-timer-pause-or-continue')' + Pause the timer, or continue it if it is already paused. -`C-u C-c C-x ,' +`C-c C-x _ (`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. - -`C-c C-x 0 (`org-timer-start')' - Reset the timer without inserting anything into the buffer. By - default, the timer is reset to 0. When called with a `C-u' - prefix, reset the timer to specific starting offset. The user is - prompted for the offset, with a default taken from a timer string - at point, if any, So this can be used to restart taking notes - after a break in the process. When called with a double prefix - argument `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. - - -File: org, Node: Countdown timer, Prev: Relative timer, Up: Dates and Times - -8.7 Countdown timer -=================== - -Calling `org-timer-set-timer' from an Org mode buffer runs a countdown -timer. Use `;' from agenda buffers, everywhere else. - - `org-timer-set-timer' prompts the user for a duration and displays a -countdown timer in the modeline. `org-timer-default-timer' sets the -default countdown value. Giving a prefix numeric argument overrides -this default value. + the mode line.  -File: org, Node: Capture - Refile - Archive, Next: Agenda Views, Prev: Dates and Times, Up: Top +File: org, Node: Capture - Refile - Archive, Next: Agenda views, Prev: Dates and times, Up: Top 9 Capture - Refile - Archive **************************** @@ -6327,13 +6446,13 @@ fast. * Capture:: Capturing new stuff * Attachments:: Add files to tasks -* RSS Feeds:: Getting input from RSS feeds +* RSS feeds:: Getting input from RSS feeds * Protocols:: External (e.g., Browser) access to Emacs and Org * Refile and copy:: Moving/copying a tree from one place to another * Archiving:: What to do with finished projects  -File: org, Node: Capture, Next: Attachments, Prev: Capture - Refile - Archive, Up: Capture - Refile - Archive +File: org, Node: Capture, Next: Attachments, Up: Capture - Refile - Archive 9.1 Capture =========== @@ -6359,7 +6478,7 @@ org-capture-templates', check the result, and save the customization. * Capture templates:: Define the outline of different note types  -File: org, Node: Setting up capture, Next: Using capture, Prev: Capture, Up: Capture +File: org, Node: Setting up capture, Next: Using capture, Up: Capture 9.1.1 Setting up capture ------------------------ @@ -6482,7 +6601,7 @@ key binding like this: * Templates in contexts:: Only show a template in a specific context  -File: org, Node: Template elements, Next: Template expansion, Prev: Capture templates, Up: Capture templates +File: org, Node: Template elements, Next: Template expansion, Up: Capture templates 9.1.3.1 Template elements ......................... @@ -6536,7 +6655,9 @@ TARGET 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, function, or Emacs Lisp form. + variable, function, or Emacs Lisp form. When an absolute path is + not specified for a target, it is taken as relative to + `org-directory'. Valid values are: @@ -6618,9 +6739,10 @@ PROPERTIES `: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. + should be inserted. It can be a string, a variable holding a + string or a function returning a string. The string should + look like `"II-3"' meaning that the new line should become + the third line before the second horizontal separator line. `:kill-buffer' If the target file was not yet visited when capture was @@ -6737,7 +6859,7 @@ template. In that case, add this command key like this: See the docstring of the variable for more information.  -File: org, Node: Attachments, Next: RSS Feeds, Prev: Capture, Up: Capture - Refile - Archive +File: org, Node: Attachments, Next: RSS feeds, Prev: Capture, Up: Capture - Refile - Archive 9.2 Attachments =============== @@ -6822,7 +6944,7 @@ you may want to configure `org-attach-directory' to contain an absolute path.  -File: org, Node: RSS Feeds, Next: Protocols, Prev: Attachments, Up: Capture - Refile - Archive +File: org, Node: RSS feeds, Next: Protocols, Prev: Attachments, Up: Capture - Refile - Archive 9.3 RSS feeds ============= @@ -6856,16 +6978,13 @@ following command is used: Under the same headline, Org will create a drawer `FEEDSTATUS' in which it will store information about the status of items in the feed, -to avoid adding the same item several times. You should add -`FEEDSTATUS' to the list of drawers in that file: - - #+DRAWERS: LOGBOOK PROPERTIES FEEDSTATUS +to avoid 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'.  -File: org, Node: Protocols, Next: Refile and copy, Prev: RSS Feeds, Up: Capture - Refile - Archive +File: org, Node: Protocols, Next: Refile and copy, Prev: RSS feeds, Up: Capture - Refile - Archive 9.4 Protocols for external access ================================= @@ -6960,7 +7079,7 @@ global searches like the construction of agenda views fast. * Internal archiving:: Switch off a tree but keep it in the file  -File: org, Node: Moving subtrees, Next: Internal archiving, Prev: Archiving, Up: Archiving +File: org, Node: Moving subtrees, Next: Internal archiving, Up: Archiving 9.6.1 Moving a tree to the archive file --------------------------------------- @@ -6977,7 +7096,12 @@ file, the archive file. moved to the archive. To do this, each subtree is checked for open TODO entries. If none are found, the command offers to move it to the archive location. If the cursor is _not_ on a headline - when this command is invoked, the level 1 trees will be checked. + when this command is invoked, the level 1 trees will be checked. + +`C-u C-u C-c C-x C-s' + As above, but check subtree for timestamps instead of TODO + entries. The command will offer to archive the subtree if it + _does_ contain a timestamp, and that timestamp is in the past. The default archive location is a file in the same directory as the current file, with the name derived by appending `_archive' to the @@ -6987,13 +7111,13 @@ 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(1): +example: #+ARCHIVE: %s_done:: 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 (*note Properties and Columns::). +location as the value (*note Properties and columns::). When a subtree is moved, it receives a number of special properties that record context information like the file from where the entry @@ -7001,16 +7125,6 @@ came, its outline path the archiving time etc. Configure the variable `org-archive-save-context-info' to adjust the amount of information added. - ---------- Footnotes ---------- - - (1) For backward compatibility, the following also works: If there -are several such lines in a file, each specifies the archive location -for the text below it. The first such line also applies to any text -before its definition. However, using this method is _strongly_ -deprecated as it is incompatible with the outline structure of the -document. The correct method for setting multiple archive locations in -a buffer is using properties. -  File: org, Node: Internal archiving, Prev: Moving subtrees, Up: Archiving @@ -7032,7 +7146,7 @@ at its location in the outline tree, but behaves in the following way: archived subtrees are not exposed, unless you configure the option `org-sparse-tree-open-archived-trees'. - - During agenda view construction (*note Agenda Views::), the + - During agenda view construction (*note Agenda views::), the content of archived trees is ignored unless you configure the option `org-agenda-skip-archived-trees', in which case these trees will always be included. In the agenda you can press `v a' to get @@ -7070,7 +7184,7 @@ at its location in the outline tree, but behaves in the following way: tags and approximate position in the outline.  -File: org, Node: Agenda Views, Next: Markup, Prev: Capture - Refile - Archive, Up: Top +File: org, Node: Agenda views, Next: Markup, Prev: Capture - Refile - Archive, Up: Top 10 Agenda views *************** @@ -7121,11 +7235,11 @@ the window configuration is restored when the agenda exits: * Presentation and sorting:: How agenda items are prepared for display * Agenda commands:: Remote editing of Org trees * Custom agenda views:: Defining special searches and views -* Exporting Agenda Views:: Writing a view to a file +* Exporting agenda views:: Writing a view to a file * Agenda column view:: Using column view for collected entries  -File: org, Node: Agenda files, Next: Agenda dispatcher, Prev: Agenda Views, Up: Agenda Views +File: org, Node: Agenda files, Next: Agenda dispatcher, Up: Agenda views 10.1 Agenda files ================= @@ -7201,7 +7315,7 @@ command will actually limit the command to the current file, and ignore `org-agenda-files' until the next dispatcher command.  -File: org, Node: Agenda dispatcher, Next: Built-in agenda views, Prev: Agenda files, Up: Agenda Views +File: org, Node: Agenda dispatcher, Next: Built-in agenda views, Prev: Agenda files, Up: Agenda views 10.2 The agenda dispatcher ========================== @@ -7255,13 +7369,14 @@ dispatcher offers the following default commands: `*' 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 `r' or `g'. You can toggle sticky agenda view any - time with `org-toggle-sticky-agenda'. + view, to make sure everything is always up to date. If you often + switch between agenda views and the build time bothers you, you + can turn on sticky agenda buffers or make this the default by + customizing the variable `org-agenda-sticky'. With sticky + agendas, the agenda dispatcher will not recreate agenda views from + scratch, it will only switch to the selected one, and you need to + update the agenda by hand with `r' or `g' when needed. You can + toggle sticky agenda view any time with `org-toggle-sticky-agenda'. You can also define custom commands that will be accessible through the dispatcher, just like the default commands. This includes the @@ -7278,7 +7393,7 @@ to the current buffer. to the current region/subtree.  -File: org, Node: Built-in agenda views, Next: Presentation and sorting, Prev: Agenda dispatcher, Up: Agenda Views +File: org, Node: Built-in agenda views, Next: Presentation and sorting, Prev: Agenda dispatcher, Up: Agenda views 10.3 The built-in agenda views ============================== @@ -7295,7 +7410,7 @@ In this section we describe the built-in views. * Stuck projects:: Find projects you need to review  -File: org, Node: Weekly/daily agenda, Next: Global TODO list, Prev: Built-in agenda views, Up: Built-in agenda views +File: org, Node: Weekly/daily agenda, Next: Global TODO list, Up: Built-in agenda views 10.3.1 The weekly/daily agenda ------------------------------ @@ -7357,10 +7472,16 @@ the left margin, no whitespace is allowed before them. For example, the following segment of an Org file will be processed and entries will be made in the agenda: - * Birthdays and similar stuff - #+CATEGORY: Holiday + * Holidays + :PROPERTIES: + :CATEGORY: Holiday + :END: %%(org-calendar-holiday) ; special function for holiday names - #+CATEGORY: Ann + + * Birthdays + :PROPERTIES: + :CATEGORY: Ann + :END: %%(org-anniversary 1956 5 14)(2) Arthur Dent is %d years old %%(org-anniversary 1869 10 2) Mahatma Gandhi would be %d years old @@ -7432,7 +7553,7 @@ collected into a single place. `C-c a t (`org-todo-list')' Show the global TODO list. This collects the TODO items from all - agenda files (*note Agenda Views::) into a single buffer. By + agenda files (*note 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 (*note @@ -7480,7 +7601,7 @@ File: org, Node: Matching tags and properties, Next: Timeline, Prev: Global T ----------------------------------- If headlines in the agenda files are marked with _tags_ (*note Tags::), -or have properties (*note Properties and Columns::), you can select +or have properties (*note Properties and columns::), 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 `C-c / m'. @@ -7538,22 +7659,22 @@ only tags. in curly braces. For example, `work+{^boss.*}' matches headlines that contain the tag `:work:' and any tag starting with `boss'. - Group tags (*note Tag groups::) are expanded as regular expressions. -E.g., if `:work:' is a group tag for the group `:work:lab:conf:', then -searching for `work' will search for `{\(?:work\|lab\|conf\)}' and -searching for `-work' will search for all headlines but those with one -of the tag in the group (i.e., `-{\(?:work\|lab\|conf\)}'). + Group tags (*note Tag hierarchy::) are expanded as regular +expressions. E.g., if `:work:' is a group tag for the group +`:work:lab:conf:', then searching for `work' will search for +`{\(?:work\|lab\|conf\)}' and searching for `-work' will search for all +headlines but those with one of the tags in the group (i.e., +`-{\(?:work\|lab\|conf\)}'). - You may also test for properties (*note Properties and Columns::) at + You may also test for properties (*note Properties and columns::) at the same time as matching tags. The properties may be real properties, or special properties that represent other metadata (*note Special properties::). For example, the "property" `TODO' represents the TODO keyword of the entry and the "property" `PRIORITY' represents the -PRIORITY keyword of the entry. The ITEM special property cannot -currently be used in tags/property searches(1). +PRIORITY keyword of the entry. - Except the *note Special properties::, one other "property" can also -be used. `LEVEL' represents the level of an entry. So a search + In addition to the *note Special properties::, one other "property" +can also be used. `LEVEL' represents the level of an entry. So a search `+LEVEL=3+boss-TODO="DONE"' lists all level three headlines that have the tag `boss' and are _not_ marked with the TODO keyword DONE. In buffers with `org-odd-levels-only' set, `LEVEL' does not count the @@ -7588,7 +7709,7 @@ written: assumed to be date/time specifications in the standard Org way, and the comparison will be done accordingly. Special values that will be recognized are `""' for now (including time), and - `""', and `""' for these days at 0:00 hours, + `""', and `""' for these days at 00:00 hours, i.e., without a time specification. Also strings like `"<+5d>"' or `"<-2m>"' with units `d', `w', `m', and `y' for day, week, month, and year, respectively, can be used. @@ -7604,11 +7725,6 @@ numerically smaller than 2, a `:With:' property that is matched by the regular expression `Sarah\|Denny', and that are scheduled on or after October 11, 2008. - Accessing TODO, LEVEL, and CATEGORY during a search is fast. -Accessing any other properties will slow down the search. However, -once you have paid the price by accessing one property, testing -additional properties is cheap again. - You can configure Org mode to use property inheritance during a search, but beware that this can slow down searches considerably. See *note Property inheritance::, for details. @@ -7637,11 +7753,6 @@ a M' or `/!' will not match TODO keywords in a DONE state. Examples: Select `:work:'-tagged TODO lines that are either `WAITING' or `NEXT'. - ---------- Footnotes ---------- - - (1) But *note skipping entries based on regexp: -x-agenda-skip-entry-regexp. -  File: org, Node: Timeline, Next: Search view, Prev: Matching tags and properties, Up: Built-in agenda views @@ -7736,7 +7847,7 @@ this entry will still be searched for stuck projects. (1) *Note Tag searches::.  -File: org, Node: Presentation and sorting, Next: Agenda commands, Prev: Built-in agenda views, Up: Agenda Views +File: org, Node: Presentation and sorting, Next: Agenda commands, Prev: Built-in agenda views, Up: Agenda views 10.4 Presentation and sorting ============================= @@ -7758,14 +7869,14 @@ associated with the item. * Filtering/limiting agenda items:: Dynamically narrow the agenda  -File: org, Node: Categories, Next: Time-of-day specifications, Prev: Presentation and sorting, Up: Presentation and sorting +File: org, Node: Categories, Next: Time-of-day specifications, Up: Presentation and sorting 10.4.1 Categories ----------------- -The category is a broad label assigned to each agenda item. By default, -the category is simply derived from the file name, but you can also -specify it with a special line in the buffer, like this(1): +The category is a broad label assigned to each agenda item. By +default, the category is simply derived from the file name, but you can +also specify it with a special line in the buffer, like this: #+CATEGORY: Thesis @@ -7779,16 +7890,6 @@ longer than 10 characters. You can set up icons for category by customizing the `org-agenda-category-icon-alist' variable. - ---------- Footnotes ---------- - - (1) For backward compatibility, the following also works: if there -are several such lines in a file, each specifies the category for the -text below it. The first category also applies to any text before the -first CATEGORY line. However, using this method is _strongly_ -deprecated as it is incompatible with the outline structure of the -document. The correct method for setting multiple categories in a -buffer is using a property. -  File: org, Node: Time-of-day specifications, Next: Sorting agenda items, Prev: Categories, Up: Presentation and sorting @@ -7873,9 +7974,9 @@ File: org, Node: Filtering/limiting agenda items, Prev: Sorting agenda items, 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: _fitlers_ and _limits_. Filters only act on 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. Filter are more often used interactively, while +entries is built. Filters are more often used interactively, while limits are mostly useful when defined as local variables within custom agenda commands. @@ -7901,23 +8002,6 @@ Filtering in the agenda additional tag. Instead of pressing `+' or `-' after `/', you can also immediately use the `\' command. - In order to filter for effort estimates, you should set up allowed - efforts globally, for example - (setq org-global-properties - '(("Effort_ALL". "0 0:10 0:30 1:00 2:00 3:00 4:00"))) - You can then filter for an effort by first typing an operator, one - of `<', `>', and `=', and then the one-digit index of an effort - estimate in your array of allowed values, where `0' means the 10th - value. The filter will then restrict to entries with effort - smaller-or-equal, equal, or larger-or-equal than the selected - value. If the digits 0-9 are not used as fast access keys to - tags, you can also simply press the index digit directly without - an operator. In this case, `<' will be assumed. For application - of the operator, entries without a defined effort will be treated - according to the value of `org-sort-agenda-noeffort-is-high'. To - filter for tasks without effort definition, press `?' as the - operator. - 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 @@ -7961,8 +8045,9 @@ Filtering in the agenda `< (`org-agenda-filter-by-category')' Filter the current agenda view with respect to the category of the item at point. Pressing `<' another time will remove this filter. - You can add a filter preset through the option - `org-agenda-category-filter-preset' (see below.) + When called with a prefix argument exclude the category of the + item at point from the agenda. You can add a filter preset + through the option `org-agenda-category-filter-preset' (see below.) `^ (`org-agenda-filter-by-top-headline')' Filter the current agenda view and only display the siblings and @@ -7977,6 +8062,20 @@ Filtering in the agenda add a filter preset through the option `org-agenda-category-filter-preset' (see below.) +`_ (`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 + (setq org-global-properties + '(("Effort_ALL". "0 0:10 0:30 1:00 2:00 3:00 4:00"))) + You can then filter for an effort by first typing an operator, one + of `<', `>', and `=', and then the one-digit index of an effort + estimate in your array of allowed values, where `0' means the 10th + value. The filter will then restrict 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 will be treated according to the value of + `org-sort-agenda-noeffort-is-high'. + `| (`org-agenda-filter-remove-all')' Remove all filters in the current agenda view. @@ -7984,24 +8083,24 @@ Setting limits for the agenda ............................. Here is a list of options that you can set, either globally, or locally -in your custom agenda views*note Custom agenda views::. +in your custom agenda views (*note Custom agenda views::). -ORG-AGENDA-MAX-ENTRIES +`org-agenda-max-entries' Limit the number of entries. -ORG-AGENDA-MAX-EFFORT +`org-agenda-max-effort' Limit the duration of accumulated efforts (as minutes). -ORG-AGENDA-MAX-TODOS +`org-agenda-max-todos' Limit the number of entries with TODO keywords. -ORG-AGENDA-MAX-TAGS +`org-agenda-max-tags' Limit the number of tagged entries. When set to a positive integer, each option will exclude entries from other categories: for example, `(setq org-agenda-max-effort 100)' will limit the agenda to 100 minutes of effort and exclude any entry -that as no effort property. If you want to include entries with no +that has no effort property. If you want to include entries with no effort property, use a negative value for `org-agenda-max-effort'. One useful setup is to use `org-agenda-max-entries' locally in a @@ -8016,7 +8115,8 @@ five entries with a `NEXT' TODO keyword. agenda will again the next five entries again, including the first entry that was excluded so far. - You can also dynamically set temporary limits(2): + You can also dynamically set temporary limits, which will be lost +when rebuilding the agenda: `~ (`org-agenda-limit-interactively')' This prompts for the type of limit to apply and its value. @@ -8030,10 +8130,8 @@ 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. - (2) Those temporary limits are lost when rebuilding the agenda. -  -File: org, Node: Agenda commands, Next: Custom agenda views, Prev: Presentation and sorting, Up: Agenda Views +File: org, Node: Agenda commands, Next: Custom agenda views, Prev: Presentation and sorting, Up: Agenda views 10.5 Commands in the agenda buffer ================================== @@ -8055,7 +8153,13 @@ Motion Next line (same as and `C-n'). `p (`org-agenda-previous-line')' - Previous line (same as and `C-p'). + Previous line (same as and `C-p'). + +`N (`org-agenda-next-item')' + Next item: same as next line, but only consider items. + +`P (`org-agenda-previous-item')' + Previous item: same as previous line, but only consider items. View/Go to Org file ................... @@ -8425,8 +8529,7 @@ Bulk remote editing selected entries prefix arg to `B' will be passed through to the `s' and `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 `p' at the - prompt. + set `org-agenda-persistent-marks' to `t' or hit `p' at the prompt. `*' Toggle persistent marks. @@ -8575,7 +8678,7 @@ does not modify the contributing `.org' files `org-agenda-include-diary' is set.  -File: org, Node: Custom agenda views, Next: Exporting Agenda Views, Prev: Agenda commands, Up: Agenda Views +File: org, Node: Custom agenda views, Next: Exporting agenda views, Prev: Agenda commands, Up: Agenda views 10.6 Custom agenda views ======================== @@ -8589,10 +8692,10 @@ dispatcher (*note Agenda dispatcher::), just like the default commands. * Storing searches:: Type once, use often * Block agenda:: All the stuff you need in a single buffer -* Setting Options:: Changing the rules +* Setting options:: Changing the rules  -File: org, Node: Storing searches, Next: Block agenda, Prev: Custom agenda views, Up: Custom agenda views +File: org, Node: Storing searches, Next: Block agenda, Up: Custom agenda views 10.6.1 Storing searches ----------------------- @@ -8682,7 +8785,7 @@ deadline string. See `org-agenda-entry-types' on how to set what planning information will be taken into account.  -File: org, Node: Block agenda, Next: Setting Options, Prev: Storing searches, Up: Custom agenda views +File: org, Node: Block agenda, Next: Setting options, Prev: Storing searches, Up: Custom agenda views 10.6.2 Block agenda ------------------- @@ -8712,7 +8815,7 @@ your agenda for the current week, all TODO items that carry the tag `C-c a o' provides a similar view for office tasks.  -File: org, Node: Setting Options, Prev: Block agenda, Up: Custom agenda views +File: org, Node: Setting options, Prev: Block agenda, Up: Custom agenda views 10.6.3 Setting options for custom commands ------------------------------------------ @@ -8729,8 +8832,7 @@ right spot in `org-agenda-custom-commands'. For example: ((org-agenda-sorting-strategy '(priority-down)) (org-agenda-prefix-format " Mixed: "))) ("U" tags-tree "+boss-urgent" - ((org-show-following-heading nil) - (org-show-hierarchy-above nil))) + ((org-show-context-detail 'minimal))) ("N" search "" ((org-agenda-files '("~org/notes.org")) (org-agenda-text-search-extra-files nil))))) @@ -8776,7 +8878,7 @@ yourself. To control whether an agenda command should be accessible from a specific context, you can customize `org-agenda-custom-commands-contexts'. Let's say for example that you -have an agenda commands `"o"' displaying a view that you only need when +have an agenda command `"o"' displaying a view that you only need when reading emails. Then you would configure this option like this: (setq org-agenda-custom-commands-contexts @@ -8791,9 +8893,9 @@ command key `"r"'. In that case, add this command key like this: See the docstring of the variable for more information.  -File: org, Node: Exporting Agenda Views, Next: Agenda column view, Prev: Custom agenda views, Up: Agenda Views +File: org, Node: Exporting agenda views, Next: Agenda column view, Prev: Custom agenda views, Up: Agenda views -10.7 Exporting Agenda Views +10.7 Exporting agenda views =========================== If you are away from your computer, it can be very useful to have a @@ -8912,7 +9014,7 @@ them in order to be able to specify file names. examples.  -File: org, Node: Agenda column view, Prev: Exporting Agenda Views, Up: Agenda Views +File: org, Node: Agenda column view, Prev: Exporting agenda views, Up: Agenda views 10.8 Using column view in the agenda ==================================== @@ -8970,16 +9072,16 @@ environment. This causes the following issues: planned total effort for it.  -File: org, Node: Markup, Next: Exporting, Prev: Agenda Views, Up: Top +File: org, Node: Markup, Next: Exporting, Prev: Agenda views, Up: Top 11 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 back-end. -Since export targets like HTML, LaTeX 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. +Since export targets like HTML and LaTeX 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: @@ -8993,7 +9095,7 @@ summarizes the markup rules used in an Org mode buffer. * Special blocks:: Containers targeted at export back-ends  -File: org, Node: Structural markup elements, Next: Images and tables, Prev: Markup, Up: Markup +File: org, Node: Structural markup elements, Next: Images and tables, Up: Markup 11.1 Structural markup elements =============================== @@ -9011,7 +9113,7 @@ File: org, Node: Structural markup elements, Next: Images and tables, Prev: M * Comment lines:: What will *not* be exported  -File: org, Node: Document title, Next: Headings and sections, Prev: Structural markup elements, Up: Structural markup elements +File: org, Node: Document title, Next: Headings and sections, Up: Structural markup elements Document title -------------- @@ -9020,9 +9122,6 @@ The title of the exported document is taken from the special line #+TITLE: This is the title of the document -If this line does not exist, the title will be the name of the file -associated to buffer, without extension, or the buffer name. - If you are exporting only a subtree, its heading will become the title of the document. If the subtree has a property `EXPORT_TITLE', that will take precedence. @@ -9034,7 +9133,7 @@ Headings and sections --------------------- The outline structure of the document as described in *note Document -Structure::, forms the basis for defining sections of the exported +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 @@ -9055,30 +9154,42 @@ the number of headline levels, but you can choose a smaller number, or turn off the table of contents entirely, by configuring the variable `org-export-with-toc', or on a per-file basis with a line like - #+OPTIONS: toc:2 (only to two levels in TOC) - #+OPTIONS: toc:nil (no default TOC at all) + #+OPTIONS: toc:2 only inlcude two levels in TOC + #+OPTIONS: toc:nil no default TOC at all If you would like to move the table of contents to a different location, you should turn off the default table using `org-export-with-toc' or `#+OPTIONS' and insert `#+TOC: headlines N' at the desired location(s). - #+OPTIONS: toc:nil (no default TOC) + #+OPTIONS: toc:nil no default TOC ... - #+TOC: headlines 2 (insert TOC here, with two headline levels) + #+TOC: headlines 2 insert TOC here, with two headline levels + + Moreover, if you append `local' parameter, the table contains only +entries for the children of the current section(1). In this case, any +depth parameter becomes relative to the current level. - Multiple `#+TOC: headline' lines are allowed. The same `TOC' -keyword can also generate a list of all tables (resp. all listings) -with a caption in the buffer. + * Section + #+TOC: headlines 1 local insert local TOC, with direct children only - #+TOC: listings (build a list of listings) - #+TOC: tables (build a list of tables) + The same `TOC' keyword can also generate a list of all tables (resp. +all listings) with a caption in the document. + + #+TOC: listings build a list of listings + #+TOC: tables build a list of tables The headline's title usually determines its corresponding entry in a table of contents. However, it is possible to specify an alternative title by setting `ALT_TITLE' property accordingly. It will then be used when building the table. + ---------- Footnotes ---------- + + (1) For LaTeX export, this feature requires the `titletoc' package. +Note that `titletoc' must be loaded _before_ `hyperref'. Thus, you may +have to customize `org-latex-default-packages-alist'. +  File: org, Node: Lists, Next: Paragraphs, Prev: Table of contents, Up: Structural markup elements @@ -9171,13 +9282,25 @@ Comment lines ------------- Lines starting with zero or more whitespace characters followed by one -`#' and a whitespace are treated as comments and will never be exported. -Also entire subtrees starting with the word `COMMENT' will never be -exported. Finally, regions surrounded by `#+BEGIN_COMMENT' ... -`#+END_COMMENT' will not be exported. +`#' 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. +In this case, the subtree is not exported and no code block within it +is executed either(1). The command below helps changing the comment +status of a headline. `C-c ;' - Toggle the COMMENT keyword at the beginning of an entry. + Toggle the `COMMENT' keyword at the beginning of an entry. + + ---------- Footnotes ---------- + + (1) For a less drastic behavior, consider using a select tag (*note +Export settings::) instead.  File: org, Node: Images and tables, Next: Literal examples, Prev: Structural markup elements, Up: Markup @@ -9248,7 +9371,7 @@ 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(1). This is done with the `src' block, where you also need to specify the name of the major mode that should be used to fontify the example(2), see *note -Easy Templates:: for shortcuts to easily insert code blocks. +Easy templates:: for shortcuts to easily insert code blocks. #+BEGIN_SRC emacs-lisp (defun org-xor (a b) @@ -9278,6 +9401,9 @@ will use the labels with no parentheses. Here is an example: In line [[(sc)]] we remember the current position. [[(jump)][Line (jump)]] jumps to point-min. + Finally, you can use `-i' to preserve the indentation of a specific +code block (*note Editing source code::). + If the syntax for the label format conflicts with the language syntax, use a `-l' switch to change the format, for example `#+BEGIN_SRC pascal -n -r -l "((%s))"'. See also the variable @@ -9287,8 +9413,8 @@ syntax, use a `-l' switch to change the format, for example (*note Text areas in HTML export::). Because the `#+BEGIN_...' and `#+END_...' patterns need to be added -so often, shortcuts are provided using the Easy Templates facility -(*note Easy Templates::). +so often, shortcuts are provided using the Easy templates facility +(*note Easy templates::). `C-c '' Edit the source code example at point in its native mode. This @@ -9313,11 +9439,15 @@ so often, shortcuts are provided using the Easy Templates facility (1) This works automatically for the HTML back-end (it requires version 1.34 of the `htmlize.el' package, which is distributed with Org). Fontified code chunks in LaTeX can be achieved using either the -listings or the minted (http://code.google.com/p/minted) package. -Refer to `org-latex-listings' documentation for details. +listings +(https://www.ctan.org/tex-archive/macros/latex/contrib/listings/?lang=en) +or the minted (https://github.com/gpoore/minted) package. If you use +minted or listing, you must load the packages manually, for example by +adding the desired package to `org-latex-packages-alist'. Refer to +`org-latex-listings' for details. (2) Code in `src' blocks may also be evaluated either interactively -or on export. See *note Working With Source Code:: for more +or on export. See *note Working with source code:: for more information on evaluating code blocks. (3) Adding `-k' to `-n -r' will keep the labels in the source code @@ -9343,12 +9473,20 @@ example, to include your `.emacs' file, you could use: #+INCLUDE: "~/.emacs" src emacs-lisp -The optional second and third parameter are the markup (i.e., `example' -or `src'), and, if the markup is `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. +The first parameter names the the file to include. The optional second +and third parameter specify the markup (i.e., `example' or `src'), and, +if the markup is `src', the language for formatting the contents. + + If markup is requested, the included content will be placed within an +appropriate block(1). No changes to the included content are made and +it is the responsibility of the user to ensure that the result is valid +Org syntax. For markup `example' and `src', which is requesting a +literal example, the content will be code-escaped before inclusion. - Contents of the included file will belong to the same structure + If no markup is requested, the text will be assumed to be in Org +mode format and will be processed normally. However, footnote labels +(*note Footnotes::) in the file will be made local to that file. +Contents of the included file will belong to the same structure (headline, item) containing the `INCLUDE' keyword. In particular, headlines within the file will become children of the current section. That behavior can be changed by providing an additional keyword @@ -9360,17 +9498,40 @@ current top-level headline, use #+INCLUDE: "~/my-book/chapter2.org" :minlevel 1 You can also include a portion of a file by specifying a lines range -using the `:lines' parameter. The line at the upper end of the range -will not be included. The start and/or the end of the range may be -omitted to use the obvious defaults. +using the `:lines' keyword parameter. The line at the upper end of the +range will not be included. The start and/or the end of the range may +be omitted to use the obvious defaults. #+INCLUDE: "~/.emacs" :lines "5-10" Include lines 5 to 10, 10 excluded #+INCLUDE: "~/.emacs" :lines "-10" Include lines 1 to 10, 10 excluded #+INCLUDE: "~/.emacs" :lines "10-" Include lines from 10 to EOF + Finally, you may use a file-link to extract an object as matched by +`org-link-search'(2) (*note Search options::). If the `:only-contents' +property is non-`nil', only the contents of the requested element will +be included, omitting properties drawer and planning-line if present. +The `:lines' keyword operates locally with respect to the requested +element. Some examples: + + #+INCLUDE: "./paper.org::#theory" :only-contents t + Include the body of the heading with the custom id `theory' + #+INCLUDE: "./paper.org::mytable" Include named element. + #+INCLUDE: "./paper.org::*conclusion" :lines 1-20 + Include the first 20 lines of the headline named conclusion. + `C-c '' Visit the include file at point. + ---------- Footnotes ---------- + + (1) While you can request paragraphs (`verse', `quote', `center'), +but this places severe restrictions on the type of content that is +permissible + + (2) 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. +  File: org, Node: Index entries, Next: Macro replacement, Prev: Include files, Up: Markup @@ -9396,16 +9557,51 @@ You can define text snippets with #+MACRO: name replacement text $1, $2 are arguments -which can be referenced in paragraphs, verse blocks, table cells and -some keywords with `{{{name(arg1,arg2)}}}'(1). In addition to defined -macros, `{{{title}}}', `{{{author}}}', etc., will reference information -set by the `#+TITLE:', `#+AUTHOR:', and similar lines. Also, -`{{{time(FORMAT)}}}' and `{{{modification-time(FORMAT)}}}' refer to -current date time and to the modification time of the file being -exported, respectively. FORMAT should be a format string understood by -`format-time-string'. +which can be referenced `{{{name(arg1, arg2)}}}'(1). + + These references, called macros, can be inserted anywhere Org markup +is recognized: paragraphs, headlines, verse blocks, tables cells and +lists. They can also be used in keywords accepting Org syntax, e.g., +`#+CAPTION', `#+TITLE', `#+AUTHOR', `#+DATE' and some others, export +back-end specific, ones. + + In addition to user-defined macros, a set of predefined macros can +be used: - Macro expansion takes place during export. +`{{{title}}}' +`{{{author}}}' +`{{{email}}}' + These macros are replaced with the information available at the + time of export. + +`{{{date}}}' +`{{{date(FORMAT)}}}' + This macro refers to the `#+DATE' keyword. FORMAT is an optional + argument to the `{{{date}}}' macro that will be used only if + `#+DATE' is a single timestamp. FORMAT should be a format string + understood by `format-time-string'. + +`{{{time(FORMAT)}}}' +`{{{modification-time(FORMAT)}}}' + These macros refer to the date and time when the document is + exported and to the modification date and time of the file being + exported, respectively. FORMAT should be a format string + understood by `format-time-string'. + +`{{{input-file}}}' + This macro refers to the filename of the exported file, if any. + +`{{{property(PROPERTY-NAME)}}}' +`{{{property(PROPERTY-NAME,SEARCH-OPTION)}}}' + This macro returns the value of property PROPERTY-NAME in current + entry. If SEARCH-OPTION (*note Search options::) refers to a + remote entry, it will be used instead. + + The surrounding brackets can be made invisible by setting +`org-hide-macro-markers' non-`nil'. + + Macro expansion takes place during the very beginning of the export +process. ---------- Footnotes ---------- @@ -9443,7 +9639,7 @@ Many of the features described here as "LaTeX" are really from TeX, but for simplicity I am blurring this distinction.  -File: org, Node: Special symbols, Next: Subscripts and superscripts, Prev: Embedded LaTeX, Up: Embedded LaTeX +File: org, Node: Special symbols, Next: Subscripts and superscripts, Up: Embedded LaTeX 11.7.1 Special symbols ---------------------- @@ -9459,9 +9655,9 @@ delimiters, for example: During export, these symbols will be transformed into the native format of the exporter back-end. Strings like `\alpha' will be -exported as `α' in the HTML output, and as `$\alpha$' in the LaTeX -output. Similarly, `\nbsp' will become ` ' in HTML and `~' in -LaTeX. If you need such a symbol inside a word, terminate it like +exported as `α' in the HTML output, and as `\(\alpha\)' in the +LaTeX output. Similarly, `\nbsp' will become ` ' in HTML and `~' +in LaTeX. If you need such a symbol inside a word, terminate it like this: `\Aacute{}stor'. A large number of entities is provided, with names taken from both @@ -9518,26 +9714,26 @@ File: org, Node: LaTeX fragments, Next: Previewing LaTeX fragments, Prev: Sub Going beyond symbols and sub- and superscripts, a full formula language is needed. Org mode can contain LaTeX math fragments, and it supports ways to process these for several export back-ends. When exporting to -LaTeX, the code is obviously left as it is. When exporting to HTML, -Org invokes the MathJax library (http://www.mathjax.org) (*note Math -formatting in HTML export::) to process and display the math(1). -Finally, it can also process the mathematical expressions into -images(2) that can be displayed in a browser. +LaTeX, the code is left as it is. When exporting to HTML, Org can use +either MathJax (http://www.mathjax.org) (*note Math formatting in HTML +export::) or transcode the math into images (see *note Previewing LaTeX +fragments::). LaTeX fragments don't need any special marking at all. The following snippets will be identified as LaTeX source code: - * Environments of any kind(3). The only requirement is that the - `\begin' and `\end' statements appear on a new line, at the - beginning of the line or after whitespaces only. + * Environments of any kind(1). The only requirement is that the + `\begin' statement appears on a new line, at the beginning of the + line or after whitespaces only. * Text within the usual LaTeX math delimiters. To avoid conflicts with currency specifications, single `$' characters are only recognized as math delimiters if the enclosed text contains at most two line breaks, is directly attached to the `$' characters with no whitespace in between, and if the closing `$' is followed - by whitespace, punctuation or a dash. For the other delimiters, - there is no such restriction, so when in doubt, use `\(...\)' as - inline math delimiters. + by whitespace or punctuation (parentheses and quotes are + considered to be punctuation in this context). For the other + delimiters, there is no such restriction, so when in doubt, use + `\(...\)' as inline math delimiters. For example: @@ -9550,9 +9746,8 @@ For example: LaTeX processing can be configured with the variable `org-export-with-latex'. The default setting is `t' which means -`MathJax' for HTML, and no processing for ASCII and LaTeX back-ends. -You can also set this variable on a per-file basis using one of these -lines: +MathJax for HTML, and no processing for ASCII and LaTeX back-ends. You +can also set this variable on a per-file basis using one of these lines: #+OPTIONS: tex:t Do the right thing automatically (MathJax) #+OPTIONS: tex:nil Do not process LaTeX fragments at all @@ -9560,19 +9755,8 @@ lines: ---------- Footnotes ---------- - (1) If you plan to use this regularly or on pages with significant -page views, you should install `MathJax' on your own server in order to -limit the load of our server. - - (2) For this to work you need to be on a system with a working LaTeX -installation. You also need the `dvipng' program or the `convert', -respectively available at `http://sourceforge.net/projects/dvipng/' and -from the `imagemagick' suite. The LaTeX header that will be used when -processing a fragment can be configured with the variable -`org-format-latex-header'. - - (3) When `MathJax' is used, only the environments recognized by -`MathJax' will be processed. When `dvipng' program or `imagemagick' + (1) When MathJax is used, only the environments recognized by +MathJax will be processed. When `dvipng' program or `imagemagick' suite is used to create images, any LaTeX environment will be handled.  @@ -9581,8 +9765,16 @@ File: org, Node: Previewing LaTeX fragments, Next: CDLaTeX mode, Prev: LaTeX 11.7.4 Previewing LaTeX fragments --------------------------------- -If you have `dvipng' or `imagemagick' installed(1), LaTeX fragments can -be processed to produce preview images of the typeset expressions: +If you have a working LaTeX installation and either `dvipng' or +`convert' installed(1), LaTeX fragments can be processed to produce +images of the typeset expressions to be used for inclusion while +exporting to HTML (see *note LaTeX fragments::), or for inline +previewing within Org mode. + + You can customize the variables `org-format-latex-options' and +`org-format-latex-header' to influence some aspects of the preview. 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. `C-c C-x C-l' Produce a preview image of the LaTeX fragment at point and overlay @@ -9595,11 +9787,6 @@ be processed to produce preview images of the typeset expressions: `C-c C-c' Remove the overlay preview images. - You can customize the variable `org-format-latex-options' to -influence some aspects of the preview. In particular, the `:scale' -(and for HTML export, `:html-scale') property can be used to adjust the -size of the preview images. - You can turn on the previewing of all LaTeX fragments in a file with #+STARTUP: latexpreview @@ -9610,7 +9797,9 @@ size of the preview images. ---------- Footnotes ---------- - (1) Choose the converter by setting the variable + (1) These are respectively available at +`http://sourceforge.net/projects/dvipng/' and from the `imagemagick' +suite. Choose the converter by setting the variable `org-latex-create-formula-image-program' accordingly.  @@ -9652,15 +9841,15 @@ more details see the documentation of CDLaTeX mode): character or macro, they are removed again (depending on the variable `cdlatex-simplify-sub-super-scripts'). - * Pressing the backquote ``' followed by a character inserts math + * Pressing the grave accent ``' 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 will pop up. + seconds after the grave accent, a help window will pop up. - * 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 - will pop up. Character modification will work only inside LaTeX - fragments; outside the quote is normal. + * Pressing the apostrophe `'' 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 apostrophe, a help window will pop + up. Character modification will work only inside LaTeX fragments; + outside the quote is normal. ---------- Footnotes ---------- @@ -9676,18 +9865,18 @@ File: org, Node: Special blocks, Prev: Embedded LaTeX, Up: Markup Org syntax includes pre-defined blocks (*note Paragraphs:: and *note Literal examples::). It is also possible to create blocks containing -raw code targeted at a specific back-ends (e.g., `#+BEGIN_LATEX'). +raw code targeted at a specific back-end (e.g., `#+BEGIN_LATEX'). - Any other block is a _special block_. + Any other block is a _special block_. Its name is case-sensitive. - For example, `#+BEGIN_ABSTRACT' and `#+BEGIN_VIDEO' are special + For example, `#+BEGIN_abstract' and `#+BEGIN_video' are special blocks. The first one is useful when exporting to LaTeX, the second one when exporting to HTML5. Each export back-end decides if they should be exported, and how. When the block is ignored, its contents are still exported, as if the opening and closing block lines were not there. For example, when -exporting a `#+BEGIN_TEST' block, HTML back-end wraps its contents +exporting a `#+BEGIN_test' block, HTML back-end wraps its contents within a `
' tag. Refer to back-end specific documentation for more information. @@ -9717,7 +9906,7 @@ iCalendar format. * Menu: -* The Export Dispatcher:: The main exporter interface +* The export dispatcher:: The main exporter interface * Export back-ends:: Built-in export formats * Export settings:: Generic export settings * ASCII/Latin-1/UTF-8 export:: Exporting to flat files with encoding @@ -9734,15 +9923,14 @@ iCalendar format. * Advanced configuration:: Fine-tuning the export output  -File: org, Node: The Export Dispatcher, Next: Export back-ends, Prev: Exporting, Up: Exporting +File: org, Node: The export dispatcher, Next: Export back-ends, Up: Exporting -12.1 The Export Dispatcher +12.1 The export dispatcher ========================== The main entry point for export related tasks is the dispatcher, a hierarchical menu from which it is possible to select an export format -and toggle export options(1) from which it is possible to select an -export format and to toggle export options. +and toggle export options(1). `C-c C-e' (`org-export-dispatch') Dispatch for export and publishing commands. When called with a @@ -9784,12 +9972,7 @@ the export dispatcher with the following key combinations: `C-v' Toggle visible-only export. Only export the text that is currently - visible, i.e. not hidden by outline visibility in the buffer. - - - With the exception of asynchronous export, a successful export -process writes its output to the kill-ring. You can configure this -behavior by altering the option `org-export-copy-to-kill-ring'. + visible, i.e., not hidden by outline visibility in the buffer. ---------- Footnotes ---------- @@ -9799,7 +9982,7 @@ case, only a prompt is visible from the minibuffer. From there one can still switch back to regular menu by pressing .  -File: org, Node: Export back-ends, Next: Export settings, Prev: The Export Dispatcher, Up: Exporting +File: org, Node: Export back-ends, Next: Export settings, Prev: The export dispatcher, Up: Exporting 12.2 Export back-ends ===================== @@ -9847,13 +10030,13 @@ Export options can be set: globally with variables; for an individual file by making variables buffer-local with in-buffer settings (*note In-buffer settings::), by setting individual keywords, or by specifying them in a compact form with the `#+OPTIONS' keyword; or for a tree by -setting properties (*note Properties and Columns::). Options set at a +setting properties (*note Properties and columns::). Options set at a specific level override options set at a more general level. In-buffer settings may appear anywhere in the file, either directly or indirectly through a file included using `#+SETUPFILE: filename' syntax. Option keyword sets tailored to a particular back-end can be -inserted from the export dispatcher (*note The Export Dispatcher::) +inserted from the export dispatcher (*note The export dispatcher::) using the `Insert template' command by pressing <#>. To insert keywords individually, a good way to make sure the keyword is correct is to type `#+' and then to use `M-' for completion. @@ -9871,19 +10054,9 @@ equivalent global variables, include: `DATE' A date or a time-stamp(1). -`DESCRIPTION' - The document description. Back-ends handle it as they see fit - (e.g., for the XHTML meta tag), if at all. You can use several - such keywords for long descriptions. - `EMAIL' The email address (`user-mail-address'). -`KEYWORDS' - The keywords defining the contents of the document. Back-ends - handle it as they see fit (e.g., for the XHTML meta tag), if at - all. You can use several such keywords if the list is long. - `LANGUAGE' The language used for translating some strings (`org-export-default-language'). E.g., `#+LANGUAGE: fr' will tell @@ -9901,11 +10074,13 @@ equivalent global variables, include: The tags that exclude a tree from export (`org-export-exclude-tags'). The default value is `:noexport:'. Entries with the `:noexport:' tag will be unconditionally excluded - from the export, even if they have an `:export:' tag. + from the export, even if they have an `:export:' tag. Code blocks + contained in excluded subtrees will still be executed during + export even though the subtree is not exported. `TITLE' - The title to be shown (otherwise derived from buffer's name). You - can use several such keywords for long titles. + The title to be shown. You can use several such keywords for long + titles. The `#+OPTIONS' keyword is a compact(2) form that recognizes the following arguments: @@ -9948,13 +10123,17 @@ following arguments: Toggle inclusion of CLOCK keywords (`org-export-with-clocks'). `creator:' - Configure inclusion of creator info into exported file. It may be - set to `comment' (`org-export-with-creator'). + Toggle inclusion of creator info into exported file + (`org-export-with-creator'). `d:' Toggle inclusion of drawers, or list drawers to include (`org-export-with-drawers'). +`date:' + Toggle inclusion of a date into exported file + (`org-export-with-date'). + `e:' Toggle inclusion of entities (`org-export-with-entities'). @@ -9976,7 +10155,10 @@ following arguments: `num:' Toggle section-numbers (`org-export-with-section-numbers'). It can also be set to a number `n', so only headlines at that level - or above will be numbered. + or above will be numbered. Finally, irrespective of the level of + a specific headline, the numbering of it can be disabled by + setting the `UNNUMBERED' property to non-`nil'. This also affects + subheadings. `p:' Toggle export of planning information (`org-export-with-planning'). @@ -9986,6 +10168,10 @@ following arguments: `pri:' Toggle inclusion of priority cookies (`org-export-with-priority'). +`prop:' + Toggle inclusion of property drawers, or list properties to include + (`org-export-with-properties'). + `stat:' Toggle inclusion of statistics cookies (`org-export-with-statistics-cookies'). @@ -10007,6 +10193,9 @@ following arguments: Toggle inclusion of the creation time into exported file (`org-export-time-stamp-file'). +`title:' + Toggle inclusion of title (`org-export-with-title'). + `toc:' Toggle inclusion of the table of contents, or set the level limit (`org-export-with-toc'). @@ -10018,6 +10207,7 @@ following arguments: `|:' Toggle inclusion of tables (`org-export-with-tables'). + When exporting only a subtree, each of the previous keywords(3) can be overridden locally by special node properties. These begin with `EXPORT_', followed by the name of the keyword they supplant. For @@ -10056,6 +10246,9 @@ file, containing only plain ASCII. Latin-1 and UTF-8 export augment the file with special characters and symbols available in these encodings. + Upon exporting, text is filled and justified, when appropriate, +according the text width set in `org-ascii-text-width'. + Links are exported in a footnote-like style, with the descriptive part in the text and the link in a note before the next heading. See the variable `org-ascii-links-to-notes' for details and other options. @@ -10072,6 +10265,15 @@ ASCII export commands `C-c C-e t A/L/U (`org-ascii-export-as-ascii')' Export to a temporary buffer. Do not create a file. +ASCII specific export settings +------------------------------ + +ASCII export introduces a single of keywords, similar to the general +options settings described in *note Export settings::. + +`SUBTITLE' + The document subtitle. + Header and sectioning structure ------------------------------- @@ -10105,6 +10307,21 @@ rule. #+ATTR_ASCII: :width 10 ----- +ASCII special blocks +-------------------- + +In addition to `#+BEGIN_CENTER' blocks (*note Paragraphs::), it is +possible to justify contents to the left or the right of the page with +the following dedicated blocks. + + #+BEGIN_JUSTIFYLEFT + It's just a jump to the left... + #+END_JUSTIFYLEFT + + #+BEGIN_JUSTIFYRIGHT + ...and then a step to the right. + #+END_JUSTIFYRIGHT +  File: org, Node: Beamer export, Next: HTML export, Prev: ASCII/Latin-1/UTF-8 export, Up: Exporting @@ -10115,8 +10332,20 @@ The LaTeX class _Beamer_ allows production of high quality presentations using LaTeX and pdf processing. Org mode has special support for turning an Org mode file or tree into a Beamer presentation. -Beamer export commands ----------------------- +* Menu: + +* Beamer export commands:: How to export Beamer documents. +* Beamer specific export settings:: Export settings for Beamer export. +* Sectioning Frames and Blocks in Beamer:: Blocks and sections in Beamer. +* Beamer specific syntax:: Syntax specific to Beamer. +* Editing support:: Helper functions for Org Beamer export. +* A Beamer Example:: An complete Beamer example. + + +File: org, Node: Beamer export commands, Next: Beamer specific export settings, Up: Beamer export + +12.5.1 Beamer export commands +----------------------------- `C-c C-e l b (`org-beamer-export-to-latex')' Export as a LaTeX file. For an Org file `myfile.org', the LaTeX @@ -10133,8 +10362,59 @@ Beamer export commands Export as LaTeX and then process to PDF, then open the resulting PDF file. -Sectioning, Frames and Blocks ------------------------------ + +File: org, Node: Beamer specific export settings, Next: Sectioning Frames and Blocks in Beamer, Prev: Beamer export commands, Up: Beamer export + +12.5.2 Beamer specific export settings +-------------------------------------- + +Beamer export introduces a number of keywords, similar to the general +options settings described in *note Export settings::. + +`BEAMER_THEME' + The Beamer theme (`org-beamer-theme'). Options can be specified + via brackets, for example: + #+BEAMER_THEME: Rochester [height=20pt] + +`BEAMER_FONT_THEME' + The Beamer font theme. + +`BEAMER_INNER_THEME' + The Beamer inner theme. + +`BEAMER_OUTER_THEME' + The Beamer outer theme. + +`BEAMER_HEADER' + Arbitrary lines inserted into the preamble, just before the + `hyperref' settings. + +`DESCRIPTION' + The document description. By default these are inserted as + metadata using `hyperref'. Document metadata can be configured via + `org-latex-hyperref-template'. Description can also be typeset as + part of the front matter via `org-latex-title-command'. You can + use several `#+DESCRIPTION' keywords if the description is is long. + +`KEYWORDS' + The keywords defining the contents of the document. By default + these are inserted as metadata using `hyperref'. Document + metadata can be configured via `org-latex-hyperref-template'. + Description can also be typeset as part of the front matter via + `org-latex-title-command'. You can use several `#+KEYWORDS' if + the description is is long. + +`SUBTITLE' + The document subtitle. This is typeset using the format string + `org-beamer-subtitle-format'. It can also access via + `org-latex-hyperref-template' or typeset as part of the front + matter via `org-latex-title-command'. + + +File: org, Node: Sectioning Frames and Blocks in Beamer, Next: Beamer specific syntax, Prev: Beamer specific export settings, Up: Beamer export + +12.5.3 Sectioning, Frames and Blocks in Beamer +---------------------------------------------- Any tree with not-too-deep level nesting should in principle be exportable as a Beamer presentation. Headlines fall into three @@ -10187,23 +10467,24 @@ is generated automatically. Although, it can also be explicitly created, with a special `columns' value for `BEAMER_ENV' property (if it needs to be set up with some specific options, for example). -Beamer specific syntax ----------------------- + ---------- Footnotes ---------- + + (1) If this property is set, the entry will also get a +`:B_environment:' tag to make this visible. This tag has no semantic +meaning, it is only a visual aid. + + (2) The `fragile' option is added automatically if it contains code +that requires a verbatim environment, though. -Beamer back-end is an extension of LaTeX back-end. As such, all LaTeX -specific syntax (e.g., `#+LATEX:' or `#+ATTR_LATEX:') is recognized. -See *note LaTeX and PDF export:: for more information. + +File: org, Node: Beamer specific syntax, Next: Editing support, Prev: Sectioning Frames and Blocks in Beamer, Up: Beamer export - Beamer export introduces a number of keywords to insert code in the -document's header. Four control appearance of the presentation: -`#+BEAMER_THEME', `#+BEAMER_COLOR_THEME', `#+BEAMER_FONT_THEME', -`#+BEAMER_INNER_THEME' and `#+BEAMER_OUTER_THEME'. All of them accept -optional arguments within square brackets. The last one, -`#+BEAMER_HEADER', is more generic and allows you to append any line of -code in the header. +12.5.4 Beamer specific syntax +----------------------------- - #+BEAMER_THEME: Rochester [height=20pt] - #+BEAMER_COLOR_THEME: spruce +The Beamer back-end is an extension of the LaTeX back-end. As such, +all LaTeX specific syntax (e.g., `#+LATEX:' or `#+ATTR_LATEX:') is +recognized. See *note LaTeX and PDF export:: for more information. Table of contents generated from `toc:t' `OPTION' keyword are wrapped within a `frame' environment. Those generated from a `TOC' @@ -10239,8 +10520,11 @@ arguments in current list environment. - item 1 - item 2 -Editing support ---------------- + +File: org, Node: Editing support, Next: A Beamer Example, Prev: Beamer specific syntax, Up: Beamer export + +12.5.5 Editing support +---------------------- You can turn on a special minor mode `org-beamer-mode' for faster editing with: @@ -10251,20 +10535,18 @@ editing with: In `org-beamer-mode', this key offers fast selection of a Beamer environment or the `BEAMER_COL' property. - Also, a template for useful in-buffer settings or properties can be -inserted into the buffer with `M-x org-beamer-insert-options-template'. -Among other things, this will install a column view format which is -very handy for editing special properties used by Beamer. + +File: org, Node: A Beamer Example, Prev: Editing support, Up: Beamer export -An example ----------- +12.5.6 A Beamer example +----------------------- Here is a simple example Org document that is intended for Beamer export. #+TITLE: Example Presentation #+AUTHOR: Carsten Dominik - #+OPTIONS: H:2 + #+OPTIONS: H:2 toc:t num:t #+LATEX_CLASS: beamer #+LATEX_CLASS_OPTIONS: [presentation] #+BEAMER_THEME: Madrid @@ -10273,20 +10555,20 @@ export. * This is the first structural section ** Frame 1 - *** Thanks to Eric Fraga :B_block:BMCOL: + *** Thanks to Eric Fraga :B_block: :PROPERTIES: :BEAMER_COL: 0.48 :BEAMER_ENV: block :END: for the first viable Beamer setup in Org - *** Thanks to everyone else :B_block:BMCOL: + *** Thanks to everyone else :B_block: :PROPERTIES: :BEAMER_COL: 0.48 :BEAMER_ACT: <2-> :BEAMER_ENV: block :END: for contributing to the discussion - **** This will be formatted as a beamer note :B_note: + **** This will be formatted as a beamer note :B_note: :PROPERTIES: :BEAMER_env: note :END: @@ -10294,15 +10576,6 @@ export. *** Request Please test this stuff! - ---------- Footnotes ---------- - - (1) If this property is set, the entry will also get a -`:B_environment:' tag to make this visible. This tag has no semantic -meaning, it is only a visual aid. - - (2) The `fragile' option is added automatically if it contains code -that requires a verbatim environment, though. -  File: org, Node: HTML export, Next: LaTeX and PDF export, Prev: Beamer export, Up: Exporting @@ -10316,6 +10589,7 @@ but with additional support for tables. * Menu: * HTML Export commands:: How to invoke HTML export +* HTML Specific export settings:: Export settings for HTML export. * HTML doctypes:: Org can export to various (X)HTML flavors * HTML preamble and postamble:: How to insert a preamble and a postamble * Quoting HTML tags:: Using direct HTML in Org mode @@ -10328,7 +10602,7 @@ but with additional support for tables. * JavaScript support:: Info and Folding in a web browser  -File: org, Node: HTML Export commands, Next: HTML doctypes, Prev: HTML export, Up: HTML export +File: org, Node: HTML Export commands, Next: HTML Specific export settings, Up: HTML export 12.6.1 HTML export commands --------------------------- @@ -10343,27 +10617,82 @@ File: org, Node: HTML Export commands, Next: HTML doctypes, Prev: HTML export Export to a temporary buffer. Do not create a file.  -File: org, Node: HTML doctypes, Next: HTML preamble and postamble, Prev: HTML Export commands, Up: HTML export +File: org, Node: HTML Specific export settings, Next: HTML doctypes, Prev: HTML Export commands, Up: HTML export -12.6.2 HTML doctypes --------------------- +12.6.2 HTML Specific export settings +------------------------------------ -Org can export to various (X)HTML flavors. +HTML export introduces a number of keywords, similar to the general +options settings described in *note Export settings::. - Setting the variable `org-html-doctype' allows you to export to -different (X)HTML variants. The exported HTML will be adjusted -according to the syntax requirements of that variant. You can either -set this variable to a doctype string directly, in which case the -exporter will try to adjust the syntax automatically, or you can use a -ready-made doctype. The ready-made options are: +`DESCRIPTION' + The document description. This description is inserted as a HTML + meta tag. You can use several such keywords if the list is long. - * "html4-strict" +`HTML_DOCTYPE' + The document type, e.g. HTML5, (`org-html-doctype'). - * "html4-transitional" +`HTML_CONTAINER' + The container, e.g. `div', used to wrap sections and elements + (`org-html-container-element'). - * "html4-frameset" +`HTML_LINK_HOME' + The home link URL (`org-html-link-home'). - * "xhtml-strict" +`HTML_LINK_UP' + The up link URL (`org-html-link-up'). + +`HTML_MATHJAX' + Options for the MathJax (`org-html-mathjax-options'). MathJax is + used to typeset LaTeX math in HTML documents. *note Math + formatting in HTML export:: contains an example. + +`HTML_HEAD' + Arbitrary lines appended to the end of the head of the document + (`org-html-head'). + +`HTML_HEAD_EXTRA' + Arbitrary lines appended to the end of the header of the document + (`org-html-head-extra'). + +`KEYWORDS' + The keywords defining the contents of the document. This + description is inserted as a HTML meta tag. You can use several + such keywords if the list is long. + +`LATEX_HEADER' + Arbitrary lines appended to the preamble used when transcoding + LaTeX fragments to images. See *note Math formatting in HTML + export:: for details. + +`SUBTITLE' + The document subtitle. The formatting depends on whether HTML5 in + used and on the `subtitle' CSS class. + + These keywords are treated in details in the following sections. + + +File: org, Node: HTML doctypes, Next: HTML preamble and postamble, Prev: HTML Specific export settings, Up: HTML export + +12.6.3 HTML doctypes +-------------------- + +Org can export to various (X)HTML flavors. + + Setting the variable `org-html-doctype' allows you to export to +different (X)HTML variants. The exported HTML will be adjusted +according to the syntax requirements of that variant. You can either +set this variable to a doctype string directly, in which case the +exporter will try to adjust the syntax automatically, or you can use a +ready-made doctype. The ready-made options are: + + * "html4-strict" + + * "html4-transitional" + + * "html4-frameset" + + * "xhtml-strict" * "xhtml-transitional" @@ -10416,7 +10745,7 @@ few new block-level elements. These are created using arbitrary Special blocks that do not correspond to HTML5 elements (see `org-html-html5-elements') will revert to the usual behavior, i.e., -`#+BEGIN_LEDERHOSEN' will still export to `
'. +`#+BEGIN_lederhosen' will still export to `
'. Headlines cannot appear within special blocks. To wrap a headline and its contents in e.g., `
' or `
' tags, set the @@ -10425,7 +10754,7 @@ and its contents in e.g., `
' or `
' tags, set the  File: org, Node: HTML preamble and postamble, Next: Quoting HTML tags, Prev: HTML doctypes, Up: HTML export -12.6.3 HTML preamble and postamble +12.6.4 HTML preamble and postamble ---------------------------------- The HTML exporter lets you define a preamble and a postamble. @@ -10449,7 +10778,7 @@ Setting it to `nil' will not insert any postamble.  File: org, Node: Quoting HTML tags, Next: Links in HTML export, Prev: HTML preamble and postamble, Up: HTML export -12.6.4 Quoting HTML tags +12.6.5 Quoting HTML tags ------------------------ Plain `<' and `>' are always transformed to `<' and `>' in HTML @@ -10469,7 +10798,7 @@ or  File: org, Node: Links in HTML export, Next: Tables in HTML export, Prev: Quoting HTML tags, Up: HTML export -12.6.5 Links in HTML export +12.6.6 Links in HTML export --------------------------- Internal links (*note Internal links::) will continue to work in HTML. @@ -10478,9 +10807,11 @@ targets::). Links to external files will still work if the target file is on the same relative path as the published Org file. Links to other `.org' files will be translated into HTML links under the assumption that an HTML version also exists of the linked file, at the same -relative path. `id:' links can then be used to jump to specific -entries across files. For information related to linking files while -publishing them to a publishing directory see *note Publishing links::. +relative path; setting `org-html-link-org-files-as-html' to `nil' +disables this translation. `id:' links can then be used to jump to +specific entries across files. For information related to linking +files while publishing them to a publishing directory see *note +Publishing links::. If you want to specify attributes for links, you can do so using a special `#+ATTR_HTML' line to define attributes that will be added to @@ -10493,8 +10824,8 @@ the `' or `' tags. Here is an example that sets `title' and  File: org, Node: Tables in HTML export, Next: Images in HTML export, Prev: Links in HTML export, Up: HTML export -12.6.6 Tables -------------- +12.6.7 Tables in HTML export +---------------------------- Org mode tables are exported to HTML using the table attributes defined in `org-html-table-default-attributes'. The default setting makes @@ -10505,14 +10836,37 @@ the table: #+CAPTION: This is a table with lines around and between cells #+ATTR_HTML: :border 2 :rules all :frame border - You can also modify the default tags used for each row by setting -`org-html-table-row-tags'. See the docstring for an example on how to -use this option. + You can also group columns in the HTML output (*note Column +groups::). + + Below is a list of options for customizing tables HTML export. + +`org-html-table-align-individual-fields' + Non-`nil' means attach style attributes for alignment to each + table field. + +`org-html-table-caption-above' + When non-`nil', place caption string at the beginning of the table. + +`org-html-table-data-tags' + The opening and ending tags for table data fields. + +`org-html-table-default-attributes' + Default attributes and values which will be used in table tags. + +`org-html-table-header-tags' + The opening and ending tags for table header fields. + +`org-html-table-row-tags' + The opening and ending tags for table rows. + +`org-html-table-use-header-tags-for-first-column' + Non-`nil' means format column one in tables with header tags.  File: org, Node: Images in HTML export, Next: Math formatting in HTML export, Prev: Tables in HTML export, Up: HTML export -12.6.7 Images in HTML export +12.6.8 Images in HTML export ---------------------------- HTML export can inline images given as links in the Org file, and it @@ -10546,24 +10900,22 @@ You could use `http' addresses just as well.  File: org, Node: Math formatting in HTML export, Next: Text areas in HTML export, Prev: Images in HTML export, Up: HTML export -12.6.8 Math formatting in HTML export +12.6.9 Math formatting in HTML export ------------------------------------- LaTeX math snippets (*note LaTeX fragments::) can be displayed in two -different ways on HTML pages. The default is to use the MathJax system -(http://www.mathjax.org) which should work out of the box with Org mode -installation because `http://orgmode.org' serves `MathJax' for Org mode -users for small applications and for testing purposes. If you plan to -use this regularly or on pages with significant page views, you should -install(1) MathJax on your own server in order to limit the load of our -server. To configure `MathJax', use the variable -`org-html-mathjax-options' or insert something like the following into -the buffer: - - #+HTML_MATHJAX: align:"left" mathml:t path:"/MathJax/MathJax.js" - -See the docstring of the variable `org-html-mathjax-options' for the -meaning of the parameters in this line. +different ways on HTML pages. The default is to use MathJax +(http://www.mathjax.org) which should work out of the box with Org(1). +Some MathJax display options can be configured via +`org-html-mathjax-options', or in the buffer. For example, with the +following settings, + #+HTML_MATHJAX: align: left indent: 5em tagside: left font: Neo-Euler + equation labels will be displayed on the left marign and equations +will be five ems from the left margin. + +See the docstring of `org-html-mathjax-options' for all supported +variables. The MathJax template can be configure via +`org-html-mathjax-template'. If you prefer, you can also request that LaTeX fragments are processed into small images that will be inserted into the browser @@ -10580,14 +10932,16 @@ this processing with ---------- Footnotes ---------- - (1) Installation instructions can be found on the MathJax website, -see `http://www.mathjax.org/resources/docs/?installation.html'. + (1) By default Org loads MathJax from MathJax.org +(http://docs.mathjax.org/en/latest/start.html#using-the-mathjax-content-delivery-network-cdn). +A link to the terms of service of the MathJax CDN can be found in the +docstring of `org-html-mathjax-options'.  File: org, Node: Text areas in HTML export, Next: CSS support, Prev: Math formatting in HTML export, Up: HTML export -12.6.9 Text areas in HTML export --------------------------------- +12.6.10 Text areas in HTML export +--------------------------------- An alternative way to publish literal code examples in HTML is to use text areas, where the example can even be edited before pasting it into @@ -10608,7 +10962,7 @@ in the example, and 80, respectively. For example  File: org, Node: CSS support, Next: JavaScript support, Prev: Text areas in HTML export, Up: HTML export -12.6.10 CSS support +12.6.11 CSS support ------------------- You can modify the CSS style definitions for the exported file. The @@ -10620,6 +10974,7 @@ tables, etc. p.date publishing date p.creator creator info, about org mode version .title document title + .subtitle document subtitle .todo TODO keywords, all not-done states .done the DONE keywords, all states that count as done .WAITING each TODO keyword also uses a class named after itself @@ -10678,7 +11033,7 @@ customize `org-html-head-include-default-style' or set `html-style' to  File: org, Node: JavaScript support, Prev: CSS support, Up: HTML export -12.6.11 JavaScript supported display of web pages +12.6.12 JavaScript supported display of web pages ------------------------------------------------- Sebastian Rose has written a JavaScript program especially designed to @@ -10756,6 +11111,7 @@ item's description. * Menu: * LaTeX export commands:: How to export to LaTeX and PDF +* LaTeX specific export settings:: Export settings for LaTeX * Header and sectioning:: Setting up the export file structure * Quoting LaTeX code:: Incorporating literal LaTeX code * LaTeX specific attributes:: Controlling LaTeX output @@ -10763,13 +11119,13 @@ item's description. ---------- Footnotes ---------- (1) The default LaTeX output is designed for processing with -`pdftex' or LaTeX. It includes packages that are not compatible with -`xetex' and possibly `luatex'. The LaTeX exporter can be configured to -support alternative TeX engines, see the options -`org-latex-default-packages-alist' and `org-latex-packages-alist'. +`pdftex' or `latex'. The LaTeX exporter can be configured to support +alternative TeX engines, see see `org-latex-pdf-process', and +alternative packages, see `org-latex-default-packages-alist' and +`org-latex-packages-alist'.  -File: org, Node: LaTeX export commands, Next: Header and sectioning, Prev: LaTeX and PDF export, Up: LaTeX and PDF export +File: org, Node: LaTeX export commands, Next: LaTeX specific export settings, Up: LaTeX and PDF export 12.7.1 LaTeX export commands ---------------------------- @@ -10790,9 +11146,60 @@ File: org, Node: LaTeX export commands, Next: Header and sectioning, Prev: La PDF file.  -File: org, Node: Header and sectioning, Next: Quoting LaTeX code, Prev: LaTeX export commands, Up: LaTeX and PDF export +File: org, Node: LaTeX specific export settings, Next: Header and sectioning, Prev: LaTeX export commands, Up: LaTeX and PDF export + +12.7.2 LaTeX specific export settings +------------------------------------- + +The LaTeX exporter introduces a number of keywords, similar to the +general options settings described in *note Export settings::. + +`DESCRIPTION' + The document description. By default these are inserted as + metadata using `hyperref'. Document metadata can be configured via + `org-latex-hyperref-template'. Description can also be typeset as + part of the front matter via `org-latex-title-command'. You can + use several `#+DESCRIPTION' keywords if the description is is long. + +`LATEX_CLASS' + The predefined preamble and headline level mapping to use + (`org-latex-default-class'). Must be an element in + `org-latex-classes'. + +`LATEX_CLASS_OPTIONS' + Options given to the LaTeX document class. + +`LATEX_HEADER' + Arbitrary lines added to the preamble of the document, before the + `hyperref' settings. The location can be controlled via + `org-latex-classes'. + +`LATEX_HEADER_EXTRA' + Arbitrary lines added to the preamble of the document, before the + `hyperref' settings. The location can be controlled via + `org-latex-classes'. + +`KEYWORDS' + The keywords defining the contents of the document. By default + these are inserted as metadata using `hyperref'. Document + metadata can be configured via `org-latex-hyperref-template'. + Description can also be typeset as part of the front matter via + `org-latex-title-command'. You can use several `#+KEYWORDS' if + the description is is long. + +`SUBTITLE' + The document subtitle. This is typeset according to + `org-latex-subtitle-format'. If `org-latex-subtitle-separate' is + non-`nil' it is typed as part of the `\title'-macro. It can also + access via `org-latex-hyperref-template' or typeset as part of the + front matter via `org-latex-title-command'. + + These keywords are treated in details in the following sections. + + +File: org, Node: Header and sectioning, Next: Quoting LaTeX code, Prev: LaTeX specific export settings, Up: LaTeX and PDF export -12.7.2 Header and sectioning structure +12.7.3 Header and sectioning structure -------------------------------------- By default, the first three outline levels become headlines, defining a @@ -10841,7 +11248,7 @@ Previewing LaTeX fragments::).  File: org, Node: Quoting LaTeX code, Next: LaTeX specific attributes, Prev: Header and sectioning, Up: LaTeX and PDF export -12.7.3 Quoting LaTeX code +12.7.4 Quoting LaTeX code ------------------------- Embedded LaTeX as described in *note Embedded LaTeX::, will be correctly @@ -10860,11 +11267,12 @@ constructs:  File: org, Node: LaTeX specific attributes, Prev: Quoting LaTeX code, Up: LaTeX and PDF export -12.7.4 LaTeX specific attributes +12.7.5 LaTeX specific attributes -------------------------------- LaTeX understands attributes specified in an `ATTR_LATEX' line. They -affect tables, images, plain lists, special blocks and source blocks. +affect tables, images, plain lists, source blocks, example blocks and +special blocks. Tables in LaTeX export ...................... @@ -10897,10 +11305,12 @@ table layout and contents. Valid LaTeX attributes include: `:float' `:placement' - Float environment for the table. Possible values are - `sidewaystable', `multicolumn', `t' and `nil'. When unspecified, - a table with a caption will have a `table' environment. Moreover, - `:placement' attribute can specify the positioning of the float. + The `:float' specifies the float environment for the table. + Possible values are `sideways'(3), `multicolumn', `t' and `nil'. + When unspecified, a table with a caption will have a `table' + environment. Moreover, the `:placement' attribute can specify the + positioning of the float. Note: `:placement' is ignored for + `:float sideways' tables. `:align' `:font' @@ -10960,7 +11370,7 @@ Images in LaTeX export Images that are linked to without a description part in the link, like `[[file:img.jpg]]' or `[[./img.jpg]]' will be inserted into the PDF output file resulting from LaTeX processing. Org will use an -`\includegraphics' macro to insert the image(3). +`\includegraphics' macro to insert the image(4). You can specify specify image width or height with, respectively, `:width' and `:height' attributes. It is also possible to add any @@ -10991,6 +11401,11 @@ attribute. You may also set it to: - `wrap': if you would like to let text flow around the image. It will make the figure occupy the left half of the page. + - `sideways': if you would like the image to appear alone on a + separate page rotated ninety degrees using the `sidewaysfigure' + environment. Setting this `:float' option will ignore the + `:placement' setting. + - `nil': if you need to avoid any floating environment, even when a caption is provided. To modify the placement option of any floating environment, set the @@ -11017,8 +11432,10 @@ Source blocks in LaTeX export ............................. In addition to syntax defined in *note Literal examples::, names and -captions (*note Images and tables::), source blocks also accept a -`:float' attribute. You may set it to: +captions (*note Images and tables::), source blocks also accept two +additional attributes: `:float' and `:options'. + + You may set the former to - `t': if you want to make the source block a float. It is the default value when a caption is provided. @@ -11034,6 +11451,31 @@ captions (*note Images and tables::), source blocks also accept a Code that may not fit in a single page. #+END_SRC + The latter allows to specify options relative to the package used to +highlight code in the output (e.g., `listings'). This is the local +counterpart to `org-latex-listings-options' and +`org-latex-minted-options' variables, which see. + + #+ATTR_LATEX: :options commentstyle=\bfseries + #+BEGIN_SRC emacs-lisp + (defun Fib (n) ; Count rabbits. + (if (< n 2) n (+ (Fib (- n 1)) (Fib (- n 2))))) + #+END_SRC + +Example blocks in LaTeX export +.............................. + +By default, when exporting to LaTeX, example blocks contents are wrapped +in a `verbatim' environment. It is possible to use a different +environment globally using an appropriate export filter (*note Advanced +configuration::). You can also change this per block using +`:environment' parameter. + + #+ATTR_LATEX: :environment myverbatim + #+BEGIN_EXAMPLE + This sentence is false. + #+END_EXAMPLE + Special blocks in LaTeX export .............................. @@ -11041,15 +11483,15 @@ In LaTeX back-end, special blocks become environments of the same name. Value of `:options' attribute will be appended as-is to that environment's opening string. For example: - #+BEGIN_ABSTRACT + #+BEGIN_abstract We demonstrate how to solve the Syracuse problem. - #+END_ABSTRACT + #+END_abstract #+ATTR_LATEX: :options [Proof of important theorem] - #+BEGIN_PROOF + #+BEGIN_proof ... Therefore, any even number greater than 2 is the sum of two primes. - #+END_PROOF + #+END_proof becomes @@ -11067,9 +11509,9 @@ attribute. It will override standard `#+CAPTION' value, if any. For example: #+ATTR_LATEX: :caption \MyCaption{HeadingA} - #+BEGIN_PROOF + #+BEGIN_proof ... - #+END_PROOF + #+END_proof Horizontal rules ................ @@ -11087,7 +11529,10 @@ respectively, `:width' and `:thickness' attributes: (2) Requires adding the `tabu' package to `org-latex-packages-alist'. - (3) In the case of TikZ (`http://sourceforge.net/projects/pgf/') + (3) Formerly, the value was `sidewaystable'. This is deprecated +since Org 8.3. + + (4) In the case of TikZ (`http://sourceforge.net/projects/pgf/') images, it will become an `\input' macro wrapped within a `tikzpicture' environment. @@ -11146,6 +11591,7 @@ specification'(2) and are compatible with LibreOffice 3.4. * Pre-requisites for ODT export:: What packages ODT exporter relies on * ODT export commands:: How to invoke ODT export +* ODT specific export settings:: Export settings for ODT * Extending ODT export:: How to produce `doc', `pdf' files * Applying custom styles:: How to apply custom styles to the output * Links in ODT export:: How links will be interpreted and formatted @@ -11165,7 +11611,7 @@ Version 1.2 (http://docs.oasis-open.org/office/v1.2/OpenDocument-v1.2.html)  -File: org, Node: Pre-requisites for ODT export, Next: ODT export commands, Prev: OpenDocument Text export, Up: OpenDocument Text export +File: org, Node: Pre-requisites for ODT export, Next: ODT export commands, Up: OpenDocument Text export 12.9.1 Pre-requisites for ODT export ------------------------------------ @@ -11175,14 +11621,11 @@ output. Check the availability of this program before proceeding further.  -File: org, Node: ODT export commands, Next: Extending ODT export, Prev: Pre-requisites for ODT export, Up: OpenDocument Text export +File: org, Node: ODT export commands, Next: ODT specific export settings, Prev: Pre-requisites for ODT export, Up: OpenDocument Text export 12.9.2 ODT export commands -------------------------- -Exporting to ODT -................ - `C-c C-e o o (`org-odt-export-to-odt')' Export as OpenDocument Text file. @@ -11211,9 +11654,34 @@ Exporting to ODT (2) To select the current subtree, use `C-c @'  -File: org, Node: Extending ODT export, Next: Applying custom styles, Prev: ODT export commands, Up: OpenDocument Text export +File: org, Node: ODT specific export settings, Next: Extending ODT export, Prev: ODT export commands, Up: OpenDocument Text export -12.9.3 Extending ODT export +12.9.3 ODT specific export settings +----------------------------------- + +The ODT exporter introduces a number of keywords, similar to the general +options settings described in *note Export settings::. + +`DESCRIPTION' + The document description. These are inserted as document + metadata. You can use several such keywords if the list is long. + +`KEYWORDS' + The keywords defining the contents of the document. These are + inserted as document metadata. You can use several such keywords + if the list is long. + +`ODT_STYLES_FILE' + The style file of the document (`org-odt-styles-file'). See *note + Applying custom styles:: for details. + +`SUBTITLE' + The document subtitle. + + +File: org, Node: Extending ODT export, Next: Applying custom styles, Prev: ODT specific export settings, Up: OpenDocument Text export + +12.9.4 Extending ODT export --------------------------- The ODT exporter can interface with a variety of document converters @@ -11229,8 +11697,8 @@ also use your own favorite converter or tweak the default settings of the `LibreOffice' and `unoconv' converters. *Note Configuring a document converter::. -12.9.3.1 Automatically exporting to other formats -................................................. +Automatically exporting to other formats +........................................ Very often, you will find yourself exporting to ODT format, only to immediately save the exported document to other formats like `doc', @@ -11240,8 +11708,8 @@ preferred output format by customizing the variable (*note Exporting to ODT: x-export-to-odt.) can be extended to export to a format that is of immediate interest to you. -12.9.3.2 Converting between document formats -............................................ +Converting between document formats +................................... There are many document converters in the wild which support conversion to and from various file formats, including, but not limited to the ODT @@ -11256,7 +11724,7 @@ following command.  File: org, Node: Applying custom styles, Next: Links in ODT export, Prev: Extending ODT export, Up: OpenDocument Text export -12.9.4 Applying custom styles +12.9.5 Applying custom styles ----------------------------- The ODT exporter ships with a set of OpenDocument styles (*note Working @@ -11267,8 +11735,8 @@ directly, or generate the required styles using an application like LibreOffice. The latter method is suitable for expert and non-expert users alike, and is described here. -12.9.4.1 Applying custom styles: the easy way -............................................. +Applying custom styles: the easy way +.................................... 1. Create a sample `example.org' file with the below settings and export it to ODT format. @@ -11296,8 +11764,8 @@ users alike, and is described here. #+ODT_STYLES_FILE: ("/path/to/file.ott" ("styles.xml" "image/hdr.png")) -12.9.4.2 Using third-party styles and templates -............................................... +Using third-party styles and templates +...................................... You can use third-party styles and templates for customizing your output. This will produce the desired output only if the template @@ -11309,7 +11777,7 @@ templates that are directly derived from the factory settings.  File: org, Node: Links in ODT export, Next: Tables in ODT export, Prev: Applying custom styles, Up: OpenDocument Text export -12.9.5 Links in ODT export +12.9.6 Links in ODT export -------------------------- ODT exporter creates native cross-references for internal links. It @@ -11326,7 +11794,7 @@ with a cross-reference and sequence number of the labeled entity.  File: org, Node: Tables in ODT export, Next: Images in ODT export, Prev: Links in ODT export, Up: OpenDocument Text export -12.9.6 Tables in ODT export +12.9.7 Tables in ODT export --------------------------- Export of native Org mode tables (*note Tables::) and simple `table.el' @@ -11376,7 +11844,7 @@ default weight being 1  File: org, Node: Images in ODT export, Next: Math formatting in ODT export, Prev: Tables in ODT export, Up: OpenDocument Text export -12.9.7 Images in ODT export +12.9.8 Images in ODT export --------------------------- Embedding images @@ -11447,7 +11915,7 @@ Anchoring of images ................... You can control the manner in which an image is anchored by setting the -`:anchor' property of it's `#+ATTR_ODT' line. You can specify one of +`:anchor' property of its `#+ATTR_ODT' line. You can specify one of the following three values for the `:anchor' property: `"as-char"', `"paragraph"' and `"page"'. @@ -11465,7 +11933,7 @@ Org files that has images using a Emacs batch script, then the use of  File: org, Node: Math formatting in ODT export, Next: Labels and captions in ODT export, Prev: Images in ODT export, Up: OpenDocument Text export -12.9.8 Math formatting in ODT export +12.9.9 Math formatting in ODT export ------------------------------------ The ODT exporter has special support for handling math. @@ -11476,10 +11944,10 @@ The ODT exporter has special support for handling math. * Working with MathML or OpenDocument formula files:: How to embed equations in native format  -File: org, Node: Working with LaTeX math snippets, Next: Working with MathML or OpenDocument formula files, Prev: Math formatting in ODT export, Up: Math formatting in ODT export +File: org, Node: Working with LaTeX math snippets, Next: Working with MathML or OpenDocument formula files, Up: Math formatting in ODT export -12.9.8.1 Working with LaTeX math snippets -......................................... +Working with LaTeX math snippets +................................ LaTeX math snippets (*note LaTeX fragments::) can be embedded in the ODT document in one of the following ways: @@ -11499,13 +11967,16 @@ document in one of the following ways: variables `org-latex-to-mathml-convert-command' and `org-latex-to-mathml-jar-file'. - If you prefer to use `MathToWeb'(1) as your converter, you can - configure the above variables as shown below. + To use MathToWeb(1) as your converter, you can configure the above + variables as (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") + To use LaTeXML(2) use + (setq org-latex-to-mathml-convert-command + "latexmlmath \"%i\" --presentationmathml=%o") You can use the following commands to quickly verify the reliability of the LaTeX-to-MathML converter. @@ -11537,13 +12008,15 @@ document in one of the following ways: ---------- Footnotes ---------- (1) See MathToWeb -(http://www.mathtoweb.com/cgi-bin/mathtoweb_home.pl) +(http://www.mathtoweb.com/cgi-bin/mathtoweb_home.pl). + + (2) See `http://dlmf.nist.gov/LaTeXML/'.  File: org, Node: Working with MathML or OpenDocument formula files, Prev: Working with LaTeX math snippets, Up: Math formatting in ODT export -12.9.8.2 Working with MathML or OpenDocument formula files -.......................................................... +Working with MathML or OpenDocument formula files +................................................. For various reasons, you may find embedding LaTeX math snippets in an ODT document less than reliable. In that case, you can embed a math @@ -11559,15 +12032,15 @@ formula (`.odf') file as shown below:  File: org, Node: Labels and captions in ODT export, Next: Literal examples in ODT export, Prev: Math formatting in ODT export, Up: OpenDocument Text export -12.9.9 Labels and captions in ODT export ----------------------------------------- +12.9.10 Labels and captions in ODT export +----------------------------------------- You can label and caption various category of objects--an inline image, a table, a LaTeX fragment or a Math formula--using `#+LABEL' and `#+CAPTION' lines. *Note Images and tables::. ODT exporter enumerates each labeled or captioned object of a given category separately. As a result, each such object is assigned a sequence number based on order -of it's appearance in the Org file. +of its appearance in the Org file. In the exported document, a user-provided caption is augmented with the category and sequence number. Consider the following inline image @@ -11597,7 +12070,7 @@ document.  File: org, Node: Literal examples in ODT export, Next: Advanced topics in ODT export, Prev: Labels and captions in ODT export, Up: OpenDocument Text export -12.9.10 Literal examples in ODT export +12.9.11 Literal examples in ODT export -------------------------------------- Export of literal examples (*note Literal examples::) with full @@ -11622,7 +12095,7 @@ levels for fontification to be turned on.  File: org, Node: Advanced topics in ODT export, Prev: Literal examples in ODT export, Up: OpenDocument Text export -12.9.11 Advanced topics in ODT export +12.9.12 Advanced topics in ODT export ------------------------------------- If you rely heavily on ODT export, you may want to exploit the full set @@ -11638,10 +12111,10 @@ that would be of interest to power users. * Validating OpenDocument XML:: How to debug corrupt OpenDocument files  -File: org, Node: Configuring a document converter, Next: Working with OpenDocument style files, Prev: Advanced topics in ODT export, Up: Advanced topics in ODT export +File: org, Node: Configuring a document converter, Next: Working with OpenDocument style files, Up: Advanced topics in ODT export -12.9.11.1 Configuring a document converter -.......................................... +Configuring a document converter +................................ The ODT exporter can work with popular converters with little or no extra configuration from your side. *Note Extending ODT export::. If @@ -11673,16 +12146,16 @@ would like to tweak the default converter settings, proceed as below.  File: org, Node: Working with OpenDocument style files, Next: Creating one-off styles, Prev: Configuring a document converter, Up: Advanced topics in ODT export -12.9.11.2 Working with OpenDocument style files -............................................... +Working with OpenDocument style files +..................................... This section explores the internals of the ODT exporter and the means by which it produces styled documents. Read this section if you are interested in exploring the automatic and custom OpenDocument styles used by the exporter. -Factory styles -.............. +a) Factory styles +................. The ODT exporter relies on two files for generating its output. These files are bundled with the distribution under the directory pointed to @@ -11712,8 +12185,8 @@ by the variable `org-odt-styles-dir'. The two files are: elements that control how various entities--tables, images, equations, etc.--are numbered. -Overriding factory styles -......................... +b) Overriding factory styles +............................ The following two variables control the location from which the ODT exporter picks up the custom styles and content template files. You can @@ -11756,8 +12229,8 @@ exporter.  File: org, Node: Creating one-off styles, Next: Customizing tables in ODT export, Prev: Working with OpenDocument style files, Up: Advanced topics in ODT export -12.9.11.3 Creating one-off styles -................................. +Creating one-off styles +....................... There are times when you would want one-off formatting in the exported document. You can achieve this by embedding raw OpenDocument XML in @@ -11815,8 +12288,8 @@ couple of examples.  File: org, Node: Customizing tables in ODT export, Next: Validating OpenDocument XML, Prev: Creating one-off styles, Up: Advanced topics in ODT export -12.9.11.4 Customizing tables in ODT export -.......................................... +Customizing tables in ODT export +................................ You can override the default formatting of the table by specifying a custom table style with the `#+ATTR_ODT' line. For a discussion on @@ -11825,11 +12298,8 @@ default formatting of tables *note Tables in ODT export::. This feature closely mimics the way table templates are defined in the OpenDocument-v1.2 specification.(1) -Custom table styles: an illustration -.................................... - -To have a quick preview of this feature, install the below setting and -export the table that follows: + To have a quick preview of this feature, install the below setting +and export the table that follows: (setq org-odt-table-styles (append org-odt-table-styles @@ -11840,7 +12310,7 @@ export the table that follows: ((use-first-row-styles . t) (use-last-row-styles . t)))))) - #+ATTR_ODT: :style "TableWithHeaderRowAndColumn" + #+ATTR_ODT: :style TableWithHeaderRowAndColumn | Name | Phone | Age | | Peter | 1234 | 17 | | Anna | 4321 | 25 | @@ -11854,10 +12324,7 @@ Template' in `OrgOdtContentTemplate.xml' (*note Factory styles: x-orgodtcontenttemplate-xml.). If you need additional templates you have to define these styles yourselves. -Custom table styles: the nitty-gritty -..................................... - -To use this feature proceed as follows: + To use this feature proceed as follows: 1. Create a table template(2) @@ -11960,8 +12427,8 @@ of the `' element in the OpenDocument-v1.2 specification  File: org, Node: Validating OpenDocument XML, Prev: Customizing tables in ODT export, Up: Advanced topics in ODT export -12.9.11.5 Validating OpenDocument XML -..................................... +Validating OpenDocument XML +........................... Occasionally, you will discover that the document created by the ODT exporter cannot be opened by your favorite application. One of the @@ -12018,6 +12485,7 @@ an Info file. * Menu: * Texinfo export commands:: How to invoke Texinfo export +* Texinfo specific export settings:: Export settings for Texinfo * Document preamble:: File header, title and copyright page * Headings and sectioning structure:: Building document structure * Indices:: Creating indices @@ -12026,7 +12494,7 @@ an Info file. * An example::  -File: org, Node: Texinfo export commands, Next: Document preamble, Prev: Texinfo export, Up: Texinfo export +File: org, Node: Texinfo export commands, Next: Texinfo specific export settings, Up: Texinfo export 12.11.1 Texinfo export commands ------------------------------- @@ -12045,17 +12513,59 @@ File: org, Node: Texinfo export commands, Next: Document preamble, Prev: Texi generate other formats, including DocBook.  -File: org, Node: Document preamble, Next: Headings and sectioning structure, Prev: Texinfo export commands, Up: Texinfo export +File: org, Node: Texinfo specific export settings, Next: Document preamble, Prev: Texinfo export commands, Up: Texinfo export + +12.11.2 Texinfo specific export settings +---------------------------------------- + +The Texinfo exporter introduces a number of keywords, similar to the +general options settings described in *note Export settings::. + +`SUBTITLE' + The document subtitle. + +`SUBAUTHOR' + The document subauthor. + +`TEXINFO_FILENAME' + The Texinfo filename. + +`TEXINFO_CLASS' + The class of the document (`org-texinfo-default-class'). This + must be a member of `org-texinfo-classes'. + +`TEXINFO_HEADER' + Arbitrary lines inserted at the end of the preamble. + +`TEXINFO_POST_HEADER' + Arbitrary lines inserted at the end of the preamble. + +`TEXINFO_DIR_CATEGORY' + The directory category of the document. + +`TEXINFO_DIR_TITLE' + The directory title of the document. + +`TEXINFO_DIR_DESC' + The directory description of the document. + +`TEXINFO_PRINTED_TITLE' + The printed title of the document. + + These keywords are treated in details in the following sections. + + +File: org, Node: Document preamble, Next: Headings and sectioning structure, Prev: Texinfo specific export settings, Up: Texinfo export -12.11.2 Document preamble +12.11.3 Document preamble ------------------------- When processing a document, `texinfo' back-end generates a minimal file header along with a title page, a copyright page, and a menu. You control the latter through the structure of the document (*note -Headings and sectioning structure::). Various keywords allow to tweak -the other parts. It is also possible to give directions to install the -document in the `Top' node. +Headings and sectioning structure::). Various keywords allow you to +tweak the other parts. It is also possible to give directions to +install the document in the `Top' node. File header ........... @@ -12094,7 +12604,7 @@ are also expected to be written in Texinfo code. #+SUBAUTHOR: John Doe #+TEXINFO_PRINTED_TITLE: This Long Title@inlinefmt{tex,@*} Is Broken in @TeX{} - Copying material is defined in a dedicated headline with a non-nil + Copying material is defined in a dedicated headline with a non-`nil' `:COPYING:' property. The contents are inserted within a `@copying' command at the beginning of the document whereas the heading itself does not appear in the structure of the document. @@ -12108,7 +12618,7 @@ does not appear in the structure of the document. This is a short example of a complete Texinfo file, version 1.0. - Copyright \copy 2014 Free Software Foundation, Inc. + Copyright \copy 2016 Free Software Foundation, Inc. The Top node ............ @@ -12131,7 +12641,7 @@ example would write an entry similar to Org's in the `Top' node.  File: org, Node: Headings and sectioning structure, Next: Indices, Prev: Document preamble, Up: Texinfo export -12.11.3 Headings and sectioning structure +12.11.4 Headings and sectioning structure ----------------------------------------- `texinfo' uses a pre-defined scheme, or class, to convert headlines into @@ -12147,7 +12657,7 @@ such keyword in the document. below a certain threshold (*note Export settings::), that headline becomes a list in Texinfo output. - As an exception, a headline with a non-nil `:APPENDIX:' property + As an exception, a headline with a non-`nil' `:APPENDIX:' property becomes an appendix, independently on its level and the class used. Each regular sectioning structure creates a menu entry, named after @@ -12164,7 +12674,7 @@ specify a description for the item in `:DESCRIPTION:' property. E.g.,  File: org, Node: Indices, Next: Quoting Texinfo code, Prev: Headings and sectioning structure, Up: Texinfo export -12.11.4 Indices +12.11.5 Indices --------------- Index entries are created using dedicated keywords. `texinfo' back-end @@ -12187,7 +12697,7 @@ and the index is inserted after its contents.  File: org, Node: Quoting Texinfo code, Next: Texinfo specific attributes, Prev: Indices, Up: Texinfo export -12.11.5 Quoting Texinfo code +12.11.6 Quoting Texinfo code ---------------------------- It is possible to insert raw Texinfo code using any of the following @@ -12206,12 +12716,12 @@ constructs  File: org, Node: Texinfo specific attributes, Next: An example, Prev: Quoting Texinfo code, Up: Texinfo export -12.11.6 Texinfo specific attributes +12.11.7 Texinfo specific attributes ----------------------------------- -`texinfo' back-end understands several attributes in plain lists and -tables. They must be specified using an `#+ATTR_TEXINFO' keyword, -written just above the list or table. +`texinfo' back-end understands several attributes in plain lists, tables +and images. They must be specified using an `#+ATTR_TEXINFO' keyword, +written just above the list, table or image. Plain lists ........... @@ -12238,6 +12748,17 @@ the line length, using `:columns' attribute. #+ATTR_TEXINFO: :columns .5 .5 | a cell | another cell | +Images +...... + +Images are links to files with a supported image extension and no +description. Image scaling is set with `:width' and `:height' +attributes. You can also use `:alt' to specify alternate text, as +Texinfo code. + + #+ATTR_TEXINFO: :width 1in :alt Alternate @i{text} + [[ridt.pdf]] + ---------- Footnotes ---------- (1) For more information, *note (texinfo)Two-column Tables::. @@ -12245,11 +12766,11 @@ the line length, using `:columns' attribute.  File: org, Node: An example, Prev: Texinfo specific attributes, Up: Texinfo export -12.11.7 An example +12.11.8 An example ------------------ -Here is a thorough example, taken from *note (texinfo)GNU Sample -Texts::. +Here is a thorough example. *note (texinfo)GNU Sample Texts:: for an +equivalent Texinfo code. #+MACRO: version 2.0 #+MACRO: updated last updated 4 March 2014 @@ -12268,7 +12789,7 @@ Texts::. #+TEXINFO_DIR_DESC: Invoking sample #+TEXINFO_PRINTED_TITLE: GNU Sample - #+SUBTITLE: for version 2.0, last updated 4 March 2014 + #+SUBTITLE: for version {{{version}}}, {{{updated}}} * Copying :PROPERTIES: @@ -12389,7 +12910,7 @@ ones: To activate these export back-end, customize `org-export-backends' or load them directly with e.g., `(require 'ox-man)'. This will add new -keys in the export dispatcher (*note The Export Dispatcher::). +keys in the export dispatcher (*note The export dispatcher::). See the comment section of these files for more information on how to use them. @@ -12461,40 +12982,39 @@ functions within a given filter type are called in turn on the string produced. The string returned by the last function will be the one used in the final output. - There are filters sets for each type of element or object, for plain + There are filter sets for each type of element or object, for plain text, for the parse tree, for the export options and for the final output. They are all named after the same scheme: `org-export-filter-TYPE-functions', where `TYPE' is the type targeted by the filter. Valid types are: -bold babel-call center-block -clock code comment -comment-block diary-sexp drawer -dynamic-block entity example-block -export-block export-snippet final-output -fixed-width footnote-definition footnote-reference -headline horizontal-rule inline-babel-call -inline-src-block inlinetask italic -item keyword latex-environment -latex-fragment line-break link -node-property options paragraph -parse-tree plain-list plain-text -planning property-drawer quote-block -quote-section radio-target section -special-block src-block statistics-cookie -strike-through subscript superscript -table table-cell table-row -target timestamp underline -verbatim verse-block +body bold babel-call +center-block clock code +diary-sexp drawer dynamic-block +entity example-block export-block +export-snippet final-output fixed-width +footnote-definition footnote-reference headline +horizontal-rule inline-babel-call inline-src-block +inlinetask italic item +keyword latex-environment latex-fragment +line-break link node-property +options paragraph parse-tree +plain-list plain-text planning +property-drawer quote-block radio-target +section special-block src-block +statistics-cookie strike-through subscript +superscript table table-cell +table-row target timestamp +underline verbatim verse-block For example, the following snippet allows me to use non-breaking spaces in the Org buffer and get them translated into LaTeX without using the `\nbsp' macro (where `_' stands for the non-breaking space): (defun my-latex-filter-nobreaks (text backend info) - "Ensure \" \" are properly handled in LaTeX export." + "Ensure \"_\" are properly handled in LaTeX export." (when (org-export-derived-backend-p backend 'latex) - (replace-regexp-in-string " " "~" text))) + (replace-regexp-in-string "_" "~" text))) (add-to-list 'org-export-filter-plain-text-functions 'my-latex-filter-nobreaks) @@ -12506,12 +13026,31 @@ Note the use of `org-export-derived-backend-p', which ensures that the filter will only be applied when using `latex' back-end or any other back-end derived from it (e.g., `beamer'). +Defining filters for individual files +------------------------------------- + +You can customize the export for just a specific file by binding export +filter variables using `#+BIND'. Here is an example where we introduce +two filters, one to remove brackets from time stamps, and one to +entirely remove any strike-through text. The functions doing the +filtering are defined in an src block that allows the filter function +definitions to exist in the file itself and ensures that the functions +will be there when needed. + + #+BIND: org-export-filter-timestamp-functions (tmp-f-timestamp) + #+BIND: org-export-filter-strike-through-functions (tmp-f-strike-through) + #+begin_src emacs-lisp :exports results :results none + (defun tmp-f-timestamp (s backend info) + (replace-regexp-in-string "&[lg]t;\\|[][]" "" s)) + (defun tmp-f-strike-through (s backend info) "") + #+end_src + Extending an existing back-end ------------------------------ This is obviously the most powerful customization, since the changes happen at the parser level. Indeed, some export back-ends are built as -extensions of other ones (e.g. Markdown back-end an extension of HTML +extensions of other ones (e.g., Markdown back-end an extension of HTML back-end). Extending a back-end means that if an element type is not transcoded @@ -12557,7 +13096,7 @@ to use the new back-end is calling the following from an Org buffer: install it in the export dispatcher menu, and so on.  -File: org, Node: Publishing, Next: Working With Source Code, Prev: Exporting, Up: Top +File: org, Node: Publishing, Next: Working with source code, Prev: Exporting, Up: Top 13 Publishing ************* @@ -12582,7 +13121,7 @@ server. * Triggering publication:: Publication commands  -File: org, Node: Configuration, Next: Uploading files, Prev: Publishing, Up: Publishing +File: org, Node: Configuration, Next: Uploading files, Up: Publishing 13.1 Configuration ================== @@ -12602,7 +13141,7 @@ and many other properties of a project. * Generating an index:: An index that reaches across pages  -File: org, Node: Project alist, Next: Sources and destinations, Prev: Configuration, Up: Configuration +File: org, Node: Project alist, Next: Sources and destinations, Up: Configuration 13.1.1 The variable `org-publish-project-alist' ----------------------------------------------- @@ -12723,65 +13262,215 @@ File: org, Node: Publishing options, Next: Publishing links, Prev: Publishing 13.1.5 Options for the exporters -------------------------------- -The property list can be used to set many export options for the -exporters. In most cases, these properties correspond to user -variables in Org. The first table below lists these properties along -with the variable they belong to. The second table list HTML specific -properties. See the documentation string of these options for details. - -`:archived-trees' `org-export-with-archived-trees' -`:exclude-tags' `org-export-exclude-tags' -`:headline-levels' `org-export-headline-levels' -`:language' `org-export-default-language' -`:preserve-breaks' `org-export-preserve-breaks' -`:section-numbers' `org-export-with-section-numbers' -`:select-tags' `org-export-select-tags' -`:with-author' `org-export-with-author' -`:with-creator' `org-export-with-creator' -`:with-drawers' `org-export-with-drawers' -`:with-email' `org-export-with-email' -`:with-emphasize' `org-export-with-emphasize' -`:with-fixed-width' `org-export-with-fixed-width' -`:with-footnotes' `org-export-with-footnotes' -`:with-latex' `org-export-with-latex' -`:with-planning' `org-export-with-planning' -`:with-priority' `org-export-with-priority' -`:with-special-strings' `org-export-with-special-strings' -`:with-sub-superscript' `org-export-with-sub-superscripts' -`:with-tables' `org-export-with-tables' -`:with-tags' `org-export-with-tags' -`:with-tasks' `org-export-with-tasks' -`:with-timestamps' `org-export-with-timestamps' -`:with-toc' `org-export-with-toc' -`:with-todo-keywords' `org-export-with-todo-keywords' - -`:html-doctype' `org-html-doctype' -`:html-container' `org-html-container-element' -`:html-html5-fancy' `org-html-html5-fancy' -`:html-xml-declaration' `org-html-xml-declaration' -`:html-link-up' `org-html-link-up' -`:html-link-home' `org-html-link-home' -`:html-link-org-as-html'`org-html-link-org-files-as-html' -`:html-link-use-abs-url'`org-html-link-use-abs-url' -`:html-head' `org-html-head' -`:html-head-extra' `org-html-head-extra' -`:html-inline-images' `org-html-inline-images' -`:html-extension' `org-html-extension' -`:html-preamble' `org-html-preamble' -`:html-postamble' `org-html-postamble' -`:html-table-attributes'`org-html-table-default-attributes' -`:html-table-row-tags' `org-html-table-row-tags' -`:html-head-include-default-style'`org-html-head-include-default-style' -`:html-head-include-scripts'`org-html-head-include-scripts' - - Most of the `org-export-with-*' variables have the same effect in -each exporter. +The property list can be used to set export options during the +publishing process. In most cases, these properties correspond to user +variables in Org. While some properties are available for all export +back-ends, most of them are back-end specific. The following sections +list properties along with the variable they belong to. See the +documentation string of these options for details. When a property is given a value in `org-publish-project-alist', its setting overrides the value of the corresponding user variable (if any) during publishing. Options set within a file (*note Export settings::), however, override everything. +Generic properties +.................. + +`:archived-trees' `org-export-with-archived-trees' +`:exclude-tags' `org-export-exclude-tags' +`:headline-levels' `org-export-headline-levels' +`:language' `org-export-default-language' +`:preserve-breaks' `org-export-preserve-breaks' +`:section-numbers' `org-export-with-section-numbers' +`:select-tags' `org-export-select-tags' +`:with-author' `org-export-with-author' +`:with-creator' `org-export-with-creator' +`:with-date' `org-export-with-date' +`:with-drawers' `org-export-with-drawers' +`:with-email' `org-export-with-email' +`:with-emphasize' `org-export-with-emphasize' +`:with-fixed-width' `org-export-with-fixed-width' +`:with-footnotes' `org-export-with-footnotes' +`:with-latex' `org-export-with-latex' +`:with-planning' `org-export-with-planning' +`:with-priority' `org-export-with-priority' +`:with-properties' `org-export-with-properties' +`:with-special-strings' `org-export-with-special-strings' +`:with-sub-superscript' `org-export-with-sub-superscripts' +`:with-tables' `org-export-with-tables' +`:with-tags' `org-export-with-tags' +`:with-tasks' `org-export-with-tasks' +`:with-timestamps' `org-export-with-timestamps' +`:with-title' `org-export-with-title' +`:with-toc' `org-export-with-toc' +`:with-todo-keywords' `org-export-with-todo-keywords' + +ASCII specific properties +......................... + +`:ascii-bullets' `org-ascii-bullets' +`:ascii-caption-above' `org-ascii-caption-above' +`:ascii-charset' `org-ascii-charset' +`:ascii-global-margin' `org-ascii-global-margin' +`:ascii-format-drawer-function' `org-ascii-format-drawer-function' +`:ascii-format-inlinetask-function' `org-ascii-format-inlinetask-function' +`:ascii-headline-spacing' `org-ascii-headline-spacing' +`:ascii-indented-line-width' `org-ascii-indented-line-width' +`:ascii-inlinetask-width' `org-ascii-inlinetask-width' +`:ascii-inner-margin' `org-ascii-inner-margin' +`:ascii-links-to-notes' `org-ascii-links-to-notes' +`:ascii-list-margin' `org-ascii-list-margin' +`:ascii-paragraph-spacing' `org-ascii-paragraph-spacing' +`:ascii-quote-margin' `org-ascii-quote-margin' +`:ascii-table-keep-all-vertical-lines' `org-ascii-table-keep-all-vertical-lines' +`:ascii-table-use-ascii-art' `org-ascii-table-use-ascii-art' +`:ascii-table-widen-columns' `org-ascii-table-widen-columns' +`:ascii-text-width' `org-ascii-text-width' +`:ascii-underline' `org-ascii-underline' +`:ascii-verbatim-format' `org-ascii-verbatim-format' + +Beamer specific properties +.......................... + +`:beamer-theme' `org-beamer-theme' +`:beamer-column-view-format' `org-beamer-column-view-format' +`:beamer-environments-extra' `org-beamer-environments-extra' +`:beamer-frame-default-options' `org-beamer-frame-default-options' +`:beamer-outline-frame-options' `org-beamer-outline-frame-options' +`:beamer-outline-frame-title' `org-beamer-outline-frame-title' +`:beamer-subtitle-format' `org-beamer-subtitle-format' + +HTML specific properties +........................ + +`:html-allow-name-attribute-in-anchors' `org-html-allow-name-attribute-in-anchors' +`:html-checkbox-type' `org-html-checkbox-type' +`:html-container' `org-html-container-element' +`:html-divs' `org-html-divs' +`:html-doctype' `org-html-doctype' +`:html-extension' `org-html-extension' +`:html-footnote-format' `org-html-footnote-format' +`:html-footnote-separator' `org-html-footnote-separator' +`:html-footnotes-section' `org-html-footnotes-section' +`:html-format-drawer-function' `org-html-format-drawer-function' +`:html-format-headline-function' `org-html-format-headline-function' +`:html-format-inlinetask-function' `org-html-format-inlinetask-function' +`:html-head-extra' `org-html-head-extra' +`:html-head-include-default-style' `org-html-head-include-default-style' +`:html-head-include-scripts' `org-html-head-include-scripts' +`:html-head' `org-html-head' +`:html-home/up-format' `org-html-home/up-format' +`:html-html5-fancy' `org-html-html5-fancy' +`:html-indent' `org-html-indent' +`:html-infojs-options' `org-html-infojs-options' +`:html-infojs-template' `org-html-infojs-template' +`:html-inline-image-rules' `org-html-inline-image-rules' +`:html-inline-images' `org-html-inline-images' +`:html-link-home' `org-html-link-home' +`:html-link-org-files-as-html' `org-html-link-org-files-as-html' +`:html-link-up' `org-html-link-up' +`:html-link-use-abs-url' `org-html-link-use-abs-url' +`:html-mathjax-options' `org-html-mathjax-options' +`:html-mathjax-template' `org-html-mathjax-template' +`:html-metadata-timestamp-format' `org-html-metadata-timestamp-format' +`:html-postamble-format' `org-html-postamble-format' +`:html-postamble' `org-html-postamble' +`:html-preamble-format' `org-html-preamble-format' +`:html-preamble' `org-html-preamble' +`:html-table-align-individual-fields' `org-html-table-align-individual-fields' +`:html-table-attributes' `org-html-table-default-attributes' +`:html-table-caption-above' `org-html-table-caption-above' +`:html-table-data-tags' `org-html-table-data-tags' +`:html-table-header-tags' `org-html-table-header-tags' +`:html-table-row-tags' `org-html-table-row-tags' +`:html-table-use-header-tags-for-first-column' `org-html-table-use-header-tags-for-first-column' +`:html-tag-class-prefix' `org-html-tag-class-prefix' +`:html-text-markup-alist' `org-html-text-markup-alist' +`:html-todo-kwd-class-prefix' `org-html-todo-kwd-class-prefix' +`:html-toplevel-hlevel' `org-html-toplevel-hlevel' +`:html-use-infojs' `org-html-use-infojs' +`:html-validation-link' `org-html-validation-link' +`:html-viewport' `org-html-viewport' +`:html-xml-declaration' `org-html-xml-declaration' + +LaTeX specific properties +......................... + +`:latex-active-timestamp-format' `org-latex-active-timestamp-format' +`:latex-caption-above' `org-latex-caption-above' +`:latex-classes' `org-latex-classes' +`:latex-class' `org-latex-default-class' +`:latex-default-figure-position' `org-latex-default-figure-position' +`:latex-default-table-environment' `org-latex-default-table-environment' +`:latex-default-table-mode' `org-latex-default-table-mode' +`:latex-diary-timestamp-format' `org-latex-diary-timestamp-format' +`:latex-footnote-separator' `org-latex-footnote-separator' +`:latex-format-drawer-function' `org-latex-format-drawer-function' +`:latex-format-headline-function' `org-latex-format-headline-function' +`:latex-format-inlinetask-function' `org-latex-format-inlinetask-function' +`:latex-hyperref-template' `org-latex-hyperref-template' +`:latex-image-default-height' `org-latex-image-default-height' +`:latex-image-default-option' `org-latex-image-default-option' +`:latex-image-default-width' `org-latex-image-default-width' +`:latex-inactive-timestamp-format' `org-latex-inactive-timestamp-format' +`:latex-inline-image-rules' `org-latex-inline-image-rules' +`:latex-link-with-unknown-path-format' `org-latex-link-with-unknown-path-format' +`:latex-listings-langs' `org-latex-listings-langs' +`:latex-listings-options' `org-latex-listings-options' +`:latex-listings' `org-latex-listings' +`:latex-minted-langs' `org-latex-minted-langs' +`:latex-minted-options' `org-latex-minted-options' +`:latex-prefer-user-labels' `org-latex-prefer-user-labels' +`:latex-subtitle-format' `org-latex-subtitle-format' +`:latex-subtitle-separate' `org-latex-subtitle-separate' +`:latex-table-scientific-notation' `org-latex-table-scientific-notation' +`:latex-tables-booktabs' `org-latex-tables-booktabs' +`:latex-tables-centered' `org-latex-tables-centered' +`:latex-text-markup-alist' `org-latex-text-markup-alist' +`:latex-title-command' `org-latex-title-command' +`:latex-toc-command' `org-latex-toc-command' + +Markdown specific properties +............................ + +`:md-headline-style' `org-md-headline-style' + +ODT specific properties +....................... + +`:odt-content-template-file' `org-odt-content-template-file' +`:odt-display-outline-level' `org-odt-display-outline-level' +`:odt-fontify-srcblocks' `org-odt-fontify-srcblocks' +`:odt-format-drawer-function' `org-odt-format-drawer-function' +`:odt-format-headline-function' `org-odt-format-headline-function' +`:odt-format-inlinetask-function' `org-odt-format-inlinetask-function' +`:odt-inline-formula-rules' `org-odt-inline-formula-rules' +`:odt-inline-image-rules' `org-odt-inline-image-rules' +`:odt-pixels-per-inch' `org-odt-pixels-per-inch' +`:odt-styles-file' `org-odt-styles-file' +`:odt-table-styles' `org-odt-table-styles' +`:odt-use-date-fields' `org-odt-use-date-fields' + +Texinfo specific properties +........................... + +`:texinfo-active-timestamp-format' `org-texinfo-active-timestamp-format' +`:texinfo-classes' `org-texinfo-classes' +`:texinfo-class' `org-texinfo-default-class' +`:texinfo-def-table-markup' `org-texinfo-def-table-markup' +`:texinfo-diary-timestamp-format' `org-texinfo-diary-timestamp-format' +`:texinfo-filename' `org-texinfo-filename' +`:texinfo-format-drawer-function' `org-texinfo-format-drawer-function' +`:texinfo-format-headline-function' `org-texinfo-format-headline-function' +`:texinfo-format-inlinetask-function' `org-texinfo-format-inlinetask-function' +`:texinfo-inactive-timestamp-format' `org-texinfo-inactive-timestamp-format' +`:texinfo-link-with-unknown-path-format' `org-texinfo-link-with-unknown-path-format' +`:texinfo-node-description-column' `org-texinfo-node-description-column' +`:texinfo-table-scientific-notation' `org-texinfo-table-scientific-notation' +`:texinfo-tables-verbatim' `org-texinfo-tables-verbatim' +`:texinfo-text-markup-alist' `org-texinfo-text-markup-alist' +  File: org, Node: Publishing links, Next: Sitemap, Prev: Publishing options, Up: Configuration @@ -12927,7 +13616,7 @@ complex, with a multi-component project. * Complex example:: A multi-component publishing example  -File: org, Node: Simple example, Next: Complex example, Prev: Sample configuration, Up: Sample configuration +File: org, Node: Simple example, Next: Complex example, Up: Sample configuration 13.3.1 Example: simple publishing configuration ----------------------------------------------- @@ -13021,7 +13710,7 @@ the commands above, or by customizing the variable if files include other files via `#+SETUPFILE:' or `#+INCLUDE:'.  -File: org, Node: Working With Source Code, Next: Miscellaneous, Prev: Publishing, Up: Top +File: org, Node: Working with source code, Next: Miscellaneous, Prev: Publishing, Up: Top 14 Working with source code *************************** @@ -13062,7 +13751,7 @@ facilities. * Batch execution:: Call functions from the command line  -File: org, Node: Structure of code blocks, Next: Editing source code, Prev: Working With Source Code, Up: Working With Source Code +File: org, Node: Structure of code blocks, Next: Editing source code, Up: Working with source code 14.1 Structure of code blocks ============================= @@ -13118,10 +13807,10 @@ block. Live code blocks require that a language be specified on the ---------- Footnotes ---------- (1) Note that `src' blocks may be inserted using Org mode's *note -Easy Templates:: system +Easy templates:: system  -File: org, Node: Editing source code, Next: Exporting code blocks, Prev: Structure of code blocks, Up: Working With Source Code +File: org, Node: Editing source code, Next: Exporting code blocks, Prev: Structure of code blocks, Up: Working with source code 14.2 Editing source code ======================== @@ -13154,7 +13843,7 @@ further configuration options. By default, the value is `nil', which means that when code blocks are evaluated during export or tangled, they are re-inserted into the code block, which may replace sequences of spaces with tab - characters. When non-nil, whitespace in code blocks will be + characters. When non-`nil', whitespace in code blocks will be preserved during export or tangling, exactly as it appears. This variable is especially useful for tangling languages such as Python, in which whitespace indentation in the output is critical. @@ -13167,7 +13856,7 @@ further configuration options. the variable `org-src-fontify-natively'.  -File: org, Node: Exporting code blocks, Next: Extracting source code, Prev: Editing source code, Up: Working With Source Code +File: org, Node: Exporting code blocks, Next: Extracting source code, Prev: Editing source code, Up: Working with source code 14.3 Exporting code blocks ========================== @@ -13177,10 +13866,12 @@ code block evaluation, _both_ the code and the results of code block evaluation, or _none_. For most languages, the default exports code. However, for some languages (e.g., `ditaa') the default exports the results of code block evaluation. For information on exporting code -block bodies, see *note Literal examples::. +block bodies, see *note Literal examples::. For information on +exporting parts of Org documents, see *note Exporting::. The `:exports' header argument can be used to specify export -behavior: +behavior (note that these arguments are only relevant for code blocks, +not inline code): Header arguments: ................. @@ -13190,11 +13881,12 @@ Header arguments: exported, as described in *note Literal examples::. `:exports results' - The code block will be evaluated and the results will be placed in - the Org mode buffer for export, either updating previous results - of the code block located anywhere in the buffer or, if no - previous results exist, placing the results immediately after the - code block. The body of the code block will not be exported. + The code block will be evaluated each time to buffer is exported, + and the results will be placed in the Org mode buffer for export, + either updating previous results of the code block located + anywhere in the buffer or, if no previous results exist, placing + the results immediately after the code block. The body of the + code block will not be exported. `:exports both' Both the code block and its results will be exported. @@ -13208,14 +13900,18 @@ ensure that no code blocks are evaluated as part of the export process. This can be useful in situations where potentially untrusted Org mode files are exported in an automated fashion, for example when Org mode is used as the markup language for a wiki. It is also possible to set -this variable to `'inline-only'. In that case, only inline code blocks +this variable to `inline-only'. In that case, only inline code blocks will be evaluated, in order to insert their results. Non-inline code blocks are assumed to have their results already inserted in the buffer by manual evaluation. This setting is useful to avoid expensive recalculations during export, not to provide security. + Code blocks in commented subtrees (*note Comment lines::) are never +evaluated on export. However, code blocks in subtrees excluded from +export (*note Export settings::) may be evaluated on export. +  -File: org, Node: Extracting source code, Next: Evaluating code blocks, Prev: Exporting code blocks, Up: Working With Source Code +File: org, Node: Extracting source code, Next: Evaluating code blocks, Prev: Exporting code blocks, Up: Working with source code 14.4 Extracting source code =========================== @@ -13272,12 +13968,12 @@ from which the code originated. from code to Org-mode functionality. Two header arguments are required for jumping to work, first the `padline' (*note padline::) option must be set to true (the default setting), second the `comments' (*note -comments::) header argument must be set to `links', which will insert +comments::) header argument must be set to `link', which will insert comments into the source code buffer which point back to the original Org-mode file.  -File: org, Node: Evaluating code blocks, Next: Library of Babel, Prev: Extracting source code, Up: Working With Source Code +File: org, Node: Evaluating code blocks, Next: Library of Babel, Prev: Extracting source code, Up: Working with source code 14.5 Evaluating code blocks =========================== @@ -13290,21 +13986,23 @@ block. The default value of `#+RESULTS' can be changed with the customizable variable `org-babel-results-keyword'. By default, the evaluation facility is only enabled for Lisp code -blocks specified as `emacs-lisp'. However, source code blocks in many -languages can be evaluated within Org mode (see *note Languages:: for a -list of supported languages and *note Structure of code blocks:: for -information on the syntax used to define a code block). +blocks specified as `emacs-lisp'. See *note Languages:: to enable other +supported languages. See *note Structure of code blocks:: for +information on the syntax used to define a code block. There are a number of ways to evaluate code blocks. The simplest is to press `C-c C-c' or `C-c C-v e' with the point on a code block(2). This will call the `org-babel-execute-src-block' function to evaluate -the block and insert its results into the Org mode buffer. +the block and insert its results into the Org mode buffer. It is also possible to evaluate named code blocks from anywhere in -an Org mode buffer or an Org mode table. Live code blocks located in -the current Org mode buffer or in the "Library of Babel" (see *note -Library of Babel::) can be executed. Named code blocks can be executed -with a separate `#+CALL:' line or inline within a block of text. +an Org mode buffer or an Org mode table. These named code blocks can +be located in the current Org mode buffer or in the "Library of Babel" +(*note Library of Babel::). Named code blocks can be evaluated with a +separate `#+CALL:' line or inline within a block of text. In both +cases the result is wrapped according to the value of +`org-babel-inline-result-wrap', which by default is `"=%s="' for markup +that produces verbatim text. The syntax of the `#+CALL:' line is @@ -13359,7 +14057,7 @@ evaluation security::. remove code evaluation from the `C-c C-c' key binding.  -File: org, Node: Library of Babel, Next: Languages, Prev: Evaluating code blocks, Up: Working With Source Code +File: org, Node: Library of Babel, Next: Languages, Prev: Evaluating code blocks, Up: Working with source code 14.6 Library of Babel ===================== @@ -13371,8 +14069,7 @@ be called remotely as if they were in the current Org mode buffer (see code block evaluation). The central repository of code blocks in the "Library of Babel" is -housed in an Org mode file located in the `contrib' directory of Org -mode. +housed in an Org mode file located in the `doc' directory of Org mode. Users can add code blocks they believe to be generally useful to their "Library of Babel." The code blocks can be stored in any Org @@ -13383,32 +14080,35 @@ mode file and then loaded into the library with `org-babel-lob-ingest'. `C-c C-v i'.  -File: org, Node: Languages, Next: Header arguments, Prev: Library of Babel, Up: Working With Source Code +File: org, Node: Languages, Next: Header arguments, Prev: Library of Babel, Up: Working with source code 14.7 Languages ============== Code blocks in the following languages are supported. -Language Identifier Language Identifier -Asymptote asymptote Awk awk -Emacs Calc calc C C -C++ C++ Clojure clojure -CSS css ditaa ditaa -Graphviz dot Emacs Lisp emacs-lisp -gnuplot gnuplot Haskell haskell -Java java -Javascript js LaTeX latex -Ledger ledger Lisp lisp -Lilypond lilypond MATLAB matlab -Mscgen mscgen Objective Caml ocaml -Octave octave Org mode org -Oz oz Perl perl -Plantuml plantuml Python python -R R Ruby ruby -Sass sass Scheme scheme -GNU Screen screen shell sh -SQL sql SQLite sqlite +Language Identifier Language Identifier +---------------------------------------------------------------------------- +Asymptote asymptote Awk awk +C C C++ C++ +Clojure clojure CSS css +D d ditaa ditaa +Graphviz dot Emacs Calc calc +Emacs Lisp emacs-lisp Fortran fortran +gnuplot gnuplot Haskell haskell +Java java Javascript js +LaTeX latex Ledger ledger +Lisp lisp Lilypond lilypond +MATLAB matlab Mscgen mscgen +Objective Caml ocaml Octave octave +Org mode org Oz oz +Perl perl Plantuml plantuml +Processing.js processing Python python +R R Ruby ruby +Sass sass Scheme scheme +GNU Screen screen Sed sed +shell sh SQL sql +SQLite sqlite Language-specific documentation is available for some languages. If available, it can be found at @@ -13419,8 +14119,8 @@ enabled for evaluation (by default only `emacs-lisp' is enabled). This variable can be set using the customization interface or by adding code like the following to your emacs configuration. - The following disables `emacs-lisp' evaluation and enables - evaluation of `R' code blocks. + The following disables `emacs-lisp' evaluation and enables +evaluation of `R' code blocks. (org-babel-do-load-languages 'org-babel-load-languages @@ -13430,12 +14130,12 @@ like the following to your emacs configuration. It is also possible to enable support for a language by loading the related elisp file with `require'. - The following adds support for evaluating `clojure' code blocks. + The following adds support for evaluating `clojure' code blocks. (require 'ob-clojure)  -File: org, Node: Header arguments, Next: Results of evaluation, Prev: Languages, Up: Working With Source Code +File: org, Node: Header arguments, Next: Results of evaluation, Prev: Languages, Up: Working with source code 14.8 Header arguments ===================== @@ -13450,7 +14150,7 @@ describes each header argument in detail. * Specific header arguments:: List of header arguments  -File: org, Node: Using header arguments, Next: Specific header arguments, Prev: Header arguments, Up: Header arguments +File: org, Node: Using header arguments, Next: Specific header arguments, Up: Header arguments 14.8.1 Using header arguments ----------------------------- @@ -13472,7 +14172,7 @@ specified at lower priority. * Header arguments in function calls:: The most specific level  -File: org, Node: System-wide header arguments, Next: Language-specific header arguments, Prev: Using header arguments, Up: Using header arguments +File: org, Node: System-wide header arguments, Next: Language-specific header arguments, Up: Using header arguments System-wide header arguments ............................ @@ -13669,6 +14369,8 @@ defined: be collected and handled * file:: Specify a path for file output * file-desc:: Specify a description for file results +* file-ext:: Specify an extension for file output +* output-dir:: Specify a directory to write file output to * dir:: Specify the default (possibly remote) directory for code block execution * exports:: Export code and/or results @@ -13702,7 +14404,7 @@ defined: basis, see *note Languages::.  -File: org, Node: var, Next: results, Prev: Specific header arguments, Up: Specific header arguments +File: org, Node: var, Next: results, Up: Specific header arguments 14.8.2.1 `:var' ............... @@ -14081,7 +14783,7 @@ element of the list should be the path to a file and the second a description for the link.  -File: org, Node: file-desc, Next: dir, Prev: file, Up: Specific header arguments +File: org, Node: file-desc, Next: file-ext, Prev: file, Up: Specific header arguments 14.8.2.4 `:file-desc' ..................... @@ -14093,9 +14795,36 @@ is given with no value the link path will be placed in both the "link" and the "description" portion of the Org mode link.  -File: org, Node: dir, Next: exports, Prev: file-desc, Up: Specific header arguments +File: org, Node: file-ext, Next: output-dir, Prev: file-desc, Up: Specific header arguments + +14.8.2.5 `:file-ext' +.................... + +The value of the `:file-ext' header argument is used to provide an +extension to write the file output to. It is combined with the +`#+NAME:' of the source block and the value of the *note output-dir:: +header argument to generate a complete file name. + + This header arg will be overridden by `:file', and thus has no effect +when the latter is specified. + + +File: org, Node: output-dir, Next: dir, Prev: file-ext, Up: Specific header arguments + +14.8.2.6 `:output-dir' +...................... + +The value of the `:output-dir' header argument is used to provide a +directory to write the file output to. It may specify an absolute +directory (beginning with `/') or a relative directory (without `/'). +It can be combined with the `#+NAME:' of the source block and the value +of the *note file-ext:: header argument to generate a complete file +name, or used along with a *note file:: header arg. -14.8.2.5 `:dir' and remote execution + +File: org, Node: dir, Next: exports, Prev: output-dir, Up: Specific header arguments + +14.8.2.7 `:dir' and remote execution .................................... While the `:file' header argument can be used to specify the path to the @@ -14165,11 +14894,12 @@ Further points  File: org, Node: exports, Next: tangle, Prev: dir, Up: Specific header arguments -14.8.2.6 `:exports' +14.8.2.8 `:exports' ................... The `:exports' header argument specifies what should be included in HTML -or LaTeX exports of the Org mode file. +or LaTeX exports of the Org mode file. Note that the `:exports' option +is only relevant for code blocks, not inline code. * `code' The default. The body of code is included into the exported file. E.g., `:exports code'. @@ -14186,7 +14916,7 @@ or LaTeX exports of the Org mode file.  File: org, Node: tangle, Next: mkdirp, Prev: exports, Up: Specific header arguments -14.8.2.7 `:tangle' +14.8.2.9 `:tangle' .................. The `:tangle' header argument specifies whether or not the code block @@ -14207,8 +14937,8 @@ should be included in tangled extraction of source code files.  File: org, Node: mkdirp, Next: comments, Prev: tangle, Up: Specific header arguments -14.8.2.8 `:mkdirp' -.................. +14.8.2.10 `:mkdirp' +................... The `:mkdirp' header argument can be used to create parent directories of tangled files when missing. This can be set to `yes' to enable @@ -14217,8 +14947,8 @@ directory creation or to `no' to inhibit directory creation.  File: org, Node: comments, Next: padline, Prev: mkdirp, Up: Specific header arguments -14.8.2.9 `:comments' -.................... +14.8.2.11 `:comments' +..................... By default code blocks are tangled to source-code files without any insertion of comments beyond those which may already exist in the body @@ -14246,7 +14976,7 @@ code file.  File: org, Node: padline, Next: no-expand, Prev: comments, Up: Specific header arguments -14.8.2.10 `:padline' +14.8.2.12 `:padline' .................... Control in insertion of padding lines around code block bodies in @@ -14262,7 +14992,7 @@ following arguments are accepted.  File: org, Node: no-expand, Next: session, Prev: padline, Up: Specific header arguments -14.8.2.11 `:no-expand' +14.8.2.13 `:no-expand' ...................... By default, code blocks are expanded with `org-babel-expand-src-block' @@ -14270,26 +15000,38 @@ during tangling. This has the effect of assigning values to variables specified with `:var' (see *note var::), and of replacing "noweb" references (see *note Noweb reference syntax::) with their targets. The `:no-expand' header argument can be used to turn off this behavior. +Note: The `:no-expand' header argument has no impact on export, i.e. +code blocks will irrespective of this header argument expanded for +execution.  File: org, Node: session, Next: noweb, Prev: no-expand, Up: Specific header arguments -14.8.2.12 `:session' +14.8.2.14 `:session' .................... -The `:session' header argument starts a session for an interpreted -language where state is preserved. +The `:session' header argument starts a (possibly named) session for an +interpreted language where the interpreter’s state is preserved. All +code blocks sharing the same name are exectuted by the same interpreter +process. By default, a session is not started. + + * `none' The default. Each block is evaluated in its own + interpreter process, which is terminated after the evaluation. - By default, a session is not started. + * `other' Any other string passed to the `:session' header argument + will give the session a name. For example, `:session mysession'. + If `:session' is given but no name string is specified, the + session is named according to the language used in the block. All + blocks with the same session name share the same session. Using + different session names enables concurrent sessions (even for the + same interpreted language, if the language supports multiple + sessions). - A string passed to the `:session' header argument will give the -session a name. This makes it possible to run concurrent sessions for -each interpreted language.  File: org, Node: noweb, Next: noweb-ref, Prev: session, Up: Specific header arguments -14.8.2.13 `:noweb' +14.8.2.15 `:noweb' .................. The `:noweb' header argument controls expansion of "noweb" syntax @@ -14349,17 +15091,17 @@ inline noweb references.  File: org, Node: noweb-ref, Next: noweb-sep, Prev: noweb, Up: Specific header arguments -14.8.2.14 `:noweb-ref' +14.8.2.16 `:noweb-ref' ...................... -When expanding "noweb" style references the bodies of all code block +When expanding "noweb" style references, the bodies of all code block with _either_ a block name matching the reference name _or_ a `:noweb-ref' header argument matching the reference name will be concatenated together to form the replacement text. - By setting this header argument at the sub-tree or file level, -simple code block concatenation may be achieved. For example, when -tangling the following Org mode file, the bodies of code blocks will be + By setting this header argument at the subtree or file level, simple +code block concatenation may be achieved. For example, when tangling +the following Org mode file, the bodies of code blocks will be concatenated into the resulting pure code file(1). #+BEGIN_SRC sh :tangle yes :noweb yes :shebang #!/bin/sh @@ -14402,7 +15144,7 @@ By default a newline is used.  File: org, Node: noweb-sep, Next: cache, Prev: noweb-ref, Up: Specific header arguments -14.8.2.15 `:noweb-sep' +14.8.2.17 `:noweb-sep' ...................... The `:noweb-sep' header argument holds the string used to separate @@ -14412,7 +15154,7 @@ newline is used.  File: org, Node: cache, Next: sep, Prev: noweb-sep, Up: Specific header arguments -14.8.2.16 `:cache' +14.8.2.18 `:cache' .................. The `:cache' header argument controls the use of in-buffer caching of @@ -14457,7 +15199,7 @@ last run.  File: org, Node: sep, Next: hlines, Prev: cache, Up: Specific header arguments -14.8.2.17 `:sep' +14.8.2.19 `:sep' ................ The `:sep' header argument can be used to control the delimiter used @@ -14473,7 +15215,7 @@ delimited.  File: org, Node: hlines, Next: colnames, Prev: sep, Up: Specific header arguments -14.8.2.18 `:hlines' +14.8.2.20 `:hlines' ................... Tables are frequently represented with one or more horizontal lines, or @@ -14528,7 +15270,7 @@ hlines. The `:hlines' argument to a code block accepts the values  File: org, Node: colnames, Next: rownames, Prev: hlines, Up: Specific header arguments -14.8.2.19 `:colnames' +14.8.2.21 `:colnames' ..................... The `:colnames' header argument accepts the values `yes', `no', or @@ -14569,7 +15311,7 @@ behavior of the `:colnames' header argument may differ across languages.  File: org, Node: rownames, Next: shebang, Prev: colnames, Up: Specific header arguments -14.8.2.20 `:rownames' +14.8.2.22 `:rownames' ..................... The `:rownames' header argument can take on the values `yes' or `no', @@ -14603,7 +15345,7 @@ tables with row names may be handled directly in Emacs Lisp.  File: org, Node: shebang, Next: tangle-mode, Prev: rownames, Up: Specific header arguments -14.8.2.21 `:shebang' +14.8.2.23 `:shebang' .................... Setting the `:shebang' header argument to a string value (e.g., @@ -14614,7 +15356,7 @@ permissions of the tangled file are set to make it executable.  File: org, Node: tangle-mode, Next: eval, Prev: shebang, Up: Specific header arguments -14.8.2.22 `:tangle-mode' +14.8.2.24 `:tangle-mode' ........................ The `tangle-mode' header argument controls the permission set on tangled @@ -14630,7 +15372,7 @@ undefined if multiple code blocks with different values for the  File: org, Node: eval, Next: wrap, Prev: tangle-mode, Up: Specific header arguments -14.8.2.23 `:eval' +14.8.2.25 `:eval' ................. The `:eval' header argument can be used to limit the evaluation of @@ -14660,7 +15402,7 @@ evaluation security::.  File: org, Node: wrap, Next: post, Prev: eval, Up: Specific header arguments -14.8.2.24 `:wrap' +14.8.2.26 `:wrap' ................. The `:wrap' header argument is used to mark the results of source block @@ -14672,7 +15414,7 @@ in a `#+BEGIN/END_RESULTS' block.  File: org, Node: post, Next: prologue, Prev: wrap, Up: Specific header arguments -14.8.2.25 `:post' +14.8.2.27 `:post' ................. The `:post' header argument is used to post-process the results of a @@ -14681,14 +15423,16 @@ the code block will temporarily be bound to the `*this*' variable. This variable may then be included in header argument forms such as those used in *note var:: header argument specifications allowing passing of results to other code blocks, or direct execution via Emacs -Lisp. +Lisp. Additional header arguments may be passed to the +`:post'-function. - The following example illustrates the usage of the `:post' header -argument. + The following two examples illustrate the usage of the `:post' header +argument. The first example shows how to attach a attribute-line via +`:post'. #+name: attr_wrap #+begin_src sh :var data="" :var width="\\textwidth" :results output - echo "#+ATTR_LATEX :width $width" + echo "#+ATTR_LATEX: :width $width" echo "$data" #+end_src @@ -14707,10 +15451,33 @@ argument. [[file:/tmp/it.png]] :END: + The second examples shows how to use `:post' together with the +`:colnames' header argument. + #+name: round-tbl + #+begin_src emacs-lisp :var tbl="" fmt="%.3f" + (mapcar (lambda (row) + (mapcar (lambda (cell) + (if (numberp cell) + (format fmt cell) + cell)) + row)) + tbl) + #+end_src + + #+begin_src R :colnames yes :post round-tbl[:colnames yes](*this*) + set.seed(42) + data.frame(foo=rnorm(1)) + #+end_src + + #+RESULTS: + | foo | + |-------| + | 1.371 | +  File: org, Node: prologue, Next: epilogue, Prev: post, Up: Specific header arguments -14.8.2.26 `:prologue' +14.8.2.28 `:prologue' ..................... The value of the `prologue' header argument will be prepended to the @@ -14725,14 +15492,14 @@ gnuplot code blocks. Also see *note epilogue::.  File: org, Node: epilogue, Prev: prologue, Up: Specific header arguments -14.8.2.27 `:epilogue' +14.8.2.29 `:epilogue' ..................... The value of the `epilogue' header argument will be appended to the code block body before execution. Also see *note prologue::.  -File: org, Node: Results of evaluation, Next: Noweb reference syntax, Prev: Header arguments, Up: Working With Source Code +File: org, Node: Results of evaluation, Next: Noweb reference syntax, Prev: Header arguments, Up: Working with source code 14.9 Results of evaluation ========================== @@ -14817,7 +15584,7 @@ as an external process. For example, compare the following two blocks: : hello : bye - In non-session mode, the `2' is not printed and does not appear. + In non-session mode, the "2" is not printed and does not appear. #+BEGIN_SRC python :results output :session print "hello" @@ -14831,11 +15598,11 @@ as an external process. For example, compare the following two blocks: : bye But in `:session' mode, the interactive interpreter receives input -`2' and prints out its value, `2'. (Indeed, the other print statements +"2" and prints out its value, "2". (Indeed, the other print statements are unnecessary here).  -File: org, Node: Noweb reference syntax, Next: Key bindings and useful functions, Prev: Results of evaluation, Up: Working With Source Code +File: org, Node: Noweb reference syntax, Next: Key bindings and useful functions, Prev: Results of evaluation, Up: Working with source code 14.10 Noweb reference syntax ============================ @@ -14872,7 +15639,7 @@ expense of not correctly resolving inherited values of the `:noweb-ref' header argument.  -File: org, Node: Key bindings and useful functions, Next: Batch execution, Prev: Noweb reference syntax, Up: Working With Source Code +File: org, Node: Key bindings and useful functions, Next: Batch execution, Prev: Noweb reference syntax, Up: Working with source code 14.11 Key bindings and useful functions ======================================= @@ -14935,7 +15702,7 @@ C-h' C-x'  -File: org, Node: Batch execution, Prev: Key bindings and useful functions, Up: Working With Source Code +File: org, Node: Batch execution, Prev: Key bindings and useful functions, Up: Working with source code 14.12 Batch execution ===================== @@ -14969,7 +15736,7 @@ script calls `org-babel-tangle' on every one of its arguments. (kill-buffer)) '($FILES)))" 2>&1 |grep tangled  -File: org, Node: Miscellaneous, Next: Hacking, Prev: Working With Source Code, Up: Top +File: org, Node: Miscellaneous, Next: Hacking, Prev: Working with source code, Up: Top 15 Miscellaneous **************** @@ -14977,7 +15744,7 @@ File: org, Node: Miscellaneous, Next: Hacking, Prev: Working With Source Code * Menu: * Completion:: M-TAB knows what you need -* Easy Templates:: Quick insertion of structural elements +* Easy templates:: Quick insertion of structural elements * Speed keys:: Electric commands at the beginning of a headline * Code evaluation security:: Org mode files evaluate inline code * Customization:: Adapting Org to your taste @@ -14989,7 +15756,7 @@ File: org, Node: Miscellaneous, Next: Hacking, Prev: Working With Source Code * org-crypt:: Encrypting Org files  -File: org, Node: Completion, Next: Easy Templates, Prev: Miscellaneous, Up: Miscellaneous +File: org, Node: Completion, Next: Easy templates, Up: Miscellaneous 15.1 Completion =============== @@ -15038,9 +15805,9 @@ buffer and use the key to complete text right there. * Elsewhere, complete dictionary words using Ispell.  -File: org, Node: Easy Templates, Next: Speed keys, Prev: Completion, Up: Miscellaneous +File: org, Node: Easy templates, Next: Speed keys, Prev: Completion, Up: Miscellaneous -15.2 Easy Templates +15.2 Easy templates =================== Org mode supports insertion of empty structural elements (like @@ -15077,7 +15844,7 @@ will expand into a complete EXAMPLE template. additional details.  -File: org, Node: Speed keys, Next: Code evaluation security, Prev: Easy Templates, Up: Miscellaneous +File: org, Node: Speed keys, Next: Code evaluation security, Prev: Easy templates, Up: Miscellaneous 15.3 Speed keys =============== @@ -15086,7 +15853,7 @@ Single keys can be made to execute commands when the cursor is at the beginning of a headline, i.e., before the first star. Configure the variable `org-use-speed-commands' to activate this feature. There is a pre-defined list of commands, and you can add more such commands using -the variable `org-speed-commands-user'. Speed keys do not only speed up +the variable `org-speed-commands-user'. Speed keys not only speed up navigation and other commands, but they also provide an alternative way to execute commands bound to keys that are not or not easily available on a TTY, or on a small mobile device with a limited keyboard. @@ -15100,7 +15867,7 @@ File: org, Node: Code evaluation security, Next: Customization, Prev: Speed k 15.4 Code evaluation and security issues ======================================== -Org provides tools to work with the code snippets, including evaluating +Org provides tools to work with code snippets, including evaluating them. Running code on your machine always comes with a security risk. @@ -15182,7 +15949,7 @@ per-file basis. These lines start with a `#+' followed by a keyword, a colon, and then individual words defining a setting. Several setting words can be in the same line, but you can also have multiple lines for the keyword. While these settings are described throughout the manual, -here is a summary. After changing any of those lines in the buffer, +here is a summary. After changing any of these lines in the buffer, press `C-c C-c' with the cursor still in the line to activate the changes immediately. Otherwise they become effective only when the file is visited again in a new Emacs session. @@ -15196,9 +15963,7 @@ file is visited again in a new Emacs session. `#+CATEGORY:' This line sets the category for the agenda file. The category - applies for all subsequent lines until the next `#+CATEGORY' line, - or the end of the file. The first such line also applies to any - entries before it. + applies to the whole document. `#+COLUMNS: %25ITEM ...' Set the default format for columns view. This format applies when @@ -15215,10 +15980,6 @@ file is visited again in a new Emacs session. Set tags that can be inherited by any entry in the file, including the top-level entries. -`#+DRAWERS: NAME1 ...' - Set the file-local set of additional drawers. The corresponding - global variable is `org-drawers'. - `#+LINK: linkword replace' These lines (several are allowed) specify link abbreviations. *Note Link abbreviations::. The corresponding variable is @@ -15368,9 +16129,6 @@ file is visited again in a new Emacs session. `#+TITLE:, #+AUTHOR:, #+EMAIL:, #+LANGUAGE:, #+DATE:,' `#+OPTIONS:, #+BIND:,' -`#+DESCRIPTION:, #+KEYWORDS:,' -`#+LaTeX_HEADER:, #+LaTeX_HEADER_EXTRA:,' -`#+HTML_HEAD:, #+HTML_HEAD_EXTRA:, #+HTML_LINK_UP:, #+HTML_LINK_HOME:,' `#+SELECT_TAGS:, #+EXCLUDE_TAGS:' These lines provide settings for exporting files. For more details see *note Export settings::. @@ -15601,7 +16359,7 @@ other code out there. * Conflicts:: Packages that lead to conflicts  -File: org, Node: Cooperation, Next: Conflicts, Prev: Interaction, Up: Interaction +File: org, Node: Cooperation, Next: Conflicts, Up: Interaction 15.10.1 Packages that Org cooperates with ----------------------------------------- @@ -15827,7 +16585,7 @@ File: org, Node: Hacking, Next: MobileOrg, Prev: Miscellaneous, Up: Top Appendix A Hacking ****************** -This appendix covers some aspects where users can extend the +This appendix covers some areas where users can extend the functionality of Org. * Menu: @@ -15846,7 +16604,7 @@ functionality of Org. * Using the mapping API:: Mapping over all or selected entries  -File: org, Node: Hooks, Next: Add-on packages, Prev: Hacking, Up: Hacking +File: org, Node: Hooks, Next: Add-on packages, Up: Hacking A.1 Hooks ========= @@ -15973,8 +16731,8 @@ A.4 Adding export back-ends =========================== Org 8.0 comes with a completely rewritten export engine which makes it -easy to write new export back-ends, either from scratch, or from -deriving them from existing ones. +easy to write new export back-ends, either from scratch, or by deriving +them from existing ones. Your two entry points are respectively `org-export-define-backend' and `org-export-define-derived-backend'. To grok these functions, you @@ -15983,7 +16741,7 @@ back-end from scratch) and `ox-beamer.el' (for how to derive a new back-end from an existing one. When creating a new back-end from scratch, the basic idea is to set -the name of the back-end (as a symbol) and an an alist of elements and +the name of the back-end (as a symbol) and an alist of elements and export functions. On top of this, you will need to set additional keywords like `:menu-entry' (to display the back-end in the export dispatcher), `:export-block' (to specify what blocks should not be @@ -16035,7 +16793,7 @@ returns `nil' so that other, similar functions can have a try. ---------- Footnotes ---------- (1) `org-R.el' has been replaced by the Org mode functionality -described in *note Working With Source Code:: and is now obsolete. +described in *note Working with source code:: and is now obsolete.  File: org, Node: Tables in arbitrary syntax, Next: Dynamic blocks, Prev: Context-sensitive commands, Up: Hacking @@ -16069,7 +16827,7 @@ another format (HTML, LaTeX or Texinfo.) * Radio lists:: Sending and receiving lists  -File: org, Node: Radio tables, Next: A LaTeX example, Prev: Tables in arbitrary syntax, Up: Tables in arbitrary syntax +File: org, Node: Radio tables, Next: A LaTeX example, Up: Tables in arbitrary syntax A.6.1 Radio tables ------------------ @@ -16107,10 +16865,6 @@ acted upon before the translation function is called: _after_ the removal of these columns, the function never knows that there have been additional columns. -`:no-escape t' - When non-`nil', do not escape special characters `&%#_^' when - exporting the table. The default value is `nil'. - The one problem remaining is how to keep the source table in the buffer without disturbing the normal workings of the file, for example during compilation of a C file or processing of a LaTeX file. There are a @@ -16194,13 +16948,14 @@ header and footer commands of the target table: \end{comment} The LaTeX translator function `orgtbl-to-latex' is already part of -Orgtbl mode. It uses a `tabular' environment to typeset the table and -marks horizontal lines with `\hline'. Furthermore, it interprets the -following parameters (see also *note Translator functions::): +Orgtbl mode. By default, it uses a `tabular' environment to typeset the +table and marks horizontal lines with `\hline'. You can control the +output through several parameters (see also *note Translator +functions::), including the following ones : `:splice nil/t' - When set to t, return only table body lines, don't wrap them into a - tabular environment. Default is `nil'. + When non-`nil', return only table body lines, don't wrap them into + a tabular environment. Default is `nil'. `:fmt fmt' A format to be used to wrap each field, it should contain `%s' for @@ -16213,12 +16968,12 @@ following parameters (see also *note Translator functions::): `:efmt efmt' Use this format to print numbers with exponentials. The format should have `%s' twice for inserting mantissa and exponent, for - example `"%s\\times10^{%s}"'. The default is `"%s\\,(%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 `efmt' has been applied to a value, `fmt' will also be - applied. Similar to `fmt', functions of two arguments can be - supplied instead of strings. + 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 `efmt' has + been applied to a value, `fmt' will also be applied. Similar to + `fmt', functions of two arguments can be supplied instead of + strings. By default, no special formatting is applied. ---------- Footnotes ---------- @@ -16242,45 +16997,32 @@ A.6.3 Translator functions Orgtbl mode has several translator functions built-in: `orgtbl-to-csv' (comma-separated values), `orgtbl-to-tsv' (TAB-separated values) -`orgtbl-to-latex', `orgtbl-to-html', and `orgtbl-to-texinfo'. Except -for `orgtbl-to-html'(1), these all use a generic translator, -`orgtbl-to-generic'. For example, `orgtbl-to-latex' itself is a very -short function that computes the column definitions for the `tabular' -environment, defines a few field and line separators and then hands -processing over to the generic translator. Here is the entire code: - - (defun orgtbl-to-latex (table params) - "Convert the Orgtbl mode TABLE to LaTeX." - (let* ((alignment (mapconcat (lambda (x) (if x "r" "l")) - org-table-last-alignment "")) - (params2 - (list - :tstart (concat "\\begin{tabular}{" alignment "}") - :tend "\\end{tabular}" - :lstart "" :lend " \\\\" :sep " & " - :efmt "%s\\,(%s)" :hline "\\hline"))) - (orgtbl-to-generic table (org-combine-plists params2 params)))) - - As you can see, the properties passed into the function (variable -PARAMS) are combined with the ones newly defined in the function -(variable PARAMS2). The ones passed into the function (i.e., the ones -set by the `ORGTBL SEND' line) take precedence. So if you would like -to use the LaTeX translator, but wanted the line endings to be -`\\[2mm]' instead of the default `\\', you could just overrule the -default with +`orgtbl-to-latex', `orgtbl-to-html', `orgtbl-to-texinfo', +`orgtbl-to-unicode' and `orgtbl-to-orgtbl'. These all use a generic +translator, `orgtbl-to-generic', which, in turn, can delegate +translations to various export back-ends (*note Export back-ends::). + + In particular, properties passed into the function (i.e., the ones +set by the `ORGTBL SEND' line) take precedence over translations +defined in the function. So if you would like to use the LaTeX +translator, but wanted the line endings to be `\\[2mm]' instead of the +default `\\', you could just overrule the default with #+ORGTBL: SEND test orgtbl-to-latex :lend " \\\\[2mm]" - For a new language, you can either write your own converter function -in analogy with the LaTeX translator, or you can use the generic -function directly. For example, if you have a language where a table -is started with `!BTBL!', ended with `!ETBL!', and where table lines are -started with `!BL!', ended with `!EL!', and where the field separator -is a TAB, you could call the generic translator like this (on a single -line!): + For a new language, you can use the generic function to write your +own converter function. For example, if you have a language where a +table is started with `!BTBL!', ended with `!ETBL!', and where table +lines are started with `!BL!', ended with `!EL!', and where the field +separator is a TAB, you could define your generic translator like this: - #+ORGTBL: SEND test orgtbl-to-generic :tstart "!BTBL!" :tend "!ETBL!" - :lstart "!BL! " :lend " !EL!" :sep "\t" + (defun orgtbl-to-language (table params) + "Convert the orgtbl-mode TABLE to language." + (orgtbl-to-generic + table + (org-combine-plists + '(:tstart "!BTBL!" :tend "!ETBL!" :lstart "!BL!" :lend "!EL!" :sep "\t") + params))) Please check the documentation string of the function `orgtbl-to-generic' for a full list of parameters understood by that @@ -16298,11 +17040,6 @@ single string containing the formatted table. If you write a generally useful translator, please post it on so that others can benefit from your work. - ---------- Footnotes ---------- - - (1) The HTML translator uses the same code that produces tables -during HTML export. -  File: org, Node: Radio lists, Prev: Translator functions, Up: Tables in arbitrary syntax @@ -16389,7 +17126,7 @@ The corresponding block writer function could look like this: (defun org-dblock-write:block-update-time (params) (let ((fmt (or (plist-get params :format) "%d. %m. %Y"))) (insert "Last block update at: " - (format-time-string fmt (current-time))))) + (format-time-string fmt)))) If you want to make sure that all dynamic blocks are always up-to-date, you could add the function `org-update-all-dblocks' to a @@ -16500,7 +17237,7 @@ like this, even without defining a special function: ---------- Footnotes ---------- - (1) The `agenda*' view is the same than `agenda' except that it only + (1) 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. @@ -16518,7 +17255,7 @@ start to become slow. Below are some tips on how to speed up the agenda commands. 1. Reduce the number of Org agenda files: this will reduce the - slowness caused by accessing a hard drive. + slowdown caused by accessing a hard drive. 2. Reduce the number of DONE and archived headlines: this way the agenda does not need to skip them. @@ -16666,7 +17403,7 @@ properties. Get all property keys in the current buffer. -- Function: org-insert-property-drawer - Insert a property drawer for the current entry. Also + Insert a property drawer for the current entry. -- Function: org-entry-put-multivalued-property pom property &rest values @@ -16804,7 +17541,7 @@ ignored. (length (org-map-entries t "/+WAITING" 'agenda))  -File: org, Node: MobileOrg, Next: History and Acknowledgments, Prev: Hacking, Up: Top +File: org, Node: MobileOrg, Next: History and acknowledgments, Prev: Hacking, Up: Top Appendix B MobileOrg ******************** @@ -16812,8 +17549,8 @@ Appendix B MobileOrg MobileOrg is the name of the mobile companion app for Org mode, currently available for iOS and for Android. 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 iOS implementation (https://github.com/MobileOrg/) for the +computer. It also allows you to record changes to existing entries. +The iOS implementation (https://github.com/MobileOrg/) for the iPhone/iPod Touch/iPad series of devices, was started by Richard Moreland and is now in the hands Sean Escriva. Android users should check out MobileOrg Android @@ -16840,13 +17577,13 @@ TODO state sets (*note Per-file keywords::) and mutually exclusive tags * Pulling from MobileOrg:: Integrating captured and flagged items  -File: org, Node: Setting up the staging area, Next: Pushing to MobileOrg, Prev: MobileOrg, Up: MobileOrg +File: org, Node: Setting up the staging area, Next: Pushing to MobileOrg, Up: MobileOrg B.1 Setting up the staging area =============================== MobileOrg needs to interact with Emacs through a directory on a server. -If you are using a public server, you should consider to encrypt the +If you are using a public server, you should consider encrypting the files that are uploaded to the server. This can be done with Org mode 7.02 and with MobileOrg 1.5 (iPhone version), and you need an `openssl' installation on your system. To turn on encryption, set a password in @@ -16900,8 +17637,8 @@ changed. ---------- Footnotes ---------- - (1) Symbolic links in `org-directory' need to have the same name -than their targets. + (1) Symbolic links in `org-directory' need to have the same name as +their targets. (2) While creating the agendas, Org mode will force ID properties on all referenced entries, so that these entries can be uniquely @@ -16972,7 +17709,7 @@ you later use `C-c a ?' to regenerate the view, only the current agenda files will be searched.  -File: org, Node: History and Acknowledgments, Next: GNU Free Documentation License, Prev: MobileOrg, Up: Top +File: org, Node: History and acknowledgments, Next: GNU Free Documentation License, Prev: MobileOrg, Up: Top Appendix C History and acknowledgments ************************************** @@ -17011,15 +17748,18 @@ 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, when he basically acted as co-maintainer, 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. + 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 desparately 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. John Wiegley John has contributed a number of great ideas and patches directly @@ -17043,9 +17783,9 @@ know what I am missing here! C.2 From Bastien ================ -I (Bastien) have been maintaining Org since January 2011. This appendix -would not be complete without adding a few more acknowledgements and -thanks to Carsten's ones above. +I (Bastien) have been maintaining Org between 2011 and 2013. This +appendix would not be complete without adding a few more +acknowledgements and thanks. I am first grateful to Carsten for his trust while handing me over the maintainership of Org. His unremitting support is what really @@ -17066,12 +17806,12 @@ Eric Schulte 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 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. + 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_ @@ -17126,13 +17866,14 @@ C.3 List of contributions calculations and improved XEmacs compatibility, in particular by porting `nouline.el' to XEmacs. - * Sacha Chua suggested copying some linking code from Planner. + * Sacha Chua suggested copying some linking code from Planner, and + helped make Org pupular through her blog. * Toby S. Cubitt contributed to the code for clock formats. - * Baoqiu Cui contributed the DocBook exporter. It has been deleted - from Org 8.0: you can now export to Texinfo and export the `.texi' - file to DocBook using `makeinfo'. + * Baoqiu Cui contributed the first DocBook exporter. In Org 8.0, we + go a different route: you can now export to Texinfo and export the + `.texi' file to DocBook using `makeinfo'. * Eddward DeVilla proposed and tested checkbox statistics. He also came up with the idea of properties, and that there should be an @@ -17357,7 +18098,7 @@ C.3 List of contributions contributed various ideas and code snippets.  -File: org, Node: GNU Free Documentation License, Next: Main Index, Prev: History and Acknowledgments, Up: Top +File: org, Node: GNU Free Documentation License, Next: Main Index, Prev: History and acknowledgments, Up: Top Appendix D GNU Free Documentation License ***************************************** @@ -17851,18 +18592,19 @@ Concept index [index] * Menu: -* #+ARCHIVE: Moving subtrees. (line 30) +* #+ARCHIVE: Moving subtrees. (line 35) * #+ASCII: ASCII/Latin-1/UTF-8 export. - (line 41) + (line 53) * #+ATTR_ASCII: ASCII/Latin-1/UTF-8 export. - (line 52) -* #+ATTR_BEAMER: Beamer export. (line 124) + (line 64) +* #+ATTR_BEAMER: Beamer specific syntax. + (line 34) * #+ATTR_HTML <1>: Images in HTML export. (line 24) * #+ATTR_HTML <2>: Tables in HTML export. (line 12) * #+ATTR_HTML: Links in HTML export. - (line 21) + (line 23) * #+ATTR_LATEX: LaTeX specific attributes. (line 6) * #+ATTR_ODT <1>: Customizing tables in ODT export. @@ -17873,23 +18615,35 @@ Concept index (line 17) * #+ATTR_TEXINFO: Texinfo specific attributes. (line 6) -* #+BEAMER: Beamer export. (line 109) -* #+BEAMER_COLOR_THEME: Beamer export. (line 89) -* #+BEAMER_FONT_THEME: Beamer export. (line 89) -* #+BEAMER_INNER_THEME: Beamer export. (line 89) -* #+BEAMER_OUTER_THEME: Beamer export. (line 89) -* #+BEAMER_THEME: Beamer export. (line 89) +* #+AUTHOR: Export settings. (line 25) +* #+BEAMER: Beamer specific syntax. + (line 19) +* #+BEAMER_FONT_THEME: Beamer specific export settings. + (line 15) +* #+BEAMER_HEADER: Beamer specific export settings. + (line 24) +* #+BEAMER_INNER_THEME: Beamer specific export settings. + (line 18) +* #+BEAMER_OUTER_THEME: Beamer specific export settings. + (line 21) +* #+BEAMER_THEME: Beamer specific export settings. + (line 10) * #+BEGIN, clocktable: The clock table. (line 36) * #+BEGIN, columnview: Capturing column view. (line 11) * #+BEGIN:dynamic block: Dynamic blocks. (line 15) * #+BEGIN_ASCII: ASCII/Latin-1/UTF-8 export. - (line 41) -* #+BEGIN_BEAMER: Beamer export. (line 109) + (line 53) +* #+BEGIN_BEAMER: Beamer specific syntax. + (line 19) * #+BEGIN_CENTER: Paragraphs. (line 31) * #+BEGIN_COMMENT: Comment lines. (line 6) * #+BEGIN_EXAMPLE: Literal examples. (line 8) * #+BEGIN_HTML: Quoting HTML tags. (line 12) +* #+BEGIN_JUSTIFYLEFT: ASCII/Latin-1/UTF-8 export. + (line 75) +* #+BEGIN_JUSTIFYRIGHT: ASCII/Latin-1/UTF-8 export. + (line 75) * #+BEGIN_LATEX: Quoting LaTeX code. (line 11) * #+BEGIN_QUOTE: Paragraphs. (line 26) * #+BEGIN_SRC <1>: Structure of code blocks. @@ -17898,9 +18652,9 @@ Concept index * #+BEGIN_TEXINFO: Quoting Texinfo code. (line 9) * #+BEGIN_VERSE: Paragraphs. (line 13) -* #+BIND: Export settings. (line 187) +* #+BIND: Export settings. (line 194) * #+CALL: Evaluating code blocks. - (line 22) + (line 23) * #+CAPTION <1>: Images in HTML export. (line 24) * #+CAPTION <2>: Tables in HTML export. @@ -17910,8 +18664,19 @@ Concept index * #+CINDEX: Indices. (line 6) * #+COLUMNS: Scope of column definitions. (line 8) -* #+CONSTANTS: References. (line 102) -* #+DRAWERS: Drawers. (line 6) +* #+CONSTANTS: References. (line 110) +* #+CREATOR: Export settings. (line 28) +* #+DATE: Export settings. (line 32) +* #+DESCRIPTION (Beamer): Beamer specific export settings. + (line 28) +* #+DESCRIPTION (HTML): HTML Specific export settings. + (line 10) +* #+DESCRIPTION (LaTeX): LaTeX specific export settings. + (line 10) +* #+DESCRIPTION (ODT): ODT specific export settings. + (line 10) +* #+EMAIL: Export settings. (line 35) +* #+EXCLUDE_TAGS: Export settings. (line 51) * #+FILETAGS: Tag inheritance. (line 20) * #+FINDEX: Indices. (line 6) * #+HEADER:: Code block specific header arguments. @@ -17919,30 +18684,64 @@ Concept index * #+HEADERS:: Code block specific header arguments. (line 30) * #+HTML: Quoting HTML tags. (line 12) -* #+HTML_HEAD: CSS support. (line 47) -* #+HTML_HEAD_EXTRA: CSS support. (line 47) -* #+HTML_INCLUDE_STYLE: CSS support. (line 41) +* #+HTML_CONTAINER: HTML Specific export settings. + (line 17) +* #+HTML_DOCTYPE: HTML Specific export settings. + (line 14) +* #+HTML_HEAD <1>: CSS support. (line 48) +* #+HTML_HEAD: HTML Specific export settings. + (line 32) +* #+HTML_HEAD_EXTRA <1>: CSS support. (line 48) +* #+HTML_HEAD_EXTRA: HTML Specific export settings. + (line 36) +* #+HTML_INCLUDE_STYLE: CSS support. (line 42) +* #+HTML_LINK_HOME: HTML Specific export settings. + (line 21) +* #+HTML_LINK_UP: HTML Specific export settings. + (line 24) +* #+HTML_MATHJAX: HTML Specific export settings. + (line 27) * #+INCLUDE: Include files. (line 7) * #+INFOJS_OPT: JavaScript support. (line 23) +* #+KEYWORDS (Beamer): Beamer specific export settings. + (line 35) +* #+KEYWORDS (HTML): HTML Specific export settings. + (line 40) +* #+KEYWORDS (LaTeX): LaTeX specific export settings. + (line 35) +* #+KEYWORDS (ODT): ODT specific export settings. + (line 14) * #+KINDEX: Indices. (line 6) +* #+LANGUAGE: Export settings. (line 38) * #+LATEX: Quoting LaTeX code. (line 11) -* #+LATEX_CLASS: Header and sectioning. +* #+LATEX_CLASS <1>: Header and sectioning. (line 22) -* #+LATEX_CLASS_OPTIONS: Header and sectioning. +* #+LATEX_CLASS: LaTeX specific export settings. + (line 17) +* #+LATEX_CLASS_OPTIONS <1>: Header and sectioning. (line 22) -* #+LATEX_HEADER: Header and sectioning. +* #+LATEX_CLASS_OPTIONS: LaTeX specific export settings. + (line 22) +* #+LATEX_HEADER <1>: Header and sectioning. (line 27) -* #+LATEX_HEADER_EXTRA: Header and sectioning. +* #+LATEX_HEADER: LaTeX specific export settings. + (line 25) +* #+LATEX_HEADER (HTML): HTML Specific export settings. + (line 45) +* #+LATEX_HEADER_EXTRA <1>: Header and sectioning. (line 27) +* #+LATEX_HEADER_EXTRA: LaTeX specific export settings. + (line 30) * #+LINK: Link abbreviations. (line 49) * #+MACRO: Macro replacement. (line 6) * #+NAME <1>: Structure of code blocks. (line 6) * #+NAME <2>: Images and tables. (line 6) * #+NAME: Internal links. (line 21) -* #+NAME, for table: References. (line 123) +* #+NAME, for table: References. (line 131) * #+ODT_STYLES_FILE: Applying custom styles. (line 28) +* #+OPTIONS <1>: Export settings. (line 6) * #+OPTIONS: Headings and sections. (line 14) * #+ORGLST: Radio lists. (line 25) @@ -17951,17 +18750,29 @@ Concept index * #+PINDEX: Indices. (line 6) * #+PLOT: Org-Plot. (line 6) * #+PRIORITIES: Priorities. (line 44) -* #+PROPERTY: Property syntax. (line 42) +* #+PROPERTY: Property syntax. (line 44) * #+RESULTS: Evaluating code blocks. (line 6) +* #+SELECT_TAGS: Export settings. (line 44) * #+SEQ_TODO: Per-file keywords. (line 6) -* #+SETUPFILE <1>: In-buffer settings. (line 61) +* #+SETUPFILE <1>: In-buffer settings. (line 55) * #+SETUPFILE: Export settings. (line 13) -* #+STARTUP: In-buffer settings. (line 74) -* #+SUBAUTHOR: Document preamble. (line 42) -* #+SUBTITLE: Document preamble. (line 35) +* #+STARTUP: In-buffer settings. (line 68) +* #+SUBAUTHOR <1>: Document preamble. (line 42) +* #+SUBAUTHOR: Texinfo specific export settings. + (line 13) +* #+SUBTILE (HTML): HTML Specific export settings. + (line 50) +* #+SUBTITLE (ASCII): ASCII/Latin-1/UTF-8 export. + (line 37) +* #+SUBTITLE (Beamer): Beamer specific export settings. + (line 43) +* #+SUBTITLE (LaTeX): LaTeX specific export settings. + (line 43) +* #+SUBTITLE (Texinfo): Texinfo specific export settings. + (line 10) * #+TAGS: Setting tags. (line 29) -* #+TBLFM <1>: In-buffer settings. (line 184) +* #+TBLFM <1>: In-buffer settings. (line 178) * #+TBLFM <2>: Editing and debugging formulas. (line 99) * #+TBLFM: Field and range formulas. @@ -17974,42 +18785,103 @@ Concept index (line 9) * #+TEXINFO_CLASS <1>: Headings and sectioning structure. (line 6) -* #+TEXINFO_CLASS: Document preamble. (line 22) -* #+TEXINFO_DIR_CATEGORY: Document preamble. (line 69) -* #+TEXINFO_DIR_DESC: Document preamble. (line 69) -* #+TEXINFO_DIR_TITLE: Document preamble. (line 69) -* #+TEXINFO_FILENAME: Document preamble. (line 16) -* #+TEXINFO_HEADER: Document preamble. (line 22) -* #+TEXINFO_PRINTED_TITLE: Document preamble. (line 35) +* #+TEXINFO_CLASS <2>: Document preamble. (line 22) +* #+TEXINFO_CLASS: Texinfo specific export settings. + (line 19) +* #+TEXINFO_DIR_CATEGORY <1>: Document preamble. (line 69) +* #+TEXINFO_DIR_CATEGORY: Texinfo specific export settings. + (line 29) +* #+TEXINFO_DIR_DESC <1>: Document preamble. (line 69) +* #+TEXINFO_DIR_DESC: Texinfo specific export settings. + (line 35) +* #+TEXINFO_DIR_TITLE <1>: Document preamble. (line 69) +* #+TEXINFO_DIR_TITLE: Texinfo specific export settings. + (line 32) +* #+TEXINFO_FILENAME <1>: Document preamble. (line 16) +* #+TEXINFO_FILENAME: Texinfo specific export settings. + (line 16) +* #+TEXINFO_HEADER <1>: Document preamble. (line 22) +* #+TEXINFO_HEADER: Texinfo specific export settings. + (line 23) +* #+TEXINFO_POST_HEADER: Texinfo specific export settings. + (line 26) +* #+TEXINFO_PRINTED_TITLE <1>: Document preamble. (line 35) +* #+TEXINFO_PRINTED_TITLE: Texinfo specific export settings. + (line 38) * #+TINDEX: Indices. (line 6) +* #+TITLE <1>: Export settings. (line 59) * #+TITLE: Document title. (line 8) * #+TOC: Table of contents. (line 6) * #+TODO: Per-file keywords. (line 6) * #+TYP_TODO: Per-file keywords. (line 6) * #+VINDEX: Indices. (line 6) +* :cache, src header argument <1>: cache. (line 6) +* :cache, src header argument: System-wide header arguments. + (line 9) +* :colnames, src header argument: colnames. (line 6) +* :comments, src header argument: comments. (line 6) +* :dir, src header argument: dir. (line 6) +* :epilogue, src header argument: epilogue. (line 6) +* :eval, src header argument: eval. (line 6) +* :exports, src header argument <1>: exports. (line 6) +* :exports, src header argument <2>: System-wide header arguments. + (line 9) +* :exports, src header argument: Exporting code blocks. + (line 21) +* :file, src header argument: file. (line 6) +* :file-ext, src header argument: file-ext. (line 6) +* :hlines, src header argument: hlines. (line 6) +* :mkdirp, src header argument: mkdirp. (line 6) +* :no-expand, src header argument: no-expand. (line 6) +* :noweb, src header argument <1>: noweb. (line 6) +* :noweb, src header argument: System-wide header arguments. + (line 9) +* :noweb-ref, src header argument: noweb-ref. (line 6) +* :noweb-sep, src header argument: noweb-sep. (line 6) +* :output-dir, src header argument: output-dir. (line 6) +* :padline, src header argument: padline. (line 6) +* :post, src header argument: post. (line 6) +* :prologue, src header argument: prologue. (line 6) +* :results, src header argument <1>: Results of evaluation. + (line 27) +* :results, src header argument <2>: results. (line 6) +* :results, src header argument: System-wide header arguments. + (line 9) +* :rownames, src header argument: rownames. (line 6) +* :sep, src header argument: sep. (line 6) +* :session, src header argument <1>: session. (line 6) +* :session, src header argument: System-wide header arguments. + (line 9) +* :shebang, src header argument: shebang. (line 6) +* :tangle, src header argument <1>: tangle. (line 6) +* :tangle, src header argument: Extracting source code. + (line 15) +* :tangle-mode, src header argument: tangle-mode. (line 6) +* :var, src header argument: var. (line 6) +* :wrap, src header argument: wrap. (line 6) * abbreviation, links: Link abbreviations. (line 6) * abstract, in LaTeX export: LaTeX specific attributes. - (line 180) -* acknowledgments: History and Acknowledgments. + (line 215) +* acknowledgments: History and acknowledgments. (line 6) * action, for publishing: Publishing action. (line 6) * activation: Activation. (line 6) -* active region <1>: ODT export commands. (line 9) +* active region <1>: ODT export commands. (line 6) * active region <2>: Built-in table editor. - (line 156) -* active region: Structure editing. (line 137) + (line 162) +* active region: Structure editing. (line 146) * add-on packages: Add-on packages. (line 6) * add-ons, context-sensitive commands: Context-sensitive commands. (line 6) * agenda: Weekly/daily agenda. (line 6) * agenda dispatcher: Agenda dispatcher. (line 6) * agenda files: Agenda files. (line 6) -* agenda files, removing buffers: Agenda commands. (line 521) -* agenda views: Agenda Views. (line 6) +* agenda files, removing buffers: Agenda commands. (line 526) +* agenda views: Agenda views. (line 6) * agenda views, custom: Custom agenda views. (line 6) -* agenda views, exporting <1>: Exporting Agenda Views. +* agenda views, exporting <1>: Exporting agenda views. (line 6) -* agenda views, exporting: Agenda commands. (line 507) +* agenda views, exporting: Agenda commands. (line 512) * agenda views, main example: Storing searches. (line 9) * agenda views, optimization: Speeding up your agendas. (line 6) @@ -18020,34 +18892,37 @@ Concept index * agenda, column view: Agenda column view. (line 6) * agenda, pipe: Extracting agenda information. (line 6) +* agenda, sticky: Agenda dispatcher. (line 53) * agenda, with block views: Block agenda. (line 6) -* align, STARTUP keyword: In-buffer settings. (line 94) +* align, STARTUP keyword: In-buffer settings. (line 88) * alignment in tables: Column width and alignment. (line 6) -* anniversaries, from BBDB: Weekly/daily agenda. (line 73) +* anniversaries, from BBDB: Weekly/daily agenda. (line 79) * API, for mapping: Using the mapping API. (line 6) * API, for properties <1>: Using the property API. (line 6) * API, for properties: Property API. (line 6) -* appointment <1>: Weekly/daily agenda. (line 107) +* appointment <1>: Weekly/daily agenda. (line 113) * appointment: Timestamps. (line 14) -* appointment reminders: Weekly/daily agenda. (line 107) -* appt.el: Weekly/daily agenda. (line 107) -* archive locations: Moving subtrees. (line 20) +* appointment reminders: Weekly/daily agenda. (line 113) +* appt.el: Weekly/daily agenda. (line 113) +* archive locations: Moving subtrees. (line 25) +* Archives mode: Agenda commands. (line 135) * archiving: Archiving. (line 6) * ASCII export: ASCII/Latin-1/UTF-8 export. (line 6) -* Atom feeds: RSS Feeds. (line 6) +* Atom feeds: RSS feeds. (line 6) * attachments: Attachments. (line 6) * author: Feedback. (line 6) +* author, macro: Macro replacement. (line 24) * autoload: Activation. (line 6) * babel, languages: Languages. (line 6) * babel, library of: Library of Babel. (line 6) -* backtrace of an error: Feedback. (line 65) +* backtrace of an error: Feedback. (line 66) * Baur, Steven L.: Cooperation. (line 74) * BBDB links: External links. (line 6) -* BBDB, anniversaries: Weekly/daily agenda. (line 73) +* BBDB, anniversaries: Weekly/daily agenda. (line 79) * Beamer export: Beamer export. (line 6) * block agenda: Block agenda. (line 6) * blocking, of checkboxes: Checkboxes. (line 46) @@ -18063,26 +18938,26 @@ Concept index * calc.el: Cooperation. (line 6) * calculations, in tables <1>: The spreadsheet. (line 6) * calculations, in tables: Built-in table editor. - (line 156) -* calendar commands, from agenda: Agenda commands. (line 456) + (line 162) +* calendar commands, from agenda: Agenda commands. (line 461) * calendar integration: Weekly/daily agenda. (line 32) * calendar, for selecting date: The date/time prompt. (line 76) * capture <1>: Capture. (line 6) * capture: Capture - Refile - Archive. (line 6) -* capturing, from agenda: Agenda commands. (line 349) +* capturing, from agenda: Agenda commands. (line 355) * category: Categories. (line 6) * category filtering, in agenda: Filtering/limiting agenda items. (line 17) * category, require for tags/property match: Matching tags and properties. - (line 71) + (line 72) * CDLaTeX: CDLaTeX mode. (line 6) * cdlatex.el: Cooperation. (line 29) * checkbox blocking: Checkboxes. (line 46) * checkbox statistics: Checkboxes. (line 30) * checkboxes: Checkboxes. (line 6) -* checkboxes and TODO dependencies: TODO dependencies. (line 44) +* checkboxes and TODO dependencies: TODO dependencies. (line 52) * children, subtree visibility state: Global and local cycling. (line 10) * clean outline view: Clean view. (line 6) @@ -18121,18 +18996,18 @@ Concept index * completion, of link abbreviations: Completion. (line 6) * completion, of links: Handling links. (line 66) * completion, of option keywords <1>: Completion. (line 6) -* completion, of option keywords: Per-file keywords. (line 24) +* completion, of option keywords: Per-file keywords. (line 23) * completion, of property keys: Completion. (line 6) * completion, of tags <1>: Completion. (line 6) * completion, of tags: Setting tags. (line 11) * completion, of TeX symbols: Completion. (line 6) * completion, of TODO keywords <1>: Completion. (line 6) * completion, of TODO keywords: Workflow states. (line 15) -* constants, in calculations: References. (line 102) +* constants, in calculations: References. (line 110) * constants.el: Cooperation. (line 17) -* constcgs, STARTUP keyword: In-buffer settings. (line 154) -* constSI, STARTUP keyword: In-buffer settings. (line 154) -* content, STARTUP keyword <1>: In-buffer settings. (line 80) +* constcgs, STARTUP keyword: In-buffer settings. (line 148) +* constSI, STARTUP keyword: In-buffer settings. (line 148) +* content, STARTUP keyword <1>: In-buffer settings. (line 74) * content, STARTUP keyword: Initial visibility. (line 6) * contents, global visibility state: Global and local cycling. (line 22) @@ -18146,7 +19021,7 @@ Concept index * coordinates, of field: References. (line 86) * copying notes: Refile and copy. (line 6) * copying, of subtrees: Structure editing. (line 6) -* Countdown timer: Countdown timer. (line 6) +* countdown timer: Timers. (line 6) * creating timestamps: Creating timestamps. (line 6) * CSS, for HTML export: CSS support. (line 6) * CUA.el: Conflicts. (line 19) @@ -18154,7 +19029,7 @@ Concept index * custom date/time format: Custom time format. (line 6) * custom search strings: Custom searches. (line 6) * customization: Customization. (line 6) -* customtime, STARTUP keyword: In-buffer settings. (line 150) +* customtime, STARTUP keyword: In-buffer settings. (line 144) * cutting, of subtrees: Structure editing. (line 6) * cycling, in plain lists: Plain lists. (line 69) * cycling, of agenda files: Agenda files. (line 22) @@ -18163,13 +19038,14 @@ Concept index * daily agenda: Weekly/daily agenda. (line 6) * date format, custom: Custom time format. (line 6) * date range: Timestamps. (line 43) -* date stamp: Dates and Times. (line 6) +* date stamp: Dates and times. (line 6) * date stamps: Timestamps. (line 6) * date tree: Using capture. (line 9) +* date, macro: Macro replacement. (line 29) * date, reading in minibuffer: The date/time prompt. (line 6) -* dates: Dates and Times. (line 6) -* Davison, Dan: Working With Source Code. +* dates: Dates and times. (line 6) +* Davison, Dan: Working with source code. (line 6) * DEADLINE keyword: Deadlines and scheduling. (line 9) @@ -18178,20 +19054,20 @@ Concept index (line 132) * demotion, of subtrees: Structure editing. (line 6) * dependencies, of TODO states: TODO dependencies. (line 6) -* diary entries, creating from agenda: Agenda commands. (line 461) +* diary entries, creating from agenda: Agenda commands. (line 466) * diary integration: Weekly/daily agenda. (line 32) * dictionary word completion: Completion. (line 6) * directories, for publishing: Sources and destinations. (line 6) * dispatching agenda commands: Agenda dispatcher. (line 6) -* display changing, in agenda: Agenda commands. (line 64) +* display changing, in agenda: Agenda commands. (line 70) * doc, docx, rtf: Configuring a document converter. (line 6) -* document structure: Document Structure. (line 6) +* document structure: Document structure. (line 6) * document title, markup rules: Document title. (line 6) * Dominik, Carsten: Cooperation. (line 17) -* DONE, final TODO keyword: Per-file keywords. (line 27) -* dragging, agenda lines: Agenda commands. (line 354) +* DONE, final TODO keyword: Per-file keywords. (line 26) +* dragging, agenda lines: Agenda commands. (line 360) * drawer, for properties: Property syntax. (line 6) * drawer, for state change recording: Tracking TODO state changes. (line 6) @@ -18199,7 +19075,7 @@ Concept index * Duration, computing: Durations and time values. (line 6) * dvipng <1>: Working with LaTeX math snippets. - (line 44) + (line 47) * dvipng: Math formatting in HTML export. (line 6) * dynamic blocks: Dynamic blocks. (line 6) @@ -18216,17 +19092,20 @@ Concept index * Elisp links: External links. (line 6) * ELPA: Activation. (line 6) * emacsserver: Protocols. (line 6) +* email, macro: Macro replacement. (line 24) * embedding images in ODT: Images in ODT export. (line 6) -* entitiesplain, STARTUP keyword: In-buffer settings. (line 177) -* entitiespretty, STARTUP keyword <1>: In-buffer settings. (line 177) +* entitiesplain, STARTUP keyword: In-buffer settings. (line 171) +* entitiespretty, STARTUP keyword <1>: In-buffer settings. (line 171) * entitiespretty, STARTUP keyword: Special symbols. (line 31) * evaluate time range: Creating timestamps. (line 62) -* even, STARTUP keyword: In-buffer settings. (line 140) +* even, STARTUP keyword: In-buffer settings. (line 134) +* example blocks, in LaTeX export: LaTeX specific attributes. + (line 201) * export back-ends, built-in: Other built-in back-ends. (line 6) * Export, back-ends: Export back-ends. (line 6) -* Export, dispatcher: The Export Dispatcher. +* Export, dispatcher: The export dispatcher. (line 6) * export, OpenDocument: OpenDocument Text export. (line 6) @@ -18234,9 +19113,9 @@ Concept index * Export, writing back-ends: Adding export back-ends. (line 6) * exporting: Exporting. (line 6) -* exporting agenda views <1>: Exporting Agenda Views. +* exporting agenda views <1>: Exporting agenda views. (line 13) -* exporting agenda views: Agenda commands. (line 507) +* exporting agenda views: Agenda commands. (line 512) * exporting, not: Comment lines. (line 6) * extended TODO keywords: TODO extensions. (line 6) * external archiving: Moving subtrees. (line 6) @@ -18245,7 +19124,7 @@ Concept index (line 6) * faces, for TODO keywords: Faces for TODO keywords. (line 6) -* FAQ: Summary. (line 53) +* FAQ: Summary. (line 49) * feedback: Feedback. (line 6) * field coordinates: References. (line 86) * field formula: Field and range formulas. @@ -18262,13 +19141,13 @@ Concept index (line 17) * Filters, exporting: Advanced configuration. (line 32) -* fnadjust, STARTUP keyword: In-buffer settings. (line 160) -* fnauto, STARTUP keyword: In-buffer settings. (line 160) -* fnconfirm, STARTUP keyword: In-buffer settings. (line 160) -* fninline, STARTUP keyword: In-buffer settings. (line 160) -* fnlocal, STARTUP keyword: In-buffer settings. (line 160) -* fnplain, STARTUP keyword: In-buffer settings. (line 160) -* fnprompt, STARTUP keyword: In-buffer settings. (line 160) +* fnadjust, STARTUP keyword: In-buffer settings. (line 154) +* fnauto, STARTUP keyword: In-buffer settings. (line 154) +* fnconfirm, STARTUP keyword: In-buffer settings. (line 154) +* fninline, STARTUP keyword: In-buffer settings. (line 154) +* fnlocal, STARTUP keyword: In-buffer settings. (line 154) +* fnplain, STARTUP keyword: In-buffer settings. (line 154) +* fnprompt, STARTUP keyword: In-buffer settings. (line 154) * folded, subtree visibility state: Global and local cycling. (line 10) * folding, sparse trees: Sparse trees. (line 6) @@ -18293,7 +19172,7 @@ Concept index (line 6) * formula, for table column: Column formulas. (line 6) * formula, in tables: Built-in table editor. - (line 156) + (line 162) * Gillespie, Dave: Cooperation. (line 6) * global cycling: Global and local cycling. (line 22) @@ -18303,7 +19182,7 @@ Concept index (line 22) * Gnus links: External links. (line 6) * graph, in tables: Org-Plot. (line 6) -* group tags: Tag groups. (line 6) +* group tags: Tag hierarchy. (line 6) * group tags, as regular expressions: Matching tags and properties. (line 65) * grouping columns in tables: Column groups. (line 6) @@ -18319,17 +19198,17 @@ Concept index * headline, promotion and demotion: Structure editing. (line 6) * headlines: Headlines. (line 6) * hide text: Visibility cycling. (line 6) -* hideblocks, STARTUP keyword <1>: In-buffer settings. (line 172) +* hideblocks, STARTUP keyword <1>: In-buffer settings. (line 166) * hideblocks, STARTUP keyword: Blocks. (line 13) -* hidestars, STARTUP keyword: In-buffer settings. (line 140) +* hidestars, STARTUP keyword: In-buffer settings. (line 134) * hiding leading stars: Clean view. (line 6) -* history: History and Acknowledgments. +* history: History and acknowledgments. (line 6) * hooks: Hooks. (line 6) * horizontal rules, in ASCII export: ASCII/Latin-1/UTF-8 export. - (line 52) + (line 64) * horizontal rules, in LaTeX export: LaTeX specific attributes. - (line 217) + (line 252) * horizontal rules, markup rules: Horizontal rules. (line 6) * HTML entities: Special symbols. (line 6) * HTML export: HTML export. (line 6) @@ -18344,7 +19223,7 @@ Concept index (line 33) * idle, resolve, dangling: Resolving idle time. (line 9) * imagemagick <1>: Working with LaTeX math snippets. - (line 44) + (line 47) * imagemagick: Math formatting in HTML export. (line 6) * images, embedding in ODT: Images in ODT export. @@ -18352,13 +19231,15 @@ Concept index * images, inline in HTML: Images in HTML export. (line 6) * images, inline in LaTeX: LaTeX specific attributes. - (line 100) + (line 103) * images, inlining: Handling links. (line 136) * imenu.el: Cooperation. (line 33) * in-buffer settings: In-buffer settings. (line 6) * inactive timestamp: Timestamps. (line 52) * include files, markup rules: Include files. (line 6) -* indent, STARTUP keyword: In-buffer settings. (line 86) +* indent, STARTUP keyword: In-buffer settings. (line 80) +* indentation, in source blocks <1>: Editing source code. (line 31) +* indentation, in source blocks: Literal examples. (line 58) * index entries, for publishing: Index entries. (line 6) * index, in a publishing project: Generating an index. (line 6) * Info links: External links. (line 6) @@ -18366,15 +19247,16 @@ Concept index (line 6) * inheritance, of tags: Tag inheritance. (line 6) * inlined images, markup rules: Images and tables. (line 22) -* inlineimages, STARTUP keyword <1>: In-buffer settings. (line 101) +* inlineimages, STARTUP keyword <1>: In-buffer settings. (line 95) * inlineimages, STARTUP keyword: Handling links. (line 136) * inlining images: Handling links. (line 136) * inlining images in HTML: Images in HTML export. (line 6) * inlining images in LaTeX: LaTeX specific attributes. - (line 100) + (line 103) +* input file, macro: Macro replacement. (line 42) * inserting links: Handling links. (line 66) -* insertion, of templates: Easy Templates. (line 6) +* insertion, of templates: Easy templates. (line 6) * installation: Installation. (line 6) * internal links: Internal links. (line 6) * internal links, in HTML export: Links in HTML export. @@ -18402,17 +19284,17 @@ Concept index * LaTeX sectioning structure: Header and sectioning. (line 6) * LaTeX, and Orgtbl mode: A LaTeX example. (line 6) -* latexpreview, STARTUP keyword: In-buffer settings. (line 108) +* latexpreview, STARTUP keyword: In-buffer settings. (line 102) * Latin-1 export: ASCII/Latin-1/UTF-8 export. (line 6) * level, require for tags/property match: Matching tags and properties. - (line 71) + (line 72) * LibreOffice <1>: Extending ODT export. (line 11) * LibreOffice: OpenDocument Text export. (line 6) * limits, in agenda: Filtering/limiting agenda items. - (line 118) + (line 116) * link abbreviations: Link abbreviations. (line 6) * link abbreviations, completion of: Completion. (line 6) * link completion: Handling links. (line 66) @@ -18435,20 +19317,20 @@ Concept index * lists, ordered: Plain lists. (line 6) * lists, plain: Plain lists. (line 6) * literal examples, markup rules: Literal examples. (line 6) -* logdone, STARTUP keyword: In-buffer settings. (line 114) -* logdrawer, STARTUP keyword: In-buffer settings. (line 114) +* logdone, STARTUP keyword: In-buffer settings. (line 108) +* logdrawer, STARTUP keyword: In-buffer settings. (line 108) * logging, of progress: Progress logging. (line 6) -* lognoteclock-out, STARTUP keyword: In-buffer settings. (line 114) -* lognotedone, STARTUP keyword: In-buffer settings. (line 114) -* lognoteredeadline, STARTUP keyword: In-buffer settings. (line 114) -* lognoterefile, STARTUP keyword: In-buffer settings. (line 114) -* lognoterepeat, STARTUP keyword: In-buffer settings. (line 114) -* lognotereschedule, STARTUP keyword: In-buffer settings. (line 114) -* logredeadline, STARTUP keyword: In-buffer settings. (line 114) -* logrefile, STARTUP keyword: In-buffer settings. (line 114) -* logrepeat, STARTUP keyword: In-buffer settings. (line 114) -* logreschedule, STARTUP keyword: In-buffer settings. (line 114) -* logstatesreversed, STARTUP keyword: In-buffer settings. (line 114) +* lognoteclock-out, STARTUP keyword: In-buffer settings. (line 108) +* lognotedone, STARTUP keyword: In-buffer settings. (line 108) +* lognoteredeadline, STARTUP keyword: In-buffer settings. (line 108) +* lognoterefile, STARTUP keyword: In-buffer settings. (line 108) +* lognoterepeat, STARTUP keyword: In-buffer settings. (line 108) +* lognotereschedule, STARTUP keyword: In-buffer settings. (line 108) +* logredeadline, STARTUP keyword: In-buffer settings. (line 108) +* logrefile, STARTUP keyword: In-buffer settings. (line 108) +* logrepeat, STARTUP keyword: In-buffer settings. (line 108) +* logreschedule, STARTUP keyword: In-buffer settings. (line 108) +* logstatesreversed, STARTUP keyword: In-buffer settings. (line 108) * lookup functions in tables: Lookup functions. (line 6) * Ludlam, Eric M.: Cooperation. (line 45) * macro replacement, during export: Macro replacement. (line 6) @@ -18476,40 +19358,43 @@ Concept index * MobileOrg: MobileOrg. (line 6) * mode, for calc: Formula syntax for Calc. (line 14) +* modification time, macro: Macro replacement. (line 36) * motion commands in agenda: Agenda commands. (line 19) * motion, between headlines: Motion. (line 6) -* name, of column or field: References. (line 102) -* named references: References. (line 102) +* name, of column or field: References. (line 110) +* named references: References. (line 110) * names as TODO keywords: TODO types. (line 6) * narrow columns in tables: Column width and alignment. (line 6) -* noalign, STARTUP keyword: In-buffer settings. (line 94) -* nofnadjust, STARTUP keyword: In-buffer settings. (line 160) -* nofninline, STARTUP keyword: In-buffer settings. (line 160) -* nohideblocks, STARTUP keyword <1>: In-buffer settings. (line 172) +* noalign, STARTUP keyword: In-buffer settings. (line 88) +* nofnadjust, STARTUP keyword: In-buffer settings. (line 154) +* nofninline, STARTUP keyword: In-buffer settings. (line 154) +* nohideblocks, STARTUP keyword <1>: In-buffer settings. (line 166) * nohideblocks, STARTUP keyword: Blocks. (line 13) -* noindent, STARTUP keyword: In-buffer settings. (line 86) -* noinlineimages, STARTUP keyword <1>: In-buffer settings. (line 101) +* noindent, STARTUP keyword: In-buffer settings. (line 80) +* noinlineimages, STARTUP keyword <1>: In-buffer settings. (line 95) * noinlineimages, STARTUP keyword: Handling links. (line 136) -* nolatexpreview, STARTUP keyword: In-buffer settings. (line 108) -* nologdone, STARTUP keyword: In-buffer settings. (line 114) -* nologdrawer, STARTUP keyword: In-buffer settings. (line 114) -* nolognoteclock-out, STARTUP keyword: In-buffer settings. (line 114) -* nologredeadline, STARTUP keyword: In-buffer settings. (line 114) -* nologrefile, STARTUP keyword: In-buffer settings. (line 114) -* nologrepeat, STARTUP keyword: In-buffer settings. (line 114) -* nologreschedule, STARTUP keyword: In-buffer settings. (line 114) -* nologstatesreversed, STARTUP keyword: In-buffer settings. (line 114) +* nolatexpreview, STARTUP keyword: In-buffer settings. (line 102) +* nologdone, STARTUP keyword: In-buffer settings. (line 108) +* nologdrawer, STARTUP keyword: In-buffer settings. (line 108) +* nolognoteclock-out, STARTUP keyword: In-buffer settings. (line 108) +* nologredeadline, STARTUP keyword: In-buffer settings. (line 108) +* nologrefile, STARTUP keyword: In-buffer settings. (line 108) +* nologrepeat, STARTUP keyword: In-buffer settings. (line 108) +* nologreschedule, STARTUP keyword: In-buffer settings. (line 108) +* nologstatesreversed, STARTUP keyword: In-buffer settings. (line 108) * occur, command: Sparse trees. (line 6) * occur-tree: Storing searches. (line 9) -* odd, STARTUP keyword: In-buffer settings. (line 140) +* odd, STARTUP keyword: In-buffer settings. (line 134) * odd-levels-only outlines: Clean view. (line 6) * ODT: OpenDocument Text export. (line 6) +* ODT_STYLES_FILE: ODT specific export settings. + (line 19) * OpenDocument: OpenDocument Text export. (line 6) * option keyword completion: Completion. (line 6) -* options, for custom agenda views: Setting Options. (line 6) +* options, for custom agenda views: Setting options. (line 6) * options, for customization: Customization. (line 6) * options, for publishing: Publishing options. (line 6) * ordered lists: Plain lists. (line 6) @@ -18520,11 +19405,11 @@ Concept index * org-capture-last-stored: Using capture. (line 50) * org-crypt.el: org-crypt. (line 6) * org-decrypt-entry: org-crypt. (line 6) -* org-hide-block-startup: In-buffer settings. (line 171) -* org-insert-drawer <1>: Property syntax. (line 88) +* org-hide-block-startup: In-buffer settings. (line 165) +* org-insert-drawer <1>: Property syntax. (line 90) * org-insert-drawer: Drawers. (line 6) * org-list-insert-radio-list: Radio lists. (line 6) -* org-pretty-entities: In-buffer settings. (line 176) +* org-pretty-entities: In-buffer settings. (line 170) * org-publish-project-alist: Project alist. (line 6) * Orgstruct mode: Orgstruct mode. (line 6) * Orgtbl mode <1>: Tables in arbitrary syntax. @@ -18536,7 +19421,7 @@ Concept index * outlines: Outlines. (line 6) * overview, global visibility state: Global and local cycling. (line 22) -* overview, STARTUP keyword <1>: In-buffer settings. (line 80) +* overview, STARTUP keyword <1>: In-buffer settings. (line 74) * overview, STARTUP keyword: Initial visibility. (line 6) * packages, interaction with other: Interaction. (line 6) * paragraphs, markup rules: Paragraphs. (line 6) @@ -18546,12 +19431,12 @@ Concept index * per-file keywords: Per-file keywords. (line 6) * plain lists: Plain lists. (line 6) * plain lists, in LaTeX export: LaTeX specific attributes. - (line 148) -* plain text external links: External links. (line 70) + (line 156) +* plain text external links: External links. (line 71) * plot tables using Gnuplot: Org-Plot. (line 6) * presentation, of agenda items: Presentation and sorting. (line 6) -* print edition: Summary. (line 58) +* print edition: Summary. (line 52) * printing sparse trees: Sparse trees. (line 53) * priorities: Priorities. (line 6) * priorities, of agenda items: Sorting agenda items. @@ -18560,8 +19445,8 @@ Concept index * projects, for publishing: Project alist. (line 6) * promotion, of subtrees: Structure editing. (line 6) * proof, in LaTeX export: LaTeX specific attributes. - (line 180) -* properties: Properties and Columns. + (line 215) +* properties: Properties and columns. (line 6) * properties, API <1>: Using the property API. (line 6) @@ -18571,27 +19456,32 @@ Concept index (line 6) * properties, searching: Property searches. (line 6) * properties, special: Special properties. (line 6) -* property EXPORT_FILE_NAME: ODT export commands. (line 10) +* property EXPORT_FILE_NAME: ODT export commands. (line 7) * property syntax: Property syntax. (line 6) -* property, +: Property syntax. (line 50) -* property, _ALL: Property syntax. (line 42) -* property, ALT_TITLE: Table of contents. (line 31) +* property, +: Property syntax. (line 52) +* property, _ALL: Property syntax. (line 44) +* property, ALT_TITLE: Table of contents. (line 37) * property, APPENDIX: Headings and sectioning structure. (line 19) -* property, ARCHIVE <1>: Moving subtrees. (line 32) +* property, ARCHIVE <1>: Moving subtrees. (line 37) * property, ARCHIVE: Property inheritance. (line 34) * property, ATTACH_DIR: Attachments. (line 71) * property, ATTACH_DIR_INHERIT: Attachments. (line 76) -* property, BEAMER_ACT: Beamer export. (line 63) -* property, BEAMER_COL: Beamer export. (line 70) -* property, BEAMER_ENV: Beamer export. (line 39) -* property, BEAMER_OPT: Beamer export. (line 63) -* property, BEAMER_REF: Beamer export. (line 50) +* property, BEAMER_ACT: Sectioning Frames and Blocks in Beamer. + (line 38) +* property, BEAMER_COL: Sectioning Frames and Blocks in Beamer. + (line 45) +* property, BEAMER_ENV: Sectioning Frames and Blocks in Beamer. + (line 14) +* property, BEAMER_OPT: Sectioning Frames and Blocks in Beamer. + (line 38) +* property, BEAMER_REF: Sectioning Frames and Blocks in Beamer. + (line 25) * property, CATEGORY <1>: Categories. (line 12) * property, CATEGORY: Property inheritance. (line 30) -* property, COLUMNS <1>: In-buffer settings. (line 30) +* property, COLUMNS <1>: In-buffer settings. (line 28) * property, COLUMNS: Property inheritance. (line 22) * property, COOKIE_DATA <1>: Checkboxes. (line 30) @@ -18603,12 +19493,12 @@ Concept index * property, DESCRIPTION: Headings and sectioning structure. (line 22) * property, Effort: Effort estimates. (line 6) -* property, EXPORT_FILE_NAME: Export settings. (line 192) +* property, EXPORT_FILE_NAME: Export settings. (line 199) * property, EXPORT_LATEX_CLASS: Header and sectioning. (line 22) * property, EXPORT_LATEX_CLASS_OPTIONS: Header and sectioning. (line 22) -* property, EXPORT_TITLE: Document title. (line 13) +* property, EXPORT_TITLE: Document title. (line 10) * property, ID <1>: iCalendar export. (line 21) * property, ID <2>: Capturing column view. (line 22) @@ -18622,11 +19512,11 @@ Concept index (line 38) * property, LOGGING: Tracking TODO state changes. (line 45) +* property, macro: Macro replacement. (line 46) * property, ORDERED <1>: Checkboxes. (line 46) * property, ORDERED: TODO dependencies. (line 6) * property, special, ALLTAGS: Special properties. (line 13) * property, special, BLOCKED: Special properties. (line 13) -* property, special, CATEGORY: Special properties. (line 13) * property, special, CLOCKSUM <1>: Agenda column view. (line 28) * property, special, CLOCKSUM: Special properties. (line 13) * property, special, CLOCKSUM_T <1>: Agenda column view. (line 51) @@ -18634,7 +19524,6 @@ Concept index * property, special, CLOSED: Special properties. (line 13) * property, special, DEADLINE: Special properties. (line 13) * property, special, FILE: Special properties. (line 13) -* property, special, ID: Special properties. (line 13) * property, special, ITEM: Special properties. (line 13) * property, special, PRIORITY: Special properties. (line 13) * property, special, SCHEDULED: Special properties. (line 13) @@ -18643,6 +19532,7 @@ Concept index * property, special, TIMESTAMP_IA: Special properties. (line 13) * property, special, TODO: Special properties. (line 13) * property, SUMMARY: iCalendar export. (line 46) +* property, UNNUMBERED: Export settings. (line 133) * property, VISIBILITY: Initial visibility. (line 21) * property: CLOCK_MODELINE_TOTAL: Clocking commands. (line 20) * property: LAST_REPEAT: Clocking commands. (line 20) @@ -18659,25 +19549,25 @@ Concept index * ranges, time: Timestamps. (line 6) * recomputing table fields: Updating the table. (line 6) * references: References. (line 6) -* references, named: References. (line 102) -* references, remote: References. (line 123) -* references, to a different table: References. (line 123) +* references, named: References. (line 110) +* references, remote: References. (line 131) +* references, to a different table: References. (line 131) * references, to fields: References. (line 15) * references, to ranges: References. (line 63) * refiling notes: Refile and copy. (line 6) -* region, active <1>: ODT export commands. (line 9) +* region, active <1>: ODT export commands. (line 6) * region, active <2>: Built-in table editor. - (line 156) -* region, active: Structure editing. (line 137) + (line 162) +* region, active: Structure editing. (line 146) * regular expressions, with tags search: Matching tags and properties. (line 61) -* relative timer: Relative timer. (line 6) +* relative timer: Timers. (line 6) * remember.el: Cooperation. (line 42) -* reminders: Weekly/daily agenda. (line 107) -* remote editing, bulk, from agenda: Agenda commands. (line 365) -* remote editing, from agenda: Agenda commands. (line 228) -* remote editing, undo: Agenda commands. (line 229) -* remote references: References. (line 123) +* reminders: Weekly/daily agenda. (line 113) +* remote editing, bulk, from agenda: Agenda commands. (line 371) +* remote editing, from agenda: Agenda commands. (line 234) +* remote editing, undo: Agenda commands. (line 235) +* remote references: References. (line 131) * repeated tasks: Repeated tasks. (line 6) * report, of clocked time: The clock table. (line 6) * resolve idle time: Resolving idle time. (line 9) @@ -18686,12 +19576,12 @@ Concept index * RMAIL links: External links. (line 6) * Rose, Sebastian: JavaScript support. (line 6) * row, of field coordinates: References. (line 86) -* RSS feeds: RSS Feeds. (line 6) +* RSS feeds: RSS feeds. (line 6) * rsync: Uploading files. (line 6) * SCHEDULED keyword: Deadlines and scheduling. (line 29) * scheduling: Timestamps. (line 6) -* Schulte, Eric: Working With Source Code. +* Schulte, Eric: Working with source code. (line 6) * Scripts, for agenda processing: Extracting agenda information. (line 6) @@ -18718,18 +19608,18 @@ Concept index * show children, command: Global and local cycling. (line 51) * show hidden text: Visibility cycling. (line 6) -* showall, STARTUP keyword <1>: In-buffer settings. (line 80) +* showall, STARTUP keyword <1>: In-buffer settings. (line 74) * showall, STARTUP keyword: Initial visibility. (line 6) -* showeverything, STARTUP keyword <1>: In-buffer settings. (line 80) +* showeverything, STARTUP keyword <1>: In-buffer settings. (line 74) * showeverything, STARTUP keyword: Initial visibility. (line 6) -* showstars, STARTUP keyword: In-buffer settings. (line 140) +* showstars, STARTUP keyword: In-buffer settings. (line 134) * sitemap, of published pages: Sitemap. (line 6) * sorting, of agenda items: Sorting agenda items. (line 6) * sorting, of plain list: Plain lists. (line 154) * sorting, of subtrees: Structure editing. (line 6) * source blocks, in LaTeX export: LaTeX specific attributes. - (line 159) + (line 167) * source code, batch execution: Batch execution. (line 6) * source code, block header arguments: Header arguments. (line 6) * source code, block structure: Structure of code blocks. @@ -18753,22 +19643,24 @@ Concept index (line 6) * source code, switches: Structure of code blocks. (line 41) -* source code, working with: Working With Source Code. +* source code, working with: Working with source code. (line 6) * sparse tree, for deadlines: Inserting deadline/schedule. - (line 32) + (line 26) * sparse tree, for TODO: TODO basics. (line 42) * sparse tree, tag based: Tags. (line 6) * sparse trees: Sparse trees. (line 6) * Special blocks: Special blocks. (line 6) +* special blocks, in ASCII export: ASCII/Latin-1/UTF-8 export. + (line 75) * special blocks, in LaTeX export: LaTeX specific attributes. - (line 180) + (line 215) * special keywords: In-buffer settings. (line 6) * special symbols: Special symbols. (line 6) * speed keys: Speed keys. (line 6) * speedbar.el: Cooperation. (line 45) * spreadsheet capabilities: The spreadsheet. (line 6) -* square brackets, around links: External links. (line 70) +* square brackets, around links: External links. (line 71) * statistics, for checkboxes: Checkboxes. (line 30) * statistics, for TODO items: Breaking down tasks. (line 6) * storing links: Handling links. (line 10) @@ -18776,7 +19668,7 @@ Concept index * strike-through text, markup rules: Emphasis and monospace. (line 6) * structure editing: Structure editing. (line 6) -* structure of document: Document Structure. (line 6) +* structure of document: Document structure. (line 6) * styles, custom <1>: Working with OpenDocument style files. (line 6) * styles, custom: Applying custom styles. @@ -18785,6 +19677,8 @@ Concept index * sublevels, inclusion into TODO list: Global TODO list. (line 35) * subscript: Subscripts and superscripts. (line 6) +* SUBTITLE (ODT): ODT specific export settings. + (line 23) * subtree cycling: Global and local cycling. (line 10) * subtree visibility states: Global and local cycling. @@ -18810,7 +19704,7 @@ Concept index * tables, in HTML: Tables in HTML export. (line 6) * tables, in LaTeX export: LaTeX specific attributes. - (line 12) + (line 13) * tables, in ODT export <1>: Customizing tables in ODT export. (line 6) * tables, in ODT export: Tables in ODT export. @@ -18821,13 +19715,14 @@ Concept index * tag completion: Completion. (line 6) * tag filtering, in agenda: Filtering/limiting agenda items. (line 17) +* tag hierarchy: Tag hierarchy. (line 6) * tag inheritance: Tag inheritance. (line 6) * tag searches: Tag searches. (line 6) * tags: Tags. (line 6) * tags view: Matching tags and properties. (line 6) * tags, as an agenda view: Storing searches. (line 9) -* tags, groups: Tag groups. (line 6) +* tags, groups: Tag hierarchy. (line 6) * tags, setting: Setting tags. (line 6) * tags-todo: Storing searches. (line 9) * tags-tree: Storing searches. (line 9) @@ -18837,7 +19732,7 @@ Concept index * targets, radio: Radio targets. (line 6) * tasks, breaking down: Breaking down tasks. (line 6) * tasks, repeated: Repeated tasks. (line 6) -* template insertion: Easy Templates. (line 6) +* template insertion: Easy templates. (line 6) * template, custom <1>: Working with OpenDocument style files. (line 6) * template, custom: Applying custom styles. @@ -18850,7 +19745,7 @@ Concept index * text areas, in HTML: Text areas in HTML export. (line 6) * text search: Search view. (line 6) -* thanks: History and Acknowledgments. +* thanks: History and acknowledgments. (line 6) * time clocking: Clocking work time. (line 6) * time format, custom: Custom time format. (line 6) @@ -18858,6 +19753,7 @@ Concept index (line 26) * Time, computing: Durations and time values. (line 6) +* time, macro: Macro replacement. (line 36) * time, reading in minibuffer: The date/time prompt. (line 6) * time-of-day specification: Time-of-day specifications. @@ -18865,18 +19761,20 @@ Concept index * time-sorted view: Timeline. (line 6) * timeline, single file: Timeline. (line 6) * timerange: Timestamps. (line 43) -* times: Dates and Times. (line 6) +* times: Dates and times. (line 6) * timestamp <1>: Timestamps. (line 14) -* timestamp: Dates and Times. (line 6) +* timestamp: Dates and times. (line 6) * timestamp, inactive: Timestamps. (line 52) * timestamp, with repeater interval: Timestamps. (line 26) * timestamps: Timestamps. (line 6) * timestamps, creating: Creating timestamps. (line 6) +* title, macro: Macro replacement. (line 24) * TODO dependencies: TODO dependencies. (line 6) -* TODO items: TODO Items. (line 6) +* TODO dependencies, NOBLOCKING: TODO dependencies. (line 6) +* TODO items: TODO items. (line 6) * TODO keyword matching: Global TODO list. (line 18) * TODO keyword matching, with tags search: Matching tags and properties. - (line 71) + (line 72) * TODO keyword sets: Multiple sets in one file. (line 6) * TODO keywords completion: Completion. (line 6) @@ -18888,9 +19786,9 @@ Concept index * top headline filtering, in agenda: Filtering/limiting agenda items. (line 17) * transient mark mode <1>: Built-in table editor. - (line 156) -* transient mark mode: Structure editing. (line 137) -* transient-mark-mode: ODT export commands. (line 9) + (line 162) +* transient mark mode: Structure editing. (line 146) +* transient-mark-mode: ODT export commands. (line 6) * translator function: Translator functions. (line 6) * trees, sparse: Sparse trees. (line 6) @@ -18899,7 +19797,7 @@ Concept index * types as TODO keywords: TODO types. (line 6) * underlined text, markup rules: Emphasis and monospace. (line 6) -* undoing remote-editing events: Agenda commands. (line 229) +* undoing remote-editing events: Agenda commands. (line 235) * unison: Uploading files. (line 6) * unoconv: Extending ODT export. (line 11) @@ -18911,6 +19809,8 @@ Concept index * variables, for customization: Customization. (line 6) * vectors, in table calculations: Formula syntax for Calc. (line 11) +* verbatim blocks, in LaTeX export: LaTeX specific attributes. + (line 201) * verbatim text, markup rules: Emphasis and monospace. (line 6) * viper.el: Conflicts. (line 97) @@ -18918,8 +19818,8 @@ Concept index * visibility cycling, drawers: Drawers. (line 6) * visibility, initialize: Initial visibility. (line 6) * visible text, printing: Sparse trees. (line 53) -* VM links: External links. (line 43) -* WANDERLUST links: External links. (line 43) +* VM links: External links. (line 44) +* WANDERLUST links: External links. (line 44) * weekly agenda: Weekly/daily agenda. (line 6) * Wiegley, John: Cooperation. (line 42) * windmove.el: Conflicts. (line 84) @@ -18938,83 +19838,85 @@ Key index [index] * Menu: -* $: Agenda commands. (line 263) -* %: Agenda commands. (line 382) +* $: Agenda commands. (line 269) +* %: Agenda commands. (line 388) * ': CDLaTeX mode. (line 43) -* *: Agenda commands. (line 367) -* +: Agenda commands. (line 285) -* ,: Agenda commands. (line 277) -* -: Agenda commands. (line 290) -* .: Agenda commands. (line 97) -* / <1>: Agenda commands. (line 198) +* *: Agenda commands. (line 373) +* +: Agenda commands. (line 291) +* ,: Agenda commands. (line 283) +* -: Agenda commands. (line 296) +* .: Agenda commands. (line 103) +* / <1>: Agenda commands. (line 204) * /: Filtering/limiting agenda items. (line 17) -* :: Agenda commands. (line 273) -* ;: Countdown timer. (line 6) -* < <1>: Agenda commands. (line 205) +* :: Agenda commands. (line 279) +* ;: Timers. (line 6) +* < <1>: Agenda commands. (line 211) * < <2>: Filtering/limiting agenda items. - (line 93) + (line 76) * < <3>: Agenda files. (line 57) * < <4>: The date/time prompt. (line 82) * <: Using column view. (line 70) -* <1>: Agenda commands. (line 37) +* <1>: Agenda commands. (line 43) * <2>: The date/time prompt. (line 82) * <3>: Setting tags. (line 116) * <4>: Handling links. (line 122) * : Built-in table editor. - (line 65) -* <1>: Agenda commands. (line 28) + (line 69) +* <1>: Agenda commands. (line 34) * : Setting tags. (line 115) * <1>: CDLaTeX mode. (line 23) -* <2>: Agenda commands. (line 34) +* <2>: Agenda commands. (line 40) * <3>: Setting tags. (line 107) * <4>: Editing and debugging formulas. (line 57) * <5>: Built-in table editor. - (line 58) + (line 62) * <6>: Plain lists. (line 68) -* <7>: Structure editing. (line 33) +* <7>: Structure editing. (line 42) * : Global and local cycling. (line 10) -* = <1>: Agenda commands. (line 213) +* = <1>: Agenda commands. (line 219) * =: Filtering/limiting agenda items. - (line 103) -* > <1>: Agenda commands. (line 326) + (line 87) +* > <1>: Agenda commands. (line 332) * > <2>: Agenda files. (line 61) * > <3>: The date/time prompt. (line 82) * >: Using column view. (line 70) * ?: Pulling from MobileOrg. (line 34) -* [ <1>: Agenda commands. (line 121) +* [ <1>: Agenda commands. (line 127) * [: Filtering/limiting agenda items. - (line 83) -* \ <1>: Agenda commands. (line 202) + (line 66) +* \ <1>: Agenda commands. (line 208) * \: Filtering/limiting agenda items. - (line 76) + (line 59) * ]: Filtering/limiting agenda items. - (line 83) + (line 66) * ^ <1>: CDLaTeX mode. (line 33) -* ^ <2>: Agenda commands. (line 209) +* ^ <2>: Agenda commands. (line 215) * ^: Filtering/limiting agenda items. - (line 99) -* _: CDLaTeX mode. (line 33) + (line 83) +* _ <1>: CDLaTeX mode. (line 33) +* _: Filtering/limiting agenda items. + (line 96) * `: CDLaTeX mode. (line 39) -* a: Agenda commands. (line 251) -* A: Agenda commands. (line 64) +* a: Agenda commands. (line 257) +* A: Agenda commands. (line 70) * a: Using column view. (line 59) -* B: Agenda commands. (line 385) -* b: Agenda commands. (line 94) -* C: Agenda commands. (line 489) -* c: Agenda commands. (line 456) +* B: Agenda commands. (line 391) +* b: Agenda commands. (line 100) +* C: Agenda commands. (line 494) +* c: Agenda commands. (line 461) * C-#: Advanced features. (line 10) * C-': Agenda files. (line 22) * C-,: Agenda files. (line 22) * C-0 C-c C-w: Refile and copy. (line 47) -* C-: Structure editing. (line 19) -* C-_: Agenda commands. (line 229) +* C-: Structure editing. (line 28) +* C-_: Agenda commands. (line 235) * C-c !: Creating timestamps. (line 15) * C-c #: Checkboxes. (line 84) * C-c $: Moving subtrees. (line 9) @@ -19022,37 +19924,38 @@ Key index * C-c &: Handling links. (line 146) * C-c ' <1>: Cooperation. (line 61) * C-c ' <2>: Editing source code. (line 6) -* C-c ' <3>: Include files. (line 36) -* C-c ' <4>: Literal examples. (line 70) -* C-c ': Editing and debugging formulas. +* C-c ' <3>: Include files. (line 57) +* C-c ' <4>: Literal examples. (line 73) +* C-c ' <5>: Editing and debugging formulas. (line 36) +* C-c ': Footnotes. (line 97) * C-c * <1>: Updating the table. (line 13) * C-c * <2>: Plain lists. (line 139) -* C-c *: Structure editing. (line 126) +* C-c *: Structure editing. (line 135) * C-c +: Built-in table editor. - (line 156) + (line 162) * C-c ,: Priorities. (line 24) * C-c - <1>: Built-in table editor. - (line 101) + (line 105) * C-c -: Plain lists. (line 127) * C-c .: Creating timestamps. (line 10) * C-c / <1>: Conflicts. (line 97) * C-c /: Sparse trees. (line 15) * C-c / a: Inserting deadline/schedule. - (line 39) + (line 33) * C-c / b: Inserting deadline/schedule. - (line 36) + (line 30) * C-c / d: Inserting deadline/schedule. - (line 29) + (line 23) * C-c / m <1>: Property searches. (line 10) * C-c / m: Tag searches. (line 9) * C-c / p: Property searches. (line 29) * C-c / r: Sparse trees. (line 17) * C-c / t: TODO basics. (line 39) -* C-c ;: Comment lines. (line 12) +* C-c ;: Comment lines. (line 19) * C-c <: Creating timestamps. (line 29) * C-c : Built-in table editor. - (line 105) + (line 109) * C-c : Global and local cycling. (line 51) * C-c = <1>: Editing and debugging formulas. @@ -19061,17 +19964,17 @@ Key index * C-c >: Creating timestamps. (line 33) * C-c ?: Editing and debugging formulas. (line 22) -* C-c @: Structure editing. (line 63) +* C-c @: Structure editing. (line 72) * C-c [: Agenda files. (line 15) * C-c \ <1>: Property searches. (line 10) * C-c \: Tag searches. (line 9) * C-c ]: Agenda files. (line 19) * C-c ^ <1>: Built-in table editor. - (line 109) + (line 113) * C-c ^ <2>: Plain lists. (line 154) -* C-c ^: Structure editing. (line 105) +* C-c ^: Structure editing. (line 114) * C-c `: Built-in table editor. - (line 174) + (line 180) * C-c a: Conventions. (line 35) * C-c a !: Stuck projects. (line 14) * C-c a #: Stuck projects. (line 13) @@ -19079,7 +19982,7 @@ Key index (line 44) * C-c a a: Weekly/daily agenda. (line 9) * C-c a C: Storing searches. (line 9) -* C-c a e: Exporting Agenda Views. +* C-c a e: Exporting agenda views. (line 64) * C-c a L: Timeline. (line 10) * C-c a M: Matching tags and properties. @@ -19098,7 +20001,7 @@ Key index * C-c c: Conventions. (line 35) * C-c c C: Capture templates. (line 10) * C-c C-*: Plain lists. (line 144) -* C-c C-a <1>: Agenda commands. (line 298) +* C-c C-a <1>: Agenda commands. (line 304) * C-c C-a: Attachments. (line 26) * C-c C-a a: Attachments. (line 31) * C-c C-a c: Attachments. (line 37) @@ -19114,7 +20017,7 @@ Key index * C-c C-a o: Attachments. (line 48) * C-c C-a s: Attachments. (line 70) * C-c C-a z: Attachments. (line 44) -* C-c C-b <1>: Beamer export. (line 142) +* C-c C-b <1>: Editing support. (line 11) * C-c C-b: Motion. (line 15) * C-c C-c <1>: Cooperation. (line 52) * C-c C-c <2>: The very busy C-c C-c key. @@ -19122,9 +20025,9 @@ Key index * C-c C-c <3>: Key bindings and useful functions. (line 11) * C-c C-c <4>: Evaluating code blocks. - (line 19) + (line 18) * C-c C-c <5>: Previewing LaTeX fragments. - (line 15) + (line 23) * C-c C-c <6>: Using capture. (line 15) * C-c C-c <7>: The clock table. (line 16) * C-c C-c <8>: Clocking commands. (line 51) @@ -19132,24 +20035,24 @@ Key index * C-c C-c <10>: Capturing column view. (line 51) * C-c C-c <11>: Using column view. (line 52) -* C-c C-c <12>: Property syntax. (line 90) +* C-c C-c <12>: Property syntax. (line 92) * C-c C-c <13>: Setting tags. (line 20) * C-c C-c <14>: Checkboxes. (line 52) * C-c C-c <15>: Editing and debugging formulas. (line 47) * C-c C-c <16>: Built-in table editor. - (line 57) + (line 58) * C-c C-c <17>: Footnotes. (line 86) * C-c C-c: Plain lists. (line 122) -* C-c C-c c: Property syntax. (line 108) -* C-c C-c D: Property syntax. (line 105) -* C-c C-c d: Property syntax. (line 102) -* C-c C-c s: Property syntax. (line 94) -* C-c C-d <1>: Agenda commands. (line 305) +* C-c C-c c: Property syntax. (line 110) +* C-c C-c D: Property syntax. (line 107) +* C-c C-c d: Property syntax. (line 104) +* C-c C-c s: Property syntax. (line 96) +* C-c C-d <1>: Agenda commands. (line 311) * C-c C-d: Inserting deadline/schedule. (line 9) -* C-c C-e: The Export Dispatcher. - (line 11) +* C-c C-e: The export dispatcher. + (line 10) * C-c C-e c a: iCalendar export. (line 34) * C-c C-e c c: iCalendar export. (line 39) * C-c C-e c f: iCalendar export. (line 32) @@ -19162,20 +20065,23 @@ Key index (line 9) * C-c C-e i t: Texinfo export commands. (line 6) -* C-c C-e l B: Beamer export. (line 16) -* C-c C-e l b: Beamer export. (line 13) +* C-c C-e l B: Beamer export commands. + (line 9) +* C-c C-e l b: Beamer export commands. + (line 6) * C-c C-e l L: LaTeX export commands. (line 9) * C-c C-e l l: LaTeX export commands. (line 6) * C-c C-e l p: LaTeX export commands. (line 12) -* C-c C-e l P: Beamer export. (line 19) +* C-c C-e l P: Beamer export commands. + (line 12) * C-c C-e m M: Markdown export. (line 19) * C-c C-e m m: Markdown export. (line 16) * C-c C-e O O: Org export. (line 16) * C-c C-e O o: Org export. (line 13) -* C-c C-e o o: ODT export commands. (line 9) +* C-c C-e o o: ODT export commands. (line 6) * C-c C-e P a: Triggering publication. (line 16) * C-c C-e P f: Triggering publication. @@ -19185,9 +20091,9 @@ Key index * C-c C-e P x: Triggering publication. (line 8) * C-c C-e t A/L/U: ASCII/Latin-1/UTF-8 export. - (line 22) + (line 25) * C-c C-e t a/l/u: ASCII/Latin-1/UTF-8 export. - (line 18) + (line 21) * C-c C-f: Motion. (line 12) * C-c C-j: Motion. (line 21) * C-c C-k <1>: Using capture. (line 31) @@ -19197,7 +20103,7 @@ Key index * C-c C-n: Motion. (line 8) * C-c C-o <1>: Key bindings and useful functions. (line 11) -* C-c C-o <2>: Agenda commands. (line 56) +* C-c C-o <2>: Agenda commands. (line 62) * C-c C-o <3>: Creating timestamps. (line 38) * C-c C-o <4>: Handling links. (line 101) * C-c C-o: Footnotes. (line 90) @@ -19209,7 +20115,7 @@ Key index (line 53) * C-c C-r: Global and local cycling. (line 38) -* C-c C-s <1>: Agenda commands. (line 301) +* C-c C-s <1>: Agenda commands. (line 307) * C-c C-s: Inserting deadline/schedule. (line 17) * C-c C-t <1>: Clocking commands. (line 67) @@ -19279,7 +20185,7 @@ Key index (line 50) * C-c C-v i <1>: Key bindings and useful functions. (line 48) -* C-c C-v i: Library of Babel. (line 20) +* C-c C-v i: Library of Babel. (line 19) * C-c C-v j: Key bindings and useful functions. (line 44) * C-c C-v l: Key bindings and useful functions. @@ -19306,50 +20212,49 @@ Key index (line 58) * C-c C-v z: Key bindings and useful functions. (line 52) -* C-c C-w <1>: Agenda commands. (line 248) +* C-c C-w <1>: Agenda commands. (line 254) * C-c C-w <2>: Refile and copy. (line 14) * C-c C-w <3>: Using capture. (line 22) -* C-c C-w: Structure editing. (line 101) -* C-c C-x ,: Relative timer. (line 21) -* C-c C-x -: Relative timer. (line 13) -* C-c C-x .: Relative timer. (line 10) -* C-c C-x 0: Relative timer. (line 30) -* C-c C-x ;: Countdown timer. (line 6) +* C-c C-w: Structure editing. (line 110) +* C-c C-x -: Timers. (line 35) +* C-c C-x .: Timers. (line 31) +* C-c C-x 0: Timers. (line 12) +* C-c C-x ;: Timers. (line 20) * C-c C-x <: Agenda files. (line 42) -* C-c C-x > <1>: Agenda commands. (line 188) +* C-c C-x > <1>: Agenda commands. (line 194) * C-c C-x >: Agenda files. (line 49) * C-c C-x \ <1>: Subscripts and superscripts. (line 21) -* C-c C-x \: Special symbols. (line 31) -* C-c C-x A: Agenda commands. (line 259) -* C-c C-x a: Agenda commands. (line 256) +* C-c C-x \ <2>: Special symbols. (line 31) +* C-c C-x \: Timers. (line 44) +* C-c C-x _: Timers. (line 47) +* C-c C-x A: Agenda commands. (line 265) +* C-c C-x a: Agenda commands. (line 262) * C-c C-x A: Internal archiving. (line 49) * C-c C-x a: Internal archiving. (line 36) -* C-c C-x b <1>: Agenda commands. (line 47) +* C-c C-x b <1>: Agenda commands. (line 53) * C-c C-x b: Global and local cycling. (line 55) -* C-c C-x c: Structure editing. (line 93) -* C-c C-x C-a <1>: Agenda commands. (line 251) +* C-c C-x c: Structure editing. (line 102) +* C-c C-x C-a <1>: Agenda commands. (line 257) * C-c C-x C-a: Archiving. (line 11) * C-c C-x C-b: Checkboxes. (line 56) * C-c C-x C-c <1>: Agenda column view. (line 11) -* C-c C-x C-c <2>: Agenda commands. (line 177) +* C-c C-x C-c <2>: Agenda commands. (line 183) * C-c C-x C-c: Using column view. (line 9) * C-c C-x C-d: Clocking commands. (line 80) * C-c C-x C-e <1>: Effort estimates. (line 17) * C-c C-x C-e: Clocking commands. (line 48) * C-c C-x C-i: Clocking commands. (line 6) * C-c C-x C-j: Clocking commands. (line 75) -* C-c C-x C-k: Inserting deadline/schedule. - (line 23) * C-c C-x C-l: Previewing LaTeX fragments. - (line 9) + (line 17) * C-c C-x C-n: Handling links. (line 152) * C-c C-x C-o: Clocking commands. (line 34) * C-c C-x C-p: Handling links. (line 152) * C-c C-x C-q: Clocking commands. (line 71) * C-c C-x C-r: The clock table. (line 10) -* C-c C-x C-s <1>: Agenda commands. (line 263) +* C-c C-x C-s <1>: Agenda commands. (line 269) * C-c C-x C-s: Moving subtrees. (line 9) * C-c C-x C-t: Custom time format. (line 12) * C-c C-x C-u <1>: Dynamic blocks. (line 21) @@ -19358,37 +20263,39 @@ Key index (line 51) * C-c C-x C-v: Handling links. (line 133) * C-c C-x C-w <1>: Built-in table editor. - (line 130) -* C-c C-x C-w: Structure editing. (line 67) + (line 136) +* C-c C-x C-w: Structure editing. (line 76) * C-c C-x C-x: Clocking commands. (line 42) * C-c C-x C-y <1>: Built-in table editor. - (line 134) -* C-c C-x C-y: Structure editing. (line 75) + (line 140) +* C-c C-x C-y: Structure editing. (line 84) * C-c C-x d: Drawers. (line 6) * C-c C-x e: Effort estimates. (line 14) * C-c C-x f: Footnotes. (line 51) -* C-c C-x G: RSS Feeds. (line 27) -* C-c C-x g: RSS Feeds. (line 23) +* C-c C-x G: RSS feeds. (line 27) +* C-c C-x g: RSS feeds. (line 23) * C-c C-x i: Capturing column view. (line 49) * C-c C-x M-w <1>: Built-in table editor. - (line 126) -* C-c C-x M-w: Structure editing. (line 71) + (line 132) +* C-c C-x M-w: Structure editing. (line 80) * C-c C-x o <1>: Checkboxes. (line 76) -* C-c C-x o: TODO dependencies. (line 29) +* C-c C-x o: TODO dependencies. (line 37) * C-c C-x p <1>: Header arguments in Org mode properties. (line 34) -* C-c C-x p: Property syntax. (line 81) -* C-c C-x q: Tag groups. (line 34) +* C-c C-x p: Property syntax. (line 83) +* C-c C-x q: Tag hierarchy. (line 87) * C-c C-x v: Global and local cycling. (line 61) * C-c C-y <1>: Clocking commands. (line 51) * C-c C-y: Creating timestamps. (line 59) -* C-c C-z <1>: Agenda commands. (line 293) +* C-c C-z <1>: Agenda commands. (line 299) * C-c C-z: Drawers. (line 35) -* C-c l <1>: Literal examples. (line 78) +* C-c l <1>: Literal examples. (line 81) * C-c l: Handling links. (line 9) * C-c M-w: Refile and copy. (line 12) +* C-c SPC: Built-in table editor. + (line 59) * C-c { <1>: CDLaTeX mode. (line 21) * C-c {: Editing and debugging formulas. (line 32) @@ -19397,12 +20304,12 @@ Key index * C-c }: Editing and debugging formulas. (line 26) * C-c ~: Cooperation. (line 63) -* C-k: Agenda commands. (line 242) -* C-S- <1>: Agenda commands. (line 240) +* C-k: Agenda commands. (line 248) +* C-S- <1>: Agenda commands. (line 246) * C-S-: Multiple sets in one file. (line 25) -* C-S-: Structure editing. (line 28) -* C-S- <1>: Agenda commands. (line 237) +* C-S-: Structure editing. (line 37) +* C-S- <1>: Agenda commands. (line 243) * C-S-: Multiple sets in one file. (line 25) * C-S-: Clocking commands. (line 56) @@ -19413,13 +20320,12 @@ Key index * C-u C-c = <1>: Editing and debugging formulas. (line 13) * C-u C-c =: Field and range formulas. - (line 28) + (line 27) * C-u C-c c: Using capture. (line 43) * C-u C-c C-c: Updating the table. (line 19) * C-u C-c C-l: Handling links. (line 86) * C-u C-c C-t: TODO basics. (line 28) * C-u C-c C-w: Refile and copy. (line 33) -* C-u C-c C-x ,: Relative timer. (line 25) * C-u C-c C-x a: Internal archiving. (line 39) * C-u C-c C-x C-s: Moving subtrees. (line 11) * C-u C-c C-x C-u <1>: Dynamic blocks. (line 22) @@ -19437,113 +20343,114 @@ Key index * C-u C-u C-c C-t: Multiple sets in one file. (line 25) * C-u C-u C-c C-w: Refile and copy. (line 36) +* C-u C-u C-c C-x C-s: Moving subtrees. (line 18) * C-u C-u C-u : Global and local cycling. (line 35) -* C-u C-u C-u C-c C-t: TODO dependencies. (line 34) +* C-u C-u C-u C-c C-t: TODO dependencies. (line 42) * C-v: The date/time prompt. (line 82) -* C-x C-s <1>: Agenda commands. (line 173) +* C-x C-s <1>: Agenda commands. (line 179) * C-x C-s: Editing and debugging formulas. (line 47) -* C-x C-w <1>: Exporting Agenda Views. +* C-x C-w <1>: Exporting agenda views. (line 12) -* C-x C-w: Agenda commands. (line 506) -* C-x n b: Structure editing. (line 120) -* C-x n s: Structure editing. (line 117) -* C-x n w: Structure editing. (line 123) -* C-y: Structure editing. (line 81) -* D: Agenda commands. (line 106) -* d: Agenda commands. (line 69) -* E: Agenda commands. (line 151) +* C-x C-w: Agenda commands. (line 511) +* C-x n b: Structure editing. (line 129) +* C-x n s: Structure editing. (line 126) +* C-x n w: Structure editing. (line 132) +* C-y: Structure editing. (line 90) +* D: Agenda commands. (line 112) +* d: Agenda commands. (line 75) +* E: Agenda commands. (line 157) * e: Using column view. (line 46) -* f: Agenda commands. (line 88) -* F: Agenda commands. (line 40) -* g: Agenda commands. (line 170) -* G: Agenda commands. (line 159) +* f: Agenda commands. (line 94) +* F: Agenda commands. (line 46) +* g: Agenda commands. (line 176) +* G: Agenda commands. (line 165) * g: Using column view. (line 23) -* H: Agenda commands. (line 493) -* i: Agenda commands. (line 461) -* I: Agenda commands. (line 331) -* J: Agenda commands. (line 103) -* j: Agenda commands. (line 100) -* k: Agenda commands. (line 344) -* k a: Inserting deadline/schedule. - (line 26) -* k s: Inserting deadline/schedule. - (line 26) -* l: Agenda commands. (line 110) -* L: Agenda commands. (line 31) -* M: Agenda commands. (line 480) -* m: Agenda commands. (line 365) -* M-*: Agenda commands. (line 379) -* M- <1>: Agenda commands. (line 358) +* H: Agenda commands. (line 498) +* i: Agenda commands. (line 466) +* I: Agenda commands. (line 337) +* J: Agenda commands. (line 109) +* j: Agenda commands. (line 106) +* k: Agenda commands. (line 350) +* l: Agenda commands. (line 116) +* L: Agenda commands. (line 37) +* M: Agenda commands. (line 485) +* m: Agenda commands. (line 371) +* M-*: Agenda commands. (line 385) +* M- <1>: Agenda commands. (line 364) * M- <2>: Editing and debugging formulas. (line 77) * M- <3>: Built-in table editor. - (line 90) + (line 94) * M-: Plain lists. (line 97) * M- <1>: Built-in table editor. - (line 82) + (line 86) * M- <2>: Plain lists. (line 103) -* M-: Structure editing. (line 39) -* M- <1>: Relative timer. (line 17) +* M-: Structure editing. (line 48) +* M- <1>: Timers. (line 40) * M- <2>: Built-in table editor. - (line 141) + (line 147) * M- <3>: Plain lists. (line 79) * M-: Structure editing. (line 6) * M- <1>: Built-in table editor. - (line 82) + (line 86) * M- <2>: Plain lists. (line 103) -* M-: Structure editing. (line 42) +* M-: Structure editing. (line 51) * M- <1>: Completion. (line 16) -* M- <2>: Property syntax. (line 78) +* M- <2>: Property syntax. (line 80) * M- <3>: Setting tags. (line 6) -* M- <4>: Per-file keywords. (line 24) +* M- <4>: Per-file keywords. (line 23) * M-: Editing and debugging formulas. (line 64) -* M- <1>: Agenda commands. (line 354) +* M- <1>: Agenda commands. (line 360) * M- <2>: Editing and debugging formulas. (line 77) * M- <3>: Built-in table editor. - (line 90) + (line 94) * M-: Plain lists. (line 97) * M-a: Built-in table editor. - (line 70) + (line 74) * M-down: Key bindings and useful functions. (line 13) * M-e: Built-in table editor. - (line 74) + (line 78) * M-g M-n: Sparse trees. (line 29) * M-g M-p: Sparse trees. (line 32) * M-g n: Sparse trees. (line 29) * M-g p: Sparse trees. (line 32) -* M-h: Structure editing. (line 57) -* M-m: Agenda commands. (line 376) -* M-S- <1>: Editing and debugging formulas. +* M-h: Structure editing. (line 66) +* M-m: Agenda commands. (line 382) +* M-S- <1>: The date/time prompt. + (line 82) +* M-S- <2>: Editing and debugging formulas. (line 72) -* M-S- <2>: Built-in table editor. - (line 97) -* M-S-: Structure editing. (line 54) +* M-S- <3>: Built-in table editor. + (line 101) +* M-S-: Structure editing. (line 63) * M-S- <1>: The date/time prompt. (line 82) * M-S- <2>: Built-in table editor. - (line 84) + (line 88) * M-S- <3>: Plain lists. (line 108) -* M-S-: Structure editing. (line 45) +* M-S-: Structure editing. (line 54) * M-S- <1>: Checkboxes. (line 73) * M-S- <2>: Plain lists. (line 89) -* M-S-: Structure editing. (line 24) +* M-S-: Structure editing. (line 33) * M-S- <1>: The date/time prompt. (line 82) * M-S- <2>: Built-in table editor. - (line 87) + (line 91) * M-S- <3>: Plain lists. (line 108) -* M-S-: Structure editing. (line 48) -* M-S- <1>: Editing and debugging formulas. +* M-S-: Structure editing. (line 57) +* M-S- <1>: The date/time prompt. + (line 82) +* M-S- <2>: Editing and debugging formulas. (line 72) -* M-S- <2>: Built-in table editor. - (line 94) -* M-S-: Structure editing. (line 51) +* M-S- <3>: Built-in table editor. + (line 98) +* M-S-: Structure editing. (line 60) * M-up: Key bindings and useful functions. (line 12) * M-v: The date/time prompt. @@ -19553,27 +20460,28 @@ Key index (line 82) * mouse-1 <2>: Handling links. (line 124) * mouse-1: Footnotes. (line 90) -* mouse-2 <1>: Agenda commands. (line 34) +* mouse-2 <1>: Agenda commands. (line 40) * mouse-2 <2>: Handling links. (line 124) * mouse-2: Footnotes. (line 90) -* mouse-3 <1>: Agenda commands. (line 28) +* mouse-3 <1>: Agenda commands. (line 34) * mouse-3: Handling links. (line 129) +* N: Agenda commands. (line 23) * n <1>: Agenda commands. (line 19) * n: Using column view. (line 42) -* O: Agenda commands. (line 335) -* o: Agenda commands. (line 66) -* P: Agenda commands. (line 282) +* O: Agenda commands. (line 341) +* o: Agenda commands. (line 72) +* P: Agenda commands. (line 26) * p <1>: Agenda commands. (line 20) * p: Using column view. (line 42) -* q <1>: Agenda commands. (line 520) +* q <1>: Agenda commands. (line 525) * q: Using column view. (line 26) -* r: Agenda commands. (line 163) -* R: Agenda commands. (line 132) +* r: Agenda commands. (line 169) +* R: Agenda commands. (line 138) * r <1>: Global TODO list. (line 23) * r: Using column view. (line 19) -* S: Agenda commands. (line 484) -* s: Agenda commands. (line 173) -* S- <1>: Agenda commands. (line 290) +* S: Agenda commands. (line 489) +* s: Agenda commands. (line 179) +* S- <1>: Agenda commands. (line 296) * S- <2>: The date/time prompt. (line 82) * S- <3>: Creating timestamps. (line 47) @@ -19581,13 +20489,13 @@ Key index * S- <5>: Editing and debugging formulas. (line 67) * S-: Plain lists. (line 90) -* S- <1>: Agenda commands. (line 322) +* S- <1>: Agenda commands. (line 328) * S- <2>: The clock table. (line 24) * S- <3>: The date/time prompt. (line 82) * S- <4>: Creating timestamps. (line 42) * S- <5>: Using column view. (line 35) -* S- <6>: Property syntax. (line 98) +* S- <6>: Property syntax. (line 100) * S- <7>: Multiple sets in one file. (line 32) * S- <8>: TODO basics. (line 34) @@ -19595,14 +20503,14 @@ Key index (line 67) * S-: Plain lists. (line 149) * S-: Built-in table editor. - (line 159) -* S- <1>: Agenda commands. (line 308) + (line 165) +* S- <1>: Agenda commands. (line 314) * S- <2>: The clock table. (line 24) * S- <3>: The date/time prompt. (line 82) * S- <4>: Creating timestamps. (line 42) * S- <5>: Using column view. (line 35) -* S- <6>: Property syntax. (line 98) +* S- <6>: Property syntax. (line 100) * S- <7>: Multiple sets in one file. (line 32) * S- <8>: TODO basics. (line 34) @@ -19610,10 +20518,10 @@ Key index (line 67) * S-: Plain lists. (line 149) * S- <1>: Built-in table editor. - (line 62) + (line 66) * S-: Global and local cycling. (line 22) -* S- <1>: Agenda commands. (line 285) +* S- <1>: Agenda commands. (line 291) * S- <2>: The date/time prompt. (line 82) * S- <3>: Creating timestamps. (line 47) @@ -19624,38 +20532,38 @@ Key index * S-M-: TODO basics. (line 58) * S-M-: Using column view. (line 72) * S-M-: Clocking commands. (line 60) -* T: Agenda commands. (line 268) -* t: Agenda commands. (line 233) -* U: Agenda commands. (line 373) -* u: Agenda commands. (line 370) +* T: Agenda commands. (line 274) +* t: Agenda commands. (line 239) +* U: Agenda commands. (line 379) +* u: Agenda commands. (line 376) * v: Using column view. (line 55) -* v [: Agenda commands. (line 121) -* v A: Agenda commands. (line 128) -* v a: Agenda commands. (line 125) -* v c: Agenda commands. (line 143) -* v d: Agenda commands. (line 69) -* v E: Agenda commands. (line 151) -* v L: Agenda commands. (line 113) -* v l: Agenda commands. (line 110) -* v m: Agenda commands. (line 74) -* v R: Agenda commands. (line 132) -* v SPC: Agenda commands. (line 76) -* v t: Agenda commands. (line 73) -* v w: Agenda commands. (line 72) -* v y: Agenda commands. (line 75) -* w: Agenda commands. (line 72) -* x: Agenda commands. (line 521) -* X: Agenda commands. (line 338) -* z: Agenda commands. (line 293) +* v [: Agenda commands. (line 127) +* v A: Agenda commands. (line 134) +* v a: Agenda commands. (line 131) +* v c: Agenda commands. (line 149) +* v d: Agenda commands. (line 75) +* v E: Agenda commands. (line 157) +* v L: Agenda commands. (line 119) +* v l: Agenda commands. (line 116) +* v m: Agenda commands. (line 80) +* v R: Agenda commands. (line 138) +* v SPC: Agenda commands. (line 82) +* v t: Agenda commands. (line 79) +* v w: Agenda commands. (line 78) +* v y: Agenda commands. (line 81) +* w: Agenda commands. (line 78) +* x: Agenda commands. (line 526) +* X: Agenda commands. (line 344) +* z: Agenda commands. (line 299) * {: Filtering/limiting agenda items. - (line 83) -* | <1>: Agenda commands. (line 222) + (line 66) +* | <1>: Agenda commands. (line 228) * |: Filtering/limiting agenda items. - (line 112) + (line 110) * }: Filtering/limiting agenda items. - (line 83) + (line 66) * ~: Filtering/limiting agenda items. - (line 153) + (line 152)  File: org, Node: Command and Function Index, Next: Variable Index, Prev: Key Index, Up: Top @@ -19671,118 +20579,122 @@ Command and function index * next-error: Sparse trees. (line 29) * org-agenda <1>: Conventions. (line 35) * org-agenda: Activation. (line 6) -* org-agenda-add-note: Agenda commands. (line 293) -* org-agenda-archive: Agenda commands. (line 263) +* org-agenda-add-note: Agenda commands. (line 299) +* org-agenda-archive: Agenda commands. (line 269) * org-agenda-archive-default-with-confirmation: Agenda commands. - (line 251) -* org-agenda-archive-to-archive-sibling: Agenda commands. (line 259) -* org-agenda-archives-mode: Agenda commands. (line 125) -* org-agenda-archives-mode 'files: Agenda commands. (line 128) -* org-agenda-bulk-action: Agenda commands. (line 385) -* org-agenda-bulk-mark: Agenda commands. (line 365) -* org-agenda-bulk-mark-all: Agenda commands. (line 367) -* org-agenda-bulk-mark-regexp: Agenda commands. (line 382) -* org-agenda-bulk-remove-all-marks: Agenda commands. (line 373) -* org-agenda-bulk-toggle: Agenda commands. (line 376) -* org-agenda-bulk-toggle-all: Agenda commands. (line 379) -* org-agenda-bulk-unmark: Agenda commands. (line 370) -* org-agenda-capture: Agenda commands. (line 344) -* org-agenda-clock-cancel: Agenda commands. (line 338) -* org-agenda-clock-goto: Agenda commands. (line 103) -* org-agenda-clock-in: Agenda commands. (line 331) -* org-agenda-clock-out: Agenda commands. (line 335) -* org-agenda-clockreport-mode: Agenda commands. (line 132) + (line 257) +* org-agenda-archive-to-archive-sibling: Agenda commands. (line 265) +* org-agenda-archives-mode: Agenda commands. (line 131) +* org-agenda-archives-mode 'files: Agenda commands. (line 134) +* org-agenda-bulk-action: Agenda commands. (line 391) +* org-agenda-bulk-mark: Agenda commands. (line 371) +* org-agenda-bulk-mark-all: Agenda commands. (line 373) +* org-agenda-bulk-mark-regexp: Agenda commands. (line 388) +* org-agenda-bulk-remove-all-marks: Agenda commands. (line 379) +* org-agenda-bulk-toggle: Agenda commands. (line 382) +* org-agenda-bulk-toggle-all: Agenda commands. (line 385) +* org-agenda-bulk-unmark: Agenda commands. (line 376) +* org-agenda-capture: Agenda commands. (line 350) +* org-agenda-clock-cancel: Agenda commands. (line 344) +* org-agenda-clock-goto: Agenda commands. (line 109) +* org-agenda-clock-in: Agenda commands. (line 337) +* org-agenda-clock-out: Agenda commands. (line 341) +* org-agenda-clockreport-mode: Agenda commands. (line 138) * org-agenda-columns <1>: Agenda column view. (line 11) -* org-agenda-columns: Agenda commands. (line 177) -* org-agenda-convert-date: Agenda commands. (line 489) -* org-agenda-date-prompt: Agenda commands. (line 326) -* org-agenda-day-view: Agenda commands. (line 69) -* org-agenda-deadline: Agenda commands. (line 305) -* org-agenda-diary-entry: Agenda commands. (line 461) -* org-agenda-do-date-earlier: Agenda commands. (line 322) -* org-agenda-do-date-later: Agenda commands. (line 308) -* org-agenda-drag-line-backward: Agenda commands. (line 354) -* org-agenda-drag-line-forward: Agenda commands. (line 358) -* org-agenda-earlier: Agenda commands. (line 94) -* org-agenda-entry-text-mode: Agenda commands. (line 151) -* org-agenda-exit: Agenda commands. (line 521) +* org-agenda-columns: Agenda commands. (line 183) +* org-agenda-convert-date: Agenda commands. (line 494) +* org-agenda-date-prompt: Agenda commands. (line 332) +* org-agenda-day-view: Agenda commands. (line 75) +* org-agenda-deadline: Agenda commands. (line 311) +* org-agenda-diary-entry: Agenda commands. (line 466) +* org-agenda-do-date-earlier: Agenda commands. (line 328) +* org-agenda-do-date-later: Agenda commands. (line 314) +* org-agenda-drag-line-backward: Agenda commands. (line 360) +* org-agenda-drag-line-forward: Agenda commands. (line 364) +* org-agenda-earlier: Agenda commands. (line 100) +* org-agenda-entry-text-mode: Agenda commands. (line 157) +* org-agenda-exit: Agenda commands. (line 526) * org-agenda-file-to-front: Agenda files. (line 15) -* org-agenda-filter-by-category <1>: Agenda commands. (line 205) +* org-agenda-filter-by-category <1>: Agenda commands. (line 211) * org-agenda-filter-by-category: Filtering/limiting agenda items. - (line 93) -* org-agenda-filter-by-regexp <1>: Agenda commands. (line 213) + (line 76) +* org-agenda-filter-by-effort: Filtering/limiting agenda items. + (line 96) +* org-agenda-filter-by-regexp <1>: Agenda commands. (line 219) * org-agenda-filter-by-regexp: Filtering/limiting agenda items. - (line 103) -* org-agenda-filter-by-tag <1>: Agenda commands. (line 198) + (line 87) +* org-agenda-filter-by-tag <1>: Agenda commands. (line 204) * org-agenda-filter-by-tag: Filtering/limiting agenda items. (line 17) -* org-agenda-filter-by-tag-refine <1>: Agenda commands. (line 202) +* org-agenda-filter-by-tag-refine <1>: Agenda commands. (line 208) * org-agenda-filter-by-tag-refine: Filtering/limiting agenda items. - (line 76) -* org-agenda-filter-by-top-headline <1>: Agenda commands. (line 209) + (line 59) +* org-agenda-filter-by-top-headline <1>: Agenda commands. (line 215) * org-agenda-filter-by-top-headline: Filtering/limiting agenda items. - (line 99) -* org-agenda-filter-remove-all <1>: Agenda commands. (line 222) + (line 83) +* org-agenda-filter-remove-all <1>: Agenda commands. (line 228) * org-agenda-filter-remove-all: Filtering/limiting agenda items. - (line 112) -* org-agenda-follow-mode: Agenda commands. (line 40) -* org-agenda-fortnight-view: Agenda commands. (line 73) -* org-agenda-goto: Agenda commands. (line 34) -* org-agenda-goto-calendar: Agenda commands. (line 456) -* org-agenda-goto-date: Agenda commands. (line 100) -* org-agenda-goto-today: Agenda commands. (line 97) -* org-agenda-holidays: Agenda commands. (line 493) -* org-agenda-kill: Agenda commands. (line 242) -* org-agenda-later: Agenda commands. (line 88) + (line 110) +* org-agenda-follow-mode: Agenda commands. (line 46) +* org-agenda-fortnight-view: Agenda commands. (line 79) +* org-agenda-goto: Agenda commands. (line 40) +* org-agenda-goto-calendar: Agenda commands. (line 461) +* org-agenda-goto-date: Agenda commands. (line 106) +* org-agenda-goto-today: Agenda commands. (line 103) +* org-agenda-holidays: Agenda commands. (line 498) +* org-agenda-kill: Agenda commands. (line 248) +* org-agenda-later: Agenda commands. (line 94) * org-agenda-limit-interactively: Filtering/limiting agenda items. - (line 153) + (line 152) * org-agenda-list: Weekly/daily agenda. (line 9) * org-agenda-list-stuck-projects: Stuck projects. (line 13) -* org-agenda-log-mode: Agenda commands. (line 110) -* org-agenda-manipulate-query-add: Agenda commands. (line 121) -* org-agenda-month-view: Agenda commands. (line 74) +* org-agenda-log-mode: Agenda commands. (line 116) +* org-agenda-manipulate-query-add: Agenda commands. (line 127) +* org-agenda-month-view: Agenda commands. (line 80) +* org-agenda-next-item: Agenda commands. (line 23) * org-agenda-next-line: Agenda commands. (line 19) -* org-agenda-open-link: Agenda commands. (line 56) -* org-agenda-phases-of-moon: Agenda commands. (line 480) +* org-agenda-open-link: Agenda commands. (line 62) +* org-agenda-phases-of-moon: Agenda commands. (line 485) +* org-agenda-previous-item: Agenda commands. (line 26) * org-agenda-previous-line: Agenda commands. (line 20) -* org-agenda-priority-down: Agenda commands. (line 290) -* org-agenda-priority-up: Agenda commands. (line 285) -* org-agenda-quit: Agenda commands. (line 520) -* org-agenda-recenter: Agenda commands. (line 31) -* org-agenda-redo: Agenda commands. (line 163) -* org-agenda-refile: Agenda commands. (line 248) -* org-agenda-remove-restriction-lock <1>: Agenda commands. (line 188) +* org-agenda-priority-down: Agenda commands. (line 296) +* org-agenda-priority-up: Agenda commands. (line 291) +* org-agenda-quit: Agenda commands. (line 525) +* org-agenda-recenter: Agenda commands. (line 37) +* org-agenda-redo: Agenda commands. (line 169) +* org-agenda-refile: Agenda commands. (line 254) +* org-agenda-remove-restriction-lock <1>: Agenda commands. (line 194) * org-agenda-remove-restriction-lock: Agenda files. (line 49) -* org-agenda-reset-view: Agenda commands. (line 76) -* org-agenda-schedule: Agenda commands. (line 301) +* org-agenda-reset-view: Agenda commands. (line 82) +* org-agenda-schedule: Agenda commands. (line 307) * org-agenda-set-restriction-lock: Agenda files. (line 42) -* org-agenda-set-tags: Agenda commands. (line 273) -* org-agenda-show-and-scroll-up: Agenda commands. (line 28) -* org-agenda-show-priority: Agenda commands. (line 282) -* org-agenda-show-tags: Agenda commands. (line 268) -* org-agenda-sunrise-sunset: Agenda commands. (line 484) -* org-agenda-switch-to: Agenda commands. (line 37) -* org-agenda-todo: Agenda commands. (line 233) -* org-agenda-todo-nextset: Agenda commands. (line 237) -* org-agenda-todo-previousset: Agenda commands. (line 240) -* org-agenda-toggle-archive-tag: Agenda commands. (line 256) -* org-agenda-toggle-diary: Agenda commands. (line 106) -* org-agenda-toggle-time-grid: Agenda commands. (line 159) -* org-agenda-tree-to-indirect-buffer: Agenda commands. (line 47) -* org-agenda-undo: Agenda commands. (line 229) -* org-agenda-week-view: Agenda commands. (line 72) -* org-agenda-write <1>: Exporting Agenda Views. +* org-agenda-set-tags: Agenda commands. (line 279) +* org-agenda-show-and-scroll-up: Agenda commands. (line 34) +* org-agenda-show-priority: Agenda commands. (line 288) +* org-agenda-show-tags: Agenda commands. (line 274) +* org-agenda-sunrise-sunset: Agenda commands. (line 489) +* org-agenda-switch-to: Agenda commands. (line 43) +* org-agenda-todo: Agenda commands. (line 239) +* org-agenda-todo-nextset: Agenda commands. (line 243) +* org-agenda-todo-previousset: Agenda commands. (line 246) +* org-agenda-toggle-archive-tag: Agenda commands. (line 262) +* org-agenda-toggle-diary: Agenda commands. (line 112) +* org-agenda-toggle-time-grid: Agenda commands. (line 165) +* org-agenda-tree-to-indirect-buffer: Agenda commands. (line 53) +* org-agenda-undo: Agenda commands. (line 235) +* org-agenda-week-view: Agenda commands. (line 78) +* org-agenda-write <1>: Exporting agenda views. (line 12) -* org-agenda-write: Agenda commands. (line 506) -* org-agenda-year-view: Agenda commands. (line 75) +* org-agenda-write: Agenda commands. (line 511) +* org-agenda-year-view: Agenda commands. (line 81) * org-archive-subtree: Moving subtrees. (line 9) * org-archive-subtree-default: Archiving. (line 11) * org-archive-to-archive-sibling: Internal archiving. (line 49) * org-ascii-export-as-ascii: ASCII/Latin-1/UTF-8 export. - (line 22) + (line 25) * org-ascii-export-to-ascii: ASCII/Latin-1/UTF-8 export. - (line 18) -* org-attach <1>: Agenda commands. (line 298) + (line 21) +* org-attach <1>: Agenda commands. (line 304) * org-attach: Attachments. (line 26) * org-attach-attach: Attachments. (line 31) * org-attach-delete-all: Attachments. (line 66) @@ -19796,13 +20708,16 @@ Command and function index * org-attach-set-inherit: Attachments. (line 75) * org-attach-sync: Attachments. (line 44) * org-backward-same-level: Motion. (line 15) -* org-beamer-export-as-latex: Beamer export. (line 16) -* org-beamer-export-to-latex: Beamer export. (line 13) -* org-beamer-export-to-pdf: Beamer export. (line 19) -* org-beamer-select-environment: Beamer export. (line 142) +* org-beamer-export-as-latex: Beamer export commands. + (line 9) +* org-beamer-export-to-latex: Beamer export commands. + (line 6) +* org-beamer-export-to-pdf: Beamer export commands. + (line 12) +* org-beamer-select-environment: Editing support. (line 11) * org-buffer-property-keys: Using the property API. (line 35) -* org-calendar-goto-agenda: Agenda commands. (line 457) +* org-calendar-goto-agenda: Agenda commands. (line 462) * org-capture <1>: Using capture. (line 6) * org-capture <2>: Conventions. (line 35) * org-capture: Activation. (line 6) @@ -19810,11 +20725,11 @@ Command and function index * org-capture-kill: Using capture. (line 31) * org-capture-refile: Using capture. (line 22) * org-check-after-date: Inserting deadline/schedule. - (line 39) + (line 33) * org-check-before-date: Inserting deadline/schedule. - (line 36) + (line 30) * org-check-deadlines: Inserting deadline/schedule. - (line 29) + (line 23) * org-clock-cancel: Clocking commands. (line 71) * org-clock-display: Clocking commands. (line 80) * org-clock-goto: Clocking commands. (line 75) @@ -19826,7 +20741,7 @@ Command and function index * org-clock-report: The clock table. (line 10) * org-clock-timestamps-up/down: Clocking commands. (line 56) * org-clocktable-try-shift: The clock table. (line 24) -* org-clone-subtree-with-time-shift: Structure editing. (line 93) +* org-clone-subtree-with-time-shift: Structure editing. (line 102) * org-columns: Using column view. (line 9) * org-columns-delete: Using column view. (line 75) * org-columns-edit-allowed: Using column view. (line 59) @@ -19840,14 +20755,14 @@ Command and function index * org-columns-set-tags-or-toggle: Using column view. (line 52) * org-columns-show-value: Using column view. (line 55) * org-columns-widen: Using column view. (line 70) -* org-compute-property-at-point: Property syntax. (line 108) +* org-compute-property-at-point: Property syntax. (line 110) * org-copy: Refile and copy. (line 12) -* org-copy-subtree: Structure editing. (line 71) +* org-copy-subtree: Structure editing. (line 80) * org-copy-visible: Global and local cycling. (line 61) -* org-cut-subtree: Structure editing. (line 67) +* org-cut-subtree: Structure editing. (line 76) * org-cycle <1>: Plain lists. (line 68) -* org-cycle <2>: Structure editing. (line 33) +* org-cycle <2>: Structure editing. (line 42) * org-cycle: Global and local cycling. (line 10) * org-cycle-agenda-files: Agenda files. (line 22) @@ -19858,13 +20773,13 @@ Command and function index (line 51) * org-deadline: Inserting deadline/schedule. (line 9) -* org-delete-property: Property syntax. (line 102) -* org-delete-property-globally: Property syntax. (line 105) +* org-delete-property: Property syntax. (line 104) +* org-delete-property-globally: Property syntax. (line 107) * org-demote: Using the mapping API. (line 83) -* org-demote-subtree: Structure editing. (line 48) -* org-do-demote: Structure editing. (line 42) -* org-do-promote: Structure editing. (line 39) +* org-demote-subtree: Structure editing. (line 57) +* org-do-demote: Structure editing. (line 51) +* org-do-promote: Structure editing. (line 48) * org-edit-special: Cooperation. (line 61) * org-entry-add-to-multivalued-property: Using the property API. (line 52) @@ -19886,10 +20801,10 @@ Command and function index (line 58) * org-evaluate-time-range <1>: Clocking commands. (line 51) * org-evaluate-time-range: Creating timestamps. (line 59) -* org-export-dispatch: The Export Dispatcher. - (line 11) -* org-feed-goto-inbox: RSS Feeds. (line 27) -* org-feed-update-all: RSS Feeds. (line 23) +* org-export-dispatch: The export dispatcher. + (line 10) +* org-feed-goto-inbox: RSS feeds. (line 27) +* org-feed-update-all: RSS feeds. (line 23) * org-force-cycle-archived: Internal archiving. (line 46) * org-forward-same-level: Motion. (line 12) * org-global-cycle: Global and local cycling. @@ -19905,17 +20820,17 @@ Command and function index * org-icalendar-export-to-ics: iCalendar export. (line 32) * org-insert-columns-dblock: Capturing column view. (line 49) -* org-insert-heading <1>: Relative timer. (line 17) +* org-insert-heading <1>: Timers. (line 40) * org-insert-heading <2>: Plain lists. (line 79) * org-insert-heading: Structure editing. (line 6) -* org-insert-heading-respect-content: Structure editing. (line 19) +* org-insert-heading-respect-content: Structure editing. (line 28) * org-insert-link: Handling links. (line 65) * org-insert-property-drawer: Using the property API. (line 18) * org-insert-todo-heading <1>: Checkboxes. (line 73) * org-insert-todo-heading <2>: TODO basics. (line 58) -* org-insert-todo-heading: Structure editing. (line 24) -* org-insert-todo-heading-respect-content: Structure editing. (line 28) +* org-insert-todo-heading: Structure editing. (line 33) +* org-insert-todo-heading-respect-content: Structure editing. (line 37) * org-iswitchb: Activation. (line 6) * org-latex-export-as-latex: LaTeX export commands. (line 9) @@ -19928,28 +20843,26 @@ Command and function index * org-lookup-last: Lookup functions. (line 18) * org-map-entries: Using the mapping API. (line 13) -* org-mark-element: Structure editing. (line 57) -* org-mark-entry-for-agenda-action: Inserting deadline/schedule. - (line 23) +* org-mark-element: Structure editing. (line 66) * org-mark-ring-goto: Handling links. (line 146) * org-mark-ring-push: Handling links. (line 142) -* org-mark-subtree: Structure editing. (line 63) +* org-mark-subtree: Structure editing. (line 72) * org-match-sparse-tree <1>: Property searches. (line 10) * org-match-sparse-tree: Tag searches. (line 9) * org-md-export-as-markdown: Markdown export. (line 19) * org-md-export-to-markdown: Markdown export. (line 16) -* org-move-subtree-down: Structure editing. (line 54) -* org-move-subtree-up: Structure editing. (line 51) -* org-narrow-to-block: Structure editing. (line 120) -* org-narrow-to-subtree: Structure editing. (line 117) +* org-move-subtree-down: Structure editing. (line 63) +* org-move-subtree-up: Structure editing. (line 60) +* org-narrow-to-block: Structure editing. (line 129) +* org-narrow-to-subtree: Structure editing. (line 126) * org-next-link: Handling links. (line 152) * org-occur: Sparse trees. (line 17) -* org-odt-export-to-odt: ODT export commands. (line 9) +* org-odt-export-to-odt: ODT export commands. (line 6) * org-open-at-point <1>: Creating timestamps. (line 38) * org-open-at-point: Handling links. (line 101) * org-org-export-as-org: Org export. (line 16) * org-org-export-to-org: Org export. (line 13) -* org-paste-subtree: Structure editing. (line 75) +* org-paste-subtree: Structure editing. (line 84) * org-previous-link: Handling links. (line 152) * org-priority <1>: Using the mapping API. (line 71) @@ -19958,10 +20871,10 @@ Command and function index * org-priority-up: Priorities. (line 29) * org-promote: Using the mapping API. (line 80) -* org-promote-subtree: Structure editing. (line 45) -* org-property-action: Property syntax. (line 90) -* org-property-next-allowed-value: Property syntax. (line 98) -* org-property-previous-allowed-value: Property syntax. (line 98) +* org-promote-subtree: Structure editing. (line 54) +* org-property-action: Property syntax. (line 92) +* org-property-next-allowed-value: Property syntax. (line 100) +* org-property-previous-allowed-value: Property syntax. (line 100) * org-publish: Triggering publication. (line 8) * org-publish-all: Triggering publication. @@ -19971,58 +20884,60 @@ Command and function index * org-publish-current-project: Triggering publication. (line 10) * org-refile <1>: Refile and copy. (line 14) -* org-refile: Structure editing. (line 101) +* org-refile: Structure editing. (line 110) * org-refile-cache-clear: Refile and copy. (line 47) * org-refile-goto-last-stored: Refile and copy. (line 36) * org-remove-file: Agenda files. (line 19) * org-reveal: Global and local cycling. (line 38) -* org-save-all-org-buffers: Agenda commands. (line 173) +* org-save-all-org-buffers: Agenda commands. (line 179) * org-schedule: Inserting deadline/schedule. (line 17) * org-search-view: Search view. (line 9) * org-set-effort: Effort estimates. (line 14) -* org-set-property: Property syntax. (line 81) +* org-set-property: Property syntax. (line 83) * org-set-startup-visibility <1>: Initial visibility. (line 25) * org-set-startup-visibility: Global and local cycling. (line 33) * org-set-tags-command: Setting tags. (line 10) * org-show-todo-tree: TODO basics. (line 39) -* org-sort: Structure editing. (line 105) +* org-sort: Structure editing. (line 114) * org-sparse-tree: Sparse trees. (line 15) * org-speedbar-set-agenda-restriction: Agenda files. (line 57) -* org-store-agenda-views: Exporting Agenda Views. +* org-store-agenda-views: Exporting agenda views. (line 64) * org-store-link <1>: Handling links. (line 9) * org-store-link: Activation. (line 6) * org-table-align: Built-in table editor. - (line 57) + (line 58) * org-table-beginning-of-field: Built-in table editor. - (line 70) + (line 74) +* org-table-blank-field: Built-in table editor. + (line 59) * org-table-copy-down: Built-in table editor. - (line 159) + (line 165) * org-table-copy-region: Built-in table editor. - (line 126) + (line 132) * org-table-create-or-convert-from-region: Built-in table editor. (line 41) * org-table-create-with-table.el: Cooperation. (line 63) * org-table-cut-region: Built-in table editor. - (line 130) + (line 136) * org-table-delete-column: Built-in table editor. - (line 84) + (line 88) * org-table-edit-field: Built-in table editor. - (line 174) + (line 180) * org-table-edit-formulas: Editing and debugging formulas. (line 36) * org-table-end-of-field: Built-in table editor. - (line 74) + (line 78) * org-table-eval-formula <1>: Editing and debugging formulas. (line 13) * org-table-eval-formula <2>: Column formulas. (line 32) * org-table-eval-formula: Field and range formulas. - (line 28) + (line 27) * org-table-export: Built-in table editor. - (line 199) + (line 205) * org-table-fedit-abort: Editing and debugging formulas. (line 50) * org-table-fedit-finish: Editing and debugging formulas. @@ -20050,46 +20965,46 @@ Command and function index * org-table-field-info: Editing and debugging formulas. (line 22) * org-table-hline-and-move: Built-in table editor. - (line 105) + (line 109) * org-table-insert-column: Built-in table editor. - (line 87) + (line 91) * org-table-insert-hline: Built-in table editor. - (line 101) + (line 105) * org-table-insert-row: Built-in table editor. - (line 97) + (line 101) * org-table-iterate: Updating the table. (line 22) * org-table-iterate-buffer-tables: Updating the table. (line 33) * org-table-kill-row: Built-in table editor. - (line 94) + (line 98) * org-table-move-column-left: Built-in table editor. - (line 82) + (line 86) * org-table-move-column-right: Built-in table editor. - (line 82) + (line 86) * org-table-move-row-down: Built-in table editor. - (line 90) + (line 94) * org-table-move-row-up: Built-in table editor. - (line 90) + (line 94) * org-table-next-field: Built-in table editor. - (line 58) + (line 62) * org-table-next-row: Built-in table editor. - (line 65) + (line 69) * org-table-paste-rectangle: Built-in table editor. - (line 134) + (line 140) * org-table-previous-field: Built-in table editor. - (line 62) + (line 66) * org-table-recalculate: Updating the table. (line 13) * org-table-recalculate-buffer-tables: Updating the table. (line 30) * org-table-rotate-recalc-marks: Advanced features. (line 10) * org-table-sort-lines: Built-in table editor. - (line 109) + (line 113) * org-table-sum: Built-in table editor. - (line 156) + (line 162) * org-table-toggle-coordinate-overlays: Editing and debugging formulas. (line 26) * org-table-toggle-formula-debugger: Editing and debugging formulas. (line 32) * org-table-wrap-region: Built-in table editor. - (line 141) + (line 147) * org-tags-view <1>: Matching tags and properties. (line 12) * org-tags-view <2>: Property searches. (line 12) @@ -20101,9 +21016,12 @@ Command and function index * org-time-stamp: Creating timestamps. (line 10) * org-time-stamp-inactive: Creating timestamps. (line 15) * org-timeline: Timeline. (line 10) -* org-timer: Relative timer. (line 10) -* org-timer-item: Relative timer. (line 13) -* org-timer-start: Relative timer. (line 30) +* org-timer: Timers. (line 31) +* org-timer-item: Timers. (line 35) +* org-timer-pause-or-continue: Timers. (line 44) +* org-timer-set-timer: Timers. (line 20) +* org-timer-start: Timers. (line 12) +* org-timer-stop: Timers. (line 47) * org-timestamp-down-day: Creating timestamps. (line 42) * org-timestamp-down-down: Creating timestamps. (line 47) * org-timestamp-up: Creating timestamps. (line 47) @@ -20117,10 +21035,10 @@ Command and function index * org-todo-list: TODO basics. (line 50) * org-toggle-archive-tag: Internal archiving. (line 36) * org-toggle-checkbox: Checkboxes. (line 52) -* org-toggle-heading: Structure editing. (line 126) +* org-toggle-heading: Structure editing. (line 135) * org-toggle-inline-images: Handling links. (line 133) * org-toggle-ordered-property <1>: Checkboxes. (line 76) -* org-toggle-ordered-property: TODO dependencies. (line 29) +* org-toggle-ordered-property: TODO dependencies. (line 37) * org-toggle-tag: Using the mapping API. (line 75) * org-toggle-time-stamp-overlays: Custom time format. (line 12) @@ -20129,11 +21047,11 @@ Command and function index * org-update-all-dblocks: Capturing column view. (line 55) * org-update-statistics-cookies: Checkboxes. (line 84) -* org-yank: Structure editing. (line 81) +* org-yank: Structure editing. (line 90) * outline-next-visible-heading: Motion. (line 8) * outline-previous-visible-heading: Motion. (line 9) * outline-up-heading: Motion. (line 18) -* pcomplete: Property syntax. (line 78) +* pcomplete: Property syntax. (line 80) * previous-error: Sparse trees. (line 32) * show-all: Global and local cycling. (line 35) @@ -20141,7 +21059,7 @@ Command and function index (line 47) * show-children: Global and local cycling. (line 51) -* widen: Structure editing. (line 123) +* widen: Structure editing. (line 132)  File: org, Node: Variable Index, Prev: Command and Function Index, Up: Top @@ -20157,36 +21075,38 @@ org-customize ' and then click yourself through the tree. * Menu: * cdlatex-simplify-sub-super-scripts: CDLaTeX mode. (line 33) -* constants-unit-system <1>: In-buffer settings. (line 153) -* constants-unit-system: References. (line 109) -* htmlize-output-type: Exporting Agenda Views. +* constants-unit-system <1>: In-buffer settings. (line 147) +* constants-unit-system: References. (line 117) +* htmlize-output-type: Exporting agenda views. (line 20) * LaTeX-verbatim-environments: A LaTeX example. (line 21) * org-adapt-indentation: Clean view. (line 46) -* org-agenda-add-entry-text-maxlines: Exporting Agenda Views. +* org-agenda-add-entry-text-maxlines: Exporting agenda views. (line 20) -* org-agenda-bulk-custom-functions: Agenda commands. (line 365) -* org-agenda-category-filter-preset <1>: Agenda commands. (line 206) +* org-agenda-bulk-custom-functions: Agenda commands. (line 371) +* org-agenda-category-filter-preset <1>: Agenda commands. (line 212) * org-agenda-category-filter-preset: Filtering/limiting agenda items. - (line 94) -* org-agenda-clock-consistency-checks: Agenda commands. (line 146) + (line 77) +* org-agenda-clock-consistency-checks: Agenda commands. (line 152) * org-agenda-columns-add-appointments-to-effort-sum: Effort estimates. (line 41) -* org-agenda-confirm-kill: Agenda commands. (line 245) +* org-agenda-confirm-kill: Agenda commands. (line 251) * org-agenda-custom-commands <1>: Extracting agenda information. (line 6) -* org-agenda-custom-commands <2>: Setting Options. (line 6) +* org-agenda-custom-commands <2>: Setting options. (line 6) * org-agenda-custom-commands <3>: Storing searches. (line 9) * org-agenda-custom-commands: Sparse trees. (line 37) -* org-agenda-custom-commands-contexts: Setting Options. (line 62) -* org-agenda-diary-file: Agenda commands. (line 464) +* org-agenda-custom-commands-contexts: Setting options. (line 61) +* org-agenda-diary-file: Agenda commands. (line 469) * org-agenda-dim-blocked-tasks <1>: Speeding up your agendas. (line 16) -* org-agenda-dim-blocked-tasks: TODO dependencies. (line 39) -* org-agenda-entry-text-maxlines: Agenda commands. (line 154) -* org-agenda-exporter-settings <1>: Exporting Agenda Views. +* org-agenda-dim-blocked-tasks: TODO dependencies. (line 47) +* org-agenda-effort-filter-preset: Filtering/limiting agenda items. + (line 97) +* org-agenda-entry-text-maxlines: Agenda commands. (line 160) +* org-agenda-exporter-settings <1>: Exporting agenda views. (line 13) -* org-agenda-exporter-settings: Agenda commands. (line 507) +* org-agenda-exporter-settings: Agenda commands. (line 512) * org-agenda-files <1>: iCalendar export. (line 37) * org-agenda-files <2>: Sorting agenda items. (line 8) @@ -20194,27 +21114,27 @@ org-customize ' and then click yourself through the tree. * org-agenda-inhibit-startup <1>: Speeding up your agendas. (line 19) * org-agenda-inhibit-startup: Initial visibility. (line 6) -* org-agenda-log-mode-items: Agenda commands. (line 113) +* org-agenda-log-mode-items: Agenda commands. (line 119) * org-agenda-max-effort: Filtering/limiting agenda items. - (line 118) + (line 116) * org-agenda-max-entries: Filtering/limiting agenda items. - (line 118) + (line 116) * org-agenda-max-tags: Filtering/limiting agenda items. - (line 118) + (line 116) * org-agenda-max-todos: Filtering/limiting agenda items. - (line 118) + (line 116) * org-agenda-ndays: Weekly/daily agenda. (line 15) * org-agenda-overriding-header: Special agenda views. (line 45) * org-agenda-prefix-format: Presentation and sorting. (line 6) -* org-agenda-regexp-filter-preset <1>: Agenda commands. (line 214) +* org-agenda-regexp-filter-preset <1>: Agenda commands. (line 220) * org-agenda-regexp-filter-preset: Filtering/limiting agenda items. - (line 104) -* org-agenda-restore-windows-after-quit: Agenda Views. (line 40) + (line 88) +* org-agenda-restore-windows-after-quit: Agenda views. (line 40) * org-agenda-show-inherited-tags <1>: Speeding up your agendas. (line 22) -* org-agenda-show-inherited-tags: Agenda commands. (line 271) +* org-agenda-show-inherited-tags: Agenda commands. (line 277) * org-agenda-skip-archived-trees: Internal archiving. (line 21) * org-agenda-skip-deadline-prewarning-if-scheduled: Deadlines and scheduling. (line 12) @@ -20227,20 +21147,20 @@ org-customize ' and then click yourself through the tree. * org-agenda-skip-scheduled-delay-if-deadline: Deadlines and scheduling. (line 40) * org-agenda-skip-scheduled-if-deadline-is-shown: Repeated tasks. - (line 62) + (line 65) * org-agenda-skip-scheduled-if-done: Deadlines and scheduling. (line 32) * org-agenda-sorting-strategy: Sorting agenda items. (line 27) -* org-agenda-span <1>: Agenda commands. (line 77) +* org-agenda-span <1>: Agenda commands. (line 83) * org-agenda-span: Weekly/daily agenda. (line 15) * org-agenda-start-day: Weekly/daily agenda. (line 15) * org-agenda-start-on-weekday: Weekly/daily agenda. (line 15) -* org-agenda-start-with-clockreport-mode: Agenda commands. (line 135) -* org-agenda-start-with-entry-text-mode: Agenda commands. (line 154) -* org-agenda-start-with-follow-mode: Agenda commands. (line 43) +* org-agenda-start-with-clockreport-mode: Agenda commands. (line 141) +* org-agenda-start-with-entry-text-mode: Agenda commands. (line 160) +* org-agenda-start-with-follow-mode: Agenda commands. (line 49) * org-agenda-sticky: Agenda dispatcher. (line 53) -* org-agenda-tag-filter-preset <1>: Agenda commands. (line 199) +* org-agenda-tag-filter-preset <1>: Agenda commands. (line 205) * org-agenda-tag-filter-preset: Filtering/limiting agenda items. (line 18) * org-agenda-tags-column: Presentation and sorting. @@ -20249,7 +21169,7 @@ org-customize ' and then click yourself through the tree. (line 20) * org-agenda-text-search-extra-files <1>: Search view. (line 24) * org-agenda-text-search-extra-files: Agenda dispatcher. (line 32) -* org-agenda-time-grid <1>: Agenda commands. (line 162) +* org-agenda-time-grid <1>: Agenda commands. (line 168) * org-agenda-time-grid: Time-of-day specifications. (line 41) * org-agenda-todo-ignore-deadlines: Global TODO list. (line 38) @@ -20261,16 +21181,18 @@ org-customize ' and then click yourself through the tree. * org-agenda-use-tag-inheritance <1>: Speeding up your agendas. (line 22) * org-agenda-use-tag-inheritance: Tag inheritance. (line 32) -* org-agenda-use-time-grid <1>: Agenda commands. (line 162) +* org-agenda-use-time-grid <1>: Agenda commands. (line 168) * org-agenda-use-time-grid: Time-of-day specifications. (line 41) -* org-agenda-window-setup: Agenda Views. (line 40) -* org-archive-default-command <1>: Agenda commands. (line 254) +* org-agenda-window-setup: Agenda views. (line 40) +* org-archive-default-command <1>: Agenda commands. (line 260) * org-archive-default-command: Archiving. (line 12) * org-archive-location <1>: In-buffer settings. (line 16) * org-archive-location: Moving subtrees. (line 10) -* org-archive-save-context-info: Moving subtrees. (line 36) +* org-archive-save-context-info: Moving subtrees. (line 41) * org-ascii-links-to-notes: ASCII/Latin-1/UTF-8 export. + (line 14) +* org-ascii-text-width: ASCII/Latin-1/UTF-8 export. (line 11) * org-attach-directory: Attachments. (line 6) * org-attach-method: Attachments. (line 32) @@ -20278,15 +21200,22 @@ org-customize ' and then click yourself through the tree. (line 34) * org-babel-default-header-args: System-wide header arguments. (line 6) -* org-beamer-environments-default: Beamer export. (line 44) -* org-beamer-environments-extra: Beamer export. (line 44) -* org-beamer-frame-level: Beamer export. (line 35) +* org-beamer-environments-default: Sectioning Frames and Blocks in Beamer. + (line 19) +* org-beamer-environments-extra: Sectioning Frames and Blocks in Beamer. + (line 19) +* org-beamer-frame-level: Sectioning Frames and Blocks in Beamer. + (line 10) +* org-beamer-subtitle-format: Beamer specific export settings. + (line 43) +* org-beamer-theme: Beamer specific export settings. + (line 10) * org-calc-default-modes: Formula syntax for Calc. (line 14) * org-capture-bookmark: Using capture. (line 50) * org-capture-templates-contexts: Templates in contexts. (line 6) -* org-capture-use-agenda-date: Agenda commands. (line 349) +* org-capture-use-agenda-date: Agenda commands. (line 355) * org-catch-invisible-edits: Catching invisible edits. (line 6) * org-checkbox-hierarchical-statistics: Checkboxes. (line 30) @@ -20295,13 +21224,13 @@ org-customize ' and then click yourself through the tree. * org-clock-idle-time: Resolving idle time. (line 14) * org-clock-into-drawer: Clocking commands. (line 7) * org-clock-modeline-total: Clocking commands. (line 20) -* org-clock-report-include-clocking-task: Agenda commands. (line 135) +* org-clock-report-include-clocking-task: Agenda commands. (line 141) * org-clock-x11idle-program-name: Resolving idle time. (line 9) * org-clocktable-defaults: The clock table. (line 38) * org-closed-keep-when-no-todo: Closing items. (line 11) -* org-coderef-label-format: Literal examples. (line 58) +* org-coderef-label-format: Literal examples. (line 61) * org-columns-default-format <1>: Agenda column view. (line 18) -* org-columns-default-format <2>: Agenda commands. (line 180) +* org-columns-default-format <2>: Agenda commands. (line 186) * org-columns-default-format <3>: Effort estimates. (line 31) * org-columns-default-format: Using column view. (line 10) * org-columns-skip-archived-trees: Internal archiving. (line 31) @@ -20321,24 +21250,22 @@ org-customize ' and then click yourself through the tree. (line 16) * org-cycle-include-plain-lists: Plain lists. (line 69) * org-cycle-open-archived-trees: Internal archiving. (line 11) -* org-cycle-separator-lines: Headlines. (line 22) +* org-cycle-separator-lines: Headlines. (line 26) * org-deadline-warning-days <1>: Inserting deadline/schedule. - (line 32) + (line 26) * org-deadline-warning-days: Deadlines and scheduling. (line 12) * org-default-notes-file <1>: Template elements. (line 49) * org-default-notes-file: Setting up capture. (line 9) -* org-default-priority <1>: In-buffer settings. (line 54) +* org-default-priority <1>: In-buffer settings. (line 48) * org-default-priority: Priorities. (line 38) -* org-display-custom-times <1>: Publishing options. (line 12) * org-display-custom-times: Custom time format. (line 6) * org-display-internal-link-with-indirect-buffer: Handling links. (line 132) * org-disputed-keys: Conflicts. (line 34) * org-done (face): Faces for TODO keywords. (line 6) -* org-drawers <1>: In-buffer settings. (line 45) -* org-drawers: Drawers. (line 6) +* org-edit-footnote-reference: Footnotes. (line 97) * org-edit-src-auto-save-idle-delay: Editing source code. (line 6) * org-edit-src-turn-on-auto-save: Editing source code. (line 6) * org-emphasis-alist: Emphasis and monospace. @@ -20350,9 +21277,9 @@ org-customize ' and then click yourself through the tree. * org-enforce-todo-dependencies: TODO dependencies. (line 6) * org-entities: Special symbols. (line 15) * org-execute-file-search-functions: Custom searches. (line 12) -* org-export-allow-bind-keywords: Export settings. (line 187) -* org-export-async-init-file: The Export Dispatcher. - (line 25) +* org-export-allow-bind-keywords: Export settings. (line 194) +* org-export-async-init-file: The export dispatcher. + (line 24) * org-export-backends <1>: Other built-in back-ends. (line 6) * org-export-backends: Export back-ends. (line 10) @@ -20360,81 +21287,58 @@ org-customize ' and then click yourself through the tree. (line 9) * org-export-before-processing-hook: Advanced configuration. (line 9) -* org-export-copy-to-kill-ring: The Export Dispatcher. - (line 54) * org-export-creator-string <1>: HTML preamble and postamble. (line 6) * org-export-creator-string: Export settings. (line 28) * org-export-date-timestamp-format: Export settings. (line 32) -* org-export-default-language <1>: Publishing options. (line 12) -* org-export-default-language: Export settings. (line 48) -* org-export-dispatch-use-expert-ui: The Export Dispatcher. +* org-export-default-language: Export settings. (line 38) +* org-export-dispatch-use-expert-ui: The export dispatcher. (line 6) -* org-export-exclude-tags: Publishing options. (line 12) -* org-export-headline-levels <1>: Publishing options. (line 12) -* org-export-headline-levels <2>: Export settings. (line 129) +* org-export-exclude-tags: Export settings. (line 51) +* org-export-headline-levels <1>: Export settings. (line 125) * org-export-headline-levels: Headings and sections. (line 6) -* org-export-in-background: The Export Dispatcher. - (line 34) -* org-export-initial-scope: The Export Dispatcher. - (line 44) -* org-export-preserve-breaks <1>: Publishing options. (line 12) -* org-export-preserve-breaks: Export settings. (line 91) -* org-export-publishing-directory: Publishing options. (line 12) -* org-export-select-tags <1>: Publishing options. (line 12) -* org-export-select-tags: Export settings. (line 54) +* org-export-in-background: The export dispatcher. + (line 33) +* org-export-initial-scope: The export dispatcher. + (line 43) +* org-export-preserve-breaks: Export settings. (line 83) +* org-export-select-tags: Export settings. (line 44) * org-export-time-stamp-file <1>: HTML preamble and postamble. (line 6) -* org-export-time-stamp-file: Export settings. (line 167) -* org-export-with-archived-trees <1>: Publishing options. (line 12) -* org-export-with-archived-trees <2>: Export settings. (line 99) +* org-export-time-stamp-file: Export settings. (line 170) +* org-export-with-archived-trees <1>: Export settings. (line 91) * org-export-with-archived-trees: Internal archiving. (line 27) -* org-export-with-author <1>: Publishing options. (line 12) -* org-export-with-author: Export settings. (line 104) -* org-export-with-clocks: Export settings. (line 108) -* org-export-with-creator <1>: Publishing options. (line 12) -* org-export-with-creator: Export settings. (line 111) -* org-export-with-drawers <1>: Publishing options. (line 12) -* org-export-with-drawers <2>: Export settings. (line 115) +* org-export-with-author: Export settings. (line 96) +* org-export-with-clocks: Export settings. (line 100) +* org-export-with-creator: Export settings. (line 103) +* org-export-with-date: Export settings. (line 111) +* org-export-with-drawers <1>: Export settings. (line 107) * org-export-with-drawers: Drawers. (line 38) -* org-export-with-email <1>: Publishing options. (line 12) -* org-export-with-email: Export settings. (line 122) -* org-export-with-emphasize: Publishing options. (line 12) -* org-export-with-entities: Export settings. (line 119) -* org-export-with-fixed-width <1>: Publishing options. (line 12) -* org-export-with-fixed-width: Export settings. (line 84) -* org-export-with-footnotes <1>: Publishing options. (line 12) -* org-export-with-footnotes: Export settings. (line 126) -* org-export-with-inlinetasks: Export settings. (line 134) -* org-export-with-latex <1>: Publishing options. (line 12) -* org-export-with-latex <2>: Export settings. (line 163) +* org-export-with-email: Export settings. (line 118) +* org-export-with-entities: Export settings. (line 115) +* org-export-with-fixed-width: Export settings. (line 76) +* org-export-with-footnotes: Export settings. (line 122) +* org-export-with-inlinetasks: Export settings. (line 130) +* org-export-with-latex <1>: Export settings. (line 166) * org-export-with-latex: LaTeX fragments. (line 39) -* org-export-with-planning <1>: Publishing options. (line 12) -* org-export-with-planning: Export settings. (line 142) -* org-export-with-priority <1>: Publishing options. (line 12) -* org-export-with-priority: Export settings. (line 147) -* org-export-with-section-numbers <1>: Publishing options. (line 12) -* org-export-with-section-numbers: Export settings. (line 137) -* org-export-with-smart-quotes: Export settings. (line 74) -* org-export-with-special-strings <1>: Publishing options. (line 12) -* org-export-with-special-strings: Export settings. (line 80) -* org-export-with-statistics-cookies: Export settings. (line 150) -* org-export-with-sub-superscripts <1>: Publishing options. (line 12) -* org-export-with-sub-superscripts: Export settings. (line 94) -* org-export-with-tables <1>: Publishing options. (line 12) -* org-export-with-tables: Export settings. (line 179) -* org-export-with-tags <1>: Publishing options. (line 12) -* org-export-with-tags: Export settings. (line 154) -* org-export-with-tasks <1>: Publishing options. (line 12) -* org-export-with-tasks: Export settings. (line 158) -* org-export-with-timestamps <1>: Publishing options. (line 12) -* org-export-with-timestamps: Export settings. (line 87) -* org-export-with-toc <1>: Publishing options. (line 12) -* org-export-with-toc <2>: Export settings. (line 171) +* org-export-with-planning: Export settings. (line 141) +* org-export-with-priority: Export settings. (line 146) +* org-export-with-properties <1>: Export settings. (line 149) +* org-export-with-properties: Drawers. (line 38) +* org-export-with-section-numbers: Export settings. (line 133) +* org-export-with-smart-quotes: Export settings. (line 66) +* org-export-with-special-strings: Export settings. (line 72) +* org-export-with-statistics-cookies: Export settings. (line 153) +* org-export-with-sub-superscripts: Export settings. (line 86) +* org-export-with-tables: Export settings. (line 185) +* org-export-with-tags: Export settings. (line 157) +* org-export-with-tasks: Export settings. (line 161) +* org-export-with-timestamps: Export settings. (line 79) +* org-export-with-title: Export settings. (line 174) +* org-export-with-toc <1>: Export settings. (line 177) * org-export-with-toc: Table of contents. (line 6) -* org-export-with-todo-keywords <1>: Publishing options. (line 12) -* org-export-with-todo-keywords: Export settings. (line 175) +* org-export-with-todo-keywords: Export settings. (line 181) * org-fast-tag-selection-include-todo: Fast access to TODO states. (line 16) * org-fast-tag-selection-single-key: Setting tags. (line 144) @@ -20442,76 +21346,86 @@ org-customize ' and then click yourself through the tree. * org-file-apps: Handling links. (line 104) * org-fontify-emphasized-text: Emphasis and monospace. (line 6) -* org-footnote-auto-adjust <1>: In-buffer settings. (line 158) +* org-footnote-auto-adjust <1>: In-buffer settings. (line 152) * org-footnote-auto-adjust: Footnotes. (line 58) -* org-footnote-auto-label <1>: In-buffer settings. (line 158) +* org-footnote-auto-label <1>: In-buffer settings. (line 152) * org-footnote-auto-label: Footnotes. (line 44) -* org-footnote-define-inline <1>: In-buffer settings. (line 158) +* org-footnote-define-inline <1>: In-buffer settings. (line 152) * org-footnote-define-inline: Footnotes. (line 58) -* org-footnote-section: Footnotes. (line 58) +* org-footnote-section <1>: Footnotes. (line 58) +* org-footnote-section: Headlines. (line 18) +* org-format-latex-header <1>: Previewing LaTeX fragments. + (line 12) * org-format-latex-header: LaTeX fragments. (line 6) * org-format-latex-options: Previewing LaTeX fragments. - (line 20) + (line 12) * org-from-is-user-regexp: Template expansion. (line 49) * org-global-properties <1>: Effort estimates. (line 31) -* org-global-properties: Property syntax. (line 73) +* org-global-properties: Property syntax. (line 75) * org-goto-auto-isearch: Motion. (line 26) * org-goto-interface: Motion. (line 37) -* org-group-tags: Tag groups. (line 34) +* org-group-tags: Tag hierarchy. (line 87) * org-hide (face): Clean view. (line 66) * org-hide-block-startup: Blocks. (line 6) * org-hide-leading-stars <1>: Clean view. (line 50) -* org-hide-leading-stars: In-buffer settings. (line 137) +* org-hide-leading-stars: In-buffer settings. (line 131) * org-hierarchical-todo-statistics: Breaking down tasks. (line 25) -* org-highest-priority <1>: In-buffer settings. (line 54) +* org-highest-priority <1>: In-buffer settings. (line 48) * org-highest-priority: Priorities. (line 38) -* org-html-container-element: Publishing options. (line 38) -* org-html-doctype <1>: Publishing options. (line 38) -* org-html-doctype: HTML doctypes. (line 6) +* org-html-container-element: HTML Specific export settings. + (line 17) +* org-html-doctype <1>: HTML doctypes. (line 6) +* org-html-doctype: HTML Specific export settings. + (line 14) * org-html-doctype-alist: HTML doctypes. (line 6) -* org-html-extension: Publishing options. (line 38) -* org-html-head <1>: Publishing options. (line 38) -* org-html-head: CSS support. (line 41) -* org-html-head-extra <1>: Publishing options. (line 38) -* org-html-head-extra: CSS support. (line 41) -* org-html-head-include-default-style <1>: Publishing options. - (line 38) -* org-html-head-include-default-style: CSS support. (line 41) -* org-html-head-include-scripts: Publishing options. (line 38) +* org-html-head <1>: CSS support. (line 42) +* org-html-head: HTML Specific export settings. + (line 32) +* org-html-head-extra <1>: CSS support. (line 42) +* org-html-head-extra: HTML Specific export settings. + (line 36) +* org-html-head-include-default-style: CSS support. (line 42) * org-html-html5-elements: HTML doctypes. (line 39) -* org-html-html5-fancy <1>: Publishing options. (line 38) * org-html-html5-fancy: HTML doctypes. (line 39) * org-html-infojs-options: JavaScript support. (line 54) -* org-html-inline-images <1>: Publishing options. (line 38) * org-html-inline-images: Images in HTML export. (line 6) -* org-html-link-home: Publishing options. (line 38) -* org-html-link-org-files-as-html: Publishing options. (line 38) -* org-html-link-up: Publishing options. (line 38) -* org-html-link-use-abs-url: Publishing options. (line 38) -* org-html-postamble <1>: Publishing options. (line 38) +* org-html-link-home: HTML Specific export settings. + (line 21) +* org-html-link-org-files-as-html: Links in HTML export. + (line 6) +* org-html-link-up: HTML Specific export settings. + (line 24) +* org-html-mathjax-options: HTML Specific export settings. + (line 27) * org-html-postamble: HTML preamble and postamble. (line 6) * org-html-postamble-format: HTML preamble and postamble. (line 6) -* org-html-preamble <1>: Publishing options. (line 38) * org-html-preamble: HTML preamble and postamble. (line 6) * org-html-preamble-format: HTML preamble and postamble. (line 6) -* org-html-style-default: CSS support. (line 41) -* org-html-table-default-attributes <1>: Publishing options. (line 38) +* org-html-style-default: CSS support. (line 42) +* org-html-table-align-individual-fields: Tables in HTML export. + (line 20) +* org-html-table-caption-above: Tables in HTML export. + (line 24) +* org-html-table-data-tags: Tables in HTML export. + (line 27) * org-html-table-default-attributes: Tables in HTML export. (line 6) -* org-html-table-row-tags <1>: Publishing options. (line 38) +* org-html-table-header-tags: Tables in HTML export. + (line 33) * org-html-table-row-tags: Tables in HTML export. - (line 15) + (line 36) +* org-html-table-use-header-tags-for-first-column: Tables in HTML export. + (line 39) * org-html-tag-class-prefix: CSS support. (line 6) * org-html-todo-kwd-class-prefix: CSS support. (line 6) * org-html-use-infojs: JavaScript support. (line 54) * org-html-validation-link: HTML preamble and postamble. (line 6) -* org-html-xml-declaration: Publishing options. (line 38) * org-icalendar-alarm-time: iCalendar export. (line 6) * org-icalendar-categories: iCalendar export. (line 6) * org-icalendar-combined-agenda-file: iCalendar export. (line 42) @@ -20522,32 +21436,45 @@ org-customize ' and then click yourself through the tree. * org-icalendar-use-scheduled: iCalendar export. (line 6) * org-id-link-to-org-use-id: Handling links. (line 21) * org-imenu-depth: Cooperation. (line 38) -* org-insert-mode-line-in-empty-file: Activation. (line 33) +* org-insert-mode-line-in-empty-file: Activation. (line 32) * org-irc-link-to-logs: Handling links. (line 45) * org-keep-stored-link-after-insertion: Handling links. (line 66) -* org-latex-classes: Header and sectioning. +* org-latex-classes <1>: Header and sectioning. (line 13) +* org-latex-classes: LaTeX specific export settings. + (line 17) * org-latex-create-formula-image-program: Previewing LaTeX fragments. (line 6) -* org-latex-default-class: Header and sectioning. +* org-latex-default-class <1>: Header and sectioning. (line 13) +* org-latex-default-class: LaTeX specific export settings. + (line 17) * org-latex-default-packages-alist: Header and sectioning. (line 13) * org-latex-default-table-environment: LaTeX specific attributes. - (line 26) + (line 27) * org-latex-default-table-mode: LaTeX specific attributes. - (line 17) + (line 18) +* org-latex-listings: Literal examples. (line 23) +* org-latex-listings-options: LaTeX specific attributes. + (line 187) +* org-latex-minted-options: LaTeX specific attributes. + (line 187) * org-latex-packages-alist: Header and sectioning. (line 13) +* org-latex-subtitle-format: LaTeX specific export settings. + (line 43) +* org-latex-subtitle-separate: LaTeX specific export settings. + (line 43) * org-latex-tables-booktabs: LaTeX specific attributes. - (line 60) + (line 63) * org-latex-tables-centered: LaTeX specific attributes. - (line 60) + (line 63) * org-latex-to-mathml-convert-command: Working with LaTeX math snippets. (line 20) * org-latex-to-mathml-jar-file: Working with LaTeX math snippets. (line 20) -* org-link-abbrev-alist <1>: In-buffer settings. (line 49) +* org-link-abbrev-alist <1>: In-buffer settings. (line 43) * org-link-abbrev-alist: Link abbreviations. (line 12) * org-link-frame-setup: Handling links. (line 104) * org-list-allow-alphabetical: Plain lists. (line 14) @@ -20557,21 +21484,21 @@ org-customize ' and then click yourself through the tree. * org-list-empty-line-terminates-plain-lists: Plain lists. (line 30) * org-list-indent-offset: Plain lists. (line 56) * org-list-use-circular-motion: Plain lists. (line 94) -* org-log-done <1>: In-buffer settings. (line 112) -* org-log-done <2>: Agenda commands. (line 113) +* org-log-done <1>: In-buffer settings. (line 106) +* org-log-done <2>: Agenda commands. (line 119) * org-log-done: Tracking TODO state changes. (line 29) -* org-log-into-drawer <1>: Agenda commands. (line 296) +* org-log-into-drawer <1>: Agenda commands. (line 302) * org-log-into-drawer: Tracking TODO state changes. (line 6) -* org-log-note-clock-out <1>: In-buffer settings. (line 112) +* org-log-note-clock-out <1>: In-buffer settings. (line 106) * org-log-note-clock-out: Clocking commands. (line 37) * org-log-refile: Refile and copy. (line 17) -* org-log-repeat <1>: In-buffer settings. (line 112) -* org-log-repeat: Repeated tasks. (line 34) +* org-log-repeat <1>: In-buffer settings. (line 106) +* org-log-repeat: Repeated tasks. (line 37) * org-log-states-order-reversed: Tracking TODO state changes. (line 6) -* org-lowest-priority <1>: In-buffer settings. (line 54) +* org-lowest-priority <1>: In-buffer settings. (line 48) * org-lowest-priority: Priorities. (line 38) * org-M-RET-may-split-line <1>: Plain lists. (line 82) * org-M-RET-may-split-line: Structure editing. (line 7) @@ -20579,9 +21506,9 @@ org-customize ' and then click yourself through the tree. * org-odd-levels-only <1>: Special agenda views. (line 48) * org-odd-levels-only <2>: Clean view. (line 74) -* org-odd-levels-only <3>: In-buffer settings. (line 137) +* org-odd-levels-only <3>: In-buffer settings. (line 131) * org-odd-levels-only: Matching tags and properties. - (line 71) + (line 72) * org-odt-category-map-alist: Labels and captions in ODT export. (line 25) * org-odt-convert: Extending ODT export. @@ -20600,13 +21527,15 @@ org-customize ' and then click yourself through the tree. (line 33) * org-odt-preferred-output-format <1>: Extending ODT export. (line 22) -* org-odt-preferred-output-format: ODT export commands. (line 12) +* org-odt-preferred-output-format: ODT export commands. (line 9) * org-odt-schema-dir: Validating OpenDocument XML. (line 16) -* org-odt-styles-file: Applying custom styles. +* org-odt-styles-file <1>: Applying custom styles. (line 28) +* org-odt-styles-file: ODT specific export settings. + (line 19) * org-odt-table-styles: Customizing tables in ODT export. - (line 16) + (line 13) * org-outline-path-complete-in-steps: Refile and copy. (line 17) * org-overriding-columns-format: Agenda column view. (line 18) * org-plain-list-ordered-item-terminator: Plain lists. (line 14) @@ -20616,13 +21545,13 @@ org-customize ' and then click yourself through the tree. * org-priority-start-cycle-with-default: Priorities. (line 33) * org-property-allowed-value-functions: Using the property API. (line 69) -* org-publish-project-alist <1>: Publishing options. (line 60) +* org-publish-project-alist <1>: Publishing options. (line 13) * org-publish-project-alist: Project alist. (line 6) * org-publish-use-timestamps-flag: Triggering publication. (line 21) -* org-put-time-stamp-overlays: In-buffer settings. (line 148) +* org-put-time-stamp-overlays: In-buffer settings. (line 142) * org-read-date-display-live: The date/time prompt. - (line 90) + (line 91) * org-read-date-force-compatible-dates: The date/time prompt. (line 61) * org-read-date-prefer-future: The date/time prompt. @@ -20639,29 +21568,26 @@ org-customize ' and then click yourself through the tree. * org-reverse-note-order: Refile and copy. (line 17) * org-scheduled-delay-days: Deadlines and scheduling. (line 40) -* org-show-entry-below: Sparse trees. (line 6) -* org-show-following-heading: Sparse trees. (line 6) -* org-show-hierarchy-above: Sparse trees. (line 6) -* org-show-siblings: Sparse trees. (line 6) +* org-show-context-detail: Sparse trees. (line 6) * org-sort-agenda-noeffort-is-high: Filtering/limiting agenda items. - (line 36) + (line 97) * org-sparse-tree-open-archived-trees: Internal archiving. (line 17) * org-special-ctrl-a/e: Headlines. (line 6) * org-special-ctrl-k: Headlines. (line 6) * org-speed-commands-user: Speed keys. (line 6) -* org-startup-align-all-tables <1>: In-buffer settings. (line 91) +* org-startup-align-all-tables <1>: In-buffer settings. (line 85) * org-startup-align-all-tables: Column width and alignment. (line 33) * org-startup-folded <1>: Speeding up your agendas. (line 19) -* org-startup-folded <2>: In-buffer settings. (line 80) +* org-startup-folded <2>: In-buffer settings. (line 74) * org-startup-folded: Initial visibility. (line 6) -* org-startup-indented: In-buffer settings. (line 86) -* org-startup-with-inline-images <1>: In-buffer settings. (line 98) +* org-startup-indented: In-buffer settings. (line 80) +* org-startup-with-inline-images <1>: In-buffer settings. (line 92) * org-startup-with-inline-images: Handling links. (line 136) -* org-startup-with-latex-preview <1>: In-buffer settings. (line 105) +* org-startup-with-latex-preview <1>: In-buffer settings. (line 99) * org-startup-with-latex-preview: Previewing LaTeX fragments. - (line 25) + (line 28) * org-store-link-functions: Adding hyperlink types. (line 65) * org-stuck-projects: Stuck projects. (line 17) @@ -20670,19 +21596,19 @@ org-customize ' and then click yourself through the tree. * org-table-auto-blank-field: Built-in table editor. (line 30) * org-table-copy-increment: Built-in table editor. - (line 162) + (line 168) * org-table-duration-custom-format: Durations and time values. (line 6) * org-table-export-default-format: Built-in table editor. - (line 199) -* org-table-formula: In-buffer settings. (line 35) + (line 205) +* org-table-formula: In-buffer settings. (line 33) * org-table-formula-constants <1>: Cooperation. (line 17) -* org-table-formula-constants <2>: In-buffer settings. (line 35) -* org-table-formula-constants: References. (line 102) +* org-table-formula-constants <2>: In-buffer settings. (line 33) +* org-table-formula-constants: References. (line 110) * org-table-use-standard-references <1>: Editing and debugging formulas. (line 6) * org-table-use-standard-references: References. (line 17) -* org-tag-alist <1>: In-buffer settings. (line 182) +* org-tag-alist <1>: In-buffer settings. (line 176) * org-tag-alist: Setting tags. (line 23) * org-tag-faces: Tags. (line 10) * org-tag-persistent-alist: Setting tags. (line 38) @@ -20699,27 +21625,29 @@ org-customize ' and then click yourself through the tree. * org-texinfo-coding-system: Document preamble. (line 22) * org-texinfo-def-table-markup: Texinfo specific attributes. (line 17) -* org-texinfo-default-class: Headings and sectioning structure. +* org-texinfo-default-class <1>: Headings and sectioning structure. (line 6) +* org-texinfo-default-class: Texinfo specific export settings. + (line 19) * org-texinfo-info-process: Texinfo export commands. (line 6) * org-time-stamp-custom-formats: Custom time format. (line 6) -* org-time-stamp-overlay-formats: In-buffer settings. (line 148) +* org-time-stamp-overlay-formats: In-buffer settings. (line 142) * org-time-stamp-rounding-minutes: Creating timestamps. (line 23) * org-todo (face): Faces for TODO keywords. (line 6) * org-todo-keyword-faces: Faces for TODO keywords. (line 6) -* org-todo-keywords <1>: In-buffer settings. (line 205) +* org-todo-keywords <1>: In-buffer settings. (line 196) * org-todo-keywords <2>: Global TODO list. (line 18) * org-todo-keywords <3>: TODO extensions. (line 6) * org-todo-keywords: TODO basics. (line 42) * org-todo-repeat-to-state: Repeated tasks. (line 19) * org-todo-state-tags-triggers: TODO basics. (line 63) * org-track-ordered-property-with-tag <1>: Checkboxes. (line 79) -* org-track-ordered-property-with-tag: TODO dependencies. (line 30) +* org-track-ordered-property-with-tag: TODO dependencies. (line 38) * org-treat-insert-todo-heading-as-state-change: Structure editing. - (line 27) + (line 36) * org-treat-S-cursor-todo-selection-as-state-change: TODO basics. (line 35) * org-use-fast-todo-selection: TODO basics. (line 14) @@ -20734,546 +21662,554 @@ org-customize ' and then click yourself through the tree. * org-use-sub-superscripts: Subscripts and superscripts. (line 15) * org-use-tag-inheritance: Tag inheritance. (line 22) -* org-yank-adjusted-subtrees: Structure editing. (line 84) -* org-yank-folded-subtrees: Structure editing. (line 84) +* org-yank-adjusted-subtrees: Structure editing. (line 93) +* org-yank-folded-subtrees: Structure editing. (line 93) * orgstruct-heading-prefix-regexp: Orgstruct mode. (line 26) * parse-time-months: The date/time prompt. (line 57) * parse-time-weekdays: The date/time prompt. (line 57) -* ps-landscape-mode: Exporting Agenda Views. +* ps-landscape-mode: Exporting agenda views. (line 20) -* ps-number-of-columns: Exporting Agenda Views. +* ps-number-of-columns: Exporting agenda views. (line 20) * user-full-name: Export settings. (line 25) -* user-mail-address <1>: Publishing options. (line 12) -* user-mail-address: Export settings. (line 40) +* user-mail-address: Export settings. (line 35)  Tag Table: -Node: Top895 -Node: Introduction24003 -Node: Summary24444 -Node: Installation27498 -Node: Activation30179 -Ref: Activation-Footnote-132009 -Node: Feedback32131 -Ref: Feedback-Footnote-135734 -Node: Conventions35861 -Ref: Conventions-Footnote-137872 -Node: Document Structure37964 -Node: Outlines38955 -Node: Headlines39611 -Ref: Headlines-Footnote-140615 -Ref: Headlines-Footnote-240791 -Node: Visibility cycling40862 -Node: Global and local cycling41241 -Ref: Global and local cycling-Footnote-144088 -Ref: Global and local cycling-Footnote-244146 -Ref: Global and local cycling-Footnote-344196 -Node: Initial visibility44466 -Ref: Initial visibility-Footnote-145718 -Node: Catching invisible edits45899 -Node: Motion46364 -Node: Structure editing47699 -Ref: Structure editing-Footnote-154507 -Node: Sparse trees54607 -Ref: Sparse trees-Footnote-157102 -Ref: Sparse trees-Footnote-257308 -Ref: Sparse trees-Footnote-357379 -Node: Plain lists57494 -Ref: Plain lists-Footnote-164908 -Ref: Plain lists-Footnote-265262 -Ref: Plain lists-Footnote-365358 -Ref: Plain lists-Footnote-465605 -Ref: Plain lists-Footnote-565776 -Ref: Plain lists-Footnote-665839 -Ref: Plain lists-Footnote-766015 -Ref: Plain lists-Footnote-866115 -Ref: Plain lists-Footnote-966217 -Node: Drawers66283 -Ref: Drawers-Footnote-168118 -Node: Blocks68223 -Node: Footnotes68782 -Ref: Footnotes-Footnote-173164 -Ref: Footnotes-Footnote-273261 -Node: Orgstruct mode73338 -Node: Org syntax74968 -Node: Tables75872 -Node: Built-in table editor76513 -Ref: Built-in table editor-Footnote-186003 -Node: Column width and alignment86103 -Ref: Column width and alignment-Footnote-188663 -Ref: Column width and alignment-Footnote-288709 -Node: Column groups88806 -Node: Orgtbl mode90350 -Node: The spreadsheet91159 -Node: References92619 -Ref: References-Footnote-198727 -Ref: References-Footnote-298949 -Ref: References-Footnote-399218 -Ref: References-Footnote-499321 -Node: Formula syntax for Calc99611 -Ref: Formula syntax for Calc-Footnote-1104758 -Node: Formula syntax for Lisp105082 -Node: Durations and time values106818 -Node: Field and range formulas107897 -Node: Column formulas110308 -Node: Lookup functions112397 -Node: Editing and debugging formulas114320 -Ref: Using multiple #+TBLFM lines118579 -Node: Updating the table119792 -Node: Advanced features121148 -Ref: Advanced features-Footnote-1125629 -Node: Org-Plot125735 -Node: Hyperlinks128577 -Node: Link format129334 -Node: Internal links130612 -Ref: Internal links-Footnote-1132904 -Ref: Internal links-Footnote-2133144 -Node: Radio targets133282 -Node: External links133972 -Ref: External links-Footnote-1138038 -Node: Handling links138428 -Ref: Handling links-Footnote-1146333 -Ref: Handling links-Footnote-2146492 -Ref: Handling links-Footnote-3146667 -Ref: Handling links-Footnote-4146963 -Ref: Handling links-Footnote-5147209 -Ref: Handling links-Footnote-6147286 -Ref: Handling links-Footnote-7147358 -Node: Using links outside Org147442 -Node: Link abbreviations147927 -Node: Search options150607 -Ref: Search options-Footnote-1152489 -Node: Custom searches152570 -Node: TODO Items153580 -Ref: TODO Items-Footnote-1154688 -Node: TODO basics154802 -Node: TODO extensions157667 -Node: Workflow states158697 -Ref: Workflow states-Footnote-1160022 -Node: TODO types160115 -Ref: TODO types-Footnote-1161713 -Node: Multiple sets in one file161795 -Node: Fast access to TODO states163660 -Ref: Fast access to TODO states-Footnote-1164533 -Ref: Fast access to TODO states-Footnote-2164617 -Node: Per-file keywords164910 -Ref: Per-file keywords-Footnote-1166306 -Node: Faces for TODO keywords166507 -Node: TODO dependencies167548 -Node: Progress logging169711 -Node: Closing items170423 -Ref: Closing items-Footnote-1171653 -Ref: Closing items-Footnote-2171722 -Node: Tracking TODO state changes171796 -Ref: Tracking TODO state changes-Footnote-1174832 -Ref: Tracking TODO state changes-Footnote-2174887 -Ref: Tracking TODO state changes-Footnote-3175027 -Node: Tracking your habits175315 -Node: Priorities179549 -Ref: Priorities-Footnote-1181539 -Node: Breaking down tasks181608 -Ref: Breaking down tasks-Footnote-1183587 -Node: Checkboxes183683 -Ref: Checkboxes-Footnote-1188209 -Ref: Checkboxes-Footnote-2188333 -Ref: Checkboxes-Footnote-3188507 -Node: Tags188621 -Node: Tag inheritance189689 -Ref: Tag inheritance-Footnote-1191513 -Ref: Tag inheritance-Footnote-2191613 -Node: Setting tags191739 -Ref: Setting tags-Footnote-1198043 -Node: Tag groups198126 -Node: Tag searches199575 -Node: Properties and Columns200867 -Node: Property syntax202303 -Node: Special properties206527 -Node: Property searches208361 -Node: Property inheritance209796 -Node: Column view211612 -Node: Defining columns212847 -Node: Scope of column definitions213245 -Node: Column attributes214175 -Ref: Column attributes-Footnote-1218978 -Node: Using column view219111 -Node: Capturing column view221973 -Ref: Capturing column view-Footnote-1224969 -Node: Property API225105 -Node: Dates and Times225459 -Node: Timestamps226438 -Ref: Timestamps-Footnote-1228881 -Ref: Timestamps-Footnote-2229067 -Ref: Timestamps-Footnote-3229198 -Node: Creating timestamps229967 -Node: The date/time prompt232791 -Ref: The date/time prompt-Footnote-1237317 -Ref: The date/time prompt-Footnote-2237480 -Ref: The date/time prompt-Footnote-3237586 -Node: Custom time format237680 -Node: Deadlines and scheduling239402 -Ref: Deadlines and scheduling-Footnote-1242784 -Node: Inserting deadline/schedule242939 -Ref: Inserting deadline/schedule-Footnote-1245251 -Ref: Inserting deadline/schedule-Footnote-2245403 -Ref: Inserting deadline/schedule-Footnote-3245511 -Node: Repeated tasks245619 -Ref: Repeated tasks-Footnote-1249366 -Ref: Repeated tasks-Footnote-2249615 -Node: Clocking work time249814 -Ref: Clocking work time-Footnote-1250999 -Ref: Clocking work time-Footnote-2251143 -Node: Clocking commands251281 -Ref: Clocking commands-Footnote-1256254 -Ref: Clocking commands-Footnote-2256361 -Ref: Clocking commands-Footnote-3256411 -Ref: Clocking commands-Footnote-4256469 -Node: The clock table256547 -Ref: The clock table-Footnote-1263805 -Ref: The clock table-Footnote-2263899 -Node: Resolving idle time264024 -Ref: Resolving idle time-Footnote-1267871 -Node: Effort estimates268339 -Ref: Effort estimates-Footnote-1271100 -Node: Relative timer271207 -Node: Countdown timer273054 -Node: Capture - Refile - Archive273546 -Node: Capture274536 -Node: Setting up capture275639 -Ref: Setting up capture-Footnote-1276064 -Node: Using capture276130 -Node: Capture templates278537 -Node: Template elements280498 -Ref: Template elements-Footnote-1286162 -Node: Template expansion286337 -Ref: Template expansion-Footnote-1290327 -Ref: Template expansion-Footnote-2290414 -Ref: Template expansion-Footnote-3290596 -Node: Templates in contexts290694 -Node: Attachments291516 -Ref: Attachments-Footnote-1294898 -Node: RSS Feeds295048 -Node: Protocols296638 -Node: Refile and copy297353 -Ref: Refile and copy-Footnote-1299775 -Node: Archiving299871 -Node: Moving subtrees300571 -Ref: Moving subtrees-Footnote-1302428 -Node: Internal archiving302872 -Node: Agenda Views305502 -Node: Agenda files307693 -Ref: Agenda files-Footnote-1310517 -Ref: Agenda files-Footnote-2310666 -Node: Agenda dispatcher310859 -Ref: Agenda dispatcher-Footnote-1313674 -Ref: Agenda dispatcher-Footnote-2313768 -Node: Built-in agenda views313870 -Node: Weekly/daily agenda314519 -Ref: Weekly/daily agenda-Footnote-1319827 -Ref: Weekly/daily agenda-Footnote-2320054 -Node: Global TODO list320229 -Node: Matching tags and properties322757 -Ref: Matching tags and properties-Footnote-1330084 -Node: Timeline330164 -Node: Search view330856 -Node: Stuck projects332149 -Ref: Stuck projects-Footnote-1334209 -Node: Presentation and sorting334239 -Node: Categories335196 -Ref: Categories-Footnote-1335997 -Node: Time-of-day specifications336434 -Node: Sorting agenda items338403 -Node: Filtering/limiting agenda items339972 -Ref: Filtering/limiting agenda items-Footnote-1347243 -Ref: Filtering/limiting agenda items-Footnote-2347658 -Node: Agenda commands347726 -Ref: Agenda commands-Footnote-1369053 -Ref: Agenda commands-Footnote-2369134 -Ref: Agenda commands-Footnote-3369253 -Ref: Agenda commands-Footnote-4369353 -Node: Custom agenda views369436 -Node: Storing searches370077 -Ref: Storing searches-Footnote-1373046 -Ref: Storing searches-Footnote-2373163 -Node: Block agenda373411 -Node: Setting Options374649 -Node: Exporting Agenda Views378283 -Ref: Exporting Agenda Views-Footnote-1383184 -Ref: Exporting Agenda Views-Footnote-2383242 -Ref: Exporting Agenda Views-Footnote-3383398 -Ref: Exporting Agenda Views-Footnote-4383585 -Node: Agenda column view383667 -Node: Markup386741 -Node: Structural markup elements387770 -Node: Document title388440 -Node: Headings and sections389017 -Node: Table of contents389687 -Node: Lists391171 -Node: Paragraphs391462 -Node: Footnote markup392612 -Node: Emphasis and monospace392949 -Node: Horizontal rules393806 -Node: Comment lines394063 -Node: Images and tables394571 -Node: Literal examples396288 -Ref: Literal examples-Footnote-1400167 -Ref: Literal examples-Footnote-2400497 -Ref: Literal examples-Footnote-3400669 -Ref: Literal examples-Footnote-4400848 -Ref: Literal examples-Footnote-5401098 -Node: Include files401192 -Node: Index entries402859 -Node: Macro replacement403321 -Ref: Macro replacement-Footnote-1404145 -Node: Embedded LaTeX404375 -Ref: Embedded LaTeX-Footnote-1405339 -Node: Special symbols405529 -Ref: Special symbols-Footnote-1407151 -Node: Subscripts and superscripts407306 -Node: LaTeX fragments408411 -Ref: LaTeX fragments-Footnote-1410636 -Ref: LaTeX fragments-Footnote-2410809 -Ref: LaTeX fragments-Footnote-3411178 -Node: Previewing LaTeX fragments411386 -Ref: Previewing LaTeX fragments-Footnote-1412617 -Node: CDLaTeX mode412724 -Ref: CDLaTeX mode-Footnote-1415219 -Node: Special blocks415367 -Node: Exporting416270 -Node: The Export Dispatcher418225 -Ref: The Export Dispatcher-Footnote-1420563 -Node: Export back-ends420826 -Node: Export settings421736 -Ref: Export settings-Footnote-1428706 -Ref: Export settings-Footnote-2428808 -Ref: Export settings-Footnote-3428903 -Node: ASCII/Latin-1/UTF-8 export428946 -Node: Beamer export430977 -Ref: Beamer export-Footnote-1438379 -Ref: Beamer export-Footnote-2438542 -Node: HTML export438660 -Node: HTML Export commands439745 -Node: HTML doctypes440295 -Node: HTML preamble and postamble442533 -Node: Quoting HTML tags443581 -Node: Links in HTML export444211 -Node: Tables in HTML export445344 -Node: Images in HTML export446062 -Ref: Images in HTML export-Footnote-1447352 -Node: Math formatting in HTML export447407 -Ref: Math formatting in HTML export-Footnote-1448896 -Node: Text areas in HTML export449031 -Node: CSS support449811 -Ref: CSS support-Footnote-1452875 -Ref: CSS support-Footnote-2453047 -Node: JavaScript support453289 -Node: LaTeX and PDF export456670 -Ref: LaTeX and PDF export-Footnote-1457804 -Node: LaTeX export commands458127 -Node: Header and sectioning458822 -Ref: Header and sectioning-Footnote-1460434 -Ref: Header and sectioning-Footnote-2460546 -Node: Quoting LaTeX code460709 -Node: LaTeX specific attributes461304 -Ref: LaTeX specific attributes-Footnote-1469402 -Ref: LaTeX specific attributes-Footnote-2469480 -Ref: LaTeX specific attributes-Footnote-3469554 -Node: Markdown export469708 -Ref: Markdown export-Footnote-1471012 -Node: OpenDocument Text export471098 -Ref: OpenDocument Text export-Footnote-1472231 -Ref: OpenDocument Text export-Footnote-2472261 -Node: Pre-requisites for ODT export472405 -Node: ODT export commands472764 -Ref: x-export-to-odt472993 -Ref: ODT export commands-Footnote-1473992 -Ref: ODT export commands-Footnote-2474052 -Node: Extending ODT export474103 -Ref: x-export-to-other-formats475098 -Ref: x-convert-to-other-formats475626 -Node: Applying custom styles476083 -Node: Links in ODT export478241 -Node: Tables in ODT export478886 -Ref: Tables in ODT export-Footnote-1481020 -Node: Images in ODT export481113 -Ref: Images in ODT export-Footnote-1483838 -Node: Math formatting in ODT export484071 -Node: Working with LaTeX math snippets484533 -Ref: Working with LaTeX math snippets-Footnote-1486643 -Node: Working with MathML or OpenDocument formula files486718 -Node: Labels and captions in ODT export487290 -Node: Literal examples in ODT export488745 -Ref: Literal examples in ODT export-Footnote-1489646 -Node: Advanced topics in ODT export489757 -Node: Configuring a document converter490511 -Ref: x-odt-converter-capabilities491341 -Node: Working with OpenDocument style files491922 -Ref: x-factory-styles492418 -Ref: x-orgodtstyles-xml492650 -Ref: x-orgodtcontenttemplate-xml492977 -Ref: x-overriding-factory-styles493633 -Ref: x-org-odt-styles-file493907 -Ref: x-org-odt-content-template-file494788 -Node: Creating one-off styles494929 -Node: Customizing tables in ODT export497150 -Ref: Customizing tables in ODT export-Footnote-1502295 -Ref: Customizing tables in ODT export-Footnote-2502399 -Ref: Customizing tables in ODT export-Footnote-3502487 -Node: Validating OpenDocument XML502802 -Ref: Validating OpenDocument XML-Footnote-1503821 -Node: Org export503873 -Node: Texinfo export504637 -Node: Texinfo export commands505261 -Ref: Texinfo export commands-Footnote-1505804 -Node: Document preamble505912 -Ref: Document preamble-Footnote-1509186 -Node: Headings and sectioning structure509248 -Node: Indices510700 -Node: Quoting Texinfo code511493 -Node: Texinfo specific attributes511977 -Ref: Texinfo specific attributes-Footnote-1513183 -Node: An example513249 -Node: iCalendar export515221 -Ref: iCalendar export-Footnote-1517953 -Ref: iCalendar export-Footnote-2518043 -Ref: iCalendar export-Footnote-3518143 -Node: Other built-in back-ends518280 -Node: Export in foreign buffers518873 -Node: Advanced configuration519863 -Node: Publishing525964 -Node: Configuration526832 -Node: Project alist527614 -Node: Sources and destinations528777 -Node: Selecting files530295 -Node: Publishing action531296 -Ref: Publishing action-Footnote-1533125 -Node: Publishing options533282 -Node: Publishing links536335 -Node: Sitemap537302 -Node: Generating an index540521 -Node: Uploading files541108 -Node: Sample configuration542872 -Node: Simple example543361 -Node: Complex example544037 -Node: Triggering publication546088 -Node: Working With Source Code547084 -Node: Structure of code blocks548776 -Ref: Structure of code blocks-Footnote-1550642 -Node: Editing source code550736 -Node: Exporting code blocks552857 -Node: Extracting source code554963 -Node: Evaluating code blocks557199 -Ref: Evaluating code blocks-Footnote-1560553 -Ref: Evaluating code blocks-Footnote-2560850 -Node: Library of Babel560976 -Node: Languages561953 -Node: Header arguments564269 -Node: Using header arguments564754 -Node: System-wide header arguments565809 -Node: Language-specific header arguments566647 -Node: Header arguments in Org mode properties567156 -Ref: Header arguments in Org mode properties-Footnote-1568885 -Node: Language-specific header arguments in Org mode properties569157 -Node: Code block specific header arguments570173 -Node: Header arguments in function calls572019 -Node: Specific header arguments572768 -Node: var575397 -Node: results582222 -Node: file587075 -Node: file-desc587987 -Node: dir588452 -Node: exports591386 -Node: tangle592040 -Node: mkdirp592851 -Node: comments593182 -Node: padline594315 -Node: no-expand594847 -Node: session595339 -Node: noweb595786 -Node: noweb-ref597963 -Ref: noweb-ref-Footnote-1599429 -Node: noweb-sep599558 -Node: cache599852 -Node: sep601584 -Node: hlines602156 -Node: colnames603658 -Node: rownames604961 -Node: shebang606136 -Node: tangle-mode606539 -Node: eval607290 -Node: wrap608328 -Node: post608768 -Node: prologue609884 -Node: epilogue610456 -Node: Results of evaluation610711 -Node: Noweb reference syntax614479 -Node: Key bindings and useful functions616130 -Node: Batch execution618875 -Node: Miscellaneous619909 -Node: Completion620738 -Node: Easy Templates622714 -Node: Speed keys624123 -Node: Code evaluation security624950 -Node: Customization627664 -Node: In-buffer settings628259 -Ref: In-buffer settings-Footnote-1638407 -Node: The very busy C-c C-c key638455 -Node: Clean view640439 -Ref: Clean view-Footnote-1644424 -Ref: Clean view-Footnote-2644485 -Ref: Clean view-Footnote-3644669 -Ref: Clean view-Footnote-4644730 -Ref: Clean view-Footnote-5644842 -Ref: Clean view-Footnote-6644897 -Node: TTY keys645022 -Node: Interaction646788 -Node: Cooperation647182 -Node: Conflicts650980 -Node: org-crypt655949 -Node: Hacking657260 -Node: Hooks658248 -Node: Add-on packages658664 -Node: Adding hyperlink types659218 -Node: Adding export back-ends663138 -Node: Context-sensitive commands664583 -Ref: Context-sensitive commands-Footnote-1666160 -Node: Tables in arbitrary syntax666294 -Node: Radio tables667706 -Node: A LaTeX example670466 -Ref: A LaTeX example-Footnote-1674395 -Ref: A LaTeX example-Footnote-2674552 -Node: Translator functions674987 -Ref: Translator functions-Footnote-1678211 -Node: Radio lists678299 -Node: Dynamic blocks679428 -Node: Special agenda views681641 -Ref: x-agenda-skip-entry-regexp685104 -Ref: Special agenda views-Footnote-1685907 -Ref: Special agenda views-Footnote-2686104 -Node: Speeding up your agendas686239 -Node: Extracting agenda information687342 -Node: Using the property API691420 -Node: Using the mapping API694796 -Node: MobileOrg699218 -Node: Setting up the staging area700917 -Ref: Setting up the staging area-Footnote-1702016 -Ref: Setting up the staging area-Footnote-2702317 -Node: Pushing to MobileOrg702579 -Ref: Pushing to MobileOrg-Footnote-1703579 -Ref: Pushing to MobileOrg-Footnote-2703668 -Ref: Pushing to MobileOrg-Footnote-3704084 -Node: Pulling from MobileOrg704155 -Ref: Pulling from MobileOrg-Footnote-1706576 -Ref: Pulling from MobileOrg-Footnote-2706636 -Node: History and Acknowledgments707011 -Node: GNU Free Documentation License721967 -Node: Main Index747157 -Node: Key Index824688 -Node: Command and Function Index876736 -Node: Variable Index911060 +Node: Top893 +Node: Introduction23740 +Node: Summary24181 +Node: Installation26877 +Node: Activation29559 +Ref: Activation-Footnote-131364 +Node: Feedback31486 +Ref: Feedback-Footnote-135194 +Node: Conventions35321 +Ref: Conventions-Footnote-137387 +Node: Document structure37479 +Node: Outlines38470 +Node: Headlines39099 +Ref: Headlines-Footnote-140301 +Ref: Headlines-Footnote-240477 +Node: Visibility cycling40548 +Node: Global and local cycling40927 +Ref: Global and local cycling-Footnote-143587 +Ref: Global and local cycling-Footnote-243645 +Ref: Global and local cycling-Footnote-343695 +Node: Initial visibility43964 +Ref: Initial visibility-Footnote-145216 +Node: Catching invisible edits45397 +Node: Motion45862 +Node: Structure editing47197 +Node: Sparse trees54199 +Ref: Sparse trees-Footnote-156698 +Ref: Sparse trees-Footnote-256809 +Ref: Sparse trees-Footnote-356880 +Node: Plain lists56995 +Ref: Plain lists-Footnote-164407 +Ref: Plain lists-Footnote-264761 +Ref: Plain lists-Footnote-364857 +Ref: Plain lists-Footnote-465104 +Ref: Plain lists-Footnote-565275 +Ref: Plain lists-Footnote-665338 +Ref: Plain lists-Footnote-765514 +Ref: Plain lists-Footnote-865614 +Ref: Plain lists-Footnote-965716 +Node: Drawers65782 +Node: Blocks67605 +Node: Footnotes68164 +Ref: Footnotes-Footnote-172786 +Ref: Footnotes-Footnote-272883 +Node: Orgstruct mode72960 +Node: Org syntax74590 +Node: Tables75494 +Node: Built-in table editor76135 +Ref: Built-in table editor-Footnote-185889 +Node: Column width and alignment85989 +Ref: Column width and alignment-Footnote-188552 +Ref: Column width and alignment-Footnote-288598 +Node: Column groups88695 +Node: Orgtbl mode90267 +Node: The spreadsheet91076 +Node: References92536 +Ref: References-Footnote-199254 +Ref: References-Footnote-299476 +Ref: References-Footnote-399745 +Ref: References-Footnote-499858 +Node: Formula syntax for Calc100148 +Ref: Formula syntax for Calc-Footnote-1105295 +Node: Formula syntax for Lisp105619 +Node: Durations and time values107354 +Node: Field and range formulas108432 +Node: Column formulas110829 +Node: Lookup functions112917 +Node: Editing and debugging formulas114840 +Ref: Using multiple #+TBLFM lines119099 +Node: Updating the table120312 +Node: Advanced features121668 +Ref: Advanced features-Footnote-1126149 +Node: Org-Plot126255 +Node: Hyperlinks130449 +Node: Link format131206 +Node: Internal links132465 +Ref: Internal links-Footnote-1134760 +Ref: Internal links-Footnote-2135000 +Node: Radio targets135138 +Node: External links135805 +Ref: External links-Footnote-1139877 +Ref: External links-Footnote-2140295 +Node: Handling links140552 +Ref: Handling links-Footnote-1148457 +Ref: Handling links-Footnote-2148616 +Ref: Handling links-Footnote-3148791 +Ref: Handling links-Footnote-4149086 +Ref: Handling links-Footnote-5149332 +Ref: Handling links-Footnote-6149409 +Ref: Handling links-Footnote-7149481 +Node: Using links outside Org149565 +Node: Link abbreviations150050 +Node: Search options152732 +Ref: Search options-Footnote-1154614 +Node: Custom searches154695 +Node: TODO items155705 +Ref: TODO items-Footnote-1156813 +Node: TODO basics156927 +Node: TODO extensions159773 +Node: Workflow states160803 +Ref: Workflow states-Footnote-1162104 +Node: TODO types162197 +Ref: TODO types-Footnote-1163795 +Node: Multiple sets in one file163877 +Node: Fast access to TODO states165731 +Ref: Fast access to TODO states-Footnote-1166604 +Ref: Fast access to TODO states-Footnote-2166688 +Node: Per-file keywords166981 +Ref: Per-file keywords-Footnote-1168352 +Node: Faces for TODO keywords168553 +Node: TODO dependencies169594 +Node: Progress logging171929 +Node: Closing items172641 +Ref: Closing items-Footnote-1173846 +Ref: Closing items-Footnote-2173915 +Node: Tracking TODO state changes173989 +Ref: Tracking TODO state changes-Footnote-1177025 +Ref: Tracking TODO state changes-Footnote-2177080 +Ref: Tracking TODO state changes-Footnote-3177220 +Node: Tracking your habits177508 +Node: Priorities181742 +Ref: Priorities-Footnote-1183732 +Node: Breaking down tasks183801 +Ref: Breaking down tasks-Footnote-1185780 +Node: Checkboxes185876 +Ref: Checkboxes-Footnote-1190402 +Ref: Checkboxes-Footnote-2190526 +Ref: Checkboxes-Footnote-3190700 +Node: Tags190814 +Node: Tag inheritance191870 +Ref: Tag inheritance-Footnote-1193681 +Ref: Tag inheritance-Footnote-2193781 +Node: Setting tags193907 +Ref: Setting tags-Footnote-1200214 +Node: Tag hierarchy200297 +Node: Tag searches203688 +Node: Properties and columns204983 +Node: Property syntax206419 +Node: Special properties210761 +Node: Property searches212418 +Node: Property inheritance213853 +Node: Column view215669 +Node: Defining columns216904 +Node: Scope of column definitions217282 +Node: Column attributes218187 +Ref: Column attributes-Footnote-1223011 +Node: Using column view223144 +Node: Capturing column view226005 +Ref: Capturing column view-Footnote-1229001 +Node: Property API229137 +Node: Dates and times229491 +Node: Timestamps230398 +Ref: Timestamps-Footnote-1232817 +Ref: Timestamps-Footnote-2233003 +Ref: Timestamps-Footnote-3233134 +Node: Creating timestamps233903 +Node: The date/time prompt236727 +Ref: The date/time prompt-Footnote-1241308 +Ref: The date/time prompt-Footnote-2241471 +Ref: The date/time prompt-Footnote-3241577 +Node: Custom time format241671 +Node: Deadlines and scheduling243393 +Ref: Deadlines and scheduling-Footnote-1246775 +Node: Inserting deadline/schedule246930 +Ref: Inserting deadline/schedule-Footnote-1248887 +Ref: Inserting deadline/schedule-Footnote-2249039 +Ref: Inserting deadline/schedule-Footnote-3249147 +Node: Repeated tasks249255 +Ref: Repeated tasks-Footnote-1253125 +Ref: Repeated tasks-Footnote-2253374 +Node: Clocking work time253573 +Ref: Clocking work time-Footnote-1254758 +Ref: Clocking work time-Footnote-2254902 +Node: Clocking commands255040 +Ref: Clocking commands-Footnote-1259986 +Ref: Clocking commands-Footnote-2260093 +Ref: Clocking commands-Footnote-3260143 +Ref: Clocking commands-Footnote-4260201 +Node: The clock table260279 +Ref: The clock table-Footnote-1267729 +Ref: The clock table-Footnote-2267823 +Node: Resolving idle time267948 +Ref: Resolving idle time-Footnote-1271795 +Node: Effort estimates272263 +Ref: Effort estimates-Footnote-1275016 +Node: Timers275123 +Node: Capture - Refile - Archive277422 +Node: Capture278412 +Node: Setting up capture279480 +Ref: Setting up capture-Footnote-1279889 +Node: Using capture279955 +Node: Capture templates282362 +Node: Template elements284323 +Ref: Template elements-Footnote-1290161 +Node: Template expansion290336 +Ref: Template expansion-Footnote-1294326 +Ref: Template expansion-Footnote-2294413 +Ref: Template expansion-Footnote-3294595 +Node: Templates in contexts294693 +Node: Attachments295515 +Ref: Attachments-Footnote-1298897 +Node: RSS feeds299047 +Node: Protocols300524 +Node: Refile and copy301239 +Ref: Refile and copy-Footnote-1303661 +Node: Archiving303757 +Node: Moving subtrees304457 +Node: Internal archiving306481 +Node: Agenda views309111 +Node: Agenda files311302 +Ref: Agenda files-Footnote-1314105 +Ref: Agenda files-Footnote-2314254 +Node: Agenda dispatcher314447 +Ref: Agenda dispatcher-Footnote-1317356 +Ref: Agenda dispatcher-Footnote-2317450 +Node: Built-in agenda views317552 +Node: Weekly/daily agenda318201 +Ref: Weekly/daily agenda-Footnote-1323546 +Ref: Weekly/daily agenda-Footnote-2323773 +Node: Global TODO list323948 +Node: Matching tags and properties326476 +Node: Timeline333464 +Node: Search view334156 +Node: Stuck projects335449 +Ref: Stuck projects-Footnote-1337509 +Node: Presentation and sorting337539 +Node: Categories338496 +Node: Time-of-day specifications339225 +Node: Sorting agenda items341194 +Node: Filtering/limiting agenda items342763 +Ref: Filtering/limiting agenda items-Footnote-1349991 +Node: Agenda commands350406 +Ref: Agenda commands-Footnote-1371927 +Ref: Agenda commands-Footnote-2372008 +Ref: Agenda commands-Footnote-3372127 +Ref: Agenda commands-Footnote-4372227 +Node: Custom agenda views372310 +Node: Storing searches372951 +Ref: Storing searches-Footnote-1375892 +Ref: Storing searches-Footnote-2376009 +Node: Block agenda376257 +Node: Setting options377495 +Node: Exporting agenda views381084 +Ref: Exporting agenda views-Footnote-1385985 +Ref: Exporting agenda views-Footnote-2386043 +Ref: Exporting agenda views-Footnote-3386199 +Ref: Exporting agenda views-Footnote-4386386 +Node: Agenda column view386468 +Node: Markup389542 +Node: Structural markup elements390574 +Node: Document title391229 +Node: Headings and sections391641 +Node: Table of contents392311 +Ref: Table of contents-Footnote-1394067 +Node: Lists394265 +Node: Paragraphs394556 +Node: Footnote markup395706 +Node: Emphasis and monospace396043 +Node: Horizontal rules396900 +Node: Comment lines397157 +Ref: Comment lines-Footnote-1397934 +Node: Images and tables398034 +Node: Literal examples399751 +Ref: Literal examples-Footnote-1403744 +Ref: Literal examples-Footnote-2404277 +Ref: Literal examples-Footnote-3404449 +Ref: Literal examples-Footnote-4404628 +Ref: Literal examples-Footnote-5404878 +Node: Include files404972 +Ref: Include files-Footnote-1407854 +Ref: Include files-Footnote-2408004 +Node: Index entries408170 +Node: Macro replacement408632 +Ref: Macro replacement-Footnote-1410589 +Node: Embedded LaTeX410819 +Ref: Embedded LaTeX-Footnote-1411783 +Node: Special symbols411973 +Ref: Special symbols-Footnote-1413574 +Node: Subscripts and superscripts413729 +Node: LaTeX fragments414834 +Ref: LaTeX fragments-Footnote-1417034 +Node: Previewing LaTeX fragments417238 +Ref: Previewing LaTeX fragments-Footnote-1418663 +Node: CDLaTeX mode418882 +Ref: CDLaTeX mode-Footnote-1421379 +Node: Special blocks421527 +Node: Exporting422458 +Node: The export dispatcher424413 +Ref: The export dispatcher-Footnote-1426453 +Node: Export back-ends426716 +Node: Export settings427626 +Ref: Export settings-Footnote-1434721 +Ref: Export settings-Footnote-2434823 +Ref: Export settings-Footnote-3434918 +Node: ASCII/Latin-1/UTF-8 export434961 +Node: Beamer export437733 +Node: Beamer export commands438456 +Node: Beamer specific export settings439131 +Node: Sectioning Frames and Blocks in Beamer440915 +Ref: Sectioning Frames and Blocks in Beamer-Footnote-1443871 +Ref: Sectioning Frames and Blocks in Beamer-Footnote-2444034 +Node: Beamer specific syntax444152 +Node: Editing support445784 +Node: A Beamer Example446215 +Node: HTML export447493 +Node: HTML Export commands448645 +Node: HTML Specific export settings449191 +Node: HTML doctypes450976 +Node: HTML preamble and postamble453223 +Node: Quoting HTML tags454271 +Node: Links in HTML export454901 +Node: Tables in HTML export456112 +Node: Images in HTML export457548 +Ref: Images in HTML export-Footnote-1458838 +Node: Math formatting in HTML export458893 +Ref: Math formatting in HTML export-Footnote-1460244 +Node: Text areas in HTML export460504 +Node: CSS support461286 +Ref: CSS support-Footnote-1464393 +Ref: CSS support-Footnote-2464565 +Node: JavaScript support464807 +Node: LaTeX and PDF export468188 +Ref: LaTeX and PDF export-Footnote-1469384 +Node: LaTeX export commands469674 +Node: LaTeX specific export settings470349 +Node: Header and sectioning472437 +Ref: Header and sectioning-Footnote-1474058 +Ref: Header and sectioning-Footnote-2474170 +Node: Quoting LaTeX code474333 +Node: LaTeX specific attributes474928 +Ref: LaTeX specific attributes-Footnote-1484333 +Ref: LaTeX specific attributes-Footnote-2484411 +Ref: LaTeX specific attributes-Footnote-3484485 +Ref: LaTeX specific attributes-Footnote-4484569 +Node: Markdown export484723 +Ref: Markdown export-Footnote-1486027 +Node: OpenDocument Text export486113 +Ref: OpenDocument Text export-Footnote-1487303 +Ref: OpenDocument Text export-Footnote-2487333 +Node: Pre-requisites for ODT export487477 +Node: ODT export commands487803 +Ref: x-export-to-odt488005 +Ref: ODT export commands-Footnote-1489004 +Ref: ODT export commands-Footnote-2489064 +Node: ODT specific export settings489115 +Node: Extending ODT export489955 +Ref: x-export-to-other-formats490941 +Ref: x-convert-to-other-formats491451 +Node: Applying custom styles491908 +Node: Links in ODT export494030 +Node: Tables in ODT export494675 +Ref: Tables in ODT export-Footnote-1496809 +Node: Images in ODT export496902 +Ref: Images in ODT export-Footnote-1499626 +Node: Math formatting in ODT export499859 +Node: Working with LaTeX math snippets500321 +Ref: Working with LaTeX math snippets-Footnote-1502487 +Ref: Working with LaTeX math snippets-Footnote-2502563 +Node: Working with MathML or OpenDocument formula files502608 +Node: Labels and captions in ODT export503162 +Node: Literal examples in ODT export504618 +Ref: Literal examples in ODT export-Footnote-1505519 +Node: Advanced topics in ODT export505630 +Node: Configuring a document converter506384 +Ref: x-odt-converter-capabilities507156 +Node: Working with OpenDocument style files507737 +Ref: x-factory-styles508213 +Ref: x-orgodtstyles-xml508451 +Ref: x-orgodtcontenttemplate-xml508778 +Ref: x-overriding-factory-styles509434 +Ref: x-org-odt-styles-file509714 +Ref: x-org-odt-content-template-file510595 +Node: Creating one-off styles510736 +Node: Customizing tables in ODT export512937 +Ref: Customizing tables in ODT export-Footnote-1517914 +Ref: Customizing tables in ODT export-Footnote-2518018 +Ref: Customizing tables in ODT export-Footnote-3518106 +Node: Validating OpenDocument XML518421 +Ref: Validating OpenDocument XML-Footnote-1519420 +Node: Org export519472 +Node: Texinfo export520236 +Node: Texinfo export commands520925 +Ref: Texinfo export commands-Footnote-1521460 +Node: Texinfo specific export settings521568 +Node: Document preamble522670 +Ref: Document preamble-Footnote-1525959 +Node: Headings and sectioning structure526021 +Node: Indices527475 +Node: Quoting Texinfo code528268 +Node: Texinfo specific attributes528752 +Ref: Texinfo specific attributes-Footnote-1530274 +Node: An example530340 +Node: iCalendar export532331 +Ref: iCalendar export-Footnote-1535063 +Ref: iCalendar export-Footnote-2535153 +Ref: iCalendar export-Footnote-3535253 +Node: Other built-in back-ends535390 +Node: Export in foreign buffers535983 +Node: Advanced configuration536973 +Node: Publishing543915 +Node: Configuration544783 +Node: Project alist545546 +Node: Sources and destinations546687 +Node: Selecting files548205 +Node: Publishing action549206 +Ref: Publishing action-Footnote-1551035 +Node: Publishing options551192 +Node: Publishing links563919 +Node: Sitemap564886 +Node: Generating an index568105 +Node: Uploading files568692 +Node: Sample configuration570456 +Node: Simple example570945 +Node: Complex example571592 +Node: Triggering publication573643 +Node: Working with source code574639 +Node: Structure of code blocks576331 +Ref: Structure of code blocks-Footnote-1578164 +Node: Editing source code578258 +Node: Exporting code blocks580381 +Node: Extracting source code582882 +Node: Evaluating code blocks585117 +Ref: Evaluating code blocks-Footnote-1588551 +Ref: Evaluating code blocks-Footnote-2588848 +Node: Library of Babel588974 +Node: Languages589947 +Node: Header arguments592380 +Node: Using header arguments592865 +Node: System-wide header arguments593895 +Node: Language-specific header arguments594702 +Node: Header arguments in Org mode properties595211 +Ref: Header arguments in Org mode properties-Footnote-1596940 +Node: Language-specific header arguments in Org mode properties597212 +Node: Code block specific header arguments598228 +Node: Header arguments in function calls600074 +Node: Specific header arguments600823 +Node: var603597 +Node: results610388 +Node: file615241 +Node: file-desc616153 +Node: file-ext616623 +Node: output-dir617121 +Node: dir617659 +Node: exports620594 +Node: tangle621332 +Node: mkdirp622143 +Node: comments622476 +Node: padline623611 +Node: no-expand624143 +Node: session624782 +Node: noweb625817 +Node: noweb-ref627994 +Ref: noweb-ref-Footnote-1629460 +Node: noweb-sep629589 +Node: cache629883 +Node: sep631615 +Node: hlines632187 +Node: colnames633689 +Node: rownames634992 +Node: shebang636167 +Node: tangle-mode636570 +Node: eval637321 +Node: wrap638359 +Node: post638799 +Node: prologue640691 +Node: epilogue641263 +Node: Results of evaluation641518 +Node: Noweb reference syntax645286 +Node: Key bindings and useful functions646937 +Node: Batch execution649682 +Node: Miscellaneous650716 +Node: Completion651545 +Node: Easy templates653499 +Node: Speed keys654908 +Node: Code evaluation security655732 +Node: Customization658442 +Node: In-buffer settings659037 +Ref: In-buffer settings-Footnote-1668777 +Node: The very busy C-c C-c key668825 +Node: Clean view670809 +Ref: Clean view-Footnote-1674794 +Ref: Clean view-Footnote-2674855 +Ref: Clean view-Footnote-3675039 +Ref: Clean view-Footnote-4675100 +Ref: Clean view-Footnote-5675212 +Ref: Clean view-Footnote-6675267 +Node: TTY keys675392 +Node: Interaction677158 +Node: Cooperation677552 +Node: Conflicts681330 +Node: org-crypt686299 +Node: Hacking687610 +Node: Hooks688596 +Node: Add-on packages688996 +Node: Adding hyperlink types689550 +Node: Adding export back-ends693470 +Node: Context-sensitive commands694910 +Ref: Context-sensitive commands-Footnote-1696487 +Node: Tables in arbitrary syntax696621 +Node: Radio tables698033 +Node: A LaTeX example700620 +Ref: A LaTeX example-Footnote-1704612 +Ref: A LaTeX example-Footnote-2704769 +Node: Translator functions705204 +Node: Radio lists707635 +Node: Dynamic blocks708764 +Node: Special agenda views710962 +Ref: x-agenda-skip-entry-regexp714425 +Ref: Special agenda views-Footnote-1715228 +Ref: Special agenda views-Footnote-2715423 +Node: Speeding up your agendas715558 +Node: Extracting agenda information716661 +Node: Using the property API720739 +Node: Using the mapping API724109 +Node: MobileOrg728531 +Node: Setting up the staging area730225 +Ref: Setting up the staging area-Footnote-1731306 +Ref: Setting up the staging area-Footnote-2731607 +Node: Pushing to MobileOrg731869 +Ref: Pushing to MobileOrg-Footnote-1732869 +Ref: Pushing to MobileOrg-Footnote-2732956 +Ref: Pushing to MobileOrg-Footnote-3733372 +Node: Pulling from MobileOrg733443 +Ref: Pulling from MobileOrg-Footnote-1735864 +Ref: Pulling from MobileOrg-Footnote-2735924 +Node: History and acknowledgments736299 +Node: GNU Free Documentation License751454 +Node: Main Index776644 +Node: Key Index865745 +Node: Command and Function Index918334 +Node: Variable Index953359  End Tag Table diff --git a/elpa/org-20150629/org-agenda.el b/elpa/org-20160215/org-agenda.el similarity index 93% rename from elpa/org-20150629/org-agenda.el rename to elpa/org-20160215/org-agenda.el index 4241f44c..19a40955 100644 --- a/elpa/org-20150629/org-agenda.el +++ b/elpa/org-20160215/org-agenda.el @@ -1,6 +1,6 @@ ;;; org-agenda.el --- Dynamic task and appointment lists for Org -;; Copyright (C) 2004-2014 Free Software Foundation, Inc. +;; Copyright (C) 2004-2016 Free Software Foundation, Inc. ;; Author: Carsten Dominik ;; Keywords: outlines, hypermedia, calendar, wp @@ -69,6 +69,7 @@ (declare-function calendar-persian-date-string "cal-persia" (&optional date)) (declare-function calendar-check-holidays "holidays" (date)) +(declare-function org-columns-remove-overlays "org-colview" ()) (declare-function org-datetree-find-date-create "org-datetree" (date &optional keep-restriction)) (declare-function org-columns-quit "org-colview" ()) @@ -152,7 +153,7 @@ before assigned to the variables. So make sure to quote values you do *not* want evaluated, for example (setq org-agenda-exporter-settings - '((ps-print-color-p 'black-white)))" + \\='((ps-print-color-p \\='black-white)))" :group 'org-agenda-export :type '(repeat (list @@ -360,6 +361,12 @@ the daily/weekly agenda, see `org-agenda-skip-function'.") (const :format "" quote) (repeat (string :tag "+tag or -tag")))) + (list :tag "Effort filter preset" + (const org-agenda-effort-filter-preset) + (list + (const :format "" quote) + (repeat + (string :tag "+=10 or -=10 or +<10 or ->10")))) (list :tag "Regexp filter preset" (const org-agenda-regexp-filter-preset) (list @@ -433,7 +440,7 @@ This will be spliced into the custom type of (defcustom org-agenda-custom-commands - '(("n" "Agenda and all TODO's" ((agenda "") (alltodo "")))) + '(("n" "Agenda and all TODOs" ((agenda "") (alltodo "")))) "Custom commands for the agenda. These commands will be offered on the splash screen displayed by the agenda dispatcher \\[org-agenda]. Each entry is a list like this: @@ -497,7 +504,7 @@ are prefix commands. For the dispatcher to display useful information, you should provide a description for the prefix, like (setq org-agenda-custom-commands - '((\"h\" . \"HOME + Name tag searches\") ; describe prefix \"h\" + \\='((\"h\" . \"HOME + Name tag searches\") ; describe prefix \"h\" (\"hl\" tags \"+HOME+Lisa\") (\"hp\" tags \"+HOME+Peter\") (\"hk\" tags \"+HOME+Kim\")))" @@ -610,15 +617,6 @@ or `C-c a #' to produce the list." (repeat :tag "Projects are *not* stuck if they have an entry with TAG being any of" (string)) (regexp :tag "Projects are *not* stuck if this regexp matches inside the subtree"))) -(defcustom org-agenda-filter-effort-default-operator "<" - "The default operator for effort estimate filtering. -If you select an effort estimate limit without first pressing an operator, -this one will be used." - :group 'org-agenda-custom-commands - :type '(choice (const :tag "less or equal" "<") - (const :tag "greater or equal"">") - (const :tag "equal" "="))) - (defgroup org-agenda-skip nil "Options concerning skipping parts of agenda files." :tag "Org Agenda Skip" @@ -1097,6 +1095,7 @@ Possible values for this option are: current-window Show agenda in the current window, keeping all other windows. other-window Use `switch-to-buffer-other-window' to display agenda. +only-window Show agenda, deleting all other windows. reorganize-frame Show only two windows on the current frame, the current window and the agenda. other-frame Use `switch-to-buffer-other-frame' to display agenda. @@ -1107,6 +1106,7 @@ See also the variable `org-agenda-restore-windows-after-quit'." (const current-window) (const other-frame) (const other-window) + (const only-window) (const reorganize-frame))) (defcustom org-agenda-window-frame-fractions '(0.5 . 0.75) @@ -1211,7 +1211,7 @@ For example, 9:30am would become 09:30 rather than 9:30." :type 'boolean) (defun org-agenda-time-of-day-to-ampm (time) - "Convert TIME of a string like '13:45' to an AM/PM style time string." + "Convert TIME of a string like \"13:45\" to an AM/PM style time string." (let* ((hour-number (string-to-number (substring time 0 -3))) (minute (substring time -2)) (ampm "am")) @@ -1292,12 +1292,14 @@ given here." (defcustom org-agenda-log-mode-items '(closed clock) "List of items that should be shown in agenda log mode. +\\\ This list may contain the following symbols: closed Show entries that have been closed on that day. clock Show entries that have received clocked time on that day. state Show all logged state changes. -Note that instead of changing this variable, you can also press `C-u l' in +Note that instead of changing this variable, you can also press \ +`\\[universal-argument] \\[org-agenda-log-mode]' in the agenda to display all available LOG items temporarily." :group 'org-agenda-daily/weekly :type '(set :greedy t (const closed) (const clock) (const state))) @@ -1792,7 +1794,7 @@ When non-nil, this must be the number of minutes, e.g. 60 for one hour." (defcustom org-agenda-show-inherited-tags t "Non-nil means show inherited tags in each agenda line. -When this option is set to 'always, it take precedences over +When this option is set to `always', it take precedences over `org-agenda-use-tag-inheritance' and inherited tags are shown in every agenda. @@ -1801,8 +1803,8 @@ shown when they are available, i.e. when the value of `org-agenda-use-tag-inheritance' has been taken into account. This can be set to a list of agenda types in which the agenda -must display the inherited tags. Available types are 'todo, -'agenda, 'search and 'timeline. +must display the inherited tags. Available types are `todo', +`agenda', `search' and `timeline'. When set to nil, never show inherited tags in agenda lines." :group 'org-agenda-line-format @@ -1823,10 +1825,10 @@ controlled by `org-use-tag-inheritance'. In other agenda types, agenda entries. Still, you may want the agenda to be aware of the inherited tags anyway, e.g. for later tag filtering. -Allowed value are 'todo, 'search, 'timeline and 'agenda. +Allowed value are `todo', `search', `timeline' and `agenda'. This variable has no effect if `org-agenda-show-inherited-tags' -is set to 'always. In that case, the agenda is aware of those +is set to `always'. In that case, the agenda is aware of those tags. The default value sets tags in every agenda type. Setting this @@ -1932,7 +1934,7 @@ list as second element: For example, to display a 16px horizontal space for Emacs category, you can use: - (\"Emacs\" '(space . (:width (16))))" + (\"Emacs\" \\='(space . (:width (16))))" :group 'org-agenda-line-format :version "24.1" :type '(alist :key-type (string :tag "Regexp matching category") @@ -1975,7 +1977,8 @@ estimate." :type 'boolean) (defcustom org-agenda-auto-exclude-function nil - "A function called with a tag to decide if it is filtered on '/ RET'. + "A function called with a tag to decide if it is filtered on \ +\\`\\[org-agenda-filter-by-tag] RET'. 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 @@ -1990,7 +1993,7 @@ the lower-case version of all tags." "Alist of characters and custom functions for bulk actions. For example, this value makes those two functions available: - '((?R set-category) + \\='((?R set-category) (?C bulk-cut)) With selected entries in an agenda buffer, `B R' will call @@ -2006,7 +2009,7 @@ If STRING is non-nil, the text property will be fetched from position 0 in that string. If STRING is nil, it will be fetched from the beginning of the current line." (org-with-gensyms (marker) - `(let ((,marker (get-text-property (if string 0 (point-at-bol)) + `(let ((,marker (get-text-property (if ,string 0 (point-at-bol)) 'org-hd-marker ,string))) (with-current-buffer (marker-buffer ,marker) (save-excursion @@ -2070,7 +2073,7 @@ When nil, `q' will kill the single agenda buffer." (setq org-agenda-sticky new-value) (org-agenda-kill-all-agenda-buffers) (and (org-called-interactively-p 'interactive) - (message "Sticky agenda was %s" + (message "Sticky agenda %s" (if org-agenda-sticky "enabled" "disabled")))))) (defvar org-agenda-buffer nil @@ -2080,6 +2083,8 @@ When nil, `q' will kill the single agenda buffer." (defvar org-agenda-this-buffer-name nil) (defvar org-agenda-doing-sticky-redo nil) (defvar org-agenda-this-buffer-is-sticky nil) +(defvar org-agenda-last-indirect-buffer nil + "Last buffer loaded by `org-agenda-tree-to-indirect-buffer'.") (defconst org-agenda-local-vars '(org-agenda-this-buffer-name @@ -2101,8 +2106,10 @@ When nil, `q' will kill the single agenda buffer." org-agenda-category-filter org-agenda-top-headline-filter org-agenda-regexp-filter + org-agenda-effort-filter org-agenda-markers org-agenda-last-search-view-search-was-boolean + org-agenda-last-indirect-buffer org-agenda-filtered-by-category org-agenda-filter-form org-agenda-cycle-counter @@ -2309,6 +2316,7 @@ The following commands are available: (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-effort) (org-defkey org-agenda-mode-map "=" 'org-agenda-filter-by-regexp) (org-defkey org-agenda-mode-map "|" 'org-agenda-filter-remove-all) (org-defkey org-agenda-mode-map "\\" 'org-agenda-filter-by-tag-refine) @@ -2322,6 +2330,10 @@ The following commands are available: (org-defkey org-agenda-mode-map [mouse-2] 'org-agenda-goto-mouse) (org-defkey org-agenda-mode-map [mouse-3] 'org-agenda-show-mouse) + +(define-key org-agenda-mode-map [remap forward-paragraph] 'org-agenda-forward-block) +(define-key org-agenda-mode-map [remap backward-paragraph] 'org-agenda-backward-block) + (when org-agenda-mouse-1-follows-link (org-defkey org-agenda-mode-map [follow-link] 'mouse-face)) (easy-menu-define org-agenda-menu org-agenda-mode-map "Agenda menu" @@ -2538,7 +2550,7 @@ For example, if you have a custom agenda command \"p\" and you want this command to be accessible only from plain text files, use this: - '((\"p\" ((in-file . \"\\.txt\")))) + \\='((\"p\" ((in-file . \"\\\\.txt\\\\'\")))) Here are the available contexts definitions: @@ -2556,7 +2568,7 @@ accessible if there is at least one valid check. You can also bind a key to another agenda custom command depending on contextual rules. - '((\"p\" \"q\" ((in-file . \"\\.txt\")))) + \\='((\"p\" \"q\" ((in-file . \"\\\\.txt\\\\'\")))) Here it means: in .txt files, use \"p\" as the key for the agenda command otherwise associated with \"q\". (The command @@ -3067,10 +3079,13 @@ L Timeline for current buffer # List stuck projects (!=configure) "Fit the window to the buffer size." (and (memq org-agenda-window-setup '(reorganize-frame)) (fboundp 'fit-window-to-buffer) - (org-fit-window-to-buffer - nil - (floor (* (frame-height) (cdr org-agenda-window-frame-fractions))) - (floor (* (frame-height) (car org-agenda-window-frame-fractions)))))) + (if (and (= (cdr org-agenda-window-frame-fractions) 1.0) + (= (car org-agenda-window-frame-fractions) 1.0)) + (delete-other-windows) + (org-fit-window-to-buffer + nil + (floor (* (frame-height) (cdr org-agenda-window-frame-fractions))) + (floor (* (frame-height) (car org-agenda-window-frame-fractions))))))) (defvar org-cmd nil) (defvar org-agenda-overriding-cmd nil) @@ -3306,19 +3321,20 @@ This ensures the export commands can easily use it." (defvar org-agenda-write-buffer-name "Agenda View") (defun org-agenda-write (file &optional open nosettings agenda-bufname) "Write the current buffer (an agenda view) as a file. + Depending on the extension of the file name, plain text (.txt), HTML (.html or .htm), PDF (.pdf) or Postscript (.ps) is produced. -If the extension is .ics, run icalendar export over all files used -to construct the agenda and limit the export to entries listed in the -agenda now. -If the extension is .org, collect all subtrees corresponding to the -agenda entries and add them in an .org file. -With prefix argument OPEN, open the new file immediately. -If NOSETTINGS is given, do not scope the settings of -`org-agenda-exporter-settings' into the export commands. This is used when -the settings have already been scoped and we do not wish to overrule other, -higher priority settings. -If AGENDA-BUFFER-NAME, use this as the buffer name for the agenda to write." +If the extension is .ics, translate visible agenda into iCalendar +format. If the extension is .org, collect all subtrees +corresponding to the agenda entries and add them in an .org file. + +With prefix argument OPEN, open the new file immediately. If +NOSETTINGS is given, do not scope the settings of +`org-agenda-exporter-settings' into the export commands. This is +used when the settings have already been scoped and we do not +wish to overrule other, higher priority settings. If +AGENDA-BUFFER-NAME is provided, use this as the buffer name for +the agenda to write." (interactive "FWrite agenda to file: \nP") (if (or (not (file-writable-p file)) (and (file-exists-p file) @@ -3333,7 +3349,7 @@ If AGENDA-BUFFER-NAME, use this as the buffer name for the agenda to write." (rename-buffer org-agenda-write-buffer-name t) (set-buffer-modified-p nil) (insert bs) - (org-agenda-remove-marked-text 'org-filtered) + (org-agenda-remove-marked-text 'invisible 'org-filtered) (run-hooks 'org-agenda-before-write-hook) (cond ((org-bound-and-true-p org-mobile-creating-agendas) @@ -3531,6 +3547,7 @@ removed from the entry content. Currently only `planning' is allowed here." (defvar org-agenda-tag-filter nil) (defvar org-agenda-category-filter nil) (defvar org-agenda-regexp-filter nil) +(defvar org-agenda-effort-filter nil) (defvar org-agenda-top-headline-filter nil) (defvar org-agenda-tag-filter-preset nil "A preset of the tags filter used for secondary agenda filtering. @@ -3562,6 +3579,16 @@ 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.") +(defvar org-agenda-effort-filter-preset nil + "A preset of the effort condition used for secondary agenda filtering. +This must be a list of strings, each string must be a single regexp +preceded by \"+\" or \"-\". +This variable should not be set directly, but agenda custom commands can +bind it in the options section. The preset filter is a global property of +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.") + (defun org-agenda-use-sticky-p () "Return non-nil if an agenda buffer named `org-agenda-buffer-name' exists and should be shown instead of @@ -3599,24 +3626,31 @@ FILTER-ALIST is an alist of filters we need to apply when (org-switch-to-buffer-other-window abuf)) ((equal org-agenda-window-setup 'other-frame) (switch-to-buffer-other-frame abuf)) + ((eq org-agenda-window-setup 'only-window) + (delete-other-windows) + (org-pop-to-buffer-same-window abuf)) ((equal org-agenda-window-setup 'reorganize-frame) (delete-other-windows) (org-switch-to-buffer-other-window abuf))) (setq org-agenda-tag-filter (cdr (assoc 'tag filter-alist))) (setq org-agenda-category-filter (cdr (assoc 'cat filter-alist))) + (setq org-agenda-effort-filter (cdr (assoc 'effort filter-alist))) (setq org-agenda-regexp-filter (cdr (assoc 're filter-alist))) ;; Additional test in case agenda is invoked from within agenda ;; buffer via elisp link. (unless (equal (current-buffer) abuf) (org-pop-to-buffer-same-window abuf)) (setq org-agenda-pre-window-conf - (or org-agenda-pre-window-conf wconf)))) + (or wconf org-agenda-pre-window-conf)))) (defun org-agenda-prepare (&optional name) (let ((filter-alist (if org-agenda-persistent-filter - (list `(tag . ,org-agenda-tag-filter) - `(re . ,org-agenda-regexp-filter) - `(car . ,org-agenda-category-filter))))) + (with-current-buffer + (get-buffer-create org-agenda-buffer-name) + (list `(tag . ,org-agenda-tag-filter) + `(re . ,org-agenda-regexp-filter) + `(effort . ,org-agenda-effort-filter) + `(cat . ,org-agenda-category-filter)))))) (if (org-agenda-use-sticky-p) (progn (put 'org-agenda-tag-filter :preset-filter nil) @@ -3629,13 +3663,14 @@ FILTER-ALIST is an alist of filters we need to apply when (or org-agenda-multi (org-agenda-fit-window-to-buffer)) (throw 'exit "Sticky Agenda buffer, use `r' to refresh")) (setq org-todo-keywords-for-agenda nil) - (setq org-drawers-for-agenda nil) (put 'org-agenda-tag-filter :preset-filter org-agenda-tag-filter-preset) (put 'org-agenda-category-filter :preset-filter org-agenda-category-filter-preset) (put 'org-agenda-regexp-filter :preset-filter org-agenda-regexp-filter-preset) + (put 'org-agenda-effort-filter :preset-filter + org-agenda-effort-filter-preset) (if org-agenda-multi (progn (setq buffer-read-only nil) @@ -3649,7 +3684,6 @@ FILTER-ALIST is an alist of filters we need to apply when "\n")) (narrow-to-region (point) (point-max))) (setq org-done-keywords-for-agenda nil) - ;; Setting any org variables that are in org-agenda-local-vars ;; list need to be done after the prepare call (org-agenda-prepare-window @@ -3666,7 +3700,6 @@ FILTER-ALIST is an alist of filters we need to apply when (org-uniquify org-todo-keywords-for-agenda)) (setq org-done-keywords-for-agenda (org-uniquify org-done-keywords-for-agenda)) - (setq org-drawers-for-agenda (org-uniquify org-drawers-for-agenda)) (setq org-agenda-last-prefix-arg current-prefix-arg) (setq org-agenda-this-buffer-name org-agenda-buffer-name) (and name (not org-agenda-name) @@ -3733,10 +3766,10 @@ FILTER-ALIST is an alist of filters we need to apply when (org-agenda-filter-top-headline-apply org-agenda-top-headline-filter)) (when org-agenda-tag-filter - (org-agenda-filter-apply org-agenda-tag-filter 'tag)) + (org-agenda-filter-apply org-agenda-tag-filter 'tag t)) (when (get 'org-agenda-tag-filter :preset-filter) (org-agenda-filter-apply - (get 'org-agenda-tag-filter :preset-filter) 'tag)) + (get 'org-agenda-tag-filter :preset-filter) 'tag t)) (when org-agenda-category-filter (org-agenda-filter-apply org-agenda-category-filter 'category)) (when (get 'org-agenda-category-filter :preset-filter) @@ -3747,6 +3780,11 @@ FILTER-ALIST is an alist of filters we need to apply when (when (get 'org-agenda-regexp-filter :preset-filter) (org-agenda-filter-apply (get 'org-agenda-regexp-filter :preset-filter) 'regexp)) + (when org-agenda-effort-filter + (org-agenda-filter-apply org-agenda-effort-filter 'effort)) + (when (get 'org-agenda-effort-filter :preset-filter) + (org-agenda-filter-apply + (get 'org-agenda-effort-filter :preset-filter) 'effort)) (org-add-hook 'kill-buffer-hook 'org-agenda-reset-markers 'append 'local))))) (defun org-agenda-mark-clocking-task () @@ -3816,42 +3854,42 @@ FILTER-ALIST is an alist of filters we need to apply when (defvar org-depend-tag-blocked) (defun org-agenda-dim-blocked-tasks (&optional invisible) - "Dim currently blocked TODO's in the agenda display. + "Dim currently blocked TODOs in the agenda display. When INVISIBLE is non-nil, hide currently blocked TODO instead of dimming them." (interactive "P") (when (org-called-interactively-p 'interactive) (message "Dim or hide blocked tasks...")) - (mapc (lambda (o) (if (eq (overlay-get o 'org-type) 'org-blocked-todo) - (delete-overlay o))) - (overlays-in (point-min) (point-max))) + (dolist (o (overlays-in (point-min) (point-max))) + (when (eq (overlay-get o 'org-type) 'org-blocked-todo) + (delete-overlay o))) (save-excursion (let ((inhibit-read-only t) (org-depend-tag-blocked nil) - (invis (or (not (null invisible)) - (eq org-agenda-dim-blocked-tasks 'invisible))) - org-blocked-by-checkboxes - invis1 b e p ov h l) + org-blocked-by-checkboxes) (goto-char (point-min)) - (while (let ((pos (next-single-property-change (point) 'todo-state))) - (and pos (goto-char (1+ pos)))) - (setq org-blocked-by-checkboxes nil invis1 invis) + (while (let ((pos (text-property-not-all + (point) (point-max) 'todo-state nil))) + (when pos (goto-char pos))) + (setq org-blocked-by-checkboxes nil) (let ((marker (org-get-at-bol 'org-hd-marker))) - (when (and marker + (when (and (markerp marker) (with-current-buffer (marker-buffer marker) (save-excursion (goto-char marker) (org-entry-blocked-p)))) - (if org-blocked-by-checkboxes (setq invis1 nil)) - (setq b (if invis1 - (max (point-min) (1- (point-at-bol))) - (point-at-bol)) - e (point-at-eol) - ov (make-overlay b e)) - (if invis1 - (progn (overlay-put ov 'invisible t) - (overlay-put ov 'intangible t)) - (overlay-put ov 'face 'org-agenda-dimmed-todo-face)) - (overlay-put ov 'org-type 'org-blocked-todo)))))) + ;; Entries blocked by checkboxes cannot be made invisible. + ;; See `org-agenda-dim-blocked-tasks' for details. + (let* ((really-invisible + (and (not org-blocked-by-checkboxes) + (or invisible (eq org-agenda-dim-blocked-tasks + 'invisible)))) + (ov (make-overlay (if really-invisible (line-end-position 0) + (line-beginning-position)) + (line-end-position)))) + (if really-invisible (overlay-put ov 'invisible t) + (overlay-put ov 'face 'org-agenda-dimmed-todo-face)) + (overlay-put ov 'org-type 'org-blocked-todo)))) + (forward-line)))) (when (org-called-interactively-p 'interactive) (message "Dim or hide blocked tasks...done"))) @@ -3909,9 +3947,9 @@ functions do." (defun org-agenda-new-marker (&optional pos) "Return a new agenda marker. -Org-mode keeps a list of these markers and resets them when they are -no longer in use." - (let ((m (copy-marker (or pos (point))))) +Maker is at point, or at POS if non-nil. Org mode keeps a list of +these markers and resets them when they are no longer in use." + (let ((m (copy-marker (or pos (point)) t))) (setq org-agenda-last-marker-time (org-float-time)) (if org-agenda-buffer (with-current-buffer org-agenda-buffer @@ -4445,7 +4483,7 @@ in `org-agenda-text-search-extra-files'." (full-words org-agenda-search-view-force-full-words) (org-agenda-text-search-extra-files org-agenda-text-search-extra-files) regexp rtn rtnall files file pos inherited-tags - marker category category-pos level tags c neg re boolean + marker category level tags c neg re boolean ee txt beg end words regexps+ regexps- hdl-only buffer beg1 str) (unless (and (not edit-at) (stringp string) @@ -4577,7 +4615,7 @@ in `org-agenda-text-search-extra-files'." (> (org-reduced-level (org-outline-level)) org-agenda-search-view-max-outline-level) (forward-line -1) - (outline-back-to-heading t))) + (org-back-to-heading t))) (skip-chars-forward "* ") (setq beg (point-at-bol) beg1 (point) @@ -4604,14 +4642,14 @@ in `org-agenda-text-search-extra-files'." (goto-char (1- end)) (throw :skip t))) (if todo-only - (cons (concat "^\*+[ \t]+" org-not-done-regexp) + (cons (concat "^\\*+[ \t]+" + org-not-done-regexp) regexps+) regexps+)) (goto-char beg) (setq marker (org-agenda-new-marker (point)) category (org-get-category) level (make-string (org-reduced-level (org-outline-level)) ? ) - category-pos (get-text-property (point) 'org-category-position) inherited-tags (or (eq org-agenda-show-inherited-tags 'always) (and (listp org-agenda-show-inherited-tags) @@ -4630,8 +4668,7 @@ in `org-agenda-text-search-extra-files'." 'org-todo-regexp org-todo-regexp 'level level 'org-complex-heading-regexp org-complex-heading-regexp - 'priority 1000 'org-category category - 'org-category-position category-pos + 'priority 1000 'type "search") (push txt ee) (goto-char (1- end)))))))))) @@ -4648,7 +4685,12 @@ in `org-agenda-text-search-extra-files'." (add-text-properties pos (1- (point)) (list 'face 'org-warning)) (setq pos (point)) (unless org-agenda-multi - (insert "Press `[', `]' to add/sub word, `{', `}' to add/sub regexp, `C-u r' to edit\n") + (insert (substitute-command-keys "\ +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")) (add-text-properties pos (1- (point)) (list 'face 'org-agenda-structure)))) (org-agenda-mark-header-line (point-min)) @@ -4742,7 +4784,8 @@ for a keyword. A numeric prefix directly selects the Nth keyword in org-select-this-todo-keyword)) (setq pos (point)) (unless org-agenda-multi - (insert "Available with `N r': (0)[ALL]") + (insert (substitute-command-keys "Available with \ +`N \\[org-agenda-redo]': (0)[ALL]")) (let ((n 0) s) (mapc (lambda (x) (setq s (format "(%d)%s" (setq n (1+ n)) x)) @@ -4837,7 +4880,9 @@ The prefix arg TODO-ONLY limits the search to TODO entries." (add-text-properties pos (1- (point)) (list 'face 'org-warning)) (setq pos (point)) (unless org-agenda-multi - (insert "Press `C-u r' to search again with new search string\n")) + (insert (substitute-command-keys + "Press `\\[universal-argument] \\[org-agenda-redo]' \ +to search again with new search string\n"))) (add-text-properties pos (1- (point)) (list 'face 'org-agenda-structure))) (org-agenda-mark-header-line (point-min)) (when rtnall @@ -4936,13 +4981,13 @@ the `regexp' or `notregexp' element. `todo' and `nottodo' accept as an argument a list of todo keywords, which may include \"*\" to match any todo keyword. - (org-agenda-skip-entry-if 'todo '(\"TODO\" \"WAITING\")) + (org-agenda-skip-entry-if \\='todo \\='(\"TODO\" \"WAITING\")) would skip all entries with \"TODO\" or \"WAITING\" keywords. Instead of a list, a keyword class may be given. For example: - (org-agenda-skip-entry-if 'nottodo 'done) + (org-agenda-skip-entry-if \\='nottodo \\='done) would skip entries that haven't been marked with any of \"DONE\" keywords. Possible classes are: `todo', `done', `any'. @@ -5332,6 +5377,40 @@ the documentation of `org-diary'." (defvar org-heading-keyword-regexp-format) ; defined in org.el (defvar org-agenda-sorting-strategy-selected nil) +(defun org-agenda-entry-get-agenda-timestamp (pom) + "Retrieve timestamp information for sorting agenda views. +Given a point or marker POM, returns a cons cell of the timestamp +and the timestamp type relevant for the sorting strategy in +`org-agenda-sorting-strategy-selected'." + (let (ts ts-date-type) + (save-match-data + (cond ((org-em 'scheduled-up 'scheduled-down + org-agenda-sorting-strategy-selected) + (setq ts (org-entry-get pom "SCHEDULED") + ts-date-type " scheduled")) + ((org-em 'deadline-up 'deadline-down + org-agenda-sorting-strategy-selected) + (setq ts (org-entry-get pom "DEADLINE") + ts-date-type " deadline")) + ((org-em 'ts-up 'ts-down + org-agenda-sorting-strategy-selected) + (setq ts (org-entry-get pom "TIMESTAMP") + ts-date-type " timestamp")) + ((org-em 'tsia-up 'tsia-down + org-agenda-sorting-strategy-selected) + (setq ts (org-entry-get pom "TIMESTAMP_IA") + ts-date-type " timestamp_ia")) + ((org-em 'timestamp-up 'timestamp-down + org-agenda-sorting-strategy-selected) + (setq ts (or (org-entry-get pom "SCHEDULED") + (org-entry-get pom "DEADLINE") + (org-entry-get pom "TIMESTAMP") + (org-entry-get pom "TIMESTAMP_IA")) + ts-date-type "")) + (t (setq ts-date-type ""))) + (cons (when ts (ignore-errors (org-time-string-to-absolute ts))) + ts-date-type)))) + (defun org-agenda-get-todos () "Return the TODO information for agenda display." (let* ((props (list 'face nil @@ -5356,7 +5435,8 @@ the documentation of `org-diary'." "|") "\\|") "\\)")) (t org-not-done-regexp)))) - marker priority category category-pos level tags todo-state ts-date ts-date-type + marker priority category level tags todo-state + ts-date ts-date-type ts-date-pair ee txt beg end inherited-tags todo-state-end-pos) (goto-char (point-min)) (while (re-search-forward regexp nil t) @@ -5376,36 +5456,10 @@ the documentation of `org-diary'." (goto-char (match-beginning 2)) (setq marker (org-agenda-new-marker (match-beginning 0)) category (org-get-category) - ts-date (let (ts) - (save-match-data - (cond ((org-em 'scheduled-up 'scheduled-down - org-agenda-sorting-strategy-selected) - (setq ts (org-entry-get (point) "SCHEDULED") - ts-date-type " scheduled")) - ((org-em 'deadline-up 'deadline-down - org-agenda-sorting-strategy-selected) - (setq ts (org-entry-get (point) "DEADLINE") - ts-date-type " deadline")) - ((org-em 'ts-up 'ts-down - org-agenda-sorting-strategy-selected) - (setq ts (org-entry-get (point) "TIMESTAMP") - ts-date-type " timestamp")) - ((org-em 'tsia-up 'tsia-down - org-agenda-sorting-strategy-selected) - (setq ts (org-entry-get (point) "TIMESTAMP_IA") - ts-date-type " timestamp_ia")) - ((org-em 'timestamp-up 'timestamp-down - org-agenda-sorting-strategy-selected) - (setq ts (or (org-entry-get (point) "SCHEDULED") - (org-entry-get (point) "DEADLINE") - (org-entry-get (point) "TIMESTAMP") - (org-entry-get (point) "TIMESTAMP_IA")) - ts-date-type "")) - (t (setq ts-date-type ""))) - (when ts (ignore-errors (org-time-string-to-absolute ts))))) - category-pos (get-text-property (point) 'org-category-position) - txt (org-trim - (buffer-substring (match-beginning 2) (match-end 0))) + ts-date-pair (org-agenda-entry-get-agenda-timestamp (point)) + ts-date (car ts-date-pair) + ts-date-type (cdr ts-date-pair) + txt (org-trim (buffer-substring (match-beginning 2) (match-end 0))) inherited-tags (or (eq org-agenda-show-inherited-tags 'always) (and (listp org-agenda-show-inherited-tags) @@ -5419,10 +5473,9 @@ the documentation of `org-diary'." priority (1+ (org-get-priority txt))) (org-add-props txt props 'org-marker marker 'org-hd-marker marker - 'priority priority 'org-category category + 'priority priority 'level level 'ts-date ts-date - 'org-category-position category-pos 'type (concat "todo" ts-date-type) 'todo-state todo-state) (push txt ee) (if org-agenda-todo-list-sublevels @@ -5541,7 +5594,7 @@ This function is invoked if `org-agenda-todo-ignore-deadlines', "\\|\\(<[0-9]+-[0-9]+-[0-9]+[^>\n]+?\\+[0-9]+[hdwmy]>\\)" "\\|\\(<%%\\(([^>\n]+)\\)>\\)")) marker hdmarker deadlinep scheduledp clockp closedp inactivep - donep tmp priority category category-pos level ee txt timestr tags + donep tmp priority category level ee txt timestr tags b0 b3 e3 head todo-state end-of-match show-all warntime habitp inherited-tags ts-date) (goto-char (point-min)) @@ -5585,8 +5638,7 @@ This function is invoked if `org-agenda-todo-ignore-deadlines', ;; substring should only run to end of time stamp (setq timestr (substring timestr 0 (match-end 0)))) (setq marker (org-agenda-new-marker b0) - category (org-get-category b0) - category-pos (get-text-property b0 'org-category-position)) + category (org-get-category b0)) (save-excursion (if (not (re-search-backward org-outline-regexp-bol nil t)) (throw :skip nil) @@ -5613,11 +5665,10 @@ This function is invoked if `org-agenda-todo-ignore-deadlines', (setq priority (org-get-priority txt)) (org-add-props txt props 'priority priority 'org-marker marker 'org-hd-marker hdmarker - 'org-category category 'date date + 'date date 'level level 'ts-date (ignore-errors (org-time-string-to-absolute timestr)) - 'org-category-position category-pos 'todo-state todo-state 'warntime warntime 'type "timestamp") @@ -5636,7 +5687,7 @@ This function is invoked if `org-agenda-todo-ignore-deadlines', (format "mouse-2 or RET jump to org file %s" (abbreviate-file-name buffer-file-name)))) (regexp "^&?%%(") - marker category extra category-pos level ee txt tags entry + marker category extra level ee txt tags entry result beg b sexp sexp-entry todo-state warntime inherited-tags) (goto-char (point-min)) (while (re-search-forward regexp nil t) @@ -5655,7 +5706,6 @@ This function is invoked if `org-agenda-todo-ignore-deadlines', (setq marker (org-agenda-new-marker beg) level (make-string (org-reduced-level (org-outline-level)) ? ) category (org-get-category beg) - category-pos (get-text-property beg 'org-category-position) inherited-tags (or (eq org-agenda-show-inherited-tags 'always) (and (listp org-agenda-show-inherited-tags) @@ -5680,10 +5730,8 @@ This function is invoked if `org-agenda-todo-ignore-deadlines', (setq txt "SEXP entry returned empty string")) (setq txt (org-agenda-format-item extra txt level category tags 'time)) (org-add-props txt props 'org-marker marker - 'org-category category 'date date 'todo-state todo-state - 'org-category-position category-pos - 'level level - 'type "sexp" 'warntime warntime) + 'date date 'todo-state todo-state + 'level level 'type "sexp" 'warntime warntime) (push txt ee))))) (nreverse ee))) @@ -5713,7 +5761,7 @@ This function is invoked if `org-agenda-todo-ignore-deadlines', (let ((calendar-date-style 'european) (european-calendar-style t)) (diary-date day month year mark)))) -;; Define the` org-class' function +;; Define the `org-class' function (defun org-class (y1 m1 d1 y2 m2 d2 dayname &rest skip-weeks) "Entry applies if date is between dates on DAYNAME, but skips SKIP-WEEKS. DAYNAME is a number between 0 (Sunday) and 6 (Saturday). @@ -5792,7 +5840,7 @@ please use `org-class' instead." (list 0 0 0 (nth 1 date) (car date) (nth 2 date)))) 1 11)))) (org-agenda-search-headline-for-time nil) - marker hdmarker priority category category-pos level tags closedp + marker hdmarker priority category level tags closedp statep clockp state ee txt extra timestr rest clocked inherited-tags) (goto-char (point-min)) (while (re-search-forward regexp nil t) @@ -5804,7 +5852,6 @@ please use `org-class' instead." clockp (not (or closedp statep)) state (and statep (match-string 2)) category (org-get-category (match-beginning 0)) - category-pos (get-text-property (match-beginning 0) 'org-category-position) timestr (buffer-substring (match-beginning 0) (point-at-eol))) (when (string-match "\\]" timestr) ;; substring should only run to end of time stamp @@ -5856,9 +5903,7 @@ please use `org-class' instead." (setq priority 100000) (org-add-props txt props 'org-marker marker 'org-hd-marker hdmarker 'face 'org-agenda-done - 'priority priority 'org-category category - 'org-category-position category-pos - 'level level + 'priority priority 'level level 'type "closed" 'date date 'undone-face 'org-warning 'done-face 'org-agenda-done) (push txt ee)) @@ -6004,7 +6049,7 @@ specification like [h]h:mm." (dl0 (car org-agenda-deadline-leaders)) (dl1 (nth 1 org-agenda-deadline-leaders)) (dl2 (or (nth 2 org-agenda-deadline-leaders) dl1)) - d2 diff dfrac wdays pos pos1 category category-pos level + d2 diff dfrac wdays pos pos1 category level tags suppress-prewarning ee txt head face s todo-state show-all upcomingp donep timestr warntime inherited-tags ts-date) (goto-char (point-min)) @@ -6064,8 +6109,7 @@ specification like [h]h:mm." (not (= diff 0)))) (setq txt nil) (setq category (org-get-category) - warntime (get-text-property (point) 'org-appt-warntime) - category-pos (get-text-property (point) 'org-category-position)) + warntime (get-text-property (point) 'org-appt-warntime)) (if (not (re-search-backward "^\\*+[ \t]+" nil t)) (throw :skip nil) (goto-char (match-end 0)) @@ -6110,8 +6154,6 @@ specification like [h]h:mm." 'org-hd-marker (org-agenda-new-marker pos1) 'priority (+ (- diff) (org-get-priority txt)) - 'org-category category - 'org-category-position category-pos 'todo-state todo-state 'type (if upcomingp "upcoming-deadline" "deadline") 'date (if upcomingp date d2) @@ -6151,7 +6193,7 @@ an hour specification like [h]h:mm." 0 'org-hd-marker a)) (cons (marker-position mm) a))) deadline-results)) - d2 diff pos pos1 category category-pos level tags donep + d2 diff pos pos1 category level tags donep ee txt head pastschedp todo-state face timestr s habitp show-all did-habit-check-p warntime inherited-tags ts-date suppress-delay ddays) @@ -6230,8 +6272,7 @@ an hour specification like [h]h:mm." (setq habitp (if did-habit-check-p habitp (and (functionp 'org-is-habit-p) (org-is-habit-p)))) - (setq category (org-get-category) - category-pos (get-text-property (point) 'org-category-position)) + (setq category (org-get-category)) (if (and (eq org-agenda-skip-scheduled-if-deadline-is-shown 'repeated-after-deadline) (org-get-deadline-time (point)) @@ -6299,8 +6340,6 @@ an hour specification like [h]h:mm." 'priority (if habitp (org-habit-get-priority habitp) (+ 94 (- 5 diff) (org-get-priority txt))) - 'org-category category - 'category-position category-pos 'org-habit-p habitp 'todo-state todo-state) (push txt ee)))))) @@ -6318,7 +6357,7 @@ an hour specification like [h]h:mm." (abbreviate-file-name buffer-file-name)))) (regexp org-tr-regexp) (d0 (calendar-absolute-from-gregorian date)) - marker hdmarker ee txt d1 d2 s1 s2 category category-pos + marker hdmarker ee txt d1 d2 s1 s2 category level todo-state tags pos head donep inherited-tags) (goto-char (point-min)) (while (re-search-forward regexp nil t) @@ -6339,9 +6378,8 @@ an hour specification like [h]h:mm." (setq donep (member todo-state org-done-keywords)) (if (and donep org-agenda-skip-timestamp-if-done) (throw :skip t)) - (setq marker (org-agenda-new-marker (point))) - (setq category (org-get-category) - category-pos (get-text-property (point) 'org-category-position)) + (setq marker (org-agenda-new-marker (point)) + category (org-get-category)) (if (not (re-search-backward org-outline-regexp-bol nil t)) (throw :skip nil) (goto-char (match-beginning 0)) @@ -6383,8 +6421,7 @@ an hour specification like [h]h:mm." 'type "block" 'date date 'level level 'todo-state todo-state - 'priority (org-get-priority txt) 'org-category category - 'org-category-position category-pos) + 'priority (org-get-priority txt)) (push txt ee)))) (goto-char pos))) ;; Sort the entries by expiration date. @@ -6455,9 +6492,6 @@ Any match of REMOVE-RE will be removed from TXT." org-agenda-hide-tags-regexp)) (let* ((category (or category - (if (stringp org-category) - org-category - (and org-category (symbol-name org-category))) (if buffer-file-name (file-name-sans-extension (file-name-nondirectory buffer-file-name)) @@ -6466,15 +6500,17 @@ Any match of REMOVE-RE will be removed from TXT." (category-icon (if category-icon (propertize " " 'display category-icon) "")) + (effort (and (not (string= txt "")) + (get-text-property 1 'effort txt))) ;; time, tag, effort are needed for the eval of the prefix format (tag (if tags (nth (1- (length tags)) tags) "")) - time effort neffort + time (ts (if dotime (concat (if (stringp dotime) dotime "") (and org-agenda-search-headline-for-time txt)))) (time-of-day (and dotime (org-get-time-of-day ts))) stamp plain s0 s1 s2 rtn srp l - duration thecategory breadcrumbs) + duration breadcrumbs) (and (derived-mode-p 'org-mode) buffer-file-name (add-to-list 'org-agenda-contributing-files buffer-file-name)) (when (and dotime time-of-day) @@ -6525,16 +6561,6 @@ Any match of REMOVE-RE will be removed from TXT." (concat (make-string (max (- 50 (length txt)) 1) ?\ ) (match-string 2 txt)) t t txt)))) - (when (derived-mode-p 'org-mode) - (setq effort (ignore-errors (get-text-property 0 'org-effort txt)))) - - ;; org-agenda-add-time-grid-maybe calls us with *Agenda* as - ;; current buffer, so move this check outside of above - (if effort - (setq neffort (org-duration-string-to-minutes effort) - effort (setq effort (concat "[" effort "]"))) - ;; prevent erroring out with %e format when there is no effort - (setq effort "")) (when remove-re (while (string-match remove-re txt) @@ -6561,7 +6587,6 @@ Any match of REMOVE-RE will be removed from TXT." (t "")) extra (or (and (not habitp) extra) "") category (if (symbolp category) (symbol-name category) category) - thecategory (copy-sequence category) level (or level "")) (if (string-match org-bracket-link-regexp category) (progn @@ -6582,14 +6607,12 @@ Any match of REMOVE-RE will be removed from TXT." ;; And finally add the text properties (remove-text-properties 0 (length rtn) '(line-prefix t wrap-prefix t) rtn) (org-add-props rtn nil - 'org-category (if thecategory (downcase thecategory) category) + 'org-category category 'tags (mapcar 'org-downcase-keep-props tags) 'org-highest-priority org-highest-priority 'org-lowest-priority org-lowest-priority 'time-of-day time-of-day 'duration duration - 'effort effort - 'effort-minutes neffort 'breadcrumbs breadcrumbs 'txt txt 'level level @@ -6643,7 +6666,7 @@ The modified list may contain inherited tags, and tags matched by LIST is the list of agenda items formatted by `org-agenda-list'. NDAYS is the span of the current agenda view. -TODAYP is `t' when the current agenda view is on today." +TODAYP is t when the current agenda view is on today." (catch 'exit (cond ((not org-agenda-use-time-grid) (throw 'exit list)) ((and todayp (member 'today (car org-agenda-time-grid)))) @@ -6725,10 +6748,13 @@ and stored in the variable `org-prefix-format-compiled'." (setq varform `(format ,f (org-eval ,(read (match-string 4 s))))) (if opt (setq varform - `(if (equal "" ,var) + `(if (or (equal "" ,var) (equal nil ,var)) "" - (format ,f (if (equal "" ,var) "" (concat ,var ,c))))) - (setq varform `(format ,f (if (equal ,var "") "" (concat ,var ,c (get-text-property 0 'extra-space ,var))))))) + (format ,f (concat ,var ,c)))) + (setq varform + `(format ,f (if (or (equal ,var "") + (equal ,var nil)) "" + (concat ,var ,c (get-text-property 0 'extra-space ,var))))))) (setq s (replace-match "%s" t nil s)) (push varform vars)) (setq vars (nreverse vars)) @@ -6815,7 +6841,7 @@ The optional argument TYPE tells the agenda type." (t org-agenda-max-tags))) (max-entries (cond ((listp org-agenda-max-entries) (cdr (assoc type org-agenda-max-entries))) - (t org-agenda-max-entries))) l) + (t org-agenda-max-entries)))) (when org-agenda-before-sorting-filter-function (setq list (delq nil @@ -6825,7 +6851,9 @@ The optional argument TYPE tells the agenda type." list (mapcar 'identity (sort list 'org-entries-lessp))) (when max-effort (setq list (org-agenda-limit-entries - list 'effort-minutes max-effort 'identity))) + list 'effort-minutes max-effort + (lambda (e) (or e (if org-sort-agenda-noeffort-is-high + 32767 -1)))))) (when max-todo (setq list (org-agenda-limit-entries list 'todo-state max-todo))) (when max-tags @@ -6843,26 +6871,39 @@ The optional argument TYPE tells the agenda type." (delq nil (mapcar (lambda (e) - (let ((pval (funcall fun (get-text-property 1 prop e)))) + (let ((pval (funcall + fun (get-text-property (1- (length e)) + prop e)))) (if pval (setq lim (+ lim pval))) (cond ((and pval (<= lim (abs limit))) e) ((and include (not pval)) e)))) list))) list))) -(defun org-agenda-limit-interactively () +(defun org-agenda-limit-interactively (remove) "In agenda, interactively limit entries to various maximums." - (interactive) - (let* ((max (read-char "Number of [e]ntries [t]odos [T]ags [E]ffort? ")) - (num (string-to-number (read-from-minibuffer "How many? ")))) - (cond ((equal max ?e) - (let ((org-agenda-max-entries num)) (org-agenda-redo))) - ((equal max ?t) - (let ((org-agenda-max-todos num)) (org-agenda-redo))) - ((equal max ?T) - (let ((org-agenda-max-tags num)) (org-agenda-redo))) - ((equal max ?E) - (let ((org-agenda-max-effort num)) (org-agenda-redo))))) + (interactive "P") + (if remove + (progn (setq org-agenda-max-entries nil + org-agenda-max-todos nil + org-agenda-max-tags nil + org-agenda-max-effort nil) + (org-agenda-redo)) + (let* ((max (read-char "Number of [e]ntries [t]odos [T]ags [E]ffort? ")) + (msg (cond ((= max ?E) "How many minutes? ") + ((= max ?e) "How many entries? ") + ((= max ?t) "How many TODO entries? ") + ((= max ?T) "How many tagged entries? ") + (t (user-error "Wrong input")))) + (num (string-to-number (read-from-minibuffer msg)))) + (cond ((equal max ?e) + (let ((org-agenda-max-entries num)) (org-agenda-redo))) + ((equal max ?t) + (let ((org-agenda-max-todos num)) (org-agenda-redo))) + ((equal max ?T) + (let ((org-agenda-max-tags num)) (org-agenda-redo))) + ((equal max ?E) + (let ((org-agenda-max-effort num)) (org-agenda-redo)))))) (org-agenda-fit-window-to-buffer)) (defun org-agenda-highlight-todo (x) @@ -6908,25 +6949,25 @@ The optional argument TYPE tells the agenda type." (substring x (match-end 3))))))) x))) -(defsubst org-cmp-priority (a b) - "Compare the priorities of string A and B." - (let ((pa (or (get-text-property 1 'priority a) 0)) - (pb (or (get-text-property 1 'priority b) 0))) +(defsubst org-cmp-values (a b property) + "Compare the numeric value of text PROPERTY for string A and B." + (let ((pa (or (get-text-property (1- (length a)) property a) 0)) + (pb (or (get-text-property (1- (length b)) property b) 0))) (cond ((> pa pb) +1) ((< pa pb) -1)))) (defsubst org-cmp-effort (a b) "Compare the effort values of string A and B." (let* ((def (if org-sort-agenda-noeffort-is-high 32767 -1)) - (ea (or (get-text-property 1 'effort-minutes a) def)) - (eb (or (get-text-property 1 'effort-minutes b) def))) + (ea (or (get-text-property (1- (length a)) 'effort-minutes a) def)) + (eb (or (get-text-property (1- (length b)) 'effort-minutes b) def))) (cond ((> ea eb) +1) ((< ea eb) -1)))) (defsubst org-cmp-category (a b) "Compare the string values of categories of strings A and B." - (let ((ca (or (get-text-property 1 'org-category a) "")) - (cb (or (get-text-property 1 'org-category b) ""))) + (let ((ca (or (get-text-property (1- (length a)) 'org-category a) "")) + (cb (or (get-text-property (1- (length b)) 'org-category b) ""))) (cond ((string-lessp ca cb) -1) ((string-lessp cb ca) +1)))) @@ -7036,8 +7077,11 @@ their type." (time-up (and (org-em 'time-up 'time-down ss) (org-cmp-time a b))) (time-down (if time-up (- time-up) nil)) + (stats-up (and (org-em 'stats-up 'stats-down ss) + (org-cmp-values a b 'org-stats))) + (stats-down (if stats-up (- stats-up) nil)) (priority-up (and (org-em 'priority-up 'priority-down ss) - (org-cmp-priority a b))) + (org-cmp-values a b 'priority))) (priority-down (if priority-up (- priority-up) nil)) (effort-up (and (org-em 'effort-up 'effort-down ss) (org-cmp-effort a b))) @@ -7084,9 +7128,10 @@ their type." (defun org-agenda-set-restriction-lock (&optional type) "Set restriction lock for agenda, to current subtree or file. Restriction will be the file if TYPE is `file', or if type is the -universal prefix '(4), or if the cursor is before the first headline +universal prefix \\='(4), or if the cursor is before the first headline in the file. Otherwise, restriction will be to the current subtree." (interactive "P") + (org-agenda-remove-restriction-lock 'noupdate) (and (equal type '(4)) (setq type 'file)) (setq type (cond (type type) @@ -7136,7 +7181,9 @@ in the file. Otherwise, restriction will be to the current subtree." (defun org-agenda-maybe-redo () "If there is any window showing the agenda view, update it." - (let ((w (get-buffer-window org-agenda-buffer-name t)) + (let ((w (get-buffer-window (or org-agenda-this-buffer-name + org-agenda-buffer-name) + t)) (w0 (selected-window))) (when w (select-window w) @@ -7152,7 +7199,7 @@ in the file. Otherwise, restriction will be to the current subtree." (defun org-agenda-check-type (error &rest types) "Check if agenda buffer is of allowed type. If ERROR is non-nil, throw an error, otherwise just return nil. -Allowed types are 'agenda 'timeline 'todo 'tags 'search." +Allowed types are `agenda' `timeline' `todo' `tags' `search'." (if (not org-agenda-type) (error "No Org agenda currently displayed") (if (memq org-agenda-type types) @@ -7162,77 +7209,76 @@ Allowed types are 'agenda 'timeline 'todo 'tags 'search." nil)))) (defun org-agenda-Quit () - "Exit the agenda and kill buffers loaded by `org-agenda'. -Also restore the window configuration." + "Exit the agenda, killing the agenda buffer. +Like `org-agenda-quit', but kill the buffer even when +`org-agenda-sticky' is non-nil." (interactive) - (if org-agenda-columns-active - (org-columns-quit) - (let ((buf (current-buffer))) - (if (eq org-agenda-window-setup 'other-frame) - (progn - (org-agenda-reset-markers) - (kill-buffer buf) - (org-columns-remove-overlays) - (setq org-agenda-archives-mode nil) - (delete-frame)) - (and (not (eq org-agenda-window-setup 'current-window)) - (not (one-window-p)) - (delete-window)) - (org-agenda-reset-markers) - (kill-buffer buf) - (org-columns-remove-overlays) - (setq org-agenda-archives-mode nil))) - (setq org-agenda-buffer nil) - ;; Maybe restore the pre-agenda window configuration. - (and org-agenda-restore-windows-after-quit - (not (eq org-agenda-window-setup 'other-frame)) - org-agenda-pre-window-conf - (set-window-configuration org-agenda-pre-window-conf) - (setq org-agenda-pre-window-conf nil)))) + (org-agenda--quit)) (defun org-agenda-quit () - "Exit the agenda and restore the window configuration. -When `org-agenda-sticky' is non-nil, only bury the agenda." + "Exit the agenda. + +When `org-agenda-sticky' is non-nil, bury the agenda buffer +instead of killing it. + +When `org-agenda-restore-windows-after-quit' is non-nil, restore +the pre-agenda window configuration. + +When column view is active, exit column view instead of the +agenda." (interactive) - (if (and (eq org-indirect-buffer-display 'other-window) - org-last-indirect-buffer) - (let ((org-last-indirect-window - (get-buffer-window org-last-indirect-buffer))) - (if org-last-indirect-window - (delete-window org-last-indirect-window)))) + (org-agenda--quit org-agenda-sticky)) + +(defun org-agenda--quit (&optional bury) (if org-agenda-columns-active (org-columns-quit) - (if org-agenda-sticky - (let ((buf (current-buffer))) - (if (eq org-agenda-window-setup 'other-frame) - (progn - (delete-frame)) - (and (not (eq org-agenda-window-setup 'current-window)) - (not (one-window-p)) - (delete-window))) + (let ((wconf org-agenda-pre-window-conf) + (buf (current-buffer)) + (org-agenda-last-indirect-window + (and (eq org-indirect-buffer-display 'other-window) + org-agenda-last-indirect-buffer + (get-buffer-window org-agenda-last-indirect-buffer)))) + (cond + ((eq org-agenda-window-setup 'other-frame) + (delete-frame)) + ((and org-agenda-restore-windows-after-quit + wconf) + ;; Maybe restore the pre-agenda window configuration. Reset + ;; `org-agenda-pre-window-conf' before running + ;; `set-window-configuration', which loses the current buffer. + (setq org-agenda-pre-window-conf nil) + (set-window-configuration wconf)) + (t + (when org-agenda-last-indirect-window + (delete-window org-agenda-last-indirect-window)) + (and (not (eq org-agenda-window-setup 'current-window)) + (not (one-window-p)) + (delete-window)))) + (if bury + ;; Set the agenda buffer as the current buffer instead of + ;; passing it as an argument to `bury-buffer' so that + ;; `bury-buffer' removes it from the window. (with-current-buffer buf - (bury-buffer) - ;; Maybe restore the pre-agenda window configuration. - (and org-agenda-restore-windows-after-quit - (not (eq org-agenda-window-setup 'other-frame)) - org-agenda-pre-window-conf - (set-window-configuration org-agenda-pre-window-conf) - (setq org-agenda-pre-window-conf nil)))) - (org-agenda-Quit)))) + (bury-buffer)) + (kill-buffer buf) + (setq org-agenda-archives-mode nil + org-agenda-buffer nil))))) (defun org-agenda-exit () - "Exit the agenda and restore the window configuration. -Also kill Org-mode buffers loaded by `org-agenda'. Org-mode -buffers visited directly by the user will not be touched." + "Exit the agenda, killing Org buffers loaded by the agenda. +Like `org-agenda-Quit', but kill any buffers that were created by +the agenda. Org buffers visited directly by the user will not be +touched. Also, exit the agenda even if it is in column view." (interactive) + (when org-agenda-columns-active + (org-columns-quit)) (org-release-buffers org-agenda-new-buffers) (setq org-agenda-new-buffers nil) (org-agenda-Quit)) (defun org-agenda-kill-all-agenda-buffers () "Kill all buffers in `org-agenda-mode'. -This is used when toggling sticky agendas. -You can also explicitly invoke it with `C-c a C-k'." +This is used when toggling sticky agendas." (interactive) (let (blist) (dolist (buf (buffer-list)) @@ -7265,6 +7311,9 @@ in the agenda." (cat-preset (get 'org-agenda-category-filter :preset-filter)) (re-filter org-agenda-regexp-filter) (re-preset (get 'org-agenda-regexp-filter :preset-filter)) + (effort-filter org-agenda-effort-filter) + (effort-preset (get 'org-agenda-effort-filter :preset-filter)) + (org-agenda-tag-filter-while-redo (or tag-filter tag-preset)) (cols org-agenda-columns-active) (line (org-current-line)) (window-line (- line (org-current-line (window-start)))) @@ -7282,6 +7331,7 @@ in the agenda." (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) (and cols (org-columns-quit)) (message "Rebuilding agenda buffer...") (if series-redo-cmd @@ -7292,16 +7342,20 @@ in the agenda." org-agenda-tag-filter tag-filter org-agenda-category-filter cat-filter org-agenda-regexp-filter re-filter + org-agenda-effort-filter effort-filter org-agenda-top-headline-filter top-hl-filter) (message "Rebuilding agenda buffer...done") (put 'org-agenda-tag-filter :preset-filter tag-preset) (put 'org-agenda-category-filter :preset-filter cat-preset) (put 'org-agenda-regexp-filter :preset-filter re-preset) + (put 'org-agenda-effort-filter :preset-filter effort-preset) (let ((tag (or tag-filter tag-preset)) (cat (or cat-filter cat-preset)) - (re (or re-filter re-preset))) - (when tag (org-agenda-filter-apply tag 'tag)) + (effort (or effort-filter effort-preset)) + (re (or re-filter re-preset))) + (when tag (org-agenda-filter-apply tag 'tag t)) (when cat (org-agenda-filter-apply cat 'category)) + (when effort (org-agenda-filter-apply effort 'effort)) (when re (org-agenda-filter-apply re 'regexp))) (and top-hl-filter (org-agenda-filter-top-headline-apply top-hl-filter)) (and cols (org-called-interactively-p 'any) (org-agenda-columns)) @@ -7313,18 +7367,21 @@ in the agenda." (defvar org-agenda-filtered-by-category nil) (defun org-agenda-filter-by-category (strip) - "Keep only those lines in the agenda buffer that have a specific category. -The category is that of the current line." + "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. +" (interactive "P") (if (and org-agenda-filtered-by-category org-agenda-category-filter) (org-agenda-filter-show-all-cat) - (let ((cat (org-no-properties (get-text-property (point) 'org-category)))) + (let ((cat (org-no-properties (org-get-at-eol 'org-category 1)))) (cond ((and cat strip) (org-agenda-filter-apply (push (concat "-" cat) org-agenda-category-filter) 'category)) - ((and cat) + (cat (org-agenda-filter-apply (setq org-agenda-category-filter (list (concat "+" cat))) 'category)) @@ -7373,6 +7430,39 @@ With two prefix arguments, remove the regexp filters." (org-agenda-filter-show-all-re) (message "Regexp filter removed"))) +(defvar org-agenda-effort-filter nil) +(defun org-agenda-filter-by-effort (strip) + "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." + (interactive "P") + (cond ((member strip '(nil 4)) + (let ((efforts (org-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 8:00" + ""))) + (eff -1) + effort-prompt op) + (while (not (member op '(?< ?> ?=))) + (setq op (read-char-exclusive "Effort operator? (> = or <)"))) + (loop for i from 0 to 9 do + (setq effort-prompt + (concat + effort-prompt " [" + (if (= i 9) "0" (int-to-string (1+ i))) + "]" (nth i efforts)))) + (message "Effort %s%s" (char-to-string op) effort-prompt) + (while (or (< eff 0) (> eff 9)) + (setq eff (string-to-number (char-to-string (read-char-exclusive))))) + (setq org-agenda-effort-filter + (list (concat (if strip "-" "+") + (char-to-string op) (nth (1- eff) efforts)))) + (org-agenda-filter-apply org-agenda-effort-filter 'effort))) + (t (org-agenda-filter-show-all-effort) + (message "Effort filter removed")))) + (defun org-agenda-filter-remove-all () "Remove all filters from the current agenda buffer." (interactive) @@ -7384,15 +7474,21 @@ With two prefix arguments, remove the regexp filters." (org-agenda-filter-show-all-re)) (when org-agenda-top-headline-filter (org-agenda-filter-show-all-top-filter)) + (when org-agenda-effort-filter + (org-agenda-filter-show-all-effort)) (org-agenda-finalize)) -(defun org-agenda-filter-by-tag (strip &optional char narrow) +(defun org-agenda-filter-by-tag (arg &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 prefix argument STRIP, remove all lines that do have the tag. -A lisp caller can specify CHAR. NARROW means that the new tag should be -used to narrow the search - the interactive user can also press `-' or `+' -to switch to narrowing." +The tag is selected with its fast selection letter, as +configured. With a single \\[universal-argument] prefix ARG, +exclude the agenda search. With a double \\[universal-argument] +prefix ARG, filter the literal tag. I.e. don't filter on all its +group members. + +A lisp caller can specify CHAR. EXCLUDE means that the new tag 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) (tag-chars (mapconcat @@ -7400,46 +7496,26 @@ to switch to narrowing." (cdr x)) (char-to-string (cdr x)) "")) - alist "")) - (efforts (org-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 8:00" - ""))) - (effort-op org-agenda-filter-effort-default-operator) - (effort-prompt "") + org-tag-alist-for-agenda "")) + (valid-char-list (append '(?\t ?\r ?/ ?. ?\s ?q) + (string-to-list tag-chars))) + (exclude (or exclude (equal arg '(4)))) + (expand (not (equal arg '(16)))) (inhibit-read-only t) (current org-agenda-tag-filter) - maybe-refresh a n tag) + a n tag) (unless char - (message - "%s by tag [%s ], [TAB], %s[/]:off, [+-]:narrow, [>==<]:effort: " tag-chars) - (setq char (read-char-exclusive))) - (when (member char '(?< ?> ?= ??)) - ;; An effort operator - (setq effort-op (char-to-string char)) - (setq alist nil) ; to make sure it will be interpreted as effort. - (unless (equal char ??) - (loop for i from 0 to 9 do - (setq effort-prompt - (concat - effort-prompt " [" - (if (= i 9) "0" (int-to-string (1+ i))) - "]" (nth i efforts)))) - (message "Effort%s: %s " effort-op effort-prompt) + (while (not (memq char valid-char-list)) + (message + "%s by tag [%s ], [TAB], %s[/]:off, [+/-]:filter/exclude%s, [q]:quit" + (if exclude "Exclude" "Filter") tag-chars + (if org-agenda-auto-exclude-function "[RET], " "") + (if expand "" ", no grouptag expand")) (setq char (read-char-exclusive)) - (when (or (< char ?0) (> char ?9)) - (error "Need 1-9,0 to select effort")))) - (when (equal char ?\t) + ;; 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)) (org-set-local 'org-global-tags-completion-table (org-global-tags-completion-table))) @@ -7447,7 +7523,7 @@ to switch to narrowing." (setq tag (org-icompleting-read "Tag: " org-global-tags-completion-table)))) (cond - ((equal char ?\r) + ((eq char ?\r) (org-agenda-filter-show-all-tag) (when org-agenda-auto-exclude-function (setq org-agenda-tag-filter nil) @@ -7456,39 +7532,27 @@ to switch to narrowing." (if modifier (push modifier org-agenda-tag-filter)))) (if (not (null org-agenda-tag-filter)) - (org-agenda-filter-apply org-agenda-tag-filter 'tag))) - (setq maybe-refresh t)) - ((equal char ?/) + (org-agenda-filter-apply org-agenda-tag-filter 'tag expand)))) + ((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)) - (setq maybe-refresh t)) - ((equal char ?. ) + (org-agenda-filter-apply org-agenda-tag-filter 'tag expand))) + ((eq char ?.) (setq org-agenda-tag-filter (mapcar (lambda(tag) (concat "+" tag)) (org-get-at-bol 'tags))) - (org-agenda-filter-apply org-agenda-tag-filter 'tag) - (setq maybe-refresh t)) - ((or (equal char ?\ ) + (org-agenda-filter-apply org-agenda-tag-filter 'tag expand)) + ((eq char ?q)) ;If q, abort (even if there is a q-key for a tag...) + ((or (eq char ?\s) (setq a (rassoc char alist)) - (and (>= char ?0) (<= char ?9) - (setq n (if (= char ?0) 9 (- char ?0 1)) - tag (concat effort-op (nth n efforts)) - a (cons tag nil))) - (and (= char ??) - (setq tag "?eff") - a (cons tag nil)) (and tag (setq a (cons tag nil)))) (org-agenda-filter-show-all-tag) (setq tag (car a)) (setq org-agenda-tag-filter - (cons (concat (if strip "-" "+") tag) - (if narrow current nil))) - (org-agenda-filter-apply org-agenda-tag-filter 'tag) - (setq maybe-refresh t)) - (t (error "Invalid tag selection character %c" char))) - (when maybe-refresh - (org-agenda-redo)))) + (cons (concat (if exclude "-" "+") tag) + current)) + (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." @@ -7501,13 +7565,17 @@ to switch to narrowing." (get-text-property (point) 'tags)))) tags)) -(defun org-agenda-filter-by-tag-refine (strip &optional char) +(defun org-agenda-filter-by-tag-refine (arg &optional char) "Refine the current filter. See `org-agenda-filter-by-tag'." (interactive "P") - (org-agenda-filter-by-tag strip char 'refine)) - -(defun org-agenda-filter-make-matcher (filter type) - "Create the form that tests a line for agenda filter." + (org-agenda-filter-by-tag arg char)) +(make-obsolete 'org-agenda-filter-by-tag-refine + "use `org-agenda-filter-by-tag' instead." "8.3.4") + +(defun org-agenda-filter-make-matcher (filter type &optional expand) + "Create the form that tests a line for agenda filter. Optional +argument EXPAND can be used for the TYPE tag and will expand the +tags in the FILTER if any of the tags in FILTER are grouptags." (let (f f1) (cond ;; Tag filter @@ -7517,28 +7585,11 @@ to switch to narrowing." (append (get 'org-agenda-tag-filter :preset-filter) filter))) (dolist (x filter) - (let ((nfilter (org-agenda-filter-expand-tags filter)) nf nf1 - (ffunc - (lambda (nf0 nf01 fltr notgroup op) - (dolist (x fltr) - (if (member x '("-" "+")) - (setq nf01 (if (equal x "-") 'tags '(not tags))) - (if (string-match "[<=>?]" x) - (setq nf01 (org-agenda-filter-effort-form x)) - (setq nf01 (list 'member (downcase (substring x 1)) - 'tags))) - (when (equal (string-to-char x) ?-) - (setq nf01 (list 'not nf01)) - (when (not notgroup) (setq op 'and)))) - (push nf01 nf0)) - (if notgroup - (push (cons 'and nf0) f) - (push (cons (or op 'or) nf0) f))))) - (cond ((equal filter '("+")) - (setq f (list (list 'not 'tags)))) - ((equal nfilter filter) - (funcall ffunc f1 f filter t nil)) - (t (funcall ffunc nf1 nf nfilter nil nil)))))) + (let ((op (string-to-char x))) + (if expand (setq x (org-agenda-filter-expand-tags (list x) t)) + (setq x (list x))) + (setq f1 (org-agenda-filter-make-matcher-tag-exp x op)) + (push f1 f)))) ;; Category filter ((eq type 'category) (setq filter @@ -7560,9 +7611,43 @@ to switch to narrowing." (if (equal "-" (substring x 0 1)) (setq f1 (list 'not (list 'string-match (substring x 1) 'txt))) (setq f1 (list 'string-match (substring x 1) 'txt))) - (push f1 f)))) + (push f1 f))) + ;; Effort filter + ((eq type 'effort) + (setq filter + (delete-dups + (append (get 'org-agenda-effort-filter :preset-filter) + filter))) + (dolist (x filter) + (push (org-agenda-filter-effort-form x) f)))) (cons 'and (nreverse f)))) +(defun org-agenda-filter-make-matcher-tag-exp (tags op) + "Create the form that tests a line for agenda filter for +tag-expressions. Return a match-expression given TAGS. OP is an +operator of type CHAR that allows the function to set the right +switches in the returned form." + (let (f f1) ;f = return expression. f1 = working-area + (dolist (x tags) + (let* ((tag (substring x 1)) + (isregexp (and (equal "{" (substring tag 0 1)) + (equal "}" (substring tag -1)))) + regexp) + (cond + (isregexp + (setq regexp (substring tag 1 -1)) + (setq f1 (list 'org-match-any-p regexp 'tags))) + (t + (setq f1 (list 'member (downcase tag) 'tags)))) + (when (eq op ?-) + (setq f1 (list 'not f1)))) + (push f1 f)) + ;; Any of the expressions can match if op = + + ;; all must match if the operator is -. + (if (eq op ?-) + (cons 'and f) + (cons 'or f)))) + (defun org-agenda-filter-effort-form (e) "Return the form to compare the effort of the current line with what E says. E looks like \"+<2:25\"." @@ -7579,11 +7664,9 @@ E looks like \"+<2:25\"." (defun org-agenda-compare-effort (op value) "Compare the effort of the current line with VALUE, using OP. If the line does not have an effort defined, return nil." - (let ((eff (org-get-at-bol 'effort-minutes))) - (if (equal op ??) - (not eff) - (funcall op (or eff (if org-sort-agenda-noeffort-is-high 32767 0)) - value)))) + (let ((eff (org-get-at-eol 'effort-minutes 1))) + (funcall op (or eff (if org-sort-agenda-noeffort-is-high 32767 -1)) + value))) (defun org-agenda-filter-expand-tags (filter &optional no-operator) "Expand group tags in FILTER for the agenda. @@ -7603,12 +7686,14 @@ When NO-OPERATOR is non-nil, do not add the + operator to returned tags." (reverse rtn)) filter)) -(defun org-agenda-filter-apply (filter type) - "Set FILTER as the new agenda filter and apply it." +(defun org-agenda-filter-apply (filter type &optional expand) + "Set FILTER as the new agenda filter and apply it. Optional +argument EXPAND can be used for the TYPE tag and will expand the +tags in the FILTER if any of the tags in FILTER are grouptags." ;; Deactivate `org-agenda-entry-text-mode' when filtering (if 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)) + (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 @@ -7620,13 +7705,9 @@ When NO-OPERATOR is non-nil, do not add the + operator to returned tags." (while (not (eobp)) (if (org-get-at-bol 'org-marker) (progn - (setq tags ; used in eval - (apply 'append - (mapcar (lambda (f) - (org-agenda-filter-expand-tags (list f) t)) - (org-get-at-bol 'tags))) - cat (get-text-property (point) 'org-category) - txt (get-text-property (point) 'txt)) + (setq tags (org-get-at-bol 'tags) + cat (org-get-at-eol 'org-category 1) + txt (org-get-at-bol 'txt)) (if (not (eval org-agenda-filter-form)) (org-agenda-filter-hide-line type)) (beginning-of-line 2)) @@ -7679,6 +7760,8 @@ When NO-OPERATOR is non-nil, do not add the + operator to returned tags." (org-agenda-remove-filter 'tag)) (defun org-agenda-filter-show-all-re nil (org-agenda-remove-filter 'regexp)) +(defun org-agenda-filter-show-all-effort nil + (org-agenda-remove-filter 'effort)) (defun org-agenda-filter-show-all-cat nil (org-agenda-remove-filter 'category)) (defun org-agenda-filter-show-all-top-filter nil @@ -7790,27 +7873,40 @@ Negative selection means regexp must not match for selection of an entry." (text-property-any (point-min) (point-max) 'org-today t) (text-property-any (point-min) (point-max) 'org-agenda-type 'agenda) (and (get-text-property (min (1- (point-max)) (point)) 'org-series) - (org-agenda-goto-block-beginning)) + (org-agenda-backward-block)) (point-min)))) -(defun org-agenda-goto-block-beginning () - "Go the agenda block beginning." +(defun org-agenda-backward-block () + "Move backward by one agenda block." (interactive) - (if (not (derived-mode-p 'org-agenda-mode)) - (error "Cannot execute this command outside of org-agenda-mode buffers") - (let (dest) - (save-excursion - (unless (looking-at "\\'") - (forward-char)) - (let* ((prop 'org-agenda-structural-header) - (p (previous-single-property-change (point) prop)) - (n (next-single-property-change (or (and (looking-at "\\`") 1) - (1- (point))) prop))) - (setq dest (cond ((eq n (point-at-eol)) (1- n)) (p (1- p)))))) - (if (not dest) - (error "Cannot find the beginning of the blog") - (goto-char dest) - (move-beginning-of-line 1))))) + (org-agenda-forward-block 'backward)) + +(defun org-agenda-forward-block (&optional backward) + "Move forward by one agenda block. +When optional argument BACKWARD is set, go backward" + (interactive) + (cond ((not (derived-mode-p 'org-agenda-mode)) + (user-error + "Cannot execute this command outside of org-agenda-mode buffers")) + ((looking-at (if backward "\\`" "\\'")) + (message "Already at the %s block" (if backward "first" "last"))) + (t (let ((pos (prog1 (point) + (ignore-errors (if backward (backward-char 1) + (move-end-of-line 1))))) + (f (if backward + 'previous-single-property-change + 'next-single-property-change)) + moved dest) + (while (and (setq dest (funcall + f (point) 'org-agenda-structural-header)) + (not (get-text-property + (point) 'org-agenda-structural-header))) + (setq moved t) + (goto-char dest)) + (if moved (move-beginning-of-line 1) + (goto-char (if backward (point-min) (point-max))) + (move-beginning-of-line 1) + (message "No %s block" (if backward "previous" "further"))))))) (defun org-agenda-later (arg) "Go forward in time by the current span. @@ -8091,7 +8187,8 @@ so that the date SD will be in that range." "Toggle log mode in an agenda buffer. With argument SPECIAL, show all possible log items, not only the ones configured in `org-agenda-log-mode-items'. -With a double `C-u' prefix arg, show *only* log items, nothing else." +With a double \\[universal-argument] prefix arg, show *only* \ +log items, nothing else." (interactive "P") (org-agenda-check-type t 'agenda 'timeline) (setq org-agenda-show-log @@ -8202,6 +8299,19 @@ When called with a prefix argument, include all archive files as well." "}") '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 (org-propertize + (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 (org-propertize @@ -8288,7 +8398,7 @@ When called with a prefix argument, include all archive files as well." (message "No tags associated with this line")))) (defun org-agenda-goto (&optional highlight) - "Go to the Org-mode file which contains the item at point." + "Go to the entry at point in the corresponding Org-mode file." (interactive) (let* ((marker (or (org-get-at-bol 'org-marker) (org-agenda-error))) @@ -8302,10 +8412,13 @@ When called with a prefix argument, include all archive files as well." (org-show-context 'agenda) (save-excursion (and (outline-next-heading) - (org-flag-heading nil)))) ; show the next heading - (when (outline-invisible-p) - (show-entry)) ; display invisible text - (recenter (/ (window-height) 2)) + (org-flag-heading nil))) ; show the next heading + (when (outline-invisible-p) + (outline-show-entry)) ; display invisible text + (recenter (/ (window-height) 2)) + (org-back-to-heading t) + (if (re-search-forward org-complex-heading-regexp nil t) + (goto-char (match-beginning 4)))) (run-hooks 'org-agenda-after-show-hook) (and highlight (org-highlight (point-at-bol) (point-at-eol))))) @@ -8422,8 +8535,10 @@ If this information is not given, the function uses the tree at point." (defun org-agenda-refile (&optional goto rfloc no-update) "Refile the item at point. -When GOTO is 0 or '(64), clear the refile cache. -When GOTO is '(16), go to the location of the last refiled item. +When GOTO is 0 or \\='(64) or a triple \\[universal-argument] prefix argument, +clear the refile cache. +When GOTO is \\='(16) or a double \\[universal-argument] prefix argument, +go to the location of the last refiled item. RFLOC can be a refile location obtained in a different way. When NO-UPDATE is non-nil, don't redo the agenda buffer." (interactive "P") @@ -8504,7 +8619,9 @@ It also looks at the text of the entry itself." (symbol-value var)))))) (defun org-agenda-switch-to (&optional delete-other-windows) - "Go to the Org-mode file which contains the item at point." + "Go to the Org mode file which contains the item at point. +When optional argument DELETE-OTHER-WINDOWS is non-nil, the +displayed Org file fills the frame." (interactive) (if (and org-return-follows-link (not (org-get-at-bol 'org-marker)) @@ -8514,17 +8631,13 @@ It also looks at the text of the entry itself." (org-agenda-error))) (buffer (marker-buffer marker)) (pos (marker-position marker))) + (unless buffer (user-error "Trying to switch to non-existent buffer")) (org-pop-to-buffer-same-window buffer) - (and delete-other-windows (delete-other-windows)) + (when delete-other-windows (delete-other-windows)) (widen) (goto-char pos) (when (derived-mode-p 'org-mode) (org-show-context 'agenda) - (save-excursion - (and (outline-next-heading) - (org-flag-heading nil))) ; show the next heading - (when (outline-invisible-p) - (show-entry)) ; display invisible text (run-hooks 'org-agenda-after-show-hook))))) (defun org-agenda-goto-mouse (ev) @@ -8539,10 +8652,8 @@ With prefix argument FULL-ENTRY, make the entire entry visible if it was hidden in the outline." (interactive "P") (let ((win (selected-window))) - (if full-entry - (let ((org-show-entry-below t)) - (org-agenda-goto t)) - (org-agenda-goto t)) + (org-agenda-goto t) + (when full-entry (org-show-entry)) (select-window win))) (defvar org-agenda-show-window nil) @@ -8560,7 +8671,7 @@ folded." (select-window org-agenda-show-window) (ignore-errors (scroll-up))) (org-agenda-goto t) - (if arg (org-show-entry) (show-subtree)) + (if arg (org-show-entry) (outline-show-subtree)) (setq org-agenda-show-window (selected-window))) (select-window win))) @@ -8592,7 +8703,7 @@ if it was hidden in the outline." (set-window-start (selected-window) (point-at-bol)) (cond ((= more 0) - (hide-subtree) + (outline-hide-subtree) (save-excursion (org-back-to-heading) (run-hook-with-args 'org-cycle-hook 'folded)) @@ -8600,42 +8711,38 @@ if it was hidden in the outline." ((and (org-called-interactively-p 'any) (= more 1)) (message "Remote: show with default settings")) ((= more 2) - (show-entry) - (show-children) + (outline-show-entry) + (outline-show-children) (save-excursion (org-back-to-heading) (run-hook-with-args 'org-cycle-hook 'children)) (message "Remote: CHILDREN")) ((= more 3) - (show-subtree) + (outline-show-subtree) (save-excursion (org-back-to-heading) (run-hook-with-args 'org-cycle-hook 'subtree)) (message "Remote: SUBTREE")) ((= more 4) - (let* ((org-drawers (delete "LOGBOOK" (copy-sequence org-drawers))) - (org-drawer-regexp - (concat "^[ \t]*:\\(" - (mapconcat 'regexp-quote org-drawers "\\|") - "\\):[ \t]*$"))) - (show-subtree) - (save-excursion - (org-back-to-heading) - (org-cycle-hide-drawers 'subtree))) + (outline-show-subtree) + (save-excursion + (org-back-to-heading) + (org-cycle-hide-drawers 'subtree '("LOGBOOK"))) (message "Remote: SUBTREE AND LOGBOOK")) ((> more 4) - (show-subtree) + (outline-show-subtree) (message "Remote: SUBTREE AND ALL DRAWERS"))) (select-window win))) (defvar org-agenda-cycle-counter nil) (defun org-agenda-cycle-show (&optional n) "Show the current entry in another window, with default settings. -Default settings are taken from `org-show-hierarchy-above' and siblings. -When use repeatedly in immediate succession, the remote entry will cycle -through visibility -children -> subtree -> folded +Default settings are taken from `org-show-context-detail'. When +use repeatedly in immediate succession, the remote entry will +cycle through visibility + + children -> subtree -> folded When called with a numeric prefix arg, that arg will be passed through to `org-agenda-show-1'. For the interpretation of that argument, see the @@ -8672,7 +8779,8 @@ docstring of `org-agenda-show-1'." (org-agenda-error))) (defun org-agenda-error () - (error "Command not allowed in this line")) + "Throw an error when a command is not allowed in the agenda." + (user-error "Command not allowed in this line")) (defun org-agenda-tree-to-indirect-buffer (arg) "Show the subtree corresponding to the current entry in an indirect buffer. @@ -8699,7 +8807,8 @@ use the dedicated frame)." (and indirect-window (select-window indirect-window)) (switch-to-buffer org-last-indirect-buffer :norecord) (fit-window-to-buffer indirect-window))) - (select-window (get-buffer-window agenda-buffer))))) + (select-window (get-buffer-window agenda-buffer)) + (setq org-agenda-last-indirect-buffer org-last-indirect-buffer)))) (defun org-agenda-do-tree-to-indirect-buffer (arg) "Same as `org-agenda-tree-to-indirect-buffer' without saving window." @@ -8771,7 +8880,8 @@ the same tree node, and the headline of the tree node in the Org-mode file." (string-match (concat "^" (regexp-opt org-done-keywords-for-agenda)) newhead) (org-agenda-unmark-clocking-task)) - (org-move-to-column col)))) + (org-move-to-column col) + (org-agenda-mark-clocking-task)))) (defun org-agenda-add-note (&optional arg) "Add a time-stamped note to the entry at point." @@ -8820,7 +8930,7 @@ If FORCE-TAGS is non nil, the car of it returns the new tags." (equal m hdmarker)) (setq props (text-properties-at (point)) dotime (org-get-at-bol 'dotime) - cat (org-get-at-bol 'org-category) + cat (org-get-at-eol 'org-category 1) level (org-get-at-bol 'level) tags thetags new @@ -9185,7 +9295,6 @@ ARG is passed through to `org-schedule'." (type (marker-insertion-type marker)) (buffer (marker-buffer marker)) (pos (marker-position marker)) - (org-insert-labeled-timestamps-at-point nil) ts) (set-marker-insertion-type marker t) (org-with-remote-undo buffer @@ -9206,7 +9315,6 @@ ARG is passed through to `org-deadline'." (org-agenda-error))) (buffer (marker-buffer marker)) (pos (marker-position marker)) - (org-insert-labeled-timestamps-at-point nil) ts) (org-with-remote-undo buffer (with-current-buffer buffer @@ -9432,33 +9540,30 @@ Add TEXT as headline, and position the cursor in the second line so that a timestamp can be added there." (widen) (goto-char (point-max)) - (or (bolp) (insert "\n")) - (insert "* " text "\n") - (if org-adapt-indentation (org-indent-to-column 2))) + (unless (bolp) (insert "\n")) + (org-insert-heading nil t t) + (insert text) + (org-end-of-meta-data) + (unless (bolp) (insert "\n")) + (when org-adapt-indentation (org-indent-to-column 2))) (defun org-agenda-insert-diary-make-new-entry (text) "Make a new entry with TEXT as the first child of the current subtree. -Position the point in the line right after the new heading so -that a timestamp can be added there." - (let ((org-show-following-heading t) - (org-show-siblings t) - (org-show-hierarchy-above t) - (org-show-entry-below t) - col) - (outline-next-heading) - (org-back-over-empty-lines) - (or (looking-at "[ \t]*$") - (progn (insert "\n") (backward-char 1))) - (org-insert-heading nil t) - (org-do-demote) - (setq col (current-column)) - (insert text "\n") - (if org-adapt-indentation (org-indent-to-column col)) - (let ((org-show-following-heading t) - (org-show-siblings t) - (org-show-hierarchy-above t) - (org-show-entry-below t)) - (org-show-context)))) +Position the point in the heading's first body line so that +a timestamp can be added there." + (outline-next-heading) + (org-back-over-empty-lines) + (unless (looking-at "[ \t]*$") (save-excursion (insert "\n"))) + (org-insert-heading nil t) + (org-do-demote) + (let ((col (current-column))) + (insert text) + (org-end-of-meta-data) + ;; Ensure point is left on a blank line, at proper indentation. + (unless (bolp) (insert "\n")) + (unless (org-looking-at-p "^[ \t]*$") (save-excursion (insert "\n"))) + (when org-adapt-indentation (org-indent-to-column col))) + (org-show-set-visibility 'lineage)) (defun org-agenda-diary-entry () "Make a diary entry, like the `i' command from the calendar. @@ -9573,9 +9678,13 @@ argument, latitude and longitude will be prompted for." "Compute the Org-mode agenda for the calendar date displayed at the cursor. This is a command that has to be installed in `calendar-mode-map'." (interactive) - (org-agenda-list nil (calendar-absolute-from-gregorian - (calendar-cursor-to-date)) - nil)) + ;; Temporarily disable sticky agenda since user clearly wants to + ;; refresh view anyway. + (let ((org-agenda-buffer-tmp-name "*Org Agenda(a)*") + (org-agenda-sticky nil)) + (org-agenda-list nil (calendar-absolute-from-gregorian + (calendar-cursor-to-date)) + nil))) (defun org-agenda-convert-date () (interactive) @@ -9595,7 +9704,7 @@ This is a command that has to be installed in `calendar-mode-map'." "Hebrew: " (calendar-hebrew-date-string date) " (until sunset)\n" "Islamic: " (calendar-islamic-date-string date) " (until sunset)\n" "French: " (calendar-french-date-string date) "\n" - "Baha'i: " (calendar-bahai-date-string date) " (until sunset)\n" + "Bahá’í: " (calendar-bahai-date-string date) " (until sunset)\n" "Mayan: " (calendar-mayan-date-string date) "\n" "Coptic: " (calendar-coptic-date-string date) "\n" "Ethiopic: " (calendar-ethiopic-date-string date) "\n" @@ -9872,6 +9981,11 @@ The prefix arg is passed through to the command if possible." (goto-char pos) (let (org-loop-over-headlines-in-active-region) (eval cmd)) + ;; `post-command-hook' is not run yet. We make sure any + ;; pending log note is processed. + (when (or (memq 'org-add-log-note (default-value 'post-command-hook)) + (memq 'org-add-log-note post-command-hook)) + (org-add-log-note)) (setq cnt (1+ cnt)))) (when redo-at-end (org-agenda-redo)) (unless org-agenda-persistent-marks @@ -9901,12 +10015,14 @@ current HH:MM time." (defun org-agenda-reapply-filters () "Re-apply all agenda filters." (mapcar - (lambda(f) (when (car f) (org-agenda-filter-apply (car f) (cadr f)))) + (lambda(f) (when (car f) (org-agenda-filter-apply (car f) (cadr f) t))) `((,org-agenda-tag-filter tag) (,org-agenda-category-filter category) (,org-agenda-regexp-filter regexp) + (,org-agenda-effort-filter effort) (,(get 'org-agenda-tag-filter :preset-filter) tag) (,(get 'org-agenda-category-filter :preset-filter) category) + (,(get 'org-agenda-effort-filter :preset-filter) effort) (,(get 'org-agenda-regexp-filter :preset-filter) regexp)))) (defun org-agenda-drag-line-forward (arg &optional backward) @@ -9967,7 +10083,8 @@ tag and (if present) the flagging note." (replace-match "\n" t t)) (goto-char (point-min)) (select-window win) - (message "Flagging note pushed to kill ring. Press [?] again to remove tag and note")))) + (message (substitute-command-keys "Flagging note pushed to kill ring. \ +Press \\[org-agenda-show-the-flagging-note] again to remove tag and note"))))) (defun org-agenda-remove-flag (marker) "Remove the FLAGGED tag and any flagging note in the entry." @@ -10004,9 +10121,9 @@ calling the function returns nil. This function takes one argument: an entry from `org-agenda-get-day-entries'. FILTER can also be an alist with the car of each cell being -either 'headline or 'category. For example: +either `headline' or `category'. For example: - '((headline \"IMPORTANT\") + \\='((headline \"IMPORTANT\") (category \"Work\")) will only add headlines containing IMPORTANT or headlines @@ -10051,7 +10168,7 @@ to override `appt-message-warning-time'." (replace-regexp-in-string org-bracket-link-regexp "\\3" (or (get-text-property 1 'txt x) "")))) - (cat (get-text-property 1 'org-category x)) + (cat (get-text-property (1- (length x)) 'org-category x)) (tod (get-text-property 1 'time-of-day x)) (ok (or (null filter) (and (stringp filter) (string-match filter evt)) @@ -10091,7 +10208,8 @@ to override `appt-message-warning-time'." (defun org-agenda-todo-yesterday (&optional arg) "Like `org-agenda-todo' but the time of change will be 23:59 of yesterday." (interactive "P") - (let* ((hour (third (decode-time + (let* ((org-use-effective-time t) + (hour (third (decode-time (org-current-time)))) (org-extend-today-until (1+ hour))) (org-agenda-todo arg))) diff --git a/elpa/org-20150629/org-archive.el b/elpa/org-20160215/org-archive.el similarity index 86% rename from elpa/org-20150629/org-archive.el rename to elpa/org-20160215/org-archive.el index 6deac47b..4c6a8c3f 100644 --- a/elpa/org-20150629/org-archive.el +++ b/elpa/org-20160215/org-archive.el @@ -1,6 +1,6 @@ ;;; org-archive.el --- Archiving for Org-mode -;; Copyright (C) 2004-2014 Free Software Foundation, Inc. +;; Copyright (C) 2004-2016 Free Software Foundation, Inc. ;; Author: Carsten Dominik ;; Keywords: outlines, hypermedia, calendar, wp @@ -119,9 +119,15 @@ information." (const :tag "Outline path" olpath) (const :tag "Local tags" ltags))) +(defvar org-archive-hook nil + "Hook run after successfully archiving a subtree. +Hook functions are called with point on the subtree in the +original file. At this stage, the subtree has been added to the +archive location, but not yet deleted from the original file.") + (defun org-get-local-archive-location () "Get the archive location applicable at point." - (let ((re "^#\\+ARCHIVE:[ \t]+\\(\\S-.*\\S-\\)[ \t]*$") + (let ((re "^[ \t]*#\\+ARCHIVE:[ \t]+\\(\\S-.*\\S-\\)[ \t]*$") prop) (save-excursion (save-restriction @@ -158,7 +164,7 @@ archive file is." (save-restriction (goto-char (point-min)) (while (re-search-forward - "^\\(#\\+\\|[ \t]*:\\)ARCHIVE:[ \t]+\\(.*\\)" + "^[ \t]*\\(#\\+\\|:\\)ARCHIVE:[ \t]+\\(.*\\)" nil t) (setq file (org-extract-archive-file (org-match-string-no-properties 2))) @@ -198,9 +204,11 @@ The archive can be a certain top-level heading in the current file, or in a different file. The tree will be moved to that location, the subtree heading be marked DONE, and the current time will be added. -When called with prefix argument FIND-DONE, find whole trees without any +When called with a single prefix argument FIND-DONE, find whole trees without any open TODO items and archive them (after getting confirmation from the user). -If the cursor is not at a headline when this command is called, try all level +When called with a double prefix argument, find whole trees with timestamps before +today and archive them (after getting confirmation from the user). +If the cursor is not at a headline when these commands are called, try all level 1 trees. If the cursor is on a headline, only try the direct children of this heading." (interactive "P") @@ -213,8 +221,10 @@ this heading." (org-archive-subtree ,find-done)) org-loop-over-headlines-in-active-region cl (if (outline-invisible-p) (org-end-of-subtree nil t)))) - (if find-done - (org-archive-all-done) + (cond + ((equal find-done '(4)) (org-archive-all-done)) + ((equal find-done '(16)) (org-archive-all-old)) + (t ;; Save all relevant TODO keyword-relatex variables (let ((tr-org-todo-line-regexp org-todo-line-regexp) ; keep despite compiler (tr-org-todo-keywords-1 org-todo-keywords-1) @@ -231,8 +241,7 @@ this heading." (error "No file associated to buffer")))) (olpath (mapconcat 'identity (org-get-outline-path) "/")) (time (format-time-string - (substring (cdr org-time-stamp-formats) 1 -1) - (current-time))) + (substring (cdr org-time-stamp-formats) 1 -1))) category todo priority ltags itags atags ;; end of variables that will be used for saving context location afile heading buffer level newfile-p infile-p visiting @@ -308,7 +317,7 @@ this heading." org-odd-levels-only tr-org-odd-levels-only))) (goto-char (point-min)) - (show-all) + (outline-show-all) (if (and heading (not (and datetree-date (not datetree-subheading-p)))) (progn (if (re-search-forward @@ -323,7 +332,7 @@ this heading." (insert (if datetree-date "" "\n") heading "\n") (end-of-line 0)) ;; Make the subtree visible - (show-subtree) + (outline-show-subtree) (if org-archive-reversed-order (progn (org-back-to-heading t) @@ -366,8 +375,10 @@ this heading." ;; Save and kill the buffer, if it is not the same buffer. (when (not (eq this-buffer buffer)) (save-buffer)))) - ;; Here we are back in the original buffer. Everything seems to have - ;; worked. So now cut the tree and finish up. + ;; Here we are back in the original buffer. Everything seems + ;; to have worked. So now run hooks, cut the tree and finish + ;; up. + (run-hooks 'org-archive-hook) (let (this-command) (org-cut-subtree)) (when (featurep 'org-inlinetask) (org-inlinetask-remove-END-maybe)) @@ -375,7 +386,7 @@ this heading." (message "Subtree archived %s" (if (eq this-buffer buffer) (concat "under heading: " heading) - (concat "in file: " (abbreviate-file-name afile)))))) + (concat "in file: " (abbreviate-file-name afile))))))) (org-reveal) (if (looking-at "^[ \t]*$") (outline-next-visible-heading 1)))) @@ -441,10 +452,9 @@ sibling does not exist, it will be created at the end of the subtree." (org-set-property "ARCHIVE_TIME" (format-time-string - (substring (cdr org-time-stamp-formats) 1 -1) - (current-time))) + (substring (cdr org-time-stamp-formats) 1 -1))) (outline-up-heading 1 t) - (hide-subtree) + (outline-hide-subtree) (org-cycle-show-empty-lines 'folded) (goto-char pos))) (org-reveal) @@ -456,13 +466,50 @@ sibling does not exist, it will be created at the end of the subtree." If the cursor is not on a headline, try all level 1 trees. If it is on a headline, try all direct children. When TAG is non-nil, don't move trees, but mark them with the ARCHIVE tag." - (let ((re org-not-done-heading-regexp) re1 - (rea (concat ".*:" org-archive-tag ":")) + (org-archive-all-matches + (lambda (beg end) + (unless (re-search-forward org-not-done-heading-regexp end t) + "no open TODO items")) + tag)) + +(defun org-archive-all-old (&optional tag) + "Archive sublevels of the current tree with timestamps prior to today. +If the cursor is not on a headline, try all level 1 trees. If +it is on a headline, try all direct children. +When TAG is non-nil, don't move trees, but mark them with the ARCHIVE tag." + (org-archive-all-matches + (lambda (beg end) + (let (ts) + (and (re-search-forward org-ts-regexp end t) + (setq ts (match-string 0)) + (< (org-time-stamp-to-now ts) 0) + (if (not (looking-at + (concat "--\\(" org-ts-regexp "\\)"))) + (concat "old timestamp " ts) + (setq ts (concat "old timestamp " ts (match-string 0))) + (and (< (org-time-stamp-to-now (match-string 1)) 0) + ts))))) + tag)) + +(defun org-archive-all-matches (predicate &optional tag) + "Archive sublevels of the current tree that match PREDICATE. + +PREDICATE is a function of two arguments, BEG and END, which +specify the beginning and end of the headline being considered. +It is called with point positioned at BEG. The headline will be +archived if PREDICATE returns non-nil. If the return value of +PREDICATE is a string, it should describe the reason for +archiving the heading. + +If the cursor is not on a headline, try all level 1 trees. If it +is on a headline, try all direct children. When TAG is non-nil, +don't move trees, but mark them with the ARCHIVE tag." + (let ((rea (concat ".*:" org-archive-tag ":")) re1 (begm (make-marker)) (endm (make-marker)) - (question (if tag "Set ARCHIVE tag (no open TODO items)? " - "Move subtree to archive (no open TODO items)? ")) - beg end (cntarch 0)) + (question (if tag "Set ARCHIVE tag? " + "Move subtree to archive? ")) + reason beg end (cntarch 0)) (if (org-at-heading-p) (progn (setq re1 (concat "^" (regexp-quote @@ -482,11 +529,14 @@ When TAG is non-nil, don't move trees, but mark them with the ARCHIVE tag." (setq beg (match-beginning 0) end (save-excursion (org-end-of-subtree t) (point))) (goto-char beg) - (if (re-search-forward re end t) + (if (not (setq reason (funcall predicate beg end))) (goto-char end) (goto-char beg) (if (and (or (not tag) (not (looking-at rea))) - (y-or-n-p question)) + (y-or-n-p + (if (stringp reason) + (concat question "(" reason ")") + question))) (progn (if tag (org-toggle-tag org-archive-tag 'on) @@ -515,7 +565,7 @@ the children that do not contain any open TODO items." (save-excursion (org-back-to-heading t) (setq set (org-toggle-tag org-archive-tag)) - (when set (hide-subtree))) + (when set (org-flag-subtree t))) (and set (beginning-of-line 1)) (message "Subtree %s" (if set "archived" "unarchived")))))) diff --git a/elpa/org-20150629/org-attach.el b/elpa/org-20160215/org-attach.el similarity index 94% rename from elpa/org-20150629/org-attach.el rename to elpa/org-20160215/org-attach.el index bcf7ba73..e237b2cf 100644 --- a/elpa/org-20150629/org-attach.el +++ b/elpa/org-20160215/org-attach.el @@ -1,6 +1,6 @@ ;;; org-attach.el --- Manage file attachments to org-mode tasks -;; Copyright (C) 2008-2014 Free Software Foundation, Inc. +;; Copyright (C) 2008-2016 Free Software Foundation, Inc. ;; Author: John Wiegley ;; Keywords: org data task @@ -120,6 +120,17 @@ lns create a symbol link. Note that this is not supported (const :tag "Link to origin location" t) (const :tag "Link to the attach-dir location" attached))) +(defcustom org-attach-archive-delete nil + "Non-nil means attachments are deleted upon archiving a subtree. +When set to `query', ask the user instead." + :group 'org-attach + :version "25.1" + :package-version '(Org . "8.3") + :type '(choice + (const :tag "Never delete attachments" nil) + (const :tag "Always delete attachments" t) + (const :tag "Query the user" query))) + ;;;###autoload (defun org-attach () "The dispatcher for attachment commands. @@ -272,7 +283,8 @@ This checks for the existence of a \".git\" directory in that directory." (cd dir) (let ((have-annex (and org-attach-git-annex-cutoff - (file-exists-p (expand-file-name "annex" git-dir))))) + (or (file-exists-p (expand-file-name "annex" git-dir)) + (file-exists-p (expand-file-name ".git/annex" git-dir)))))) (dolist (new-or-modified (split-string (shell-command-to-string @@ -419,15 +431,15 @@ This can be used after files have been added externally." (and files (org-attach-tag)) (when org-attach-file-list-property (dolist (file files) - (unless (string-match "^\\." file) + (unless (string-match "^\\.\\.?\\'" file) (org-entry-add-to-multivalued-property (point) org-attach-file-list-property file)))))))) (defun org-attach-file-list (dir) "Return a list of files in the attachment directory. -This ignores files starting with a \".\", and files ending in \"~\"." +This ignores files ending in \"~\"." (delq nil - (mapcar (lambda (x) (if (string-match "^\\." x) nil x)) + (mapcar (lambda (x) (if (string-match "^\\.\\.?\\'" x) nil x)) (directory-files dir nil "[^~]\\'")))) (defun org-attach-reveal (&optional if-exists) @@ -475,6 +487,17 @@ Basically, this adds the path to the attachment directory, and a \"file:\" prefix." (concat "file:" (org-attach-expand file))) +(defun org-attach-archive-delete-maybe () + "Maybe delete subtree attachments when archiving. +This function is called by `org-archive-hook'. The option +`org-attach-archive-delete' controls its behavior." + (when (if (eq org-attach-archive-delete 'query) + (yes-or-no-p "Delete all attachments? ") + org-attach-archive-delete) + (org-attach-delete-all t))) + +(add-hook 'org-archive-hook 'org-attach-archive-delete-maybe) + (provide 'org-attach) ;; Local variables: diff --git a/elpa/org-20150629/org-autoloads.el b/elpa/org-20160215/org-autoloads.el similarity index 85% rename from elpa/org-20150629/org-autoloads.el rename to elpa/org-20160215/org-autoloads.el index 7e5fba92..a41abe66 100644 --- a/elpa/org-20150629/org-autoloads.el +++ b/elpa/org-20160215/org-autoloads.el @@ -3,7 +3,7 @@ ;;; Code: (add-to-list 'load-path (or (file-name-directory #$) (car load-path))) -;;;### (autoloads nil "org" "org.el" (21908 10860 0 0)) +;;;### (autoloads nil "org" "org.el" (22216 31924 0 0)) ;;; Generated autoloads from org.el (autoload 'org-babel-do-load-languages "org" "\ @@ -21,10 +21,11 @@ file to byte-code before it is loaded. \(fn FILE &optional COMPILE)" t nil) (autoload 'org-version "org" "\ -Show the org-mode version in the echo area. -With prefix argument HERE, insert it at point. -When FULL is non-nil, use a verbose version string. -When MESSAGE is non-nil, display a message with the version. +Show the org-mode version. +Interactively, or when MESSAGE is non-nil, show it in echo area. +With prefix argument, or when HERE is non-nil, insert it at point. +In non-interactive uses, a reduced version string is output unless +FULL is given. \(fn &optional HERE FULL MESSAGE)" t nil) @@ -71,11 +72,10 @@ in special contexts. 1. OVERVIEW: Show only top-level headlines. 2. CONTENTS: Show all headlines of all levels, but no body text. 3. SHOW ALL: Show everything. - When called with two `C-u C-u' prefixes, switch to the startup visibility, + With a double \\[universal-argument] prefix argument, switch to the startup visibility, determined by the variable `org-startup-folded', and by any VISIBILITY properties in the buffer. - When called with three `C-u C-u C-u' prefixed, show the entire buffer, - including any drawers. + With a triple \\[universal-argument] prefix argument, show the entire buffer, including any drawers. - When inside a table, re-align the table and move to the next field. @@ -104,7 +104,7 @@ in special contexts. - Special case: if point is at the beginning of the buffer and there is no headline in line 1, this function will act as if called with prefix arg - (C-u TAB, same as S-TAB) also when called without prefix arg. + (\\[universal-argument] TAB, same as S-TAB) also when called without prefix arg. But only if also the variable `org-cycle-global-at-bob' is t. \(fn &optional ARG)" t nil) @@ -147,16 +147,16 @@ call CMD. (autoload 'org-store-link "org" "\ \\Store an org-link to the current location. This link is added to `org-stored-links' and can later be inserted -into an org-buffer with \\[org-insert-link]. +into an Org buffer with \\[org-insert-link]. -For some link types, a prefix arg is interpreted. -For links to Usenet articles, arg negates `org-gnus-prefer-web-links'. -For file links, arg negates `org-context-in-file-links'. +For some link types, a prefix ARG is interpreted. +For links to Usenet articles, ARG negates `org-gnus-prefer-web-links'. +For file links, ARG negates `org-context-in-file-links'. -A double prefix arg force skipping storing functions that are not +A double prefix ARG force skipping storing functions that are not part of Org's core. -A triple prefix arg force storing a link for each line in the +A triple prefix ARG force storing a link for each line in the active region. \(fn ARG)" t nil) @@ -224,7 +224,7 @@ Call the customize function with org as argument. ;;;*** -;;;### (autoloads nil "org-agenda" "org-agenda.el" (21908 10859 0 +;;;### (autoloads nil "org-agenda" "org-agenda.el" (22216 31924 0 ;;;;;; 0)) ;;; Generated autoloads from org-agenda.el @@ -450,7 +450,7 @@ Do we have a reason to ignore this TODO entry because it has a time stamp? (autoload 'org-agenda-set-restriction-lock "org-agenda" "\ Set restriction lock for agenda, to current subtree or file. Restriction will be the file if TYPE is `file', or if type is the -universal prefix '(4), or if the cursor is before the first headline +universal prefix \\='(4), or if the cursor is before the first headline in the file. Otherwise, restriction will be to the current subtree. \(fn &optional TYPE)" t nil) @@ -477,9 +477,9 @@ calling the function returns nil. This function takes one argument: an entry from `org-agenda-get-day-entries'. FILTER can also be an alist with the car of each cell being -either 'headline or 'category. For example: +either `headline' or `category'. For example: - '((headline \"IMPORTANT\") + \\='((headline \"IMPORTANT\") (category \"Work\")) will only add headlines containing IMPORTANT or headlines @@ -498,7 +498,7 @@ to override `appt-message-warning-time'. ;;;*** -;;;### (autoloads nil "org-capture" "org-capture.el" (21908 10859 +;;;### (autoloads nil "org-capture" "org-capture.el" (22216 31924 ;;;;;; 0 0)) ;;; Generated autoloads from org-capture.el @@ -541,7 +541,7 @@ Set `org-capture-templates' to be similar to `org-remember-templates'. ;;;*** -;;;### (autoloads nil "org-colview" "org-colview.el" (21908 10858 +;;;### (autoloads nil "org-colview" "org-colview.el" (22216 31924 ;;;;;; 0 0)) ;;; Generated autoloads from org-colview.el @@ -605,7 +605,7 @@ Turn on or update column view in the agenda. ;;;*** -;;;### (autoloads nil "org-compat" "org-compat.el" (21908 10857 0 +;;;### (autoloads nil "org-compat" "org-compat.el" (22216 31924 0 ;;;;;; 0)) ;;; Generated autoloads from org-compat.el @@ -616,7 +616,23 @@ Try very hard to provide sensible version strings. ;;;*** -;;;### (autoloads nil "org-macs" "org-macs.el" (21908 10859 0 0)) +;;;### (autoloads nil "org-lint" "org-lint.el" (22216 31924 0 0)) +;;; Generated autoloads from org-lint.el + +(autoload 'org-lint "org-lint" "\ +Check current Org buffer for syntax mistakes. + +By default, run all checkers. With a single prefix ARG \\[universal-argument], +select one category of checkers only. With a double prefix +\\[universal-argument] \\[universal-argument], select one precise checker by its name. + +ARG can also be a list of checker names, as symbols, to run. + +\(fn &optional ARG)" t nil) + +;;;*** + +;;;### (autoloads nil "org-macs" "org-macs.el" (22216 31924 0 0)) ;;; Generated autoloads from org-macs.el (autoload 'org-load-noerror-mustsuffix "org-macs" "\ @@ -626,7 +642,7 @@ Load FILE with optional arguments NOERROR and MUSTSUFFIX. Drop the MUSTSUFFIX a ;;;*** -;;;### (autoloads nil "org-version" "org-version.el" (21908 10860 +;;;### (autoloads nil "org-version" "org-version.el" (22216 31924 ;;;;;; 0 0)) ;;; Generated autoloads from org-version.el @@ -647,30 +663,33 @@ The location of ODT styles.") ;;;*** -;;;### (autoloads nil nil ("ob-C.el" "ob-R.el" "ob-asymptote.el" -;;;;;; "ob-awk.el" "ob-calc.el" "ob-clojure.el" "ob-comint.el" "ob-core.el" -;;;;;; "ob-css.el" "ob-ditaa.el" "ob-dot.el" "ob-emacs-lisp.el" -;;;;;; "ob-eval.el" "ob-exp.el" "ob-fortran.el" "ob-gnuplot.el" -;;;;;; "ob-haskell.el" "ob-io.el" "ob-java.el" "ob-js.el" "ob-keys.el" -;;;;;; "ob-latex.el" "ob-ledger.el" "ob-lilypond.el" "ob-lisp.el" -;;;;;; "ob-lob.el" "ob-makefile.el" "ob-matlab.el" "ob-maxima.el" -;;;;;; "ob-mscgen.el" "ob-ocaml.el" "ob-octave.el" "ob-org.el" "ob-perl.el" -;;;;;; "ob-picolisp.el" "ob-plantuml.el" "ob-python.el" "ob-ref.el" -;;;;;; "ob-ruby.el" "ob-sass.el" "ob-scala.el" "ob-scheme.el" "ob-screen.el" -;;;;;; "ob-sh.el" "ob-shen.el" "ob-sql.el" "ob-sqlite.el" "ob-table.el" -;;;;;; "ob-tangle.el" "ob.el" "org-archive.el" "org-attach.el" "org-bbdb.el" -;;;;;; "org-bibtex.el" "org-clock.el" "org-crypt.el" "org-ctags.el" -;;;;;; "org-datetree.el" "org-docview.el" "org-element.el" "org-entities.el" -;;;;;; "org-eshell.el" "org-faces.el" "org-feed.el" "org-footnote.el" -;;;;;; "org-gnus.el" "org-habit.el" "org-id.el" "org-indent.el" -;;;;;; "org-info.el" "org-inlinetask.el" "org-install.el" "org-irc.el" -;;;;;; "org-list.el" "org-loaddefs.el" "org-macro.el" "org-mhe.el" -;;;;;; "org-mobile.el" "org-mouse.el" "org-pcomplete.el" "org-pkg.el" -;;;;;; "org-plot.el" "org-protocol.el" "org-rmail.el" "org-src.el" -;;;;;; "org-table.el" "org-timer.el" "org-w3m.el" "ox-ascii.el" -;;;;;; "ox-beamer.el" "ox-html.el" "ox-icalendar.el" "ox-latex.el" -;;;;;; "ox-man.el" "ox-md.el" "ox-odt.el" "ox-org.el" "ox-publish.el" -;;;;;; "ox-texinfo.el" "ox.el") (21908 10861 443967 0)) +;;;### (autoloads nil nil ("ob-C.el" "ob-J.el" "ob-R.el" "ob-abc.el" +;;;;;; "ob-asymptote.el" "ob-awk.el" "ob-calc.el" "ob-clojure.el" +;;;;;; "ob-comint.el" "ob-coq.el" "ob-core.el" "ob-css.el" "ob-ditaa.el" +;;;;;; "ob-dot.el" "ob-ebnf.el" "ob-emacs-lisp.el" "ob-eval.el" +;;;;;; "ob-exp.el" "ob-forth.el" "ob-fortran.el" "ob-gnuplot.el" +;;;;;; "ob-groovy.el" "ob-haskell.el" "ob-io.el" "ob-java.el" "ob-js.el" +;;;;;; "ob-keys.el" "ob-latex.el" "ob-ledger.el" "ob-lilypond.el" +;;;;;; "ob-lisp.el" "ob-lob.el" "ob-makefile.el" "ob-matlab.el" +;;;;;; "ob-maxima.el" "ob-mscgen.el" "ob-ocaml.el" "ob-octave.el" +;;;;;; "ob-org.el" "ob-perl.el" "ob-picolisp.el" "ob-plantuml.el" +;;;;;; "ob-processing.el" "ob-python.el" "ob-ref.el" "ob-ruby.el" +;;;;;; "ob-sass.el" "ob-scala.el" "ob-scheme.el" "ob-screen.el" +;;;;;; "ob-sed.el" "ob-shell.el" "ob-shen.el" "ob-sql.el" "ob-sqlite.el" +;;;;;; "ob-stan.el" "ob-table.el" "ob-tangle.el" "ob.el" "org-archive.el" +;;;;;; "org-attach.el" "org-bbdb.el" "org-bibtex.el" "org-clock.el" +;;;;;; "org-crypt.el" "org-ctags.el" "org-datetree.el" "org-docview.el" +;;;;;; "org-element.el" "org-entities.el" "org-eshell.el" "org-faces.el" +;;;;;; "org-feed.el" "org-footnote.el" "org-gnus.el" "org-habit.el" +;;;;;; "org-id.el" "org-indent.el" "org-info.el" "org-inlinetask.el" +;;;;;; "org-install.el" "org-irc.el" "org-list.el" "org-loaddefs.el" +;;;;;; "org-macro.el" "org-mhe.el" "org-mobile.el" "org-mouse.el" +;;;;;; "org-pcomplete.el" "org-pkg.el" "org-plot.el" "org-protocol.el" +;;;;;; "org-rmail.el" "org-src.el" "org-table.el" "org-timer.el" +;;;;;; "org-w3m.el" "ox-ascii.el" "ox-beamer.el" "ox-html.el" "ox-icalendar.el" +;;;;;; "ox-latex.el" "ox-man.el" "ox-md.el" "ox-odt.el" "ox-org.el" +;;;;;; "ox-publish.el" "ox-texinfo.el" "ox.el") (22216 31924 500733 +;;;;;; 0)) ;;;*** diff --git a/elpa/org-20150629/org-bbdb.el b/elpa/org-20160215/org-bbdb.el similarity index 99% rename from elpa/org-20150629/org-bbdb.el rename to elpa/org-20160215/org-bbdb.el index cfd5b3b6..aeee35f7 100644 --- a/elpa/org-20150629/org-bbdb.el +++ b/elpa/org-20160215/org-bbdb.el @@ -1,6 +1,6 @@ ;;; org-bbdb.el --- Support for links to BBDB entries from within Org-mode -;; Copyright (C) 2004-2014 Free Software Foundation, Inc. +;; Copyright (C) 2004-2016 Free Software Foundation, Inc. ;; Authors: Carsten Dominik ;; Thomas Baumann @@ -37,7 +37,7 @@ ;; the diary using bbdb-anniv.el. ;; ;; Put the following in /somewhere/at/home/diary.org and make sure -;; that this file is in `org-agenda-files` +;; that this file is in `org-agenda-files'. ;; ;; %%(org-bbdb-anniversaries) ;; diff --git a/elpa/org-20150629/org-bibtex.el b/elpa/org-20160215/org-bibtex.el similarity index 95% rename from elpa/org-20150629/org-bibtex.el rename to elpa/org-20160215/org-bibtex.el index 75ac69ba..a1cd8b09 100644 --- a/elpa/org-20150629/org-bibtex.el +++ b/elpa/org-20160215/org-bibtex.el @@ -1,6 +1,6 @@ ;;; org-bibtex.el --- Org links to BibTeX entries ;; -;; Copyright (C) 2007-2014 Free Software Foundation, Inc. +;; Copyright (C) 2007-2016 Free Software Foundation, Inc. ;; ;; Authors: Bastien Guerry ;; Carsten Dominik @@ -195,7 +195,7 @@ (:howpublished . "How something strange has been published. The first word should be capitalized.") (:institution . "The sponsoring institution of a technical report.") (:journal . "A journal name.") - (:key . "Used for alphabetizing, cross-referencing, and creating a label when the author information is missing. This field should not be confused with the key that appears in the \cite command and at the beginning of the database entry.") + (:key . "Used for alphabetizing, cross-referencing, and creating a label when the author information is missing. This field should not be confused with the key that appears in the \\cite command and at the beginning of the database entry.") (:month . "The month in which the work was published or, for an unpublished work, in which it was written. You should use the standard three-letter abbreviation,") (:note . "Any additional information that can help the reader. The first word should be capitalized.") (:number . "Any additional information that can help the reader. The first word should be capitalized.") @@ -221,7 +221,7 @@ (defcustom org-bibtex-prefix nil "Optional prefix for all bibtex property names. -For example setting to 'BIB_' would allow interoperability with fireforg." +For example setting to `BIB_' would allow interoperability with fireforg." :group 'org-bibtex :version "24.1" :type '(choice @@ -264,26 +264,39 @@ IDs must be unique." (defcustom org-bibtex-tags-are-keywords nil "Convert the value of the keywords field to tags and vice versa. -If set to t, comma-separated entries in a bibtex entry's keywords -field will be converted to org tags. Note: spaces will be escaped -with underscores, and characters that are not permitted in org + +When non-nil, comma-separated entries in a bibtex entry's keywords +field will be converted to Org tags. Note: spaces will be escaped +with underscores, and characters that are not permitted in Org tags will be removed. -If t, local tags in an org entry will be exported as a -comma-separated string of keywords when exported to bibtex. Tags -defined in `org-bibtex-tags' or `org-bibtex-no-export-tags' will -not be exported." +When non-nil, local tags in an Org entry will be exported as +a comma-separated string of keywords when exported to bibtex. +If `org-bibtex-inherit-tags' is non-nil, inherited tags will also +be exported as keywords. Tags defined in `org-bibtex-tags' or +`org-bibtex-no-export-tags' will not be exported." :group 'org-bibtex :version "24.1" :type 'boolean) (defcustom org-bibtex-no-export-tags nil "List of tag(s) that should not be converted to keywords. -This variable is relevant only if `org-bibtex-tags-are-keywords' is t." +This variable is relevant only if `org-bibtex-tags-are-keywords' +is non-nil." :group 'org-bibtex :version "24.1" :type '(repeat :tag "Tag" (string))) +(defcustom org-bibtex-inherit-tags nil + "Controls whether inherited tags are converted to bibtex keywords. +It is relevant only if `org-bibtex-tags-are-keywords' is non-nil. +Tag inheritence itself is controlled by `org-use-tag-inheritence' +and `org-exclude-tags-from-inheritence'." + :group 'org-bibtex + :version "25.1" + :package-version '(Org . "8.3") + :type 'boolean) + (defcustom org-bibtex-type-property-name "btype" "Property in which to store bibtex entry type (e.g., article)." :group 'org-bibtex @@ -332,7 +345,9 @@ This variable is relevant only if `org-bibtex-tags-are-keywords' is t." (append org-bibtex-tags org-bibtex-no-export-tags)) tag)) - (org-get-local-tags-at)))))) + (if org-bibtex-inherit-tags + (org-get-tags-at) + (org-get-local-tags-at))))))) (when type (let ((entry (format "@%s{%s,\n%s\n}\n" type id @@ -534,14 +549,16 @@ With optional argument OPTIONAL, also prompt for optional fields." ;;; Bibtex <-> Org-mode headline translation functions -(defun org-bibtex (&optional filename) +(defun org-bibtex (filename) "Export each headline in the current file to a bibtex entry. Headlines are exported using `org-bibtex-headline'." (interactive (list (read-file-name "Bibtex file: " nil nil nil - (file-name-nondirectory - (concat (file-name-sans-extension (buffer-file-name)) ".bib"))))) + (let ((file (buffer-file-name (buffer-base-buffer)))) + (and file + (file-name-nondirectory + (concat (file-name-sans-extension file) ".bib"))))))) (let ((error-point (catch 'bib (let ((bibtex-entries @@ -633,7 +650,7 @@ This uses `bibtex-parse-entry'." (defun org-bibtex-read-buffer (buffer) "Read all bibtex entries in BUFFER and save to `org-bibtex-entries'. Return the number of saved entries." - (interactive "bbuffer: ") + (interactive "bBuffer: ") (let ((start-length (length org-bibtex-entries))) (with-current-buffer buffer (save-excursion @@ -643,12 +660,12 @@ Return the number of saved entries." (org-bibtex-read) (bibtex-beginning-of-entry)))) (let ((added (- (length org-bibtex-entries) start-length))) - (message "parsed %d entries" added) + (message "Parsed %d entries" added) added))) (defun org-bibtex-read-file (file) "Read FILE with `org-bibtex-read-buffer'." - (interactive "ffile: ") + (interactive "fFile: ") (org-bibtex-read-buffer (find-file-noselect file 'nowarn 'rawfile))) (defun org-bibtex-write () @@ -694,7 +711,7 @@ Return the number of saved entries." (defun org-bibtex-import-from-file (file) "Read bibtex entries from FILE and insert as Org-mode headlines after point." - (interactive "ffile: ") + (interactive "fFile: ") (dotimes (_ (org-bibtex-read-file file)) (save-excursion (org-bibtex-write)) (re-search-forward org-property-end-re) diff --git a/elpa/org-20150629/org-capture.el b/elpa/org-20160215/org-capture.el similarity index 96% rename from elpa/org-20150629/org-capture.el rename to elpa/org-20160215/org-capture.el index 88d7ee5a..5052ad81 100644 --- a/elpa/org-20150629/org-capture.el +++ b/elpa/org-20160215/org-capture.el @@ -1,6 +1,6 @@ ;;; org-capture.el --- Fast note taking in Org-mode -;; Copyright (C) 2010-2014 Free Software Foundation, Inc. +;; Copyright (C) 2010-2016 Free Software Foundation, Inc. ;; Author: Carsten Dominik ;; Keywords: outlines, hypermedia, calendar, wp @@ -53,7 +53,7 @@ (declare-function org-datetree-find-date-create "org-datetree" (date &optional keep-restriction)) -(declare-function org-table-get-specials "org-table" ()) +(declare-function org-table-analyze "org-table" ()) (declare-function org-table-goto-line "org-table" (N)) (declare-function org-pop-to-buffer-same-window "org-compat" (&optional buffer-or-name norecord label)) @@ -64,6 +64,7 @@ (defvar org-remember-default-headline) (defvar org-remember-templates) (defvar org-table-hlines) +(defvar org-table-current-begin-pos) (defvar dired-buffers) (defvar org-capture-clock-was-started nil @@ -123,7 +124,8 @@ target Specification of where the captured item should be placed. 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, function, or Emacs Lisp - form. + form. When an absolute path is not specified for a + target, it is taken as relative to `org-directory'. Valid values are: @@ -201,7 +203,7 @@ properties are: :clock-resume Start the interrupted clock when finishing the capture. Note that :clock-keep has precedence over :clock-resume. - When setting both to `t', the current clock will run and + When setting both to t, the current clock will run and the previous one will not be resumed. :unnarrowed Do not narrow the target buffer, simply show the @@ -434,7 +436,9 @@ Turning on this mode runs the normal hook `org-capture-mode-hook'." nil " Rem" org-capture-mode-map (org-set-local 'header-line-format - "Capture buffer. Finish `C-c C-c', refile `C-c C-w', abort `C-c C-k'.")) + (substitute-command-keys + "\\Capture buffer. Finish \\[org-capture-finalize], \ +refile \\[org-capture-refile], abort \\[org-capture-kill]."))) (define-key org-capture-mode-map "\C-c\C-c" 'org-capture-finalize) (define-key org-capture-mode-map "\C-c\C-k" 'org-capture-kill) (define-key org-capture-mode-map "\C-c\C-w" 'org-capture-refile) @@ -459,7 +463,7 @@ For example, if you have a capture template \"c\" and you want this template to be accessible only from `message-mode' buffers, use this: - '((\"c\" ((in-mode . \"message-mode\")))) + \\='((\"c\" ((in-mode . \"message-mode\")))) Here are the available contexts definitions: @@ -477,7 +481,7 @@ accessible if there is at least one valid check. You can also bind a key to another agenda custom command depending on contextual rules. - '((\"c\" \"d\" ((in-mode . \"message-mode\")))) + \\='((\"c\" \"d\" ((in-mode . \"message-mode\")))) Here it means: in `message-mode buffers', use \"c\" as the key for the capture template otherwise associated with \"d\". @@ -789,7 +793,10 @@ already gone. Any prefix argument will be passed to the refile command." "Refiling from a capture buffer makes only sense for `entry'-type templates")) (let ((pos (point)) (base (buffer-base-buffer (current-buffer))) - (org-refile-for-capture t)) + (org-refile-for-capture t) + (kill-buffer (org-capture-get :kill-buffer 'local))) + (org-capture-put :kill-buffer nil) + (org-capture-finalize) (save-window-excursion (with-current-buffer (or base (current-buffer)) (save-excursion @@ -797,7 +804,7 @@ already gone. Any prefix argument will be passed to the refile command." (widen) (goto-char pos) (call-interactively 'org-refile))))) - (org-capture-finalize))) + (when kill-buffer (kill-buffer base)))) (defun org-capture-kill () "Abort the current capture process." @@ -812,7 +819,8 @@ already gone. Any prefix argument will be passed to the refile command." "Go to the location where the last capture note was stored." (interactive) (org-goto-marker-or-bmk org-capture-last-stored-marker - "org-capture-last-stored") + (plist-get org-bookmark-names-plist + :last-capture)) (message "This is the last note stored by a capture process")) ;;; Supporting functions for handling the process @@ -822,7 +830,7 @@ already gone. Any prefix argument will be passed to the refile command." (org-capture-put :initial-target-region ;; Check if the buffer is currently narrowed - (when (/= (buffer-size) (- (point-max) (point-min))) + (when (org-buffer-narrowed-p) (cons (point-min) (point-max)))) ;; store the current point (org-capture-put :initial-target-position (point))) @@ -965,12 +973,15 @@ Store them in the capture property list." (defun org-capture-expand-file (file) "Expand functions and symbols for FILE. When FILE is a function, call it. When it is a form, evaluate -it. When it is a variable, retrieve the value. Return whatever we get." +it. When it is a variable, retrieve the value. When it is +a string, return it. However, if it is the empty string, return +`org-default-notes-file' instead." (cond + ((equal file "") org-default-notes-file) ((org-string-nw-p file) file) ((functionp file) (funcall file)) ((and (symbolp file) (boundp file)) (symbol-value file)) - ((and file (consp file)) (eval file)) + ((consp file) (eval file)) (t file))) (defun org-capture-target-buffer (file) @@ -999,7 +1010,7 @@ may have been stored before." (org-switch-to-buffer-other-window (org-capture-get-indirect-buffer (org-capture-get :buffer) "CAPTURE")) (widen) - (show-all) + (outline-show-all) (goto-char (org-capture-get :pos)) (org-set-local 'org-capture-target-marker (point-marker)) @@ -1022,9 +1033,9 @@ may have been stored before." (target-entry-p (org-capture-get :target-entry-p)) level beg end file) + (and (org-capture-get :exact-position) + (goto-char (org-capture-get :exact-position))) (cond - ((org-capture-get :exact-position) - (goto-char (org-capture-get :exact-position))) ((not target-entry-p) ;; Insert as top-level entry, either at beginning or at end of file (setq level 1) @@ -1074,21 +1085,18 @@ may have been stored before." (t (setq beg (1+ (point-at-eol)) end (save-excursion (outline-next-heading) (point))))) + (setq ind nil) (if (org-capture-get :prepend) (progn (goto-char beg) - (if (org-list-search-forward (org-item-beginning-re) end t) - (progn - (goto-char (match-beginning 0)) - (setq ind (org-get-indentation))) - (goto-char end) - (setq ind 0))) + (when (org-list-search-forward (org-item-beginning-re) end t) + (goto-char (match-beginning 0)) + (setq ind (org-get-indentation)))) (goto-char end) - (if (org-list-search-backward (org-item-beginning-re) beg t) - (progn - (setq ind (org-get-indentation)) - (org-end-of-item)) - (setq ind 0)))) + (when (org-list-search-backward (org-item-beginning-re) beg t) + (setq ind (org-get-indentation)) + (org-end-of-item))) + (unless ind (goto-char end))) ;; Remove common indentation (setq txt (org-remove-indentation txt)) ;; Make sure this is indeed an item @@ -1096,17 +1104,22 @@ may have been stored before." (setq txt (concat "- " (mapconcat 'identity (split-string txt "\n") "\n ")))) + ;; Prepare surrounding empty lines. + (org-capture-empty-lines-before) + (setq beg (point)) + (unless (eolp) (save-excursion (insert "\n"))) + (unless ind + (org-indent-line) + (setq ind (org-get-indentation)) + (delete-region beg (point))) ;; Set the correct indentation, depending on context (setq ind (make-string ind ?\ )) (setq txt (concat ind (mapconcat 'identity (split-string txt "\n") (concat "\n" ind)) "\n")) - ;; Insert, with surrounding empty lines - (org-capture-empty-lines-before) - (setq beg (point)) + ;; Insert item. (insert txt) - (or (bolp) (insert "\n")) (org-capture-empty-lines-after 1) (org-capture-position-for-last-stored beg) (forward-char 1) @@ -1148,21 +1161,23 @@ may have been stored before." ;; Check if the template is good (if (not (string-match org-table-dataline-regexp txt)) (setq txt "| %?Bad template |\n")) + (if (functionp table-line-pos) + (setq table-line-pos (funcall table-line-pos)) + (setq table-line-pos (eval table-line-pos))) (cond ((and table-line-pos (string-match "\\(I+\\)\\([-+][0-9]\\)" table-line-pos)) ;; we have a complex line specification - (goto-char (point-min)) - (let ((nh (- (match-end 1) (match-beginning 1))) - (delta (string-to-number (match-string 2 table-line-pos))) - ll) + (let ((ll (ignore-errors + (save-match-data (org-table-analyze)) + (aref org-table-hlines + (- (match-end 1) (match-beginning 1))))) + (delta (string-to-number (match-string 2 table-line-pos)))) ;; The user wants a special position in the table - (org-table-get-specials) - (setq ll (ignore-errors (aref org-table-hlines nh))) - (unless ll (error "Invalid table line specification \"%s\"" - table-line-pos)) - (setq ll (+ ll delta (if (< delta 0) 0 -1))) - (org-goto-line ll) + (unless ll + (error "Invalid table line specification \"%s\"" table-line-pos)) + (goto-char org-table-current-begin-pos) + (forward-line (+ ll delta (if (< delta 0) 0 -1))) (org-table-insert-row 'below) (beginning-of-line 1) (delete-region (point) (1+ (point-at-eol))) @@ -1215,7 +1230,7 @@ Of course, if exact position has been required, just put it there." ;; we should place the text into this entry (if (org-capture-get :prepend) ;; Skip meta data and drawers - (org-end-of-meta-data-and-drawers) + (org-end-of-meta-data t) ;; go to ent of the entry text, before the next headline (outline-next-heading))) (t @@ -1581,8 +1596,7 @@ The template may still contain \"%?\" for cursor positioning." (unless template (setq template "") (message "No template") (ding) (sit-for 1)) (save-window-excursion - (delete-other-windows) - (org-pop-to-buffer-same-window (get-buffer-create "*Capture*")) + (org-switch-to-buffer-other-window (get-buffer-create "*Capture*")) (erase-buffer) (insert template) (goto-char (point-min)) @@ -1600,7 +1614,7 @@ The template may still contain \"%?\" for cursor positioning." (delete-region start end) (condition-case error (insert-file-contents filename) - (error (insert (format "%%![Couldn't insert %s: %s]" + (error (insert (format "%%![Couldn not insert %s: %s]" filename error))))))) ;; The current time diff --git a/elpa/org-20150629/org-clock.el b/elpa/org-20160215/org-clock.el similarity index 84% rename from elpa/org-20150629/org-clock.el rename to elpa/org-20160215/org-clock.el index a772f03d..143f7495 100644 --- a/elpa/org-20150629/org-clock.el +++ b/elpa/org-20160215/org-clock.el @@ -1,6 +1,6 @@ ;;; org-clock.el --- The time clocking code for Org-mode -;; Copyright (C) 2004-2014 Free Software Foundation, Inc. +;; Copyright (C) 2004-2016 Free Software Foundation, Inc. ;; Author: Carsten Dominik ;; Keywords: outlines, hypermedia, calendar, wp @@ -35,7 +35,9 @@ (declare-function calendar-iso-to-absolute "cal-iso" (&optional date)) (declare-function notifications-notify "notifications" (&rest params)) (declare-function org-pop-to-buffer-same-window "org-compat" (&optional buffer-or-name norecord label)) -(declare-function org-refresh-properties "org" (dprop tprop)) +(declare-function org-element-property "org-element" (property element)) +(declare-function org-element-type "org-element" (element)) +(declare-function org-table-goto-line "org-table" (n)) (defvar org-time-stamp-formats) (defvar org-ts-what) (defvar org-frame-title-format-backup frame-title-format) @@ -45,19 +47,26 @@ :tag "Org Clock" :group 'org-progress) -(defcustom org-clock-into-drawer org-log-into-drawer - "Should clocking info be wrapped into a drawer? -When t, clocking info will always be inserted into a :LOGBOOK: drawer. -If necessary, the drawer will be created. -When nil, the drawer will not be created, but used when present. -When an integer and the number of clocking entries in an item -reaches or exceeds this number, a drawer will be created. -When a string, it names the drawer to be used. - -The default for this variable is the value of `org-log-into-drawer', -which see." +(defcustom org-clock-into-drawer t + "Non-nil when clocking info should be wrapped into a drawer. + +When non-nil, clocking info will be inserted into the same drawer +as log notes (see variable `org-log-into-drawer'), if it exists, +or \"LOGBOOK\" otherwise. If necessary, the drawer will be +created. + +When an integer, the drawer is created only when the number of +clocking entries in an item reaches or exceeds this value. + +When a string, it becomes the name of the drawer, ignoring the +log notes drawer altogether. + +Do not check directly this variable in a Lisp program. Call +function `org-clock-into-drawer' instead." :group 'org-todo :group 'org-clock + :version "25.1" + :package-version '(Org . "8.3") :type '(choice (const :tag "Always" t) (const :tag "Only when drawer exists" nil) @@ -66,26 +75,29 @@ which see." (string :tag "Into Drawer named..."))) (defun org-clock-into-drawer () - "Return the value of `org-clock-into-drawer', but let properties overrule. + "Value of `org-clock-into-drawer'. but let properties overrule. + If the current entry has or inherits a CLOCK_INTO_DRAWER -property, it will be used instead of the default value; otherwise -if the current entry has or inherits a LOG_INTO_DRAWER property, -it will be used instead of the default value. -The default is the value of the customizable variable `org-clock-into-drawer', -which see." - (let ((p (org-entry-get nil "CLOCK_INTO_DRAWER" 'inherit)) - (q (org-entry-get nil "LOG_INTO_DRAWER" 'inherit))) - (cond - ((or (not (or p q)) (equal p "nil") (equal q "nil")) org-clock-into-drawer) - ((or (equal p "t") (equal q "t")) "LOGBOOK") - ((not p) q) - (t p)))) +property, it will be used instead of the default value. + +Return value is either a string, an integer, or nil." + (let ((p (org-entry-get nil "CLOCK_INTO_DRAWER" 'inherit t))) + (cond ((equal p "nil") nil) + ((equal p "t") (or (org-log-into-drawer) "LOGBOOK")) + ((org-string-nw-p p) + (if (org-string-match-p "\\`[0-9]+\\'" p) (string-to-number p) p)) + ((org-string-nw-p org-clock-into-drawer)) + ((integerp org-clock-into-drawer) org-clock-into-drawer) + ((not org-clock-into-drawer) nil) + ((org-log-into-drawer)) + (t "LOGBOOK")))) (defcustom org-clock-out-when-done t "When non-nil, clock will be stopped when the clocked entry is marked DONE. +\\\ DONE here means any DONE-like state. A nil value means clock will keep running until stopped explicitly with -`C-c C-x C-o', or until the clock is started in a different item. +`\\[org-clock-out]', or until the clock is started in a different item. Instead of t, this can also be a list of TODO states that should trigger clocking out." :group 'org-clock @@ -389,8 +401,8 @@ nil current clock is not displayed" (defcustom org-clock-frame-title-format '(t org-mode-line-string) "The value for `frame-title-format' when clocking in. -When `org-clock-clocked-in-display' is set to 'frame-title -or 'both, clocking in will replace `frame-title-format' with +When `org-clock-clocked-in-display' is set to `frame-title' +or `both', clocking in will replace `frame-title-format' with this value. Clocking out will restore `frame-title-format'. `org-frame-title-string' is a format string using the same @@ -413,6 +425,26 @@ if you are using Debian." :package-version '(Org . "8.0") :type 'string) +(defcustom org-clock-goto-before-context 2 + "Number of lines of context to display before currently clocked-in entry. +This applies when using `org-clock-goto'." + :group 'org-clock + :type 'integer) + +(defcustom org-clock-display-default-range 'thisyear + "Default range when displaying clocks with `org-clock-display'." + :group 'org-clock + :type '(choice (const today) + (const yesterday) + (const thisweek) + (const lastweek) + (const thismonth) + (const lastmonth) + (const thisyear) + (const lastyear) + (const untilnow) + (const :tag "Select range interactively" interactive))) + (defvar org-clock-in-prepare-hook nil "Hook run when preparing the clock. This hook is run before anything happens to the task that @@ -430,6 +462,28 @@ to add an effort property.") (defvar org-clock-has-been-used nil "Has the clock been used during the current Emacs session?") +(defconst org-clock--oldest-date + (let* ((dichotomy + (lambda (min max pred) + (if (funcall pred min) min + (incf min) + (while (> (- max min) 1) + (let ((mean (+ (ash min -1) (ash max -1) (logand min max 1)))) + (if (funcall pred mean) (setq max mean) (setq min mean))))) + max)) + (high + (funcall dichotomy + most-negative-fixnum + 0 + (lambda (m) (ignore-errors (decode-time (list m 0)))))) + (low + (funcall dichotomy + most-negative-fixnum + 0 + (lambda (m) (ignore-errors (decode-time (list high m))))))) + (list high low)) + "Internal time for oldest date representable on the system.") + ;;; The clock for measuring work time. (defvar org-mode-line-string "") @@ -503,6 +557,13 @@ of a different task.") (mapc (lambda (m) (org-check-and-save-marker m beg end)) org-clock-history)) +(defun org-clock-drawer-name () + "Return clock drawer's name for current entry, or nil." + (let ((drawer (org-clock-into-drawer))) + (cond ((integerp drawer) (org-log-into-drawer)) + ((stringp drawer) drawer) + (t nil)))) + (defun org-clocking-buffer () "Return the clocking buffer if we are currently clocking a task or nil." (marker-buffer org-clock-marker)) @@ -559,6 +620,7 @@ of a different task.") (fit-window-to-buffer nil nil (if (< chl 10) chl (+ 5 chl))) (message (or prompt "Select task for clocking:")) (setq cursor-type nil rpl (read-char-exclusive)) + (kill-buffer) (cond ((eq rpl ?q) nil) ((eq rpl ?x) nil) @@ -717,8 +779,9 @@ Notification is shown only once." (unless org-clock-notification-was-shown (setq org-clock-notification-was-shown t) (org-notify - (format "Task '%s' should be finished by now. (%s)" - org-clock-heading org-clock-effort) org-clock-sound)) + (format-message "Task `%s' should be finished by now. (%s)" + org-clock-heading org-clock-effort) + org-clock-sound)) (setq org-clock-notification-was-shown nil))))) (defun org-notify (notification &optional play-sound) @@ -775,11 +838,12 @@ If CLOCK-SOUND is non-nil, it overrides `org-clock-sound'." "Search through the given file and find all open clocks." (let ((buf (or (get-file-buffer file) (find-file-noselect file))) + (org-clock-re (concat org-clock-string " \\(\\[.*?\\]\\)$")) clocks) (with-current-buffer buf (save-excursion (goto-char (point-min)) - (while (re-search-forward "CLOCK: \\(\\[.*?\\]\\)$" nil t) + (while (re-search-forward org-clock-re nil t) (push (cons (copy-marker (match-end 1) t) (org-time-string-to-time (match-string 1))) clocks)))) clocks)) @@ -811,7 +875,7 @@ This macro also protects the current active clock from being altered." (org-clock-effort) (org-clock-marker (car ,clock)) (org-clock-hd-marker (save-excursion - (outline-back-to-heading t) + (org-back-to-heading t) (point-marker)))) ,@forms))) (def-edebug-spec org-with-clock (form body)) @@ -884,7 +948,7 @@ If necessary, clock-out of the currently active clock." (defun org-clock-jump-to-current-clock (&optional effective-clock) (interactive) - (let ((org-clock-into-drawer (org-clock-into-drawer)) + (let ((drawer (org-clock-into-drawer)) (clock (or effective-clock (cons org-clock-marker org-clock-start-time)))) (unless (marker-buffer (car clock)) @@ -892,23 +956,18 @@ If necessary, clock-out of the currently active clock." (org-with-clock clock (org-clock-goto)) (with-current-buffer (marker-buffer (car clock)) (goto-char (car clock)) - (if org-clock-into-drawer - (let ((logbook - (if (stringp org-clock-into-drawer) - (concat ":" org-clock-into-drawer ":") - ":LOGBOOK:"))) - (ignore-errors - (outline-flag-region - (save-excursion - (outline-back-to-heading t) - (search-forward logbook) - (goto-char (match-beginning 0))) - (save-excursion - (outline-back-to-heading t) - (search-forward logbook) - (search-forward ":END:") - (goto-char (match-end 0))) - nil))))))) + (when drawer + (org-with-wide-buffer + (let ((drawer-re (format "^[ \t]*:%s:[ \t]*$" + (regexp-quote (if (stringp drawer) drawer "LOGBOOK")))) + (beg (save-excursion (org-back-to-heading t) (point)))) + (catch 'exit + (while (re-search-backward drawer-re beg t) + (let ((element (org-element-at-point))) + (when (eq (org-element-type element) 'drawer) + (when (> (org-element-property :end element) (car clock)) + (org-flag-drawer nil element)) + (throw 'exit nil))))))))))) (defun org-clock-resolve (clock &optional prompt-fn last-valid fail-quietly) "Resolve an open org-mode clock. @@ -937,7 +996,7 @@ was started." (org-clock-jump-to-current-clock clock)) (unless org-clock-resolve-expert (with-output-to-temp-buffer "*Org Clock*" - (princ "Select a Clock Resolution Command: + (princ (format-message "Select a Clock Resolution Command: i/q Ignore this question; the same as keeping all the idle time. @@ -947,7 +1006,7 @@ k/K Keep X minutes of the idle time (default is all). If this clocked back in at the present time. g/G Indicate that you \"got back\" X minutes ago. This is quite - different from 'k': it clocks you out from the beginning of + different from `k': it clocks you out from the beginning of the idle period and clock you back in X minutes ago. s/S Subtract the idle time from the current clock. This is the @@ -959,7 +1018,7 @@ C Cancel the open timer altogether. It will be as though you j/J Jump to the current clock, to make manual adjustments. For all these options, using uppercase makes your final state -to be CLOCKED OUT."))) +to be CLOCKED OUT.")))) (org-fit-window-to-buffer (get-buffer-window "*Org Clock*")) (let (char-pressed) (when (featurep 'xemacs) @@ -1046,9 +1105,9 @@ If `only-dangling-p' is non-nil, only ask to resolve dangling (lambda (clock) (format "Dangling clock started %d mins ago" - (floor - (/ (- (org-float-time (current-time)) - (org-float-time (cdr clock))) 60)))))) + (floor (- (org-float-time) + (org-float-time (cdr clock))) + 60))))) (or last-valid (cdr clock))))))))))) @@ -1132,7 +1191,9 @@ time as the start time \(see `org-clock-continuously' to make this the default behavior.)" (interactive "P") (setq org-clock-notification-was-shown nil) - (org-refresh-properties org-effort-property 'org-effort) + (org-refresh-properties + org-effort-property '((effort . identity) + (effort-minutes . org-duration-string-to-minutes))) (catch 'abort (let ((interrupting (and (not org-clock-resolving-clocks-due-to-idleness) (org-clocking-p))) @@ -1234,7 +1295,7 @@ make this the default behavior.)" (looking-at (concat "^[ \t]*" org-clock-string " \\[\\([0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\}" - " *\\sw+\.? +[012][0-9]:[0-5][0-9]\\)\\][ \t]*$"))) + " *\\sw+.? +[012][0-9]:[0-5][0-9]\\)\\][ \t]*$"))) (message "Matched %s" (match-string 1)) (setq ts (concat "[" (match-string 1) "]")) (goto-char (match-end 1)) @@ -1323,8 +1384,7 @@ With three universal prefix arguments, interactively prompt for a todo state to switch to, overriding the existing value `org-clock-in-switch-to-state'." (interactive "P") - (if (equal arg '(4)) - (org-clock-in (org-clock-select-task)) + (if (equal arg '(4)) (org-clock-in arg) (let ((start-time (if (or org-clock-continuously (equal arg '(16))) (or org-clock-out-time (org-current-time org-clock-rounding-minutes t)) @@ -1370,10 +1430,12 @@ decides which time to use." (current-time)) ((equal cmt "today") (setq org--msg-extra "showing today's task time.") - (let* ((dt (decode-time (current-time)))) - (setq dt (append (list 0 0 0) (nthcdr 3 dt))) - (if org-extend-today-until - (setf (nth 2 dt) org-extend-today-until)) + (let* ((dt (decode-time)) + (hour (nth 2 dt)) + (day (nth 3 dt))) + (if (< hour org-extend-today-until) (setf (nth 3 dt) (1- day))) + (setf (nth 2 dt) org-extend-today-until) + (setq dt (append (list 0 0) (nthcdr 2 dt))) (apply 'encode-time dt))) ((or (equal cmt "all") (and (or (not cmt) (equal cmt "auto")) @@ -1395,87 +1457,92 @@ When FIND-UNCLOSED is non-nil, first check if there is an unclosed clock line and position cursor in that line." (org-back-to-heading t) (catch 'exit - (let* ((org-clock-into-drawer (org-clock-into-drawer)) - (beg (save-excursion - (beginning-of-line 2) - (or (bolp) (newline)) - (point))) - (end (progn (outline-next-heading) (point))) - (re (concat "^[ \t]*" org-clock-string)) - (cnt 0) - (drawer (if (stringp org-clock-into-drawer) - org-clock-into-drawer "LOGBOOK")) - first last ind-last) - (goto-char beg) - (when (and find-unclosed - (re-search-forward - (concat "^[ \t]*" org-clock-string - " \\[\\([0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\}" - " *\\sw+ +[012][0-9]:[0-5][0-9]\\)\\][ \t]*$") - end t)) - (beginning-of-line 1) - (throw 'exit t)) - (when (eobp) (newline) (setq end (max (point) end))) - (when (re-search-forward (concat "^[ \t]*:" drawer ":") end t) - ;; we seem to have a CLOCK drawer, so go there. - (beginning-of-line 2) - (or org-log-states-order-reversed - (and (re-search-forward org-property-end-re nil t) - (goto-char (match-beginning 0)))) - (throw 'exit t)) - ;; Lets count the CLOCK lines - (goto-char beg) - (while (re-search-forward re end t) - (setq first (or first (match-beginning 0)) - last (match-beginning 0) - cnt (1+ cnt))) - (when (and (integerp org-clock-into-drawer) - last - (>= (1+ cnt) org-clock-into-drawer)) - ;; Wrap current entries into a new drawer - (goto-char last) - (setq ind-last (org-get-indentation)) - (beginning-of-line 2) - (if (and (>= (org-get-indentation) ind-last) - (org-at-item-p)) - (when (and (>= (org-get-indentation) ind-last) - (org-at-item-p)) - (let ((struct (org-list-struct))) - (goto-char (org-list-get-bottom-point struct))))) - (insert ":END:\n") - (beginning-of-line 0) - (org-indent-line-to ind-last) - (goto-char first) - (insert ":" drawer ":\n") - (beginning-of-line 0) - (org-indent-line) - (org-flag-drawer t) - (beginning-of-line 2) - (or org-log-states-order-reversed - (and (re-search-forward org-property-end-re nil t) - (goto-char (match-beginning 0)))) - (throw 'exit nil)) - + (let* ((beg (line-beginning-position)) + (end (save-excursion (outline-next-heading) (point))) + (org-clock-into-drawer (org-clock-into-drawer)) + (drawer (org-clock-drawer-name))) + ;; Look for a running clock if FIND-UNCLOSED in non-nil. + (when find-unclosed + (let ((open-clock-re + (concat "^[ \t]*" + org-clock-string + " \\[\\([0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\}" + " *\\sw+ +[012][0-9]:[0-5][0-9]\\)\\][ \t]*$"))) + (while (re-search-forward open-clock-re end t) + (let ((element (org-element-at-point))) + (when (and (eq (org-element-type element) 'clock) + (eq (org-element-property :status element) 'running)) + (beginning-of-line) + (throw 'exit t)))))) + ;; Look for an existing clock drawer. + (when drawer + (goto-char beg) + (let ((drawer-re (concat "^[ \t]*:" (regexp-quote drawer) ":[ \t]*$"))) + (while (re-search-forward drawer-re end t) + (let ((element (org-element-at-point))) + (when (eq (org-element-type element) 'drawer) + (let ((cend (org-element-property :contents-end element))) + (if (and (not org-log-states-order-reversed) cend) + (goto-char cend) + (forward-line)) + (throw 'exit t))))))) (goto-char beg) - (while (and (looking-at (concat "[ \t]*" org-keyword-time-regexp)) - (not (equal (match-string 1) org-clock-string))) - ;; Planning info, skip to after it - (beginning-of-line 2) - (or (bolp) (newline))) - (when (or (eq org-clock-into-drawer t) - (stringp org-clock-into-drawer) - (and (integerp org-clock-into-drawer) - (< org-clock-into-drawer 2))) - (insert ":" drawer ":\n:END:\n") - (beginning-of-line -1) - (org-indent-line) - (org-flag-drawer t) - (beginning-of-line 2) - (org-indent-line) - (beginning-of-line) - (or org-log-states-order-reversed - (and (re-search-forward org-property-end-re nil t) - (goto-char (match-beginning 0)))))))) + (let ((clock-re (concat "^[ \t]*" org-clock-string)) + (count 0) positions first) + ;; Count the CLOCK lines and store their positions. + (save-excursion + (while (re-search-forward clock-re end t) + (let ((element (org-element-at-point))) + (when (eq (org-element-type element) 'clock) + (setq positions (cons (line-beginning-position) positions) + count (1+ count)))))) + (cond + ((null positions) + ;; Skip planning line and property drawer, if any. + (org-end-of-meta-data) + (unless (bolp) (insert "\n")) + ;; Create a new drawer if necessary. + (when (and org-clock-into-drawer + (or (not (wholenump org-clock-into-drawer)) + (< org-clock-into-drawer 2))) + (let ((beg (point))) + (insert ":" drawer ":\n:END:\n") + (org-indent-region beg (point)) + (goto-char beg) + (org-flag-drawer t) + (forward-line)))) + ;; When a clock drawer needs to be created because of the + ;; number of clock items or simply if it is missing, collect + ;; all clocks in the section and wrap them within the drawer. + ((or drawer + (and (wholenump org-clock-into-drawer) + (>= (1+ count) org-clock-into-drawer))) + ;; Skip planning line and property drawer, if any. + (org-end-of-meta-data) + (let ((beg (point))) + (insert + (mapconcat + (lambda (p) + (save-excursion + (goto-char p) + (org-trim (delete-and-extract-region + (save-excursion (skip-chars-backward " \r\t\n") + (line-beginning-position 2)) + (line-beginning-position 2))))) + positions "\n") + "\n:END:\n") + (let ((end (point-marker))) + (goto-char beg) + (save-excursion (insert ":" drawer ":\n")) + (org-flag-drawer t) + (org-indent-region (point) end) + (forward-line) + (unless org-log-states-order-reversed + (goto-char end) + (beginning-of-line -1)) + (set-marker end nil)))) + (org-log-states-order-reversed (goto-char (car (last positions)))) + (t (goto-char (car positions)))))))) ;;;###autoload (defun org-clock-out (&optional switch-to-state fail-quietly at-time) @@ -1563,11 +1630,14 @@ to, overriding the existing value of `org-clock-out-switch-to-state'." (message (concat "Clock stopped at %s after " (org-minutes-to-clocksum-string (+ (* 60 h) m)) "%s") te (if remove " => LINE REMOVED" "")) - (let ((h org-clock-out-hook)) + (let ((h org-clock-out-hook) + (clock-drawer (org-clock-into-drawer))) ;; If a closing note needs to be stored in the drawer ;; where clocks are stored, let's temporarily disable - ;; `org-clock-remove-empty-clock-drawer' - (if (and (equal org-clock-into-drawer org-log-into-drawer) + ;; `org-clock-remove-empty-clock-drawer'. + (if (and clock-drawer + (not (stringp clock-drawer)) + (org-log-into-drawer) (eq org-log-done 'note) org-clock-out-when-done) (setq h (delq 'org-clock-remove-empty-clock-drawer h))) @@ -1577,20 +1647,19 @@ to, overriding the existing value of `org-clock-out-switch-to-state'." (add-hook 'org-clock-out-hook 'org-clock-remove-empty-clock-drawer) -(defun org-clock-remove-empty-clock-drawer nil - "Remove empty clock drawer in the current subtree." - (let* ((olid (or (org-entry-get (point) "LOG_INTO_DRAWER") - org-log-into-drawer)) - (clock-drawer (if (eq t olid) "LOGBOOK" olid)) - (end (save-excursion (org-end-of-subtree t t)))) - (when clock-drawer - (save-excursion - (org-back-to-heading t) - (while (and (< (point) end) - (search-forward clock-drawer end t)) - (goto-char (match-beginning 0)) - (org-remove-empty-drawer-at clock-drawer (point)) - (forward-line 1)))))) +(defun org-clock-remove-empty-clock-drawer () + "Remove empty clock drawers in current subtree." + (save-excursion + (org-back-to-heading t) + (org-map-tree + (lambda () + (let ((drawer (org-clock-drawer-name)) + (case-fold-search t)) + (when drawer + (let ((re (format "^[ \t]*:%s:[ \t]*$" (regexp-quote drawer))) + (end (save-excursion (outline-next-heading)))) + (while (re-search-forward re end t) + (org-remove-empty-drawer-at (point)))))))))) (defun org-clock-timestamps-up (&optional n) "Increase CLOCK timestamps at cursor. @@ -1606,7 +1675,7 @@ Optional argument N tells to change by that many units." (defun org-clock-timestamps-change (updown &optional n) "Change CLOCK timestamps synchronously at cursor. -UPDOWN tells whether to change 'up or 'down. +UPDOWN tells whether to change `up' or `down'. Optional argument N tells to change by that many units." (setq org-ts-what nil) (when (org-at-timestamp-p t) @@ -1653,12 +1722,13 @@ Optional argument N tells to change by that many units." (setq frame-title-format org-frame-title-format-backup) (force-mode-line-update) (error "No active clock")) - (save-excursion ; Do not replace this with `with-current-buffer'. + (save-excursion ; Do not replace this with `with-current-buffer'. (org-no-warnings (set-buffer (org-clocking-buffer))) (goto-char org-clock-marker) - (if (org-looking-back (concat "^[ \t]*" org-clock-string ".*")) + (if (org-looking-back (concat "^[ \t]*" org-clock-string ".*") + (line-beginning-position)) (progn (delete-region (1- (point-at-bol)) (point-at-eol)) - (org-remove-empty-drawer-at "LOGBOOK" (point))) + (org-remove-empty-drawer-at (point))) (message "Clock gone, cancel the timer anyway") (sit-for 2))) (move-marker org-clock-marker nil) @@ -1670,12 +1740,6 @@ Optional argument N tells to change by that many units." (message "Clock canceled") (run-hooks 'org-clock-cancel-hook)) -(defcustom org-clock-goto-before-context 2 - "Number of lines of context to display before currently clocked-in entry. -This applies when using `org-clock-goto'." - :group 'org-clock - :type 'integer) - ;;;###autoload (defun org-clock-goto (&optional select) "Go to the currently clocked-in entry, or to the most recently clocked one. @@ -1711,9 +1775,22 @@ With prefix arg SELECT, offer recently clocked tasks for selection." (defun org-clock-sum-today (&optional headline-filter) "Sum the times for each subtree for today." - (interactive) (let ((range (org-clock-special-range 'today))) - (org-clock-sum (car range) (cadr range) nil :org-clock-minutes-today))) + (org-clock-sum (car range) (cadr range) + headline-filter :org-clock-minutes-today))) + +(defun org-clock-sum-custom (&optional headline-filter range propname) + "Sum the times for each subtree for today." + (let ((r (or (and (symbolp range) (org-clock-special-range range)) + (org-clock-special-range + (intern (completing-read + "Range: " + '("today" "yesterday" "thisweek" "lastweek" + "thismonth" "lastmonth" "thisyear" "lastyear" + "interactive") + nil t)))))) + (org-clock-sum (car r) (cadr r) + headline-filter (or propname :org-clock-minutes-custom)))) ;;;###autoload (defun org-clock-sum (&optional tstart tend headline-filter propname) @@ -1724,7 +1801,6 @@ HEADLINE-FILTER is a zero-arg function that, if specified, is called for each headline in the time range with point at the headline. Headlines for which HEADLINE-FILTER returns nil are excluded from the clock summation. PROPNAME lets you set a custom text property instead of :org-clock-minutes." - (interactive) (org-with-silent-modifications (let* ((re (concat "^\\(\\*+\\)[ \t]\\|^[ \t]*" org-clock-string @@ -1782,6 +1858,8 @@ PROPNAME lets you set a custom text property instead of :org-clock-minutes." (save-excursion (save-match-data (funcall headline-filter)))))) (setq level (- (match-end 1) (match-beginning 1))) + (when (>= level lmax) + (setq ltimes (vconcat ltimes (make-vector lmax 0)) lmax (* 2 lmax))) (when (or (> t1 0) (> (aref ltimes level) 0)) (when (or headline-included headline-forced) (if headline-included @@ -1814,59 +1892,83 @@ PROPNAME lets you set a custom text property instead of :org-clock-minutes." org-clock-file-total-minutes))) ;;;###autoload -(defun org-clock-display (&optional total-only) +(defun org-clock-display (&optional arg) "Show subtree times in the entire buffer. -If TOTAL-ONLY is non-nil, only show the total time for the entire file -in the echo area. + +By default, show the total time for the range defined in +`org-clock-display-default-range'. With \\[universal-argument] \ +prefix, show +the total time for today instead. With \\[universal-argument] \ +\\[universal-argument] prefix, use +a custom range, entered at the prompt. With \\[universal-argument] \ +\\[universal-argument] \\[universal-argument] +prefix, display the total time in the echo area. Use \\[org-clock-remove-overlays] to remove the subtree times." - (interactive) + (interactive "P") (org-clock-remove-overlays) - (let (time h m p) - (org-clock-sum) - (unless total-only + (let* ((todayp (equal arg '(4))) + (customp (member arg '((16) today yesterday + thisweek lastweek thismonth + lastmonth thisyear lastyear + untilnow interactive))) + (prop (cond ((not arg) :org-clock-minutes-default) + (todayp :org-clock-minutes-today) + (customp :org-clock-minutes-custom) + (t :org-clock-minutes))) + time h m p) + (cond ((not arg) (org-clock-sum-custom + nil org-clock-display-default-range prop)) + (todayp (org-clock-sum-today)) + (customp (org-clock-sum-custom nil arg)) + (t (org-clock-sum))) + (unless (eq arg '(64)) (save-excursion (goto-char (point-min)) (while (or (and (equal (setq p (point)) (point-min)) - (get-text-property p :org-clock-minutes)) + (get-text-property p prop)) (setq p (next-single-property-change - (point) :org-clock-minutes))) + (point) prop))) (goto-char p) - (when (setq time (get-text-property p :org-clock-minutes)) - (org-clock-put-overlay time (funcall outline-level)))) + (when (setq time (get-text-property p prop)) + (org-clock-put-overlay time))) (setq h (/ org-clock-file-total-minutes 60) m (- org-clock-file-total-minutes (* 60 h))) ;; Arrange to remove the overlays upon next change. (when org-remove-highlights-with-change (org-add-hook 'before-change-functions 'org-clock-remove-overlays nil 'local)))) - (message (concat "Total file time: " - (org-minutes-to-clocksum-string org-clock-file-total-minutes) - " (%d hours and %d minutes)") h m))) + (message (concat (format "Total file time%s: " + (cond (todayp " for today") + (customp " (custom)") + (t ""))) + (org-minutes-to-clocksum-string + org-clock-file-total-minutes) + " (%d hours and %d minutes)") + h m))) (defvar org-clock-overlays nil) (make-variable-buffer-local 'org-clock-overlays) -(defun org-clock-put-overlay (time &optional level) +(defun org-clock-put-overlay (time) "Put an overlays on the current line, displaying TIME. -If LEVEL is given, prefix time with a corresponding number of stars. This creates a new overlay and stores it in `org-clock-overlays', so that it will be easy to remove." - (let* ((l (if level (org-get-valid-level level 0) 0)) - ov tx) + (let (ov tx) (beginning-of-line) (when (looking-at org-complex-heading-regexp) (goto-char (match-beginning 4))) (setq ov (make-overlay (point) (point-at-eol)) tx (concat (buffer-substring-no-properties (point) (match-end 4)) - (make-string - (max 0 (- (- 60 (current-column)) - (- (match-end 4) (match-beginning 4)) - (length (org-get-at-bol 'line-prefix)))) ?.) - (org-add-props (concat (make-string l ?*) " " - (org-minutes-to-clocksum-string time) - (make-string (- 16 l) ?\ )) - (list 'face 'org-clock-overlay)) + (org-add-props + (make-string + (max 0 (- (- 60 (current-column)) + (- (match-end 4) (match-beginning 4)) + (length (org-get-at-bol 'line-prefix)))) ?·) + '(face shadow)) + (org-add-props + (format " %9s " (org-minutes-to-clocksum-string time)) + '(face org-clock-overlay)) "")) (if (not (featurep 'xemacs)) (overlay-put ov 'display tx) @@ -1929,7 +2031,7 @@ fontified, and then returned." (org-mode) (org-create-dblock props) (org-update-dblock) - (font-lock-fontify-buffer) + (org-font-lock-ensure) (forward-line 2) (buffer-substring (point) (progn (re-search-forward "^[ \t]*#\\+END" nil t) @@ -2018,127 +2120,159 @@ buffer and update it." (defun org-clock-special-range (key &optional time as-strings wstart mstart) "Return two times bordering a special time range. -Key is a symbol specifying the range and can be one of `today', `yesterday', -`thisweek', `lastweek', `thismonth', `lastmonth', `thisyear', `lastyear'. -By default, a week starts Monday 0:00 and ends Sunday 24:00. -The range is determined relative to TIME, which defaults to current time. -The return value is a cons cell with two internal times like the ones -returned by `current time' or `encode-time'. -If AS-STRINGS is non-nil, the returned times will be formatted strings. -If WSTART is non-nil, use this number to specify the starting day of a -week (monday is 1). -If MSTART is non-nil, use this number to specify the starting day of a -month (1 is the first day of the month). -If you can combine both, the month starting day will have priority." - (if (integerp key) (setq key (intern (number-to-string key)))) - (let* ((tm (decode-time (or time (current-time)))) - (s 0) (m (nth 1 tm)) (h (nth 2 tm)) - (d (nth 3 tm)) (month (nth 4 tm)) (y (nth 5 tm)) + +KEY is a symbol specifying the range and can be one of `today', +`yesterday', `thisweek', `lastweek', `thismonth', `lastmonth', +`thisyear', `lastyear' or `untilnow'. If set to `interactive', +user is prompted for range boundaries. It can be a string or an +integer. + +By default, a week starts Monday 0:00 and ends Sunday 24:00. The +range is determined relative to TIME, which defaults to current +time. + +The return value is a list containing two internal times, one for +the beginning of the range and one for its end, like the ones +returned by `current time' or `encode-time' and a string used to +display information. If AS-STRINGS is non-nil, the returned +times will be formatted strings. + +If WSTART is non-nil, use this number to specify the starting day +of a week (monday is 1). If MSTART is non-nil, use this number +to specify the starting day of a month (1 is the first day of the +month). If you can combine both, the month starting day will +have priority." + (let* ((tm (decode-time time)) + (m (nth 1 tm)) + (h (nth 2 tm)) + (d (nth 3 tm)) + (month (nth 4 tm)) + (y (nth 5 tm)) (dow (nth 6 tm)) - (ws (or wstart 1)) - (ms (or mstart 1)) - (skey (symbol-name key)) + (skey (format "%s" key)) (shift 0) - (q (cond ((>= (nth 4 tm) 10) 4) - ((>= (nth 4 tm) 7) 3) - ((>= (nth 4 tm) 4) 2) - ((>= (nth 4 tm) 1) 1))) - s1 m1 h1 d1 month1 y1 diff ts te fm txt w date - interval tmp shiftedy shiftedm shiftedq) + (q (cond ((>= month 10) 4) + ((>= month 7) 3) + ((>= month 4) 2) + (t 1))) + m1 h1 d1 month1 y1 shiftedy shiftedm shiftedq) (cond - ((string-match "^[0-9]+$" skey) - (setq y (string-to-number skey) m 1 d 1 key 'year)) - ((string-match "^\\([0-9]+\\)-\\([0-9]\\{1,2\\}\\)$" skey) + ((string-match "\\`[0-9]+\\'" skey) + (setq y (string-to-number skey) month 1 d 1 key 'year)) + ((string-match "\\`\\([0-9]+\\)-\\([0-9]\\{1,2\\}\\)\\'" skey) (setq y (string-to-number (match-string 1 skey)) month (string-to-number (match-string 2 skey)) - d 1 key 'month)) - ((string-match "^\\([0-9]+\\)-[wW]\\([0-9]\\{1,2\\}\\)$" skey) + d 1 + key 'month)) + ((string-match "\\`\\([0-9]+\\)-[wW]\\([0-9]\\{1,2\\}\\)\\'" skey) (require 'cal-iso) - (setq y (string-to-number (match-string 1 skey)) - w (string-to-number (match-string 2 skey))) - (setq date (calendar-gregorian-from-absolute - (calendar-iso-to-absolute (list w 1 y)))) - (setq d (nth 1 date) month (car date) y (nth 2 date) - dow 1 - key 'week)) - ((string-match "^\\([0-9]+\\)-[qQ]\\([1-4]\\)$" skey) + (let ((date (calendar-gregorian-from-absolute + (calendar-iso-to-absolute + (list (string-to-number (match-string 2 skey)) + 1 + (string-to-number (match-string 1 skey))))))) + (setq d (nth 1 date) + month (car date) + y (nth 2 date) + dow 1 + key 'week))) + ((string-match "\\`\\([0-9]+\\)-[qQ]\\([1-4]\\)\\'" skey) (require 'cal-iso) - (setq y (string-to-number (match-string 1 skey))) (setq q (string-to-number (match-string 2 skey))) - (setq date (calendar-gregorian-from-absolute - (calendar-iso-to-absolute (org-quarter-to-date q y)))) - (setq d (nth 1 date) month (car date) y (nth 2 date) - dow 1 - key 'quarter)) - ((string-match "^\\([0-9]+\\)-\\([0-9]\\{1,2\\}\\)-\\([0-9]\\{1,2\\}\\)$" skey) + (let ((date (calendar-gregorian-from-absolute + (calendar-iso-to-absolute + (org-quarter-to-date + q (string-to-number (match-string 1 skey))))))) + (setq d (nth 1 date) + month (car date) + y (nth 2 date) + dow 1 + key 'quarter))) + ((string-match + "\\`\\([0-9]+\\)-\\([0-9]\\{1,2\\}\\)-\\([0-9]\\{1,2\\}\\)\\'" + skey) (setq y (string-to-number (match-string 1 skey)) month (string-to-number (match-string 2 skey)) d (string-to-number (match-string 3 skey)) key 'day)) - ((string-match "\\([-+][0-9]+\\)$" skey) + ((string-match "\\([-+][0-9]+\\)\\'" skey) (setq shift (string-to-number (match-string 1 skey)) - key (intern (substring skey 0 (match-beginning 1)))) - (if (and (memq key '(quarter thisq)) (> shift 0)) - (error "Looking forward with quarters isn't implemented")))) - + key (intern (substring skey 0 (match-beginning 1)))) + (when (and (memq key '(quarter thisq)) (> shift 0)) + (error "Looking forward with quarters isn't implemented")))) (when (= shift 0) - (cond ((eq key 'yesterday) (setq key 'today shift -1)) - ((eq key 'lastweek) (setq key 'week shift -1)) - ((eq key 'lastmonth) (setq key 'month shift -1)) - ((eq key 'lastyear) (setq key 'year shift -1)) - ((eq key 'lastq) (setq key 'quarter shift -1)))) - (cond - ((memq key '(day today)) - (setq d (+ d shift) h 0 m 0 h1 24 m1 0)) - ((memq key '(week thisweek)) - (setq diff (+ (* -7 shift) (if (= dow 0) (- 7 ws) (- dow ws))) - m 0 h 0 d (- d diff) d1 (+ 7 d))) - ((memq key '(month thismonth)) - (setq d (or ms 1) h 0 m 0 d1 (or ms 1) - month (+ month shift) month1 (1+ month) h1 0 m1 0)) - ((memq key '(quarter thisq)) - ;; Compute if this shift remains in this year. If not, compute - ;; how many years and quarters we have to shift (via floor*) and - ;; compute the shifted years, months and quarters. - (cond - ((< (+ (- q 1) shift) 0) ; shift not in this year - (setq interval (* -1 (+ (- q 1) shift))) - ;; Set tmp to ((years to shift) (quarters to shift)). - (setq tmp (org-floor* interval 4)) - ;; Due to the use of floor, 0 quarters actually means 4. - (if (= 0 (nth 1 tmp)) - (setq shiftedy (- y (nth 0 tmp)) - shiftedm 1 - shiftedq 1) - (setq shiftedy (- y (+ 1 (nth 0 tmp))) - shiftedm (- 13 (* 3 (nth 1 tmp))) - shiftedq (- 5 (nth 1 tmp)))) - (setq d 1 h 0 m 0 d1 1 month shiftedm month1 (+ 3 shiftedm) h1 0 m1 0 y shiftedy)) - ((> (+ q shift) 0) ; shift is within this year - (setq shiftedq (+ q shift)) - (setq shiftedy y) - (setq d 1 h 0 m 0 d1 1 month (+ 1 (* 3 (- (+ q shift) 1))) month1 (+ 4 (* 3 (- (+ q shift) 1))) h1 0 m1 0)))) - ((memq key '(year thisyear)) - (setq m 0 h 0 d 1 month 1 y (+ y shift) y1 (1+ y))) - (t (error "No such time block %s" key))) - (setq ts (encode-time s m h d month y) - te (encode-time (or s1 s) (or m1 m) (or h1 h) - (or d1 d) (or month1 month) (or y1 y))) - (setq fm (cdr org-time-stamp-formats)) - (cond - ((memq key '(day today)) - (setq txt (format-time-string "%A, %B %d, %Y" ts))) - ((memq key '(week thisweek)) - (setq txt (format-time-string "week %G-W%V" ts))) - ((memq key '(month thismonth)) - (setq txt (format-time-string "%B %Y" ts))) - ((memq key '(year thisyear)) - (setq txt (format-time-string "the year %Y" ts))) - ((memq key '(quarter thisq)) - (setq txt (concat (org-count-quarter shiftedq) " quarter of " (number-to-string shiftedy))))) - (if as-strings - (list (format-time-string fm ts) (format-time-string fm te) txt) - (list ts te txt)))) + (case key + (yesterday (setq key 'today shift -1)) + (lastweek (setq key 'week shift -1)) + (lastmonth (setq key 'month shift -1)) + (lastyear (setq key 'year shift -1)) + (lastq (setq key 'quarter shift -1)))) + ;; Prepare start and end times depending on KEY's type. + (case key + ((day today) (setq m 0 h 0 h1 24 d (+ d shift))) + ((week thisweek) + (let* ((ws (or wstart 1)) + (diff (+ (* -7 shift) (if (= dow 0) (- 7 ws) (- dow ws))))) + (setq m 0 h 0 d (- d diff) d1 (+ 7 d)))) + ((month thismonth) + (setq h 0 m 0 d (or mstart 1) month (+ month shift) month1 (1+ month))) + ((quarter thisq) + ;; Compute if this shift remains in this year. If not, compute + ;; how many years and quarters we have to shift (via floor*) and + ;; compute the shifted years, months and quarters. + (cond + ((< (+ (- q 1) shift) 0) ; Shift not in this year. + (let* ((interval (* -1 (+ (- q 1) shift))) + ;; Set tmp to ((years to shift) (quarters to shift)). + (tmp (org-floor* interval 4))) + ;; Due to the use of floor, 0 quarters actually means 4. + (if (= 0 (nth 1 tmp)) + (setq shiftedy (- y (nth 0 tmp)) + shiftedm 1 + shiftedq 1) + (setq shiftedy (- y (+ 1 (nth 0 tmp))) + shiftedm (- 13 (* 3 (nth 1 tmp))) + shiftedq (- 5 (nth 1 tmp))))) + (setq m 0 h 0 d 1 month shiftedm month1 (+ 3 shiftedm) y shiftedy)) + ((> (+ q shift) 0) ; Shift is within this year. + (setq shiftedq (+ q shift)) + (setq shiftedy y) + (let ((qshift (* 3 (1- (+ q shift))))) + (setq m 0 h 0 d 1 month (+ 1 qshift) month1 (+ 4 qshift)))))) + ((year thisyear) + (setq m 0 h 0 d 1 month 1 y (+ y shift) y1 (1+ y))) + ((interactive untilnow)) ; Special cases, ignore them. + (t (user-error "No such time block %s" key))) + ;; Format start and end times according to AS-STRINGS. + (let* ((start (case key + (interactive (org-read-date nil t nil "Range start? ")) + (untilnow org-clock--oldest-date) + (t (encode-time 0 m h d month y)))) + (end (case key + (interactive (org-read-date nil t nil "Range end? ")) + (untilnow (current-time)) + (t (encode-time 0 + (or m1 m) + (or h1 h) + (or d1 d) + (or month1 month) + (or y1 y))))) + (text + (case key + ((day today) (format-time-string "%A, %B %d, %Y" start)) + ((week thisweek) (format-time-string "week %G-W%V" start)) + ((month thismonth) (format-time-string "%B %Y" start)) + ((year thisyear) (format-time-string "the year %Y" start)) + ((quarter thisq) + (concat (org-count-quarter shiftedq) + " quarter of " (number-to-string shiftedy))) + (interactive "(Range interactively set)") + (untilnow "now")))) + (if (not as-strings) (list start end text) + (let ((f (cdr org-time-stamp-formats))) + (list (format-time-string f start) + (format-time-string f end) + text)))))) (defun org-count-quarter (n) (cond @@ -2275,7 +2409,8 @@ the currently selected interval size." (setq scope (org-agenda-files t)) (setq scope (org-add-archive-files scope))) ((eq scope 'file-with-archives) - (setq scope (org-add-archive-files (list (buffer-file-name))) + (setq scope (and buffer-file-name + (org-add-archive-files (list buffer-file-name))) one-file-with-archives t))) (setq scope-is-list (and scope (listp scope))) (if scope-is-list @@ -2291,7 +2426,8 @@ the currently selected interval size." ;; Just from the current file (save-restriction ;; get the right range into the restriction - (org-agenda-prepare-buffers (list (buffer-file-name))) + (org-agenda-prepare-buffers (list (or (buffer-file-name) + (current-buffer)))) (cond ((not scope)) ; use the restriction as it is now ((eq scope 'file) (widen)) @@ -2338,6 +2474,7 @@ from the dynamic block definition." org-clock-clocktable-language-setup)) (multifile (plist-get params :multifile)) (block (plist-get params :block)) + (sort (plist-get params :sort)) (ts (plist-get params :tstart)) (te (plist-get params :tend)) (header (plist-get params :header)) @@ -2509,12 +2646,14 @@ from the dynamic block definition." ((eq formula '%) ;; compute the column where the % numbers need to go (setq pcol (+ 2 + (length properties) (if multifile 1 0) (if level-p 1 0) (if timestamp 1 0) (min maxlevel (or ntcol 100)))) ;; compute the column where the total time is (setq tcol (+ 2 + (length properties) (if multifile 1 0) (if level-p 1 0) (if timestamp 1 0))) @@ -2544,6 +2683,11 @@ from the dynamic block definition." (when org-hide-emphasis-markers ;; we need to align a second time (org-table-align)) + (when sort + (save-excursion + (org-table-goto-line 3) + (org-table-goto-column (car sort)) + (org-table-sort-lines nil (cdr sort)))) (when recalc (if (eq formula '%) (save-excursion @@ -2558,10 +2702,10 @@ from the dynamic block definition." total-time)) (defun org-clocktable-indent-string (level) + "Return indentation string according to LEVEL. +LEVEL is an integer. Indent by two spaces per level above 1." (if (= level 1) "" - (let ((str " ")) - (dotimes (k (1- level) str) - (setq str (concat "\\emsp" str)))))) + (concat "\\_" (make-string (* 2 (1- level)) ?\s)))) (defun org-clocktable-steps (params) "Step through the range to make a number of clock tables." @@ -2672,10 +2816,8 @@ TIME: The sum of all time spend in this tree, in minutes. This time (when (and te (listp te)) (setq te (format "%4d-%02d-%02d" (nth 2 te) (car te) (nth 1 te)))) ;; Now the times are strings we can parse. - (if ts (setq ts (org-float-time - (seconds-to-time (org-matcher-time ts))))) - (if te (setq te (org-float-time - (seconds-to-time (org-matcher-time te))))) + (if ts (setq ts (org-matcher-time ts))) + (if te (setq te (org-matcher-time te))) (save-excursion (org-clock-sum ts te (unless (null matcher) @@ -2815,8 +2957,8 @@ The details of what will be saved are regulated by the variable (delete-region (point-min) (point-max)) ;;Store clock (insert (format ";; org-persist.el - %s at %s\n" - system-name (format-time-string - (cdr org-time-stamp-formats)))) + (system-name) (format-time-string + (cdr org-time-stamp-formats)))) (if (and (memq org-clock-persist '(t clock)) (setq b (org-clocking-buffer)) (setq b (or (buffer-base-buffer b) b)) diff --git a/elpa/org-20150629/org-colview.el b/elpa/org-20160215/org-colview.el similarity index 79% rename from elpa/org-20150629/org-colview.el rename to elpa/org-20160215/org-colview.el index 07ee69f1..eade7257 100644 --- a/elpa/org-20150629/org-colview.el +++ b/elpa/org-20160215/org-colview.el @@ -1,6 +1,6 @@ ;;; org-colview.el --- Column View in Org-mode -;; Copyright (C) 2004-2014 Free Software Foundation, Inc. +;; Copyright (C) 2004-2016 Free Software Foundation, Inc. ;; Author: Carsten Dominik ;; Keywords: outlines, hypermedia, calendar, wp @@ -146,11 +146,15 @@ This is the compiled version of the format.") "--" ["Quit" org-columns-quit t])) +(defun org-columns--value (property pos) + "Return value for PROPERTY at buffer position POS." + (or (cdr (assoc-string property (get-text-property pos 'org-summaries) t)) + (org-entry-get pos property 'selective t))) + (defun org-columns-new-overlay (beg end &optional string face) "Create a new column overlay and add it to the list." (let ((ov (make-overlay beg end))) (overlay-put ov 'face (or face 'secondary-selection)) - (remove-text-properties 0 (length string) '(face nil) string) (org-overlay-display ov string face) (push ov org-columns-overlays) ov)) @@ -158,109 +162,113 @@ This is the compiled version of the format.") (defun org-columns-display-here (&optional props dateline) "Overlay the current line with column display." (interactive) - (let* ((fmt org-columns-current-fmt-compiled) - (beg (point-at-bol)) - (level-face (save-excursion - (beginning-of-line 1) - (and (looking-at "\\(\\**\\)\\(\\* \\)") - (org-get-level-face 2)))) - (ref-face (or level-face - (and (eq major-mode 'org-agenda-mode) - (get-text-property (point-at-bol) 'face)) - 'default)) - (color (list :foreground (face-attribute ref-face :foreground))) - (font (list :height (face-attribute 'default :height) - :family (face-attribute 'default :family))) - (face (list color font 'org-column ref-face)) - (face1 (list color font 'org-agenda-column-dateline ref-face)) - (cphr (get-text-property (point-at-bol) 'org-complex-heading-regexp)) - pom property ass width f fc string fm ov column val modval s2 title calc) - ;; Check if the entry is in another buffer. - (unless props - (if (eq major-mode 'org-agenda-mode) - (setq pom (or (org-get-at-bol 'org-hd-marker) - (org-get-at-bol 'org-marker)) - props (if pom (org-entry-properties pom) nil)) - (setq props (org-entry-properties nil)))) - ;; Walk the format - (while (setq column (pop fmt)) - (setq property (car column) - title (nth 1 column) - ass (if (equal property "ITEM") - (cons "ITEM" - ;; When in a buffer, get the whole line, - ;; we'll clean it later… - (if (derived-mode-p 'org-mode) - (save-match-data - (org-remove-tabs - (buffer-substring-no-properties - (point-at-bol) (point-at-eol)))) - ;; In agenda, just get the `txt' property - (or (org-get-at-bol 'txt) - (buffer-substring-no-properties - (point) (progn (end-of-line) (point)))))) - (assoc property props)) - width (or (cdr (assoc property org-columns-current-maxwidths)) - (nth 2 column) - (length property)) - f (format "%%-%d.%ds | " width width) - fm (nth 4 column) - fc (nth 5 column) - calc (nth 7 column) - val (or (cdr ass) "") - modval (cond ((and org-columns-modify-value-for-display-function - (functionp - org-columns-modify-value-for-display-function)) - (funcall org-columns-modify-value-for-display-function - title val)) - ((equal property "ITEM") - (org-columns-cleanup-item - val org-columns-current-fmt-compiled - (or org-complex-heading-regexp cphr))) - (fc (org-columns-number-to-string - (org-columns-string-to-number val fm) fm fc)) - ((and calc (functionp calc) - (not (string= val "")) - (not (get-text-property 0 'org-computed val))) - (org-columns-number-to-string - (funcall calc (org-columns-string-to-number - val fm)) fm)))) - (setq s2 (org-columns-add-ellipses (or modval val) width)) - (setq string (format f s2)) - ;; Create the overlay + (save-excursion + (beginning-of-line) + (let* ((level-face (and (looking-at "\\(\\**\\)\\(\\* \\)") + (org-get-level-face 2))) + (ref-face (or level-face + (and (eq major-mode 'org-agenda-mode) + (org-get-at-bol 'face)) + 'default)) + (color (list :foreground (face-attribute ref-face :foreground))) + (font (list :height (face-attribute 'default :height) + :family (face-attribute 'default :family))) + (face (list color font 'org-column ref-face)) + (face1 (list color font 'org-agenda-column-dateline ref-face)) + (pom (and (eq major-mode 'org-agenda-mode) + (or (org-get-at-bol 'org-hd-marker) + (org-get-at-bol 'org-marker)))) + (props (cond (props) + ((eq major-mode 'org-agenda-mode) + (and pom (org-entry-properties pom))) + (t (org-entry-properties))))) + ;; Each column is an overlay on top of a character. So there has + ;; to be at least as many characters available on the line as + ;; columns to display. + (let ((columns (length org-columns-current-fmt-compiled)) + (chars (- (line-end-position) (line-beginning-position)))) + (when (> columns chars) + (save-excursion + (end-of-line) + (let ((inhibit-read-only t)) + (insert (make-string (- columns chars) ?\s)))))) + ;; Walk the format. Create and install the overlay for the + ;; current column on the next character. + (dolist (column org-columns-current-fmt-compiled) + (let* ((property (car column)) + (title (nth 1 column)) + (ass (assoc-string property props t)) + (width + (or + (cdr (assoc-string property org-columns-current-maxwidths t)) + (nth 2 column) + (length property))) + (f (format "%%-%d.%ds | " width width)) + (fm (nth 4 column)) + (fc (nth 5 column)) + (calc (nth 7 column)) + (val (or (cdr ass) "")) + (modval + (cond + ((functionp org-columns-modify-value-for-display-function) + (funcall org-columns-modify-value-for-display-function + title val)) + ((equal property "ITEM") (org-columns-compact-links val)) + (fc (org-columns-number-to-string + (org-columns-string-to-number val fm) fm fc)) + ((and calc (functionp calc) + (not (string= val "")) + (not (get-text-property 0 'org-computed val))) + (org-columns-number-to-string + (funcall calc (org-columns-string-to-number val fm)) fm)))) + (string + (format f + (let ((v (org-columns-add-ellipses + (or modval val) width))) + (cond + ((equal property "PRIORITY") + (propertize v 'face (org-get-priority-face val))) + ((equal property "TAGS") + (if (not org-tags-special-faces-re) + (propertize v 'face 'org-tag) + (replace-regexp-in-string + org-tags-special-faces-re + (lambda (m) + (propertize m 'face (org-get-tag-face m))) + v nil nil 1))) + ((equal property "TODO") + (propertize v 'face (org-get-todo-face val))) + (t v))))) + (ov (org-columns-new-overlay + (point) (1+ (point)) string (if dateline face1 face)))) + (overlay-put ov 'keymap org-columns-map) + (overlay-put ov 'org-columns-key property) + (overlay-put ov 'org-columns-value (cdr ass)) + (overlay-put ov 'org-columns-value-modified modval) + (overlay-put ov 'org-columns-pom pom) + (overlay-put ov 'org-columns-format f) + (overlay-put ov 'line-prefix "") + (overlay-put ov 'wrap-prefix "") + (forward-char))) + ;; Make the rest of the line disappear. + (let ((ov (org-columns-new-overlay (point) (line-end-position)))) + (overlay-put ov 'invisible t) + (overlay-put ov 'keymap org-columns-map) + (overlay-put ov 'line-prefix "") + (overlay-put ov 'wrap-prefix "")) + (let ((ov (make-overlay (1- (line-end-position)) + (line-beginning-position 2)))) + (overlay-put ov 'keymap org-columns-map) + (push ov org-columns-overlays)) (org-with-silent-modifications - (setq ov (org-columns-new-overlay - beg (setq beg (1+ beg)) string (if dateline face1 face))) - (overlay-put ov 'keymap org-columns-map) - (overlay-put ov 'org-columns-key property) - (overlay-put ov 'org-columns-value (cdr ass)) - (overlay-put ov 'org-columns-value-modified modval) - (overlay-put ov 'org-columns-pom pom) - (overlay-put ov 'org-columns-format f) - (overlay-put ov 'line-prefix "") - (overlay-put ov 'wrap-prefix "")) - (if (or (not (char-after beg)) - (equal (char-after beg) ?\n)) - (let ((inhibit-read-only t)) - (save-excursion - (goto-char beg) - (org-unmodified (insert " ")))))) ;; FIXME: add props and remove later? - ;; Make the rest of the line disappear. - (org-unmodified - (setq ov (org-columns-new-overlay beg (point-at-eol))) - (overlay-put ov 'invisible t) - (overlay-put ov 'keymap org-columns-map) - (overlay-put ov 'intangible t) - (overlay-put ov 'line-prefix "") - (overlay-put ov 'wrap-prefix "") - (push ov org-columns-overlays) - (setq ov (make-overlay (1- (point-at-eol)) (1+ (point-at-eol)))) - (overlay-put ov 'keymap org-columns-map) - (push ov org-columns-overlays) - (let ((inhibit-read-only t)) - (put-text-property (max (point-min) (1- (point-at-bol))) - (min (point-max) (1+ (point-at-eol))) - 'read-only "Type `e' to edit property"))))) + (let ((inhibit-read-only t)) + (put-text-property + (line-end-position 0) + (line-beginning-position 2) + 'read-only + (substitute-command-keys + "Type \\\\[org-columns-edit-value] \ +to edit property"))))))) (defun org-columns-add-ellipses (string width) "Truncate STRING with WIDTH characters, with ellipses." @@ -294,7 +302,9 @@ for the duration of the command.") (while (setq column (pop fmt)) (setq property (car column) str (or (nth 1 column) property) - width (or (cdr (assoc property org-columns-current-maxwidths)) + width (or (cdr (assoc-string property + org-columns-current-maxwidths + t)) (nth 2 column) (length str)) widths (push width widths) @@ -348,29 +358,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-cleanup-item (item fmt cphr) - "Remove from ITEM what is a column in the format FMT. -CPHR is the complex heading regexp to use for parsing ITEM." - (let (fixitem) - (if (not cphr) - item - (unless (string-match "^\*+ " item) - (setq item (concat "* " item) fixitem t)) - (if (string-match cphr item) - (setq item - (concat - (org-add-props (match-string 1 item) nil - 'org-whitespace (* 2 (1- (org-reduced-level (- (match-end 1) (match-beginning 1)))))) - (and (match-end 2) (not (assoc "TODO" fmt)) (concat " " (match-string 2 item))) - (and (match-end 3) (not (assoc "PRIORITY" fmt)) (concat " " (match-string 3 item))) - " " (save-match-data (org-columns-compact-links (or (match-string 4 item) ""))) - (and (match-end 5) (not (assoc "TAGS" fmt)) (concat " " (match-string 5 item))))) - (add-text-properties - 0 (1+ (match-end 1)) - (list 'org-whitespace (* 2 (1- (org-reduced-level (- (match-end 1) (match-beginning 1)))))) - item)) - (if fixitem (replace-regexp-in-string "^\*+ " "" item) item)))) - (defun org-columns-compact-links (s) "Replace [[link][desc]] with [desc] or [link]." (while (string-match org-bracket-link-regexp s) @@ -434,7 +421,7 @@ Where possible, use the standard interface for changing this line." (value (get-char-property (point) 'org-columns-value)) (bol (point-at-bol)) (eol (point-at-eol)) (pom (or (get-text-property bol 'org-hd-marker) - (point))) ; keep despite of compiler waring + (point))) ; keep despite of compiler waring (line-overlays (delq nil (mapcar (lambda (x) (and (eq (overlay-buffer x) (current-buffer)) @@ -510,7 +497,7 @@ Where possible, use the standard interface for changing this line." (org-columns-display-here))) (org-move-to-column col) (if (and (derived-mode-p 'org-mode) - (nth 3 (assoc key org-columns-current-fmt-compiled))) + (nth 3 (assoc-string key org-columns-current-fmt-compiled t))) (org-columns-update key))))))) (defun org-edit-headline () ; FIXME: this is not columns specific. Make interactive????? Use from agenda???? @@ -561,7 +548,7 @@ Where possible, use the standard interface for changing this line." (condition-case nil (org-no-warnings (next-line 1)) (error nil)) (setq hidep (org-at-heading-p 1))) (eval form) - (and hidep (hide-entry)))) + (and hidep (outline-hide-entry)))) (defun org-columns-previous-allowed-value () "Switch to the previous allowed value for this column." @@ -579,7 +566,7 @@ an integer, select that value." (value (get-char-property (point) 'org-columns-value)) (bol (point-at-bol)) (eol (point-at-eol)) (pom (or (get-text-property bol 'org-hd-marker) - (point))) ; keep despite of compiler waring + (point))) ; keep despite of compiler waring (line-overlays (delq nil (mapcar (lambda (x) (and (eq (overlay-buffer x) (current-buffer)) @@ -589,7 +576,9 @@ an integer, select that value." org-columns-overlays))) (allowed (or (org-property-get-allowed-values pom key) (and (memq - (nth 4 (assoc key org-columns-current-fmt-compiled)) + (nth 4 (assoc-string key + org-columns-current-fmt-compiled + t)) '(checkbox checkbox-n-of-m checkbox-percent)) '("[ ]" "[X]")) (org-colview-construct-allowed-dates value))) @@ -618,7 +607,7 @@ an integer, select that value." (t (setq nval (car allowed))))) (cond ((equal major-mode 'org-agenda-mode) - (org-columns-eval '(org-entry-put pom key nval)) + (org-columns-eval `(org-entry-put ,pom ,key ,nval)) ;; The following let preserves the current format, and makes sure ;; that in only a single file things need to be updated. (let* ((org-agenda-overriding-columns-format org-columns-current-fmt) @@ -629,16 +618,16 @@ an integer, select that value." (org-agenda-columns))) (t (let ((inhibit-read-only t)) - (remove-text-properties (1- bol) eol '(read-only t)) + (remove-text-properties (max (1- bol) (point-min)) eol '(read-only t)) (unwind-protect (progn (setq org-columns-overlays (org-delete-all line-overlays org-columns-overlays)) (mapc 'delete-overlay line-overlays) - (org-columns-eval '(org-entry-put pom key nval))) + (org-columns-eval `(org-entry-put ,pom ,key ,nval))) (org-columns-display-here))) (org-move-to-column col) - (and (nth 3 (assoc key org-columns-current-fmt-compiled)) + (and (nth 3 (assoc-string key org-columns-current-fmt-compiled t)) (org-columns-update key)))))) (defun org-colview-construct-allowed-dates (s) @@ -691,11 +680,14 @@ around it." fmt)) (defun org-columns-goto-top-level () - (when (condition-case nil (org-back-to-heading) (error nil)) - (org-entry-get nil "COLUMNS" t)) - (if (marker-position org-entry-property-inherited-from) - (move-marker org-columns-top-level-marker org-entry-property-inherited-from) - (move-marker org-columns-top-level-marker (point)))) + "Move to the beginning of the column view area. +Also sets `org-columns-top-level-marker' to the new position." + (goto-char + (move-marker + org-columns-top-level-marker + (cond ((org-before-first-heading-p) (point-min)) + ((org-entry-get nil "COLUMNS" t) org-entry-property-inherited-from) + (t (org-back-to-heading) (point)))))) ;;;###autoload (defun org-columns (&optional columns-fmt-string) @@ -705,49 +697,46 @@ When COLUMNS-FMT-STRING is non-nil, use it as the column format." (org-verify-version 'columns) (org-columns-remove-overlays) (move-marker org-columns-begin-marker (point)) - (let ((org-columns-time (time-to-number-of-days (current-time))) - beg end fmt cache maxwidths) - (org-columns-goto-top-level) - (setq fmt (org-columns-get-format columns-fmt-string)) - (save-excursion - (goto-char org-columns-top-level-marker) - (setq beg (point)) - (unless org-columns-inhibit-recalculation - (org-columns-compute-all)) - (setq end (or (condition-case nil (org-end-of-subtree t t) (error nil)) - (point-max))) - ;; Get and cache the properties - (goto-char beg) + (org-columns-goto-top-level) + ;; Initialize `org-columns-current-fmt' and + ;; `org-columns-current-fmt-compiled'. + (let ((org-columns-time (time-to-number-of-days (current-time)))) + (org-columns-get-format columns-fmt-string)) + (unless org-columns-inhibit-recalculation (org-columns-compute-all)) + (save-excursion + (save-restriction + (narrow-to-region + (point) + (if (org-at-heading-p) (org-end-of-subtree t t) (point-max))) (when (assoc "CLOCKSUM" org-columns-current-fmt-compiled) - (save-excursion - (save-restriction - (narrow-to-region beg end) - (org-clock-sum)))) + (org-clock-sum)) (when (assoc "CLOCKSUM_T" org-columns-current-fmt-compiled) - (save-excursion - (save-restriction - (narrow-to-region beg end) - (org-clock-sum-today)))) - (while (re-search-forward org-outline-regexp-bol end t) - (if (and org-columns-skip-archived-trees - (looking-at (concat ".*:" org-archive-tag ":"))) - (org-end-of-subtree t) - (push (cons (org-current-line) (org-entry-properties)) cache))) - (when cache - (setq maxwidths (org-columns-get-autowidth-alist fmt cache)) - (org-set-local 'org-columns-current-maxwidths maxwidths) - (org-columns-display-here-title) - (when (org-set-local 'org-columns-flyspell-was-active - (org-bound-and-true-p flyspell-mode)) - (flyspell-mode 0)) - (unless (local-variable-p 'org-colview-initial-truncate-line-value) - (org-set-local 'org-colview-initial-truncate-line-value - truncate-lines)) - (setq truncate-lines t) - (mapc (lambda (x) - (org-goto-line (car x)) - (org-columns-display-here (cdr x))) - cache))))) + (org-clock-sum-today)) + (let* ((column-names (mapcar #'car org-columns-current-fmt-compiled)) + (cache + (org-map-entries + (lambda () + (cons (point) + (mapcar (lambda (p) + (cons p (org-columns--value p (point)))) + column-names))) + nil nil (and org-columns-skip-archived-trees 'archive)))) + (when cache + (org-set-local 'org-columns-current-maxwidths + (org-columns-get-autowidth-alist + org-columns-current-fmt + cache)) + (org-columns-display-here-title) + (when (org-set-local 'org-columns-flyspell-was-active + (org-bound-and-true-p flyspell-mode)) + (flyspell-mode 0)) + (unless (local-variable-p 'org-colview-initial-truncate-line-value) + (org-set-local 'org-colview-initial-truncate-line-value + truncate-lines)) + (setq truncate-lines t) + (dolist (x cache) + (goto-char (car x)) + (org-columns-display-here (cdr x)))))))) (eval-when-compile (defvar org-columns-time)) @@ -791,7 +780,8 @@ calc function called on every element before summarizing. This is (defun org-columns-new (&optional prop title width op fmt fun &rest rest) "Insert a new column, to the left of the current column." (interactive) - (let ((editp (and prop (assoc prop org-columns-current-fmt-compiled))) + (let ((editp (and prop + (assoc-string prop org-columns-current-fmt-compiled t))) cell) (setq prop (org-icompleting-read "Property: " (mapcar 'list (org-buffer-property-keys t nil t)) @@ -849,7 +839,9 @@ calc function called on every element before summarizing. This is (let* ((n (current-column)) (entry (nth n org-columns-current-fmt-compiled)) (width (or (nth 2 entry) - (cdr (assoc (car entry) org-columns-current-maxwidths))))) + (cdr (assoc-string (car entry) + org-columns-current-maxwidths + t))))) (setq width (max 1 (+ width arg))) (setcar (nthcdr 2 entry) width) (org-columns-store-format) @@ -900,7 +892,7 @@ display, or in the #+COLUMNS line of the current buffer." (org-entry-put nil "COLUMNS" fmt) (goto-char (point-min)) ;; Overwrite all #+COLUMNS lines.... - (while (re-search-forward "^#\\+COLUMNS:.*" nil t) + (while (re-search-forward "^[ \t]*#\\+COLUMNS:.*" nil t) (setq cnt (1+ cnt)) (replace-match (concat "#+COLUMNS: " fmt) t t)) (unless (> cnt 0) @@ -917,11 +909,14 @@ display, or in the #+COLUMNS line of the current buffer." (push (cons (match-string 1 s) 1) rtn) (setq start (match-end 0))) (mapc (lambda (x) - (setcdr x (apply 'max + (setcdr x + (apply #'max + (let ((prop (car x))) (mapcar (lambda (y) - (length (or (cdr (assoc (car x) (cdr y))) " "))) - cache)))) + (length (or (cdr (assoc-string prop (cdr y) t)) + " "))) + cache))))) rtn) rtn)) @@ -946,9 +941,11 @@ display, or in the #+COLUMNS line of the current buffer." (when (equal (overlay-get ov 'org-columns-key) property) (setq pos (overlay-start ov)) (goto-char pos) - (when (setq val (cdr (assoc property - (get-text-property - (point-at-bol) 'org-summaries)))) + (when (setq val (cdr (assoc-string + property + (get-text-property + (point-at-bol) 'org-summaries) + t))) (setq fmt (overlay-get ov 'org-columns-format)) (overlay-put ov 'org-columns-value val) (overlay-put ov 'display (format fmt val))))) @@ -962,11 +959,11 @@ display, or in the #+COLUMNS line of the current buffer." "Sum the values of property PROPERTY hierarchically, for the entire buffer." (interactive) (let* ((re org-outline-regexp-bol) - (lmax 30) ; Does anyone use deeper levels??? + (lmax 30) ; Does anyone use deeper levels??? (lvals (make-vector lmax nil)) (lflag (make-vector lmax nil)) (level 0) - (ass (assoc property org-columns-current-fmt-compiled)) + (ass (assoc-string property org-columns-current-fmt-compiled t)) (format (nth 4 ass)) (printf (nth 5 ass)) (fun (nth 6 ass)) @@ -990,24 +987,28 @@ display, or in the #+COLUMNS line of the current buffer." valflag (and val (string-match "\\S-" val))) (cond ((< level last-level) - ;; put the sum of lower levels here as a property - (setq sum (+ (if (and (/= last-level inminlevel) - (aref lvals last-level)) - (apply fun (aref lvals last-level)) 0) - (if (aref lvals inminlevel) - (apply fun (aref lvals inminlevel)) 0)) + ;; Put the sum of lower levels here as a property. If + ;; values are estimate, use an appropriate sum function. + (setq sum (funcall + (if (eq fun 'org-estimate-combine) #'org-estimate-combine + #'+) + (if (and (/= last-level inminlevel) + (aref lvals last-level)) + (apply fun (aref lvals last-level)) 0) + (if (aref lvals inminlevel) + (apply fun (aref lvals inminlevel)) 0)) flag (or (aref lflag last-level) ; any valid entries from children? (aref lflag inminlevel)) ; or inline tasks? str (org-columns-number-to-string sum format printf) str1 (org-add-props (copy-sequence str) nil 'org-computed t 'face 'bold) useval (if flag str1 (if valflag val "")) sum-alist (get-text-property sumpos 'org-summaries)) - (if (assoc property sum-alist) - (setcdr (assoc property sum-alist) useval) - (push (cons property useval) sum-alist) - (org-with-silent-modifications - (add-text-properties sumpos (1+ sumpos) - (list 'org-summaries sum-alist)))) + (let ((old (assoc-string property sum-alist t))) + (if old (setcdr old useval) + (push (cons property useval) sum-alist) + (org-with-silent-modifications + (add-text-properties sumpos (1+ sumpos) + (list 'org-summaries sum-alist))))) (when (and val (not (equal val (if flag str val)))) (org-entry-put nil property (if flag str val))) ;; add current to current level accumulator @@ -1086,7 +1087,7 @@ display, or in the #+COLUMNS line of the current buffer." (defun org-nofm-to-completion (n m &optional percent) (if (not percent) (format "[%d/%d]" n m) - (format "[%d%%]"(floor (+ 0.5 (* 100. (/ (* 1.0 n) m))))))) + (format "[%d%%]" (round (* 100.0 n) m)))) (defun org-columns-string-to-number (s fmt) @@ -1109,6 +1110,9 @@ display, or in the #+COLUMNS line of the current buffer." (while l (setq sum (+ (string-to-number (pop l)) (/ sum 60)))) sum)) + ((memq fmt '(checkbox checkbox-n-of-m checkbox-percent)) + (if (equal s "[X]") 1. 0.000001)) + ((memq fmt '(estimate)) (org-string-to-estimate s)) ((string-match (concat "\\([0-9.]+\\) *\\(" (regexp-opt (mapcar 'car org-effort-durations)) "\\)") s) @@ -1117,14 +1121,11 @@ display, or in the #+COLUMNS line of the current buffer." (while l (setq sum (+ (string-to-number (pop l)) (/ sum 60)))) sum)) - ((memq fmt '(checkbox checkbox-n-of-m checkbox-percent)) - (if (equal s "[X]") 1. 0.000001)) - ((memq fmt '(estimate)) (org-string-to-estimate s)) (t (string-to-number s))))) (defun org-columns-uncompile-format (cfmt) "Turn the compiled columns format back into a string representation." - (let ((rtn "") e s prop title op op-match width fmt printf fun calc) + (let ((rtn "") e s prop title op op-match width fmt printf fun calc ee map) (while (setq e (pop cfmt)) (setq prop (car e) title (nth 1 e) @@ -1134,8 +1135,10 @@ display, or in the #+COLUMNS line of the current buffer." printf (nth 5 e) fun (nth 6 e) calc (nth 7 e)) - (when (setq op-match (rassoc (list fmt fun calc) org-columns-compile-map)) - (setq op (car op-match))) + (setq map (copy-sequence org-columns-compile-map)) + (while (setq ee (pop map)) + (if (equal fmt (nth 1 ee)) + (setq op (car ee) map nil))) (if (and op printf) (setq op (concat op ";" printf))) (if (equal title prop) (setq title nil)) (setq s (concat "%" (if width (number-to-string width)) @@ -1146,7 +1149,8 @@ display, or in the #+COLUMNS line of the current buffer." (org-trim rtn))) (defun org-columns-compile-format (fmt) - "Turn a column format string into an alist of specifications. + "Turn a column format string FMT into an alist of specifications. + The alist has one entry for each column in the format. The elements of that list are: property the property @@ -1156,7 +1160,9 @@ operator the operator if any format the output format for computed results, derived from operator printf a printf format for computed values fun the lisp function to compute summary values, derived from operator -calc function to get values from base elements" +calc function to get values from base elements + +This function updates `org-columns-current-fmt-compiled'." (let ((start 0) width prop title op op-match f printf fun calc) (setq org-columns-current-fmt-compiled nil) (while (string-match @@ -1187,49 +1193,41 @@ calc function to get values from base elements" ;;; Dynamic block for Column view -(defvar org-heading-regexp) ; defined in org.el -(defvar org-heading-keyword-regexp-format) ; defined in org.el (defun org-columns-capture-view (&optional maxlevel skip-empty-rows) "Get the column view of the current buffer or subtree. -The first optional argument MAXLEVEL sets the level limit. A -second optional argument SKIP-EMPTY-ROWS tells whether to skip +The first optional argument MAXLEVEL sets the level limit. +A second optional argument SKIP-EMPTY-ROWS tells whether to skip empty rows, an empty row being one where all the column view -specifiers except ITEM are empty. This function returns a list +specifiers but ITEM are empty. This function returns a list containing the title row and all other rows. Each row is a list of fields." (save-excursion - (let* ((title (mapcar 'cadr org-columns-current-fmt-compiled)) - (re-comment (format org-heading-keyword-regexp-format - org-comment-string)) - (re-archive (concat ".*:" org-archive-tag ":")) - (n (length title)) row tbl) + (let* ((title (mapcar #'cadr org-columns-current-fmt-compiled)) + (has-item? (member "ITEM" title)) + (n (length title)) + tbl) (goto-char (point-min)) - (while (re-search-forward org-heading-regexp nil t) + (while (re-search-forward org-outline-regexp-bol nil t) (catch 'next (when (and (or (null maxlevel) - (>= maxlevel - (if org-odd-levels-only - (/ (1+ (length (match-string 1))) 2) - (length (match-string 1))))) + (>= maxlevel (org-reduced-level (org-outline-level)))) (get-char-property (match-beginning 0) 'org-columns-key)) - (when (save-excursion - (goto-char (point-at-bol)) - (or (looking-at re-comment) - (looking-at re-archive))) + (when (or (org-in-commented-heading-p t) + (member org-archive-tag (org-get-tags))) (org-end-of-subtree t) (throw 'next t)) - (setq row nil) - (loop for i from 0 to (1- n) do - (push - (org-quote-vert - (or (get-char-property (+ (match-beginning 0) i) 'org-columns-value-modified) - (get-char-property (+ (match-beginning 0) i) 'org-columns-value) - "")) - row)) - (setq row (nreverse row)) - (unless (and skip-empty-rows - (eq 1 (length (delete "" (delete-dups (copy-sequence row)))))) - (push row tbl))))) + (let (row) + (dotimes (i n) + (let ((col (+ (line-beginning-position) i))) + (push (org-quote-vert + (or (get-char-property col 'org-columns-value-modified) + (get-char-property col 'org-columns-value) + "")) + row))) + (unless (and skip-empty-rows + (let ((r (delete-dups (remove "" row)))) + (or (null r) (and has-item? (= (length r) 1))))) + (push (nreverse row) tbl)))))) (append (list title 'hline) (nreverse tbl))))) ;;;###autoload @@ -1377,60 +1375,73 @@ and tailing newline characters." (org-columns-remove-overlays) (move-marker org-columns-begin-marker (point)) (let ((org-columns-time (time-to-number-of-days (current-time))) - cache maxwidths m p a d fmt) - (cond - ((and (boundp 'org-agenda-overriding-columns-format) - org-agenda-overriding-columns-format) - (setq fmt org-agenda-overriding-columns-format)) - ((setq m (org-get-at-bol 'org-hd-marker)) - (setq fmt (or (org-entry-get m "COLUMNS" t) - (with-current-buffer (marker-buffer m) - org-columns-default-format)))) - ((and (boundp 'org-columns-current-fmt) - (local-variable-p 'org-columns-current-fmt) - org-columns-current-fmt) - (setq fmt org-columns-current-fmt)) - ((setq m (next-single-property-change (point-min) 'org-hd-marker)) - (setq m (get-text-property m 'org-hd-marker)) - (setq fmt (or (org-entry-get m "COLUMNS" t) - (with-current-buffer (marker-buffer m) - org-columns-default-format))))) - (setq fmt (or fmt org-columns-default-format)) + (fmt + (cond + ((org-bound-and-true-p org-agenda-overriding-columns-format)) + ((let ((m (org-get-at-bol 'org-hd-marker))) + (and m + (or (org-entry-get m "COLUMNS" t) + (with-current-buffer (marker-buffer m) + org-columns-default-format))))) + ((and (local-variable-p 'org-columns-current-fmt) + org-columns-current-fmt)) + ((let ((m (next-single-property-change (point-min) 'org-hd-marker))) + (and m + (let ((m (get-text-property m 'org-hd-marker))) + (or (org-entry-get m "COLUMNS" t) + (with-current-buffer (marker-buffer m) + org-columns-default-format)))))) + (t org-columns-default-format)))) (org-set-local 'org-columns-current-fmt fmt) (org-columns-compile-format fmt) (when org-agenda-columns-compute-summary-properties (org-agenda-colview-compute org-columns-current-fmt-compiled)) (save-excursion - ;; Get and cache the properties + ;; Collect properties for each headline in current view. (goto-char (point-min)) - (while (not (eobp)) - (when (setq m (or (org-get-at-bol 'org-hd-marker) - (org-get-at-bol 'org-marker))) - (setq p (org-entry-properties m)) - - (when (or (not (setq a (assoc org-effort-property p))) - (not (string-match "\\S-" (or (cdr a) "")))) - ;; OK, the property is not defined. Use appointment duration? - (when (and org-agenda-columns-add-appointments-to-effort-sum - (setq d (get-text-property (point) 'duration))) - (setq d (org-minutes-to-clocksum-string d)) - (put-text-property 0 (length d) 'face 'org-warning d) - (push (cons org-effort-property d) p))) - (push (cons (org-current-line) p) cache)) - (beginning-of-line 2)) - (when cache - (setq maxwidths (org-columns-get-autowidth-alist fmt cache)) - (org-set-local 'org-columns-current-maxwidths maxwidths) - (org-columns-display-here-title) - (when (org-set-local 'org-columns-flyspell-was-active - (org-bound-and-true-p flyspell-mode)) - (flyspell-mode 0)) - (mapc (lambda (x) - (org-goto-line (car x)) - (org-columns-display-here (cdr x))) - cache) - (when org-agenda-columns-show-summaries - (org-agenda-colview-summarize cache)))))) + (let (cache) + (let ((names (mapcar #'car org-columns-current-fmt-compiled)) m) + (while (not (eobp)) + (when (setq m (or (org-get-at-bol 'org-hd-marker) + (org-get-at-bol 'org-marker))) + (push + (cons + (line-beginning-position) + (org-with-point-at m + (mapcar + (lambda (name) + (let ((value (org-columns--value name (point)))) + (cons + name + (if (and org-agenda-columns-add-appointments-to-effort-sum + (not value) + (eq (compare-strings name nil nil + org-effort-property nil nil + t) + t) + ;; Effort property is not defined. Try + ;; to use appointment duration. + (get-text-property (point) 'duration)) + (org-propertize + (org-minutes-to-clocksum-string + (get-text-property (point) 'duration)) + 'face 'org-warning) + value)))) + names))) + cache)) + (forward-line))) + (when cache + (org-set-local 'org-columns-current-maxwidths + (org-columns-get-autowidth-alist fmt cache)) + (org-columns-display-here-title) + (when (org-set-local 'org-columns-flyspell-was-active + (org-bound-and-true-p flyspell-mode)) + (flyspell-mode 0)) + (dolist (x cache) + (goto-char (car x)) + (org-columns-display-here (cdr x))) + (when org-agenda-columns-show-summaries + (org-agenda-colview-summarize cache))))))) (defun org-agenda-colview-summarize (cache) "Summarize the summarizable columns in column view in the agenda. @@ -1478,7 +1489,7 @@ This will add overlays to the date lines, to show the summary for each day." (t ;; do the summary (setq lsum nil) (dolist (x entries) - (setq v (cdr (assoc prop x))) + (setq v (cdr (assoc-string prop x t))) (if v (push (funcall @@ -1529,8 +1540,9 @@ This will add overlays to the date lines, to show the summary for each day." ((equal (car fm) "CLOCKSUM_T") (org-clock-sum-today)) ((and (nth 4 fm) - (setq a (assoc (car fm) - org-columns-current-fmt-compiled)) + (setq a (assoc-string (car fm) + org-columns-current-fmt-compiled + t)) (equal (nth 4 a) (nth 4 fm))) (org-columns-compute (car fm))))))))))) @@ -1547,7 +1559,10 @@ This will add overlays to the date lines, to show the summary for each day." (defun org-estimate-mean-and-var (v) "Return the mean and variance of an estimate." - (let* ((low (float (car v))) + (let* ((v (cond ((consp v) v) + ((numberp v) (list v v)) + (t (error "Invalid estimate type")))) + (low (float (car v))) (high (float (cadr v))) (mean (/ (+ low high) 2.0)) (var (/ (+ (expt (- mean low) 2.0) (expt (- high mean) 2.0)) 2.0))) @@ -1570,8 +1585,11 @@ and variances (respectively) of the individual estimates." (defun org-estimate-print (e &optional fmt) "Prepare a string representation of an estimate. This formats these numbers as two numbers with a \"-\" between them." - (if (null fmt) (set 'fmt "%.0f")) - (format "%s" (mapconcat (lambda (n) (format fmt n)) e "-"))) + (let ((fmt (or fmt "%.0f")) + (e (cond ((consp e) e) + ((numberp e) (list e e)) + (t (error "Invalid estimate type"))))) + (format "%s" (mapconcat (lambda (n) (format fmt n)) e "-")))) (defun org-string-to-estimate (s) "Convert a string to an estimate. diff --git a/elpa/org-20150629/org-compat.el b/elpa/org-20160215/org-compat.el similarity index 93% rename from elpa/org-20150629/org-compat.el rename to elpa/org-20160215/org-compat.el index 90380a88..70e45738 100644 --- a/elpa/org-20150629/org-compat.el +++ b/elpa/org-20160215/org-compat.el @@ -1,6 +1,6 @@ ;;; org-compat.el --- Compatibility code for Org-mode -;; Copyright (C) 2004-2014 Free Software Foundation, Inc. +;; Copyright (C) 2004-2016 Free Software Foundation, Inc. ;; Author: Carsten Dominik ;; Keywords: outlines, hypermedia, calendar, wp @@ -40,11 +40,6 @@ ;; it in org-mode, because the Byte compiler evaluates (featurep 'xemacs) ;; at compilation time and can therefore optimize code better. (defconst org-xemacs-p (featurep 'xemacs)) -(defconst org-format-transports-properties-p - (let ((x "a")) - (add-text-properties 0 1 '(test t) x) - (get-text-property 0 'test (format "%s" x))) - "Does format transport text properties?") (defun org-compatible-face (inherits specs) "Make a compatible face specification. @@ -241,7 +236,7 @@ ignored in this case." (or window (selected-window))) (defun org-number-sequence (from &optional to inc) - "Call `number-sequence or emulate it." + "Call `number-sequence' or emulate it." (if (fboundp 'number-sequence) (number-sequence from to inc) (if (or (not to) (= from to)) @@ -287,17 +282,8 @@ Works on both Emacs and XEmacs." (> (point) (region-beginning))) (exchange-point-and-mark))) -;; Emacs 22 misses `activate-mark' -(if (fboundp 'activate-mark) - (defalias 'org-activate-mark 'activate-mark) - (defun org-activate-mark () - (when (mark t) - (setq mark-active t) - (when (and (boundp 'transient-mark-mode) - (not transient-mark-mode)) - (setq transient-mark-mode 'lambda)) - (when (boundp 'zmacs-regions) - (setq zmacs-regions t))))) +;; Old alias for emacs 22 compatibility, now dropped +(define-obsolete-function-alias 'org-activate-mark 'activate-mark) ;; Invisibility compatibility @@ -347,7 +333,9 @@ Works on both Emacs and XEmacs." Pass COLUMN and FORCE to `move-to-column'. Pass BUFFER to the XEmacs version of `move-to-column'." (let ((buffer-invisibility-spec - (remove '(org-filtered) buffer-invisibility-spec))) + (if (listp buffer-invisibility-spec) + (remove '(org-filtered) buffer-invisibility-spec) + buffer-invisibility-spec))) (if (featurep 'xemacs) (org-xemacs-without-invisibility (move-to-column column force buffer)) @@ -411,17 +399,23 @@ Pass BUFFER to the XEmacs version of `move-to-column'." (when focus-follows-mouse (set-mouse-position frame (1- (frame-width frame)) 0))))) -(defun org-float-time (&optional time) - "Convert time value TIME to a floating point number. -TIME defaults to the current time." - (if (featurep 'xemacs) - (time-to-seconds (or time (current-time))) - (float-time time))) +(defalias 'org-float-time + (if (featurep 'xemacs) 'time-to-seconds 'float-time)) ;; `user-error' is only available from 24.2.50 on (unless (fboundp 'user-error) (defalias 'user-error 'error)) +;; ‘format-message’ is available only from 25 on +(unless (fboundp 'format-message) + (defalias 'format-message 'format)) + +;; `font-lock-ensure' is only available from 24.4.50 on +(defalias 'org-font-lock-ensure + (if (fboundp 'font-lock-ensure) + #'font-lock-ensure + (lambda (&optional _beg _end) (font-lock-fontify-buffer)))) + (defmacro org-no-popups (&rest body) "Suppress popup windows. Let-bind some variables to nil around BODY to achieve the desired @@ -549,6 +543,18 @@ Implements `file-equal-p' for older emacsen and XEmacs." (buffer-narrowed-p) (/= (- (point-max) (point-min)) (buffer-size)))) +;; As of Emacs 25.1, `outline-mode` functions are under the 'outline-' +;; prefix. +(when (< emacs-major-version 25) + (defalias 'outline-show-all 'show-all) + (defalias 'outline-hide-subtree 'hide-subtree) + (defalias 'outline-show-subtree 'show-subtree) + (defalias 'outline-show-branches 'show-branches) + (defalias 'outline-show-children 'show-children) + (defalias 'outline-show-entry 'show-entry) + (defalias 'outline-hide-entry 'hide-entry) + (defalias 'outline-hide-sublevels 'hide-sublevels)) + (defmacro org-with-silent-modifications (&rest body) (if (fboundp 'with-silent-modifications) `(with-silent-modifications ,@body) diff --git a/elpa/org-20150629/org-crypt.el b/elpa/org-20160215/org-crypt.el similarity index 94% rename from elpa/org-20150629/org-crypt.el rename to elpa/org-20160215/org-crypt.el index 46fd3e66..d41e80a8 100644 --- a/elpa/org-20150629/org-crypt.el +++ b/elpa/org-20160215/org-crypt.el @@ -1,6 +1,6 @@ ;;; org-crypt.el --- Public key encryption for org-mode entries -;; Copyright (C) 2007-2014 Free Software Foundation, Inc. +;; Copyright (C) 2007-2016 Free Software Foundation, Inc. ;; Emacs Lisp Archive Entry ;; Filename: org-crypt.el @@ -104,10 +104,10 @@ t : Disable auto-save-mode for the current buffer nil : Leave auto-save-mode enabled. This may cause data to be written to disk unencrypted! -'ask : Ask user whether or not to disable auto-save-mode +`ask' : Ask user whether or not to disable auto-save-mode for the current buffer. -'encrypt : Leave auto-save-mode enabled for the current buffer, +`encrypt': Leave auto-save-mode enabled for the current buffer, but automatically re-encrypt all decrypted entries *before* auto-saving. NOTE: This only works for entries which have a tag @@ -133,9 +133,10 @@ See `org-crypt-disable-auto-save'." (and (eq org-crypt-disable-auto-save 'ask) (y-or-n-p "org-decrypt: auto-save-mode may cause leakage. Disable it for current buffer? "))) - (message (concat "org-decrypt: Disabling auto-save-mode for " (or (buffer-file-name) (current-buffer)))) - ; The argument to auto-save-mode has to be "-1", since - ; giving a "nil" argument toggles instead of disabling. + (message "org-decrypt: Disabling auto-save-mode for %s" + (or (buffer-file-name) (current-buffer))) + ;; The argument to auto-save-mode has to be "-1", since + ;; giving a "nil" argument toggles instead of disabling. (auto-save-mode -1)) ((eq org-crypt-disable-auto-save nil) (message "org-decrypt: Decrypting entry with auto-save-mode enabled. This may cause leakage.")) @@ -190,7 +191,7 @@ See `org-crypt-disable-auto-save'." (insert encrypted-text) (when folded (goto-char start-heading) - (hide-subtree)) + (outline-hide-subtree)) nil))))) (defun org-decrypt-entry () @@ -224,7 +225,7 @@ See `org-crypt-disable-auto-save'." ;; outline property starts at the \n of the heading. (delete-region (1- (point)) end) ;; Store a checksum of the decrypted and the encrypted - ;; text value. This allow to reuse the same encrypted text + ;; text value. This allows reusing the same encrypted text ;; if the text does not change, and therefore avoid a ;; re-encryption process. (insert "\n" (propertize decrypted-text diff --git a/elpa/org-20150629/org-ctags.el b/elpa/org-20160215/org-ctags.el similarity index 97% rename from elpa/org-20150629/org-ctags.el rename to elpa/org-20160215/org-ctags.el index 41775bda..ea4f52b5 100644 --- a/elpa/org-20150629/org-ctags.el +++ b/elpa/org-20160215/org-ctags.el @@ -1,6 +1,6 @@ ;;; org-ctags.el - Integrate Emacs "tags" facility with org mode. ;; -;; Copyright (C) 2007-2014 Free Software Foundation, Inc. +;; Copyright (C) 2007-2016 Free Software Foundation, Inc. ;; Author: Paul Sexton @@ -63,19 +63,19 @@ ;; with the same name as the link; then, if unsuccessful, ask the user if ;; he/she wants to rebuild the 'TAGS' database and try again; then ask if ;; the user wishes to append 'tag' as a new toplevel heading at the end of -;; the buffer; and finally, defer to org's default behaviour which is to +;; the buffer; and finally, defer to org's default behavior which is to ;; search the entire text of the current buffer for 'tag'. ;; -;; This behaviour can be modified by changing the value of +;; This behavior can be modified by changing the value of ;; ORG-CTAGS-OPEN-LINK-FUNCTIONS. For example I have the following in my -;; .emacs, which describes the same behaviour as the above paragraph with +;; .emacs, which describes the same behavior as the above paragraph with ;; one difference: ;; ;; (setq org-ctags-open-link-functions ;; '(org-ctags-find-tag ;; org-ctags-ask-rebuild-tags-file-then-find-tag ;; org-ctags-ask-append-topic -;; org-ctags-fail-silently)) ; <-- prevents org default behaviour +;; org-ctags-fail-silently)) ; <-- prevents org default behavior ;; ;; ;; Usage @@ -394,7 +394,8 @@ the new file." (org-open-file filename t)) ((or (eql create t) (and (eql create 'ask) - (y-or-n-p (format "File `%s.org' not found; create?" name)))) + (y-or-n-p (format-message + "File `%s.org' not found; create?" name)))) (org-ctags-open-file filename name)) (t ;; File does not exist, and we don't want to create it. nil)))) @@ -433,8 +434,8 @@ the heading a destination for the tag `NAME'." "This function is intended to be used in ORG-OPEN-LINK-FUNCTIONS. Wrapper for org-ctags-append-topic, which first asks the user if they want to append a new topic." - (if (y-or-n-p (format "Topic `%s' not found; append to end of buffer?" - name)) + (if (y-or-n-p (format-message + "Topic `%s' not found; append to end of buffer?" name)) (org-ctags-append-topic name narrowp) nil)) @@ -455,7 +456,7 @@ to rebuild (update) the TAGS file." Wrapper for org-ctags-rebuild-tags-file-then-find-tag." (if (and (buffer-file-name) (y-or-n-p - (format + (format-message "Tag `%s' not found. Rebuild table `%s/TAGS' and look again?" name (file-name-directory (buffer-file-name))))) diff --git a/elpa/org-20150629/org-datetree.el b/elpa/org-20160215/org-datetree.el similarity index 82% rename from elpa/org-20150629/org-datetree.el rename to elpa/org-20160215/org-datetree.el index 0646c3b5..999bc240 100644 --- a/elpa/org-20150629/org-datetree.el +++ b/elpa/org-20160215/org-datetree.el @@ -1,6 +1,6 @@ ;;; org-datetree.el --- Create date entries in a tree -;; Copyright (C) 2009-2014 Free Software Foundation, Inc. +;; Copyright (C) 2009-2016 Free Software Foundation, Inc. ;; Author: Carsten Dominik ;; Keywords: outlines, hypermedia, calendar, wp @@ -39,7 +39,8 @@ property (any value), the date tree will become a subtree under that entry, so the base level will be properly adjusted.") (defcustom org-datetree-add-timestamp nil - "When non-nil, add a time stamp when create a datetree entry." + "When non-nil, add a time stamp matching date of entry. +Added time stamp is active unless value is `inactive'." :group 'org-capture :version "24.3" :type '(choice @@ -53,23 +54,22 @@ so the base level will be properly adjusted.") If KEEP-RESTRICTION is non-nil, do not widen the buffer. When it is nil, the buffer will be widened to make sure an existing date tree can be found." - (let ((year (nth 2 date)) - (month (car date)) - (day (nth 1 date))) - (org-set-local 'org-datetree-base-level 1) - (or keep-restriction (widen)) - (goto-char (point-min)) - (save-restriction - (when (re-search-forward "^[ \t]*:DATE_TREE:[ \t]+\\S-" nil t) - (org-back-to-heading t) + (org-set-local 'org-datetree-base-level 1) + (or keep-restriction (widen)) + (save-restriction + (let ((prop (org-find-property "DATE_TREE"))) + (when prop + (goto-char prop) (org-set-local 'org-datetree-base-level - (org-get-valid-level (funcall outline-level) 1)) - (org-narrow-to-subtree)) - (goto-char (point-min)) + (org-get-valid-level (org-current-level) 1)) + (org-narrow-to-subtree))) + (goto-char (point-min)) + (let ((year (nth 2 date)) + (month (car date)) + (day (nth 1 date))) (org-datetree-find-year-create year) (org-datetree-find-month-create year month) - (org-datetree-find-day-create year month day) - (goto-char (prog1 (point) (widen)))))) + (org-datetree-find-day-create year month day)))) (defun org-datetree-find-year-create (year) "Find the YEAR datetree or create it." @@ -131,28 +131,30 @@ tree can be found." (org-datetree-insert-line year month day))))) (defun org-datetree-insert-line (year &optional month day) - (let ((pos (point)) ts-type) - (skip-chars-backward " \t\n") - (delete-region (point) pos) - (insert "\n" (make-string org-datetree-base-level ?*) " \n") - (backward-char 1) - (if month (org-do-demote)) - (if day (org-do-demote)) - (insert (format "%d" year)) - (when month - (insert (format "-%02d" month)) - (if day - (insert (format "-%02d %s" - day (format-time-string - "%A" (encode-time 0 0 0 day month year)))) - (insert (format " %s" - (format-time-string - "%B" (encode-time 0 0 0 1 month year)))))) - (when (and day (setq ts-type org-datetree-add-timestamp)) + (delete-region (save-excursion (skip-chars-backward " \t\n") (point)) (point)) + (insert "\n" (make-string org-datetree-base-level ?*) " \n") + (backward-char) + (when month (org-do-demote)) + (when day (org-do-demote)) + (insert (format "%d" year)) + (when month + (insert + (format "-%02d" month) + (if day + (format "-%02d %s" + day + (format-time-string "%A" (encode-time 0 0 0 day month year))) + (format " %s" + (format-time-string "%B" (encode-time 0 0 0 1 month year)))))) + (when (and day org-datetree-add-timestamp) + (save-excursion (insert "\n") (org-indent-line) - (org-insert-time-stamp (encode-time 0 0 0 day month year) nil ts-type)) - (beginning-of-line 1))) + (org-insert-time-stamp + (encode-time 0 0 0 day month year) + nil + (eq org-datetree-add-timestamp 'inactive)))) + (beginning-of-line)) (defun org-datetree-file-entry-under (txt date) "Insert a node TXT into the date tree under DATE." diff --git a/elpa/org-20150629/org-docview.el b/elpa/org-20160215/org-docview.el similarity index 84% rename from elpa/org-20150629/org-docview.el rename to elpa/org-20160215/org-docview.el index d2db6855..d2a9525e 100644 --- a/elpa/org-20150629/org-docview.el +++ b/elpa/org-20160215/org-docview.el @@ -1,6 +1,6 @@ ;;; org-docview.el --- support for links to doc-view-mode buffers -;; Copyright (C) 2009-2014 Free Software Foundation, Inc. +;; Copyright (C) 2009-2016 Free Software Foundation, Inc. ;; Author: Jan Böcker ;; Keywords: outlines, hypermedia, calendar, wp @@ -54,25 +54,26 @@ (defun org-docview-export (link description format) "Export a docview link from Org files." - (let* ((path (when (string-match "\\(.+\\)::.+" link) - (match-string 1 link))) + (let* ((path (if (string-match "\\(.+\\)::.+" link) (match-string 1 link) + link)) (desc (or description link))) (when (stringp path) (setq path (org-link-escape (expand-file-name path))) (cond ((eq format 'html) (format "%s" path desc)) - ((eq format 'latex) (format "\href{%s}{%s}" path desc)) + ((eq format 'latex) (format "\\href{%s}{%s}" path desc)) ((eq format 'ascii) (format "%s (%s)" desc path)) (t path))))) (defun org-docview-open (link) - (when (string-match "\\(.*\\)::\\([0-9]+\\)$" link) - (let* ((path (match-string 1 link)) - (page (string-to-number (match-string 2 link)))) - (org-open-file path 1) ;; let org-mode open the file (in-emacs = 1) - ;; to ensure org-link-frame-setup is respected - (doc-view-goto-page page) - ))) + (string-match "\\(.*?\\)\\(?:::\\([0-9]+\\)\\)?$" link) + (let ((path (match-string 1 link)) + (page (and (match-beginning 2) + (string-to-number (match-string 2 link))))) + ;; Let Org mode open the file (in-emacs = 1) to ensure + ;; org-link-frame-setup is respected. + (org-open-file path 1) + (when page (doc-view-goto-page page)))) (defun org-docview-store-link () "Store a link to a docview buffer." diff --git a/elpa/org-20160215/org-element.el b/elpa/org-20160215/org-element.el new file mode 100644 index 00000000..2576c3fa --- /dev/null +++ b/elpa/org-20160215/org-element.el @@ -0,0 +1,6042 @@ +;;; org-element.el --- Parser And Applications for Org syntax + +;; Copyright (C) 2012-2016 Free Software Foundation, Inc. + +;; Author: Nicolas Goaziou +;; Keywords: outlines, hypermedia, calendar, wp + +;; 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 . + +;;; Commentary: +;; +;; Org syntax can be divided into three categories: "Greater +;; elements", "Elements" and "Objects". +;; +;; Elements are related to the structure of the document. Indeed, all +;; elements are a cover for the document: each position within belongs +;; to at least one element. +;; +;; An element always starts and ends at the beginning of a line. With +;; a few exceptions (`clock', `headline', `inlinetask', `item', +;; `planning', `property-drawer', `node-property', `section' and +;; `table-row' types), it can also accept a fixed set of keywords as +;; attributes. Those are called "affiliated keywords" to distinguish +;; them from other keywords, which are full-fledged elements. Almost +;; all affiliated keywords are referenced in +;; `org-element-affiliated-keywords'; the others are export attributes +;; and start with "ATTR_" prefix. +;; +;; Element containing other elements (and only elements) are called +;; greater elements. Concerned types are: `center-block', `drawer', +;; `dynamic-block', `footnote-definition', `headline', `inlinetask', +;; `item', `plain-list', `property-drawer', `quote-block', `section' +;; and `special-block'. +;; +;; Other element types are: `babel-call', `clock', `comment', +;; `comment-block', `diary-sexp', `example-block', `export-block', +;; `fixed-width', `horizontal-rule', `keyword', `latex-environment', +;; `node-property', `paragraph', `planning', `src-block', `table', +;; `table-row' and `verse-block'. Among them, `paragraph' and +;; `verse-block' types can contain Org objects and plain text. +;; +;; Objects are related to document's contents. Some of them are +;; recursive. Associated types are of the following: `bold', `code', +;; `entity', `export-snippet', `footnote-reference', +;; `inline-babel-call', `inline-src-block', `italic', +;; `latex-fragment', `line-break', `link', `macro', `radio-target', +;; `statistics-cookie', `strike-through', `subscript', `superscript', +;; `table-cell', `target', `timestamp', `underline' and `verbatim'. +;; +;; Some elements also have special properties whose value can hold +;; objects themselves (e.g. an item tag or a headline name). Such +;; values are called "secondary strings". Any object belongs to +;; either an element or a secondary string. +;; +;; Notwithstanding affiliated keywords, each greater element, element +;; and object has a fixed set of properties attached to it. Among +;; them, four are shared by all types: `:begin' and `:end', which +;; refer to the beginning and ending buffer positions of the +;; considered element or object, `:post-blank', which holds the number +;; of blank lines, or white spaces, at its end and `:parent' which +;; refers to the element or object containing it. Greater elements, +;; elements and objects containing objects will also have +;; `:contents-begin' and `:contents-end' properties to delimit +;; contents. Eventually, All elements have a `:post-affiliated' +;; property referring to the buffer position after all affiliated +;; keywords, if any, or to their beginning position otherwise. +;; +;; At the lowest level, a `:parent' property is also attached to any +;; string, as a text property. +;; +;; Lisp-wise, an element or an object can be represented as a list. +;; It follows the pattern (TYPE PROPERTIES CONTENTS), where: +;; TYPE is a symbol describing the Org element or object. +;; PROPERTIES is the property list attached to it. See docstring of +;; appropriate parsing function to get an exhaustive +;; list. +;; CONTENTS is a list of elements, objects or raw strings contained +;; in the current element or object, when applicable. +;; +;; An Org buffer is a nested list of such elements and objects, whose +;; type is `org-data' and properties is nil. +;; +;; The first part of this file defines Org syntax, while the second +;; one provide accessors and setters functions. +;; +;; The next part implements a parser and an interpreter for each +;; element and object type in Org syntax. +;; +;; The following part creates a fully recursive buffer parser. It +;; also provides a tool to map a function to elements or objects +;; matching some criteria in the parse tree. Functions of interest +;; are `org-element-parse-buffer', `org-element-map' and, to a lesser +;; extent, `org-element-parse-secondary-string'. +;; +;; The penultimate part is the cradle of an interpreter for the +;; obtained parse tree: `org-element-interpret-data'. +;; +;; The library ends by furnishing `org-element-at-point' function, and +;; a way to give information about document structure around point +;; with `org-element-context'. A cache mechanism is also provided for +;; these functions. + + +;;; Code: + +(eval-when-compile (require 'cl)) +(require 'org) +(require 'avl-tree) + + + +;;; Definitions And Rules +;; +;; Define elements, greater elements and specify recursive objects, +;; along with the affiliated keywords recognized. Also set up +;; restrictions on recursive objects combinations. +;; +;; `org-element-update-syntax' builds proper syntax regexps according +;; to current setup. + +(defvar org-element-paragraph-separate nil + "Regexp to separate paragraphs in an Org buffer. +In the case of lines starting with \"#\" and \":\", this regexp +is not sufficient to know if point is at a paragraph ending. See +`org-element-paragraph-parser' for more information.") + +(defvar org-element--object-regexp nil + "Regexp possibly matching the beginning of an object. +This regexp allows false positives. Dedicated parser (e.g., +`org-export-bold-parser') will take care of further filtering. +Radio links are not matched by this regexp, as they are treated +specially in `org-element--object-lex'.") + +(defun org-element--set-regexps () + "Build variable syntax regexps." + (setq org-element-paragraph-separate + (concat "^\\(?:" + ;; Headlines, inlinetasks. + org-outline-regexp "\\|" + ;; Footnote definitions. + "\\[\\(?:[0-9]+\\|fn:[-_[:word:]]+\\)\\]" "\\|" + ;; Diary sexps. + "%%(" "\\|" + "[ \t]*\\(?:" + ;; Empty lines. + "$" "\\|" + ;; Tables (any type). + "|" "\\|" + "\\+\\(?:-+\\+\\)+[ \t]*$" "\\|" + ;; Comments, keyword-like or block-like constructs. + ;; Blocks and keywords with dual values need to be + ;; double-checked. + "#\\(?: \\|$\\|\\+\\(?:" + "BEGIN_\\S-+" "\\|" + "\\S-+\\(?:\\[.*\\]\\)?:[ \t]*\\)\\)" + "\\|" + ;; Drawers (any type) and fixed-width areas. Drawers + ;; need to be double-checked. + ":\\(?: \\|$\\|[-_[:word:]]+:[ \t]*$\\)" "\\|" + ;; Horizontal rules. + "-\\{5,\\}[ \t]*$" "\\|" + ;; LaTeX environments. + "\\\\begin{\\([A-Za-z0-9*]+\\)}" "\\|" + ;; Clock lines. + (regexp-quote org-clock-string) "\\|" + ;; Lists. + (let ((term (case org-plain-list-ordered-item-terminator + (?\) ")") (?. "\\.") (otherwise "[.)]"))) + (alpha (and org-list-allow-alphabetical "\\|[A-Za-z]"))) + (concat "\\(?:[-+*]\\|\\(?:[0-9]+" alpha "\\)" term "\\)" + "\\(?:[ \t]\\|$\\)")) + "\\)\\)") + org-element--object-regexp + (mapconcat #'identity + (let ((link-types (regexp-opt org-link-types))) + (list + ;; Sub/superscript. + "\\(?:[_^][-{(*+.,[:alnum:]]\\)" + ;; Bold, code, italic, strike-through, underline + ;; and verbatim. + (concat "[*~=+_/]" + (format "[^%s]" + (nth 2 org-emphasis-regexp-components))) + ;; Plain links. + (concat "\\<" link-types ":") + ;; Objects starting with "[": regular link, + ;; footnote reference, statistics cookie, + ;; timestamp (inactive). + "\\[\\(?:fn:\\|\\(?:[0-9]\\|\\(?:%\\|/[0-9]*\\)\\]\\)\\|\\[\\)" + ;; Objects starting with "@": export snippets. + "@@" + ;; Objects starting with "{": macro. + "{{{" + ;; Objects starting with "<" : timestamp + ;; (active, diary), target, radio target and + ;; angular links. + (concat "<\\(?:%%\\|<\\|[0-9]\\|" link-types "\\)") + ;; Objects starting with "$": latex fragment. + "\\$" + ;; Objects starting with "\": line break, + ;; entity, latex fragment. + "\\\\\\(?:[a-zA-Z[(]\\|\\\\[ \t]*$\\|_ +\\)" + ;; Objects starting with raw text: inline Babel + ;; source block, inline Babel call. + "\\(?:call\\|src\\)_")) + "\\|"))) + +(org-element--set-regexps) + +;;;###autoload +(defun org-element-update-syntax () + "Update parser internals." + (interactive) + (org-element--set-regexps) + (org-element-cache-reset 'all)) + +(defconst org-element-all-elements + '(babel-call center-block clock comment comment-block diary-sexp drawer + dynamic-block example-block export-block fixed-width + footnote-definition headline horizontal-rule inlinetask item + keyword latex-environment node-property paragraph plain-list + planning property-drawer quote-block section + special-block src-block table table-row verse-block) + "Complete list of element types.") + +(defconst org-element-greater-elements + '(center-block drawer dynamic-block footnote-definition headline inlinetask + item plain-list property-drawer quote-block section + special-block table) + "List of recursive element types aka Greater Elements.") + +(defconst org-element-all-objects + '(bold code entity export-snippet footnote-reference inline-babel-call + inline-src-block italic line-break latex-fragment link macro + radio-target statistics-cookie strike-through subscript superscript + table-cell target timestamp underline verbatim) + "Complete list of object types.") + +(defconst org-element-recursive-objects + '(bold footnote-reference italic link subscript radio-target strike-through + superscript table-cell underline) + "List of recursive object types.") + +(defconst org-element-object-containers + (append org-element-recursive-objects '(paragraph table-row verse-block)) + "List of object or element types that can directly contain objects.") + +(defvar org-element-block-name-alist + '(("CENTER" . org-element-center-block-parser) + ("COMMENT" . org-element-comment-block-parser) + ("EXAMPLE" . org-element-example-block-parser) + ("QUOTE" . org-element-quote-block-parser) + ("SRC" . org-element-src-block-parser) + ("VERSE" . org-element-verse-block-parser)) + "Alist between block names and the associated parsing function. +Names must be uppercase. Any block whose name has no association +is parsed with `org-element-special-block-parser'.") + +(defconst org-element-affiliated-keywords + '("CAPTION" "DATA" "HEADER" "HEADERS" "LABEL" "NAME" "PLOT" "RESNAME" "RESULT" + "RESULTS" "SOURCE" "SRCNAME" "TBLNAME") + "List of affiliated keywords as strings. +By default, all keywords setting attributes (e.g., \"ATTR_LATEX\") +are affiliated keywords and need not to be in this list.") + +(defconst org-element-keyword-translation-alist + '(("DATA" . "NAME") ("LABEL" . "NAME") ("RESNAME" . "NAME") + ("SOURCE" . "NAME") ("SRCNAME" . "NAME") ("TBLNAME" . "NAME") + ("RESULT" . "RESULTS") ("HEADERS" . "HEADER")) + "Alist of usual translations for keywords. +The key is the old name and the value the new one. The property +holding their value will be named after the translated name.") + +(defconst org-element-multiple-keywords '("CAPTION" "HEADER") + "List of affiliated keywords that can occur more than once in an element. + +Their value will be consed into a list of strings, which will be +returned as the value of the property. + +This list is checked after translations have been applied. See +`org-element-keyword-translation-alist'. + +By default, all keywords setting attributes (e.g., \"ATTR_LATEX\") +allow multiple occurrences and need not to be in this list.") + +(defconst org-element-parsed-keywords '("CAPTION") + "List of affiliated keywords whose value can be parsed. + +Their value will be stored as a secondary string: a list of +strings and objects. + +This list is checked after translations have been applied. See +`org-element-keyword-translation-alist'.") + +(defconst org-element--parsed-properties-alist + (mapcar (lambda (k) (cons k (intern (concat ":" (downcase k))))) + org-element-parsed-keywords) + "Alist of parsed keywords and associated properties. +This is generated from `org-element-parsed-keywords', which +see.") + +(defconst org-element-dual-keywords '("CAPTION" "RESULTS") + "List of affiliated keywords which can have a secondary value. + +In Org syntax, they can be written with optional square brackets +before the colons. For example, RESULTS keyword can be +associated to a hash value with the following: + + #+RESULTS[hash-string]: some-source + +This list is checked after translations have been applied. See +`org-element-keyword-translation-alist'.") + +(defconst org-element--affiliated-re + (format "[ \t]*#\\+\\(?:%s\\):[ \t]*" + (concat + ;; Dual affiliated keywords. + (format "\\(?1:%s\\)\\(?:\\[\\(.*\\)\\]\\)?" + (regexp-opt org-element-dual-keywords)) + "\\|" + ;; Regular affiliated keywords. + (format "\\(?1:%s\\)" + (regexp-opt + (org-remove-if + (lambda (k) (member k org-element-dual-keywords)) + org-element-affiliated-keywords))) + "\\|" + ;; Export attributes. + "\\(?1:ATTR_[-_A-Za-z0-9]+\\)")) + "Regexp matching any affiliated keyword. + +Keyword name is put in match group 1. Moreover, if keyword +belongs to `org-element-dual-keywords', put the dual value in +match group 2. + +Don't modify it, set `org-element-affiliated-keywords' instead.") + +(defconst org-element-object-restrictions + (let* ((standard-set (remq 'table-cell org-element-all-objects)) + (standard-set-no-line-break (remq 'line-break standard-set))) + `((bold ,@standard-set) + (footnote-reference ,@standard-set) + (headline ,@standard-set-no-line-break) + (inlinetask ,@standard-set-no-line-break) + (italic ,@standard-set) + (item ,@standard-set-no-line-break) + (keyword ,@(remq 'footnote-reference standard-set)) + ;; Ignore all links excepted plain links in a link description. + ;; Also ignore radio-targets and line breaks. + (link bold code entity export-snippet inline-babel-call inline-src-block + italic latex-fragment macro plain-link statistics-cookie + strike-through subscript superscript underline verbatim) + (paragraph ,@standard-set) + ;; Remove any variable object from radio target as it would + ;; prevent it from being properly recognized. + (radio-target bold code entity italic latex-fragment strike-through + subscript superscript underline superscript) + (strike-through ,@standard-set) + (subscript ,@standard-set) + (superscript ,@standard-set) + ;; Ignore inline babel call and inline src block as formulas are + ;; possible. Also ignore line breaks and statistics cookies. + (table-cell bold code entity export-snippet footnote-reference italic + latex-fragment link macro radio-target strike-through + subscript superscript target timestamp underline verbatim) + (table-row table-cell) + (underline ,@standard-set) + (verse-block ,@standard-set))) + "Alist of objects restrictions. + +key is an element or object type containing objects and value is +a list of types that can be contained within an element or object +of such type. + +For example, in a `radio-target' object, one can only find +entities, latex-fragments, subscript, superscript and text +markup. + +This alist also applies to secondary string. For example, an +`headline' type element doesn't directly contain objects, but +still has an entry since one of its properties (`:title') does.") + +(defconst org-element-secondary-value-alist + '((headline :title) + (inlinetask :title) + (item :tag)) + "Alist between element types and locations of secondary values.") + +(defconst org-element--pair-square-table + (let ((table (make-syntax-table))) + (modify-syntax-entry ?\[ "(]" table) + (modify-syntax-entry ?\] ")[" table) + (dolist (char '(?\{ ?\} ?\( ?\) ?\< ?\>) table) + (modify-syntax-entry char " " table))) + "Table used internally to pair only square brackets. +Other brackets are treated as spaces.") + + + +;;; Accessors and Setters +;; +;; Provide four accessors: `org-element-type', `org-element-property' +;; `org-element-contents' and `org-element-restriction'. +;; +;; Setter functions allow modification of elements by side effect. +;; There is `org-element-put-property', `org-element-set-contents'. +;; These low-level functions are useful to build a parse tree. +;; +;; `org-element-adopt-element', `org-element-set-element', +;; `org-element-extract-element' and `org-element-insert-before' are +;; high-level functions useful to modify a parse tree. +;; +;; `org-element-secondary-p' is a predicate used to know if a given +;; object belongs to a secondary string. `org-element-copy' returns +;; an element or object, stripping its parent property in the process. + +(defsubst org-element-type (element) + "Return type of ELEMENT. + +The function returns the type of the element or object provided. +It can also return the following special value: + `plain-text' for a string + `org-data' for a complete document + nil in any other case." + (cond + ((not (consp element)) (and (stringp element) 'plain-text)) + ((symbolp (car element)) (car element)))) + +(defsubst org-element-property (property element) + "Extract the value from the PROPERTY of an ELEMENT." + (if (stringp element) (get-text-property 0 property element) + (plist-get (nth 1 element) property))) + +(defsubst org-element-contents (element) + "Extract contents from an ELEMENT." + (cond ((not (consp element)) nil) + ((symbolp (car element)) (nthcdr 2 element)) + (t element))) + +(defsubst org-element-restriction (element) + "Return restriction associated to ELEMENT. +ELEMENT can be an element, an object or a symbol representing an +element or object type." + (cdr (assq (if (symbolp element) element (org-element-type element)) + org-element-object-restrictions))) + +(defsubst org-element-put-property (element property value) + "In ELEMENT set PROPERTY to VALUE. +Return modified element." + (if (stringp element) (org-add-props element nil property value) + (setcar (cdr element) (plist-put (nth 1 element) property value)) + element)) + +(defsubst org-element-set-contents (element &rest contents) + "Set ELEMENT contents to CONTENTS." + (cond ((not element) (list contents)) + ((not (symbolp (car element))) contents) + ((cdr element) (setcdr (cdr element) contents)) + (t (nconc element contents)))) + +(defun org-element-secondary-p (object) + "Non-nil when OBJECT directly belongs to a secondary string. +Return value is the property name, as a keyword, or nil." + (let* ((parent (org-element-property :parent object)) + (properties (cdr (assq (org-element-type parent) + org-element-secondary-value-alist)))) + (catch 'exit + (dolist (p properties) + (and (memq object (org-element-property p parent)) + (throw 'exit p)))))) + +(defsubst org-element-adopt-elements (parent &rest children) + "Append elements to the contents of another element. + +PARENT is an element or object. CHILDREN can be elements, +objects, or a strings. + +The function takes care of setting `:parent' property for CHILD. +Return parent element." + (if (not children) parent + ;; Link every child to PARENT. If PARENT is nil, it is a secondary + ;; string: parent is the list itself. + (dolist (child children) + (org-element-put-property child :parent (or parent children))) + ;; Add CHILDREN at the end of PARENT contents. + (when parent + (apply #'org-element-set-contents + parent + (nconc (org-element-contents parent) children))) + ;; Return modified PARENT element. + (or parent children))) + +(defun org-element-extract-element (element) + "Extract ELEMENT from parse tree. +Remove element from the parse tree by side-effect, and return it +with its `:parent' property stripped out." + (let ((parent (org-element-property :parent element)) + (secondary (org-element-secondary-p element))) + (if secondary + (org-element-put-property + parent secondary + (delq element (org-element-property secondary parent))) + (apply #'org-element-set-contents + parent + (delq element (org-element-contents parent)))) + ;; Return ELEMENT with its :parent removed. + (org-element-put-property element :parent nil))) + +(defun org-element-insert-before (element location) + "Insert ELEMENT before LOCATION in parse tree. +LOCATION is an element, object or string within the parse tree. +Parse tree is modified by side effect." + (let* ((parent (org-element-property :parent location)) + (property (org-element-secondary-p location)) + (siblings (if property (org-element-property property parent) + (org-element-contents parent))) + ;; Special case: LOCATION is the first element of an + ;; independent secondary string (e.g. :title property). Add + ;; ELEMENT in-place. + (specialp (and (not property) + (eq siblings parent) + (eq (car parent) location)))) + ;; Install ELEMENT at the appropriate POSITION within SIBLINGS. + (cond (specialp) + ((or (null siblings) (eq (car siblings) location)) + (push element siblings)) + ((null location) (nconc siblings (list element))) + (t (let ((previous (cadr (memq location (reverse siblings))))) + (if (not previous) + (error "No location found to insert element") + (let ((next (memq previous siblings))) + (setcdr next (cons element (cdr next)))))))) + ;; Store SIBLINGS at appropriate place in parse tree. + (cond + (specialp (setcdr parent (copy-sequence parent)) (setcar parent element)) + (property (org-element-put-property parent property siblings)) + (t (apply #'org-element-set-contents parent siblings))) + ;; Set appropriate :parent property. + (org-element-put-property element :parent parent))) + +(defun org-element-set-element (old new) + "Replace element or object OLD with element or object NEW. +The function takes care of setting `:parent' property for NEW." + ;; Ensure OLD and NEW have the same parent. + (org-element-put-property new :parent (org-element-property :parent old)) + (if (or (memq (org-element-type old) '(plain-text nil)) + (memq (org-element-type new) '(plain-text nil))) + ;; We cannot replace OLD with NEW since one of them is not an + ;; object or element. We take the long path. + (progn (org-element-insert-before new old) + (org-element-extract-element old)) + ;; Since OLD is going to be changed into NEW by side-effect, first + ;; make sure that every element or object within NEW has OLD as + ;; parent. + (dolist (blob (org-element-contents new)) + (org-element-put-property blob :parent old)) + ;; Transfer contents. + (apply #'org-element-set-contents old (org-element-contents new)) + ;; Overwrite OLD's properties with NEW's. + (setcar (cdr old) (nth 1 new)) + ;; Transfer type. + (setcar old (car new)))) + +(defun org-element-create (type &optional props &rest children) + "Create a new element of type TYPE. +Optional argument PROPS, when non-nil, is a plist defining the +properties of the element. CHILDREN can be elements, objects or +strings." + (apply #'org-element-adopt-elements (list type props) children)) + +(defun org-element-copy (datum) + "Return a copy of DATUM. +DATUM is an element, object, string or nil. `:parent' property +is cleared and contents are removed in the process." + (when datum + (let ((type (org-element-type datum))) + (case type + (org-data (list 'org-data nil)) + (plain-text (substring-no-properties datum)) + ((nil) (copy-sequence datum)) + (otherwise + (list type (plist-put (copy-sequence (nth 1 datum)) :parent nil))))))) + + + +;;; Greater elements +;; +;; For each greater element type, we define a parser and an +;; interpreter. +;; +;; A parser returns the element or object as the list described above. +;; Most of them accepts no argument. Though, exceptions exist. Hence +;; every element containing a secondary string (see +;; `org-element-secondary-value-alist') will accept an optional +;; argument to toggle parsing of these secondary strings. Moreover, +;; `item' parser requires current list's structure as its first +;; element. +;; +;; An interpreter accepts two arguments: the list representation of +;; the element or object, and its contents. The latter may be nil, +;; depending on the element or object considered. It returns the +;; appropriate Org syntax, as a string. +;; +;; Parsing functions must follow the naming convention: +;; org-element-TYPE-parser, where TYPE is greater element's type, as +;; defined in `org-element-greater-elements'. +;; +;; Similarly, interpreting functions must follow the naming +;; convention: org-element-TYPE-interpreter. +;; +;; With the exception of `headline' and `item' types, greater elements +;; cannot contain other greater elements of their own type. +;; +;; Beside implementing a parser and an interpreter, adding a new +;; greater element requires tweaking `org-element--current-element'. +;; Moreover, the newly defined type must be added to both +;; `org-element-all-elements' and `org-element-greater-elements'. + + +;;;; Center Block + +(defun org-element-center-block-parser (limit affiliated) + "Parse a center block. + +LIMIT bounds the search. AFFILIATED is a list of which CAR is +the buffer position at the beginning of the first affiliated +keyword and CDR is a plist of affiliated keywords along with +their value. + +Return a list whose CAR is `center-block' and CDR is a plist +containing `:begin', `:end', `:contents-begin', `:contents-end', +`:post-blank' and `:post-affiliated' keywords. + +Assume point is at the beginning of the block." + (let ((case-fold-search t)) + (if (not (save-excursion + (re-search-forward "^[ \t]*#\\+END_CENTER[ \t]*$" limit t))) + ;; Incomplete block: parse it as a paragraph. + (org-element-paragraph-parser limit affiliated) + (let ((block-end-line (match-beginning 0))) + (let* ((begin (car affiliated)) + (post-affiliated (point)) + ;; Empty blocks have no contents. + (contents-begin (progn (forward-line) + (and (< (point) block-end-line) + (point)))) + (contents-end (and contents-begin block-end-line)) + (pos-before-blank (progn (goto-char block-end-line) + (forward-line) + (point))) + (end (save-excursion + (skip-chars-forward " \r\t\n" limit) + (if (eobp) (point) (line-beginning-position))))) + (list 'center-block + (nconc + (list :begin begin + :end end + :contents-begin contents-begin + :contents-end contents-end + :post-blank (count-lines pos-before-blank end) + :post-affiliated post-affiliated) + (cdr affiliated)))))))) + +(defun org-element-center-block-interpreter (center-block contents) + "Interpret CENTER-BLOCK element as Org syntax. +CONTENTS is the contents of the element." + (format "#+BEGIN_CENTER\n%s#+END_CENTER" contents)) + + +;;;; Drawer + +(defun org-element-drawer-parser (limit affiliated) + "Parse a drawer. + +LIMIT bounds the search. AFFILIATED is a list of which CAR is +the buffer position at the beginning of the first affiliated +keyword and CDR is a plist of affiliated keywords along with +their value. + +Return a list whose CAR is `drawer' and CDR is a plist containing +`:drawer-name', `:begin', `:end', `:contents-begin', +`:contents-end', `:post-blank' and `:post-affiliated' keywords. + +Assume point is at beginning of drawer." + (let ((case-fold-search t)) + (if (not (save-excursion (re-search-forward "^[ \t]*:END:[ \t]*$" limit t))) + ;; Incomplete drawer: parse it as a paragraph. + (org-element-paragraph-parser limit affiliated) + (save-excursion + (let* ((drawer-end-line (match-beginning 0)) + (name (progn (looking-at org-drawer-regexp) + (org-match-string-no-properties 1))) + (begin (car affiliated)) + (post-affiliated (point)) + ;; Empty drawers have no contents. + (contents-begin (progn (forward-line) + (and (< (point) drawer-end-line) + (point)))) + (contents-end (and contents-begin drawer-end-line)) + (pos-before-blank (progn (goto-char drawer-end-line) + (forward-line) + (point))) + (end (progn (skip-chars-forward " \r\t\n" limit) + (if (eobp) (point) (line-beginning-position))))) + (list 'drawer + (nconc + (list :begin begin + :end end + :drawer-name name + :contents-begin contents-begin + :contents-end contents-end + :post-blank (count-lines pos-before-blank end) + :post-affiliated post-affiliated) + (cdr affiliated)))))))) + +(defun org-element-drawer-interpreter (drawer contents) + "Interpret DRAWER element as Org syntax. +CONTENTS is the contents of the element." + (format ":%s:\n%s:END:" + (org-element-property :drawer-name drawer) + contents)) + + +;;;; Dynamic Block + +(defun org-element-dynamic-block-parser (limit affiliated) + "Parse a dynamic block. + +LIMIT bounds the search. AFFILIATED is a list of which CAR is +the buffer position at the beginning of the first affiliated +keyword and CDR is a plist of affiliated keywords along with +their value. + +Return a list whose CAR is `dynamic-block' and CDR is a plist +containing `:block-name', `:begin', `:end', `:contents-begin', +`:contents-end', `:arguments', `:post-blank' and +`:post-affiliated' keywords. + +Assume point is at beginning of dynamic block." + (let ((case-fold-search t)) + (if (not (save-excursion + (re-search-forward "^[ \t]*#\\+END:?[ \t]*$" limit t))) + ;; Incomplete block: parse it as a paragraph. + (org-element-paragraph-parser limit affiliated) + (let ((block-end-line (match-beginning 0))) + (save-excursion + (let* ((name (progn (looking-at org-dblock-start-re) + (org-match-string-no-properties 1))) + (arguments (org-match-string-no-properties 3)) + (begin (car affiliated)) + (post-affiliated (point)) + ;; Empty blocks have no contents. + (contents-begin (progn (forward-line) + (and (< (point) block-end-line) + (point)))) + (contents-end (and contents-begin block-end-line)) + (pos-before-blank (progn (goto-char block-end-line) + (forward-line) + (point))) + (end (progn (skip-chars-forward " \r\t\n" limit) + (if (eobp) (point) (line-beginning-position))))) + (list 'dynamic-block + (nconc + (list :begin begin + :end end + :block-name name + :arguments arguments + :contents-begin contents-begin + :contents-end contents-end + :post-blank (count-lines pos-before-blank end) + :post-affiliated post-affiliated) + (cdr affiliated))))))))) + +(defun org-element-dynamic-block-interpreter (dynamic-block contents) + "Interpret DYNAMIC-BLOCK element as Org syntax. +CONTENTS is the contents of the element." + (format "#+BEGIN: %s%s\n%s#+END:" + (org-element-property :block-name dynamic-block) + (let ((args (org-element-property :arguments dynamic-block))) + (and args (concat " " args))) + contents)) + + +;;;; Footnote Definition + +(defconst org-element--footnote-separator + (concat org-outline-regexp-bol "\\|" + org-footnote-definition-re "\\|" + "^\\([ \t]*\n\\)\\{2,\\}") + "Regexp used as a footnote definition separator.") + +(defun org-element-footnote-definition-parser (limit affiliated) + "Parse a footnote definition. + +LIMIT bounds the search. AFFILIATED is a list of which CAR is +the buffer position at the beginning of the first affiliated +keyword and CDR is a plist of affiliated keywords along with +their value. + +Return a list whose CAR is `footnote-definition' and CDR is +a plist containing `:label', `:begin' `:end', `:contents-begin', +`:contents-end', `:post-blank' and `:post-affiliated' keywords. + +Assume point is at the beginning of the footnote definition." + (save-excursion + (let* ((label (progn (looking-at org-footnote-definition-re) + (org-match-string-no-properties 1))) + (begin (car affiliated)) + (post-affiliated (point)) + (ending + (save-excursion + (end-of-line) + (cond + ((not + (re-search-forward org-element--footnote-separator limit t)) + limit) + ((eq (char-after (match-beginning 0)) ?\[) + ;; At a new footnote definition, make sure we end + ;; before any affiliated keyword above. + (forward-line -1) + (while (and (> (point) post-affiliated) + (org-looking-at-p org-element--affiliated-re)) + (forward-line -1)) + (line-beginning-position 2)) + (t (match-beginning 0))))) + (contents-begin + (progn + (search-forward "]") + (skip-chars-forward " \r\t\n" ending) + (cond ((= (point) ending) nil) + ((= (line-beginning-position) post-affiliated) (point)) + (t (line-beginning-position))))) + (contents-end (and contents-begin ending)) + (end (progn (goto-char ending) + (skip-chars-forward " \r\t\n" limit) + (if (eobp) (point) (line-beginning-position))))) + (list 'footnote-definition + (nconc + (list :label label + :begin begin + :end end + :contents-begin contents-begin + :contents-end contents-end + :post-blank (count-lines ending end) + :post-affiliated post-affiliated) + (cdr affiliated)))))) + +(defun org-element-footnote-definition-interpreter (footnote-definition contents) + "Interpret FOOTNOTE-DEFINITION element as Org syntax. +CONTENTS is the contents of the footnote-definition." + (concat (format "[%s]" (org-element-property :label footnote-definition)) + " " + contents)) + + +;;;; Headline + +(defun org-element--get-node-properties () + "Return node properties associated to headline at point. +Upcase property names. It avoids confusion between properties +obtained through property drawer and default properties from the +parser (e.g. `:end' and :END:). Return value is a plist." + (save-excursion + (forward-line) + (when (org-looking-at-p org-planning-line-re) (forward-line)) + (when (looking-at org-property-drawer-re) + (forward-line) + (let ((end (match-end 0)) properties) + (while (< (line-end-position) end) + (looking-at org-property-re) + (push (org-match-string-no-properties 3) properties) + (push (intern (concat ":" (upcase (match-string 2)))) properties) + (forward-line)) + properties)))) + +(defun org-element--get-time-properties () + "Return time properties associated to headline at point. +Return value is a plist." + (save-excursion + (when (progn (forward-line) (looking-at org-planning-line-re)) + (let ((end (line-end-position)) plist) + (while (re-search-forward org-keyword-time-not-clock-regexp end t) + (goto-char (match-end 1)) + (skip-chars-forward " \t") + (let ((keyword (match-string 1)) + (time (org-element-timestamp-parser))) + (cond ((equal keyword org-scheduled-string) + (setq plist (plist-put plist :scheduled time))) + ((equal keyword org-deadline-string) + (setq plist (plist-put plist :deadline time))) + (t (setq plist (plist-put plist :closed time)))))) + plist)))) + +(defun org-element-headline-parser (limit &optional raw-secondary-p) + "Parse a headline. + +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', +`:deadline', `:closed', `:archivedp', `:commentedp' +`:footnote-section-p', `:post-blank' and `:post-affiliated' +keywords. + +The plist also contains any property set in the property drawer, +with its name in upper cases and colons added at the +beginning (e.g., `:CUSTOM_ID'). + +LIMIT is a buffer position bounding the search. + +When RAW-SECONDARY-P is non-nil, headline's title will not be +parsed as a secondary string, but as a plain string instead. + +Assume point is at beginning of the headline." + (save-excursion + (let* ((begin (point)) + (level (prog1 (org-reduced-level (skip-chars-forward "*")) + (skip-chars-forward " \t"))) + (todo (and org-todo-regexp + (let (case-fold-search) (looking-at org-todo-regexp)) + (progn (goto-char (match-end 0)) + (skip-chars-forward " \t") + (match-string 0)))) + (todo-type + (and todo (if (member todo org-done-keywords) 'done 'todo))) + (priority (and (looking-at "\\[#.\\][ \t]*") + (progn (goto-char (match-end 0)) + (aref (match-string 0) 2)))) + (commentedp + (and (let (case-fold-search) (looking-at org-comment-string)) + (goto-char (match-end 0)))) + (title-start (point)) + (tags (when (re-search-forward + (org-re "[ \t]+\\(:[[:alnum:]_@#%:]+:\\)[ \t]*$") + (line-end-position) + 'move) + (goto-char (match-beginning 0)) + (org-split-string (match-string 1) ":"))) + (title-end (point)) + (raw-value (org-trim + (buffer-substring-no-properties title-start title-end))) + (archivedp (member org-archive-tag tags)) + (footnote-section-p (and org-footnote-section + (string= org-footnote-section raw-value))) + (standard-props (org-element--get-node-properties)) + (time-props (org-element--get-time-properties)) + (end (min (save-excursion (org-end-of-subtree t t)) limit)) + (pos-after-head (progn (forward-line) (point))) + (contents-begin (save-excursion + (skip-chars-forward " \r\t\n" end) + (and (/= (point) end) (line-beginning-position)))) + (contents-end (and contents-begin + (progn (goto-char end) + (skip-chars-backward " \r\t\n") + (forward-line) + (point))))) + (let ((headline + (list 'headline + (nconc + (list :raw-value raw-value + :begin begin + :end end + :pre-blank + (if (not contents-begin) 0 + (count-lines pos-after-head contents-begin)) + :contents-begin contents-begin + :contents-end contents-end + :level level + :priority priority + :tags tags + :todo-keyword todo + :todo-type todo-type + :post-blank (count-lines + (or contents-end pos-after-head) + end) + :footnote-section-p footnote-section-p + :archivedp archivedp + :commentedp commentedp + :post-affiliated begin) + time-props + standard-props)))) + (org-element-put-property + headline :title + (if raw-secondary-p raw-value + (let ((title (org-element--parse-objects + (progn (goto-char title-start) + (skip-chars-forward " \t") + (point)) + (progn (goto-char title-end) + (skip-chars-backward " \t") + (point)) + nil + (org-element-restriction 'headline)))) + (dolist (datum title title) + (org-element-put-property datum :parent headline))))))))) + +(defun org-element-headline-interpreter (headline contents) + "Interpret HEADLINE element as Org syntax. +CONTENTS is the contents of the element." + (let* ((level (org-element-property :level headline)) + (todo (org-element-property :todo-keyword headline)) + (priority (org-element-property :priority headline)) + (title (org-element-interpret-data + (org-element-property :title headline))) + (tags (let ((tag-list (org-element-property :tags headline))) + (and tag-list + (format ":%s:" (mapconcat #'identity tag-list ":"))))) + (commentedp (org-element-property :commentedp headline)) + (pre-blank (or (org-element-property :pre-blank headline) 0)) + (heading + (concat (make-string (if org-odd-levels-only (1- (* level 2)) level) + ?*) + (and todo (concat " " todo)) + (and commentedp (concat " " org-comment-string)) + (and priority (format " [#%c]" priority)) + " " + (if (and org-footnote-section + (org-element-property :footnote-section-p headline)) + org-footnote-section + title)))) + (concat + heading + ;; Align tags. + (when tags + (cond + ((zerop org-tags-column) (format " %s" tags)) + ((< org-tags-column 0) + (concat + (make-string + (max (- (+ org-tags-column (length heading) (length tags))) 1) + ?\s) + tags)) + (t + (concat + (make-string (max (- org-tags-column (length heading)) 1) ?\s) + tags)))) + (make-string (1+ pre-blank) ?\n) + contents))) + + +;;;; Inlinetask + +(defun org-element-inlinetask-parser (limit &optional raw-secondary-p) + "Parse an inline task. + +Return a list whose CAR is `inlinetask' and CDR is a plist +containing `:title', `:begin', `:end', `:contents-begin' and +`:contents-end', `:level', `:priority', `:raw-value', `:tags', +`:todo-keyword', `:todo-type', `:scheduled', `:deadline', +`:closed', `:post-blank' and `:post-affiliated' keywords. + +The plist also contains any property set in the property drawer, +with its name in upper cases and colons added at the +beginning (e.g., `:CUSTOM_ID'). + +When optional argument RAW-SECONDARY-P is non-nil, inline-task's +title will not be parsed as a secondary string, but as a plain +string instead. + +Assume point is at beginning of the inline task." + (save-excursion + (let* ((begin (point)) + (level (prog1 (org-reduced-level (skip-chars-forward "*")) + (skip-chars-forward " \t"))) + (todo (and org-todo-regexp + (let (case-fold-search) (looking-at org-todo-regexp)) + (progn (goto-char (match-end 0)) + (skip-chars-forward " \t") + (match-string 0)))) + (todo-type (and todo + (if (member todo org-done-keywords) 'done 'todo))) + (priority (and (looking-at "\\[#.\\][ \t]*") + (progn (goto-char (match-end 0)) + (aref (match-string 0) 2)))) + (title-start (point)) + (tags (when (re-search-forward + (org-re "[ \t]+\\(:[[:alnum:]_@#%:]+:\\)[ \t]*$") + (line-end-position) + 'move) + (goto-char (match-beginning 0)) + (org-split-string (match-string 1) ":"))) + (title-end (point)) + (raw-value (org-trim + (buffer-substring-no-properties title-start title-end))) + (task-end (save-excursion + (end-of-line) + (and (re-search-forward org-outline-regexp-bol limit t) + (org-looking-at-p "END[ \t]*$") + (line-beginning-position)))) + (standard-props (and task-end (org-element--get-node-properties))) + (time-props (and task-end (org-element--get-time-properties))) + (contents-begin (progn (forward-line) + (and task-end (< (point) task-end) (point)))) + (contents-end (and contents-begin task-end)) + (before-blank (if (not task-end) (point) + (goto-char task-end) + (forward-line) + (point))) + (end (progn (skip-chars-forward " \r\t\n" limit) + (if (eobp) (point) (line-beginning-position)))) + (inlinetask + (list 'inlinetask + (nconc + (list :raw-value raw-value + :begin begin + :end end + :contents-begin contents-begin + :contents-end contents-end + :level level + :priority priority + :tags tags + :todo-keyword todo + :todo-type todo-type + :post-blank (count-lines before-blank end) + :post-affiliated begin) + time-props + standard-props)))) + (org-element-put-property + inlinetask :title + (if raw-secondary-p raw-value + (let ((title (org-element--parse-objects + (progn (goto-char title-start) + (skip-chars-forward " \t") + (point)) + (progn (goto-char title-end) + (skip-chars-backward " \t") + (point)) + nil + (org-element-restriction 'inlinetask)))) + (dolist (datum title title) + (org-element-put-property datum :parent inlinetask)))))))) + +(defun org-element-inlinetask-interpreter (inlinetask contents) + "Interpret INLINETASK element as Org syntax. +CONTENTS is the contents of inlinetask." + (let* ((level (org-element-property :level inlinetask)) + (todo (org-element-property :todo-keyword inlinetask)) + (priority (org-element-property :priority inlinetask)) + (title (org-element-interpret-data + (org-element-property :title inlinetask))) + (tags (let ((tag-list (org-element-property :tags inlinetask))) + (and tag-list + (format ":%s:" (mapconcat 'identity tag-list ":"))))) + (task (concat (make-string level ?*) + (and todo (concat " " todo)) + (and priority (format " [#%c]" priority)) + (and title (concat " " title))))) + (concat task + ;; Align tags. + (when tags + (cond + ((zerop org-tags-column) (format " %s" tags)) + ((< org-tags-column 0) + (concat + (make-string + (max (- (+ org-tags-column (length task) (length tags))) 1) + ? ) + tags)) + (t + (concat + (make-string (max (- org-tags-column (length task)) 1) ? ) + tags)))) + ;; Prefer degenerate inlinetasks when there are no + ;; contents. + (when contents + (concat "\n" + contents + (make-string level ?*) " END"))))) + + +;;;; Item + +(defun org-element-item-parser (limit struct &optional raw-secondary-p) + "Parse an item. + +STRUCT is the structure of the plain list. + +Return a list whose CAR is `item' and CDR is a plist containing +`:bullet', `:begin', `:end', `:contents-begin', `:contents-end', +`:checkbox', `:counter', `:tag', `:structure', `:post-blank' and +`:post-affiliated' keywords. + +When optional argument RAW-SECONDARY-P is non-nil, item's tag, if +any, will not be parsed as a secondary string, but as a plain +string instead. + +Assume point is at the beginning of the item." + (save-excursion + (beginning-of-line) + (looking-at org-list-full-item-re) + (let* ((begin (point)) + (bullet (org-match-string-no-properties 1)) + (checkbox (let ((box (match-string 3))) + (cond ((equal "[ ]" box) 'off) + ((equal "[X]" box) 'on) + ((equal "[-]" box) 'trans)))) + (counter (let ((c (match-string 2))) + (save-match-data + (cond + ((not c) nil) + ((string-match "[A-Za-z]" c) + (- (string-to-char (upcase (match-string 0 c))) + 64)) + ((string-match "[0-9]+" c) + (string-to-number (match-string 0 c))))))) + (end (progn (goto-char (nth 6 (assq (point) struct))) + (if (bolp) (point) (line-beginning-position 2)))) + (contents-begin + (progn (goto-char + ;; Ignore tags in un-ordered lists: they are just + ;; a part of item's body. + (if (and (match-beginning 4) + (save-match-data (string-match "[.)]" bullet))) + (match-beginning 4) + (match-end 0))) + (skip-chars-forward " \r\t\n" end) + (cond ((= (point) end) nil) + ;; If first line isn't empty, contents really + ;; start at the text after item's meta-data. + ((= (line-beginning-position) begin) (point)) + (t (line-beginning-position))))) + (contents-end (and contents-begin + (progn (goto-char end) + (skip-chars-backward " \r\t\n") + (line-beginning-position 2)))) + (item + (list 'item + (list :bullet bullet + :begin begin + :end end + :contents-begin contents-begin + :contents-end contents-end + :checkbox checkbox + :counter counter + :structure struct + :post-blank (count-lines (or contents-end begin) end) + :post-affiliated begin)))) + (org-element-put-property + item :tag + (let ((raw (org-list-get-tag begin struct))) + (when raw + (if raw-secondary-p raw + (let ((tag (org-element--parse-objects + (match-beginning 4) (match-end 4) nil + (org-element-restriction 'item)))) + (dolist (datum tag tag) + (org-element-put-property datum :parent item)))))))))) + +(defun org-element-item-interpreter (item contents) + "Interpret ITEM element as Org syntax. +CONTENTS is the contents of the element." + (let* ((bullet (let ((bullet (org-element-property :bullet item))) + (org-list-bullet-string + (cond ((not (string-match "[0-9a-zA-Z]" bullet)) "- ") + ((eq org-plain-list-ordered-item-terminator ?\)) "1)") + (t "1."))))) + (checkbox (org-element-property :checkbox item)) + (counter (org-element-property :counter item)) + (tag (let ((tag (org-element-property :tag item))) + (and tag (org-element-interpret-data tag)))) + ;; Compute indentation. + (ind (make-string (length bullet) 32)) + (item-starts-with-par-p + (eq (org-element-type (car (org-element-contents item))) + 'paragraph))) + ;; Indent contents. + (concat + bullet + (and counter (format "[@%d] " counter)) + (case checkbox + (on "[X] ") + (off "[ ] ") + (trans "[-] ")) + (and tag (format "%s :: " tag)) + (when contents + (let ((contents (replace-regexp-in-string + "\\(^\\)[ \t]*\\S-" ind contents nil nil 1))) + (if item-starts-with-par-p (org-trim contents) + (concat "\n" contents))))))) + + +;;;; Plain List + +(defun org-element--list-struct (limit) + ;; Return structure of list at point. Internal function. See + ;; `org-list-struct' for details. + (let ((case-fold-search t) + (top-ind limit) + (item-re (org-item-re)) + (inlinetask-re (and (featurep 'org-inlinetask) "^\\*+ ")) + items struct) + (save-excursion + (catch 'exit + (while t + (cond + ;; At limit: end all items. + ((>= (point) limit) + (throw 'exit + (let ((end (progn (skip-chars-backward " \r\t\n") + (forward-line) + (point)))) + (dolist (item items (sort (nconc items struct) + 'car-less-than-car)) + (setcar (nthcdr 6 item) end))))) + ;; At list end: end all items. + ((looking-at org-list-end-re) + (throw 'exit (dolist (item items (sort (nconc items struct) + 'car-less-than-car)) + (setcar (nthcdr 6 item) (point))))) + ;; At a new item: end previous sibling. + ((looking-at item-re) + (let ((ind (save-excursion (skip-chars-forward " \t") + (current-column)))) + (setq top-ind (min top-ind ind)) + (while (and items (<= ind (nth 1 (car items)))) + (let ((item (pop items))) + (setcar (nthcdr 6 item) (point)) + (push item struct))) + (push (progn (looking-at org-list-full-item-re) + (let ((bullet (match-string-no-properties 1))) + (list (point) + ind + bullet + (match-string-no-properties 2) ; counter + (match-string-no-properties 3) ; checkbox + ;; Description tag. + (and (save-match-data + (string-match "[-+*]" bullet)) + (match-string-no-properties 4)) + ;; Ending position, unknown so far. + nil))) + items)) + (forward-line 1)) + ;; Skip empty lines. + ((looking-at "^[ \t]*$") (forward-line)) + ;; Skip inline tasks and blank lines along the way. + ((and inlinetask-re (looking-at inlinetask-re)) + (forward-line) + (let ((origin (point))) + (when (re-search-forward inlinetask-re limit t) + (if (org-looking-at-p "END[ \t]*$") (forward-line) + (goto-char origin))))) + ;; At some text line. Check if it ends any previous item. + (t + (let ((ind (save-excursion (skip-chars-forward " \t") + (current-column)))) + (when (<= ind top-ind) + (skip-chars-backward " \r\t\n") + (forward-line)) + (while (<= ind (nth 1 (car items))) + (let ((item (pop items))) + (setcar (nthcdr 6 item) (line-beginning-position)) + (push item struct) + (unless items + (throw 'exit (sort struct #'car-less-than-car)))))) + ;; Skip blocks (any type) and drawers contents. + (cond + ((and (looking-at "[ \t]*#\\+BEGIN\\(:\\|_\\S-+\\)") + (re-search-forward + (format "^[ \t]*#\\+END%s[ \t]*$" (match-string 1)) + limit t))) + ((and (looking-at org-drawer-regexp) + (re-search-forward "^[ \t]*:END:[ \t]*$" limit t)))) + (forward-line)))))))) + +(defun org-element-plain-list-parser (limit affiliated structure) + "Parse a plain list. + +LIMIT bounds the search. AFFILIATED is a list of which CAR is +the buffer position at the beginning of the first affiliated +keyword and CDR is a plist of affiliated keywords along with +their value. STRUCTURE is the structure of the plain list being +parsed. + +Return a list whose CAR is `plain-list' and CDR is a plist +containing `:type', `:begin', `:end', `:contents-begin' and +`:contents-end', `:structure', `:post-blank' and +`:post-affiliated' keywords. + +Assume point is at the beginning of the list." + (save-excursion + (let* ((struct (or structure (org-element--list-struct limit))) + (type (cond ((org-looking-at-p "[ \t]*[A-Za-z0-9]") 'ordered) + ((nth 5 (assq (point) struct)) 'descriptive) + (t 'unordered))) + (contents-begin (point)) + (begin (car affiliated)) + (contents-end (let* ((item (assq contents-begin struct)) + (ind (nth 1 item)) + (pos (nth 6 item))) + (while (and (setq item (assq pos struct)) + (= (nth 1 item) ind)) + (setq pos (nth 6 item))) + pos)) + (end (progn (goto-char contents-end) + (skip-chars-forward " \r\t\n" limit) + (if (= (point) limit) limit (line-beginning-position))))) + ;; Return value. + (list 'plain-list + (nconc + (list :type type + :begin begin + :end end + :contents-begin contents-begin + :contents-end contents-end + :structure struct + :post-blank (count-lines contents-end end) + :post-affiliated contents-begin) + (cdr affiliated)))))) + +(defun org-element-plain-list-interpreter (plain-list contents) + "Interpret PLAIN-LIST element as Org syntax. +CONTENTS is the contents of the element." + (with-temp-buffer + (insert contents) + (goto-char (point-min)) + (org-list-repair) + (buffer-string))) + + +;;;; Property Drawer + +(defun org-element-property-drawer-parser (limit) + "Parse a property drawer. + +LIMIT bounds the search. + +Return a list whose car is `property-drawer' and cdr is a plist +containing `:begin', `:end', `:contents-begin', `:contents-end', +`:post-blank' and `:post-affiliated' keywords. + +Assume point is at the beginning of the property drawer." + (save-excursion + (let ((case-fold-search t) + (begin (point)) + (contents-begin (line-beginning-position 2))) + (re-search-forward "^[ \t]*:END:[ \t]*$" limit t) + (let ((contents-end (and (> (match-beginning 0) contents-begin) + (match-beginning 0))) + (before-blank (progn (forward-line) (point))) + (end (progn (skip-chars-forward " \r\t\n" limit) + (if (eobp) (point) (line-beginning-position))))) + (list 'property-drawer + (list :begin begin + :end end + :contents-begin (and contents-end contents-begin) + :contents-end contents-end + :post-blank (count-lines before-blank end) + :post-affiliated begin)))))) + +(defun org-element-property-drawer-interpreter (property-drawer contents) + "Interpret PROPERTY-DRAWER element as Org syntax. +CONTENTS is the properties within the drawer." + (format ":PROPERTIES:\n%s:END:" contents)) + + +;;;; Quote Block + +(defun org-element-quote-block-parser (limit affiliated) + "Parse a quote block. + +LIMIT bounds the search. AFFILIATED is a list of which CAR is +the buffer position at the beginning of the first affiliated +keyword and CDR is a plist of affiliated keywords along with +their value. + +Return a list whose CAR is `quote-block' and CDR is a plist +containing `:begin', `:end', `:contents-begin', `:contents-end', +`:post-blank' and `:post-affiliated' keywords. + +Assume point is at the beginning of the block." + (let ((case-fold-search t)) + (if (not (save-excursion + (re-search-forward "^[ \t]*#\\+END_QUOTE[ \t]*$" limit t))) + ;; Incomplete block: parse it as a paragraph. + (org-element-paragraph-parser limit affiliated) + (let ((block-end-line (match-beginning 0))) + (save-excursion + (let* ((begin (car affiliated)) + (post-affiliated (point)) + ;; Empty blocks have no contents. + (contents-begin (progn (forward-line) + (and (< (point) block-end-line) + (point)))) + (contents-end (and contents-begin block-end-line)) + (pos-before-blank (progn (goto-char block-end-line) + (forward-line) + (point))) + (end (progn (skip-chars-forward " \r\t\n" limit) + (if (eobp) (point) (line-beginning-position))))) + (list 'quote-block + (nconc + (list :begin begin + :end end + :contents-begin contents-begin + :contents-end contents-end + :post-blank (count-lines pos-before-blank end) + :post-affiliated post-affiliated) + (cdr affiliated))))))))) + +(defun org-element-quote-block-interpreter (quote-block contents) + "Interpret QUOTE-BLOCK element as Org syntax. +CONTENTS is the contents of the element." + (format "#+BEGIN_QUOTE\n%s#+END_QUOTE" contents)) + + +;;;; Section + +(defun org-element-section-parser (limit) + "Parse a section. + +LIMIT bounds the search. + +Return a list whose CAR is `section' and CDR is a plist +containing `:begin', `:end', `:contents-begin', `contents-end', +`:post-blank' and `:post-affiliated' keywords." + (save-excursion + ;; Beginning of section is the beginning of the first non-blank + ;; line after previous headline. + (let ((begin (point)) + (end (progn (org-with-limited-levels (outline-next-heading)) + (point))) + (pos-before-blank (progn (skip-chars-backward " \r\t\n") + (forward-line) + (point)))) + (list 'section + (list :begin begin + :end end + :contents-begin begin + :contents-end pos-before-blank + :post-blank (count-lines pos-before-blank end) + :post-affiliated begin))))) + +(defun org-element-section-interpreter (section contents) + "Interpret SECTION element as Org syntax. +CONTENTS is the contents of the element." + contents) + + +;;;; Special Block + +(defun org-element-special-block-parser (limit affiliated) + "Parse a special block. + +LIMIT bounds the search. AFFILIATED is a list of which CAR is +the buffer position at the beginning of the first affiliated +keyword and CDR is a plist of affiliated keywords along with +their value. + +Return a list whose CAR is `special-block' and CDR is a plist +containing `:type', `:begin', `:end', `:contents-begin', +`:contents-end', `:post-blank' and `:post-affiliated' keywords. + +Assume point is at the beginning of the block." + (let* ((case-fold-search t) + (type (progn (looking-at "[ \t]*#\\+BEGIN_\\(\\S-+\\)") + (match-string-no-properties 1)))) + (if (not (save-excursion + (re-search-forward + (format "^[ \t]*#\\+END_%s[ \t]*$" (regexp-quote type)) + limit t))) + ;; Incomplete block: parse it as a paragraph. + (org-element-paragraph-parser limit affiliated) + (let ((block-end-line (match-beginning 0))) + (save-excursion + (let* ((begin (car affiliated)) + (post-affiliated (point)) + ;; Empty blocks have no contents. + (contents-begin (progn (forward-line) + (and (< (point) block-end-line) + (point)))) + (contents-end (and contents-begin block-end-line)) + (pos-before-blank (progn (goto-char block-end-line) + (forward-line) + (point))) + (end (progn (skip-chars-forward " \r\t\n" limit) + (if (eobp) (point) (line-beginning-position))))) + (list 'special-block + (nconc + (list :type type + :begin begin + :end end + :contents-begin contents-begin + :contents-end contents-end + :post-blank (count-lines pos-before-blank end) + :post-affiliated post-affiliated) + (cdr affiliated))))))))) + +(defun org-element-special-block-interpreter (special-block contents) + "Interpret SPECIAL-BLOCK element as Org syntax. +CONTENTS is the contents of the element." + (let ((block-type (org-element-property :type special-block))) + (format "#+BEGIN_%s\n%s#+END_%s" block-type contents block-type))) + + + +;;; Elements +;; +;; For each element, a parser and an interpreter are also defined. +;; Both follow the same naming convention used for greater elements. +;; +;; Also, as for greater elements, adding a new element type is done +;; through the following steps: implement a parser and an interpreter, +;; tweak `org-element--current-element' so that it recognizes the new +;; type and add that new type to `org-element-all-elements'. +;; +;; As a special case, when the newly defined type is a block type, +;; `org-element-block-name-alist' has to be modified accordingly. + + +;;;; Babel Call + +(defun org-element-babel-call-parser (limit affiliated) + "Parse a babel call. + +LIMIT bounds the search. AFFILIATED is a list of which car is +the buffer position at the beginning of the first affiliated +keyword and cdr is a plist of affiliated keywords along with +their value. + +Return a list whose car is `babel-call' and cdr is a plist +containing `:call', `:inside-header', `:arguments', +`:end-header', `:begin', `:end', `:value', `:post-blank' and +`:post-affiliated' as keywords." + (save-excursion + (let* ((begin (car affiliated)) + (post-affiliated (point)) + (value (progn (search-forward ":" nil t) + (org-trim + (buffer-substring-no-properties + (point) (line-end-position))))) + (pos-before-blank (progn (forward-line) (point))) + (end (progn (skip-chars-forward " \r\t\n" limit) + (if (eobp) (point) (line-beginning-position)))) + (valid-value + (string-match + "\\([^()\n]+?\\)\\(?:\\[\\(.*?\\)\\]\\)?(\\(.*\\))[ \t]*\\(.*\\)" + value))) + (list 'babel-call + (nconc + (list :call (and valid-value (match-string 1 value)) + :inside-header (and valid-value + (org-string-nw-p (match-string 2 value))) + :arguments (and valid-value + (org-string-nw-p (match-string 3 value))) + :end-header (and valid-value + (org-string-nw-p (match-string 4 value))) + :begin begin + :end end + :value value + :post-blank (count-lines pos-before-blank end) + :post-affiliated post-affiliated) + (cdr affiliated)))))) + +(defun org-element-babel-call-interpreter (babel-call contents) + "Interpret BABEL-CALL element as Org syntax. +CONTENTS is nil." + (concat "#+CALL: " + (org-element-property :call babel-call) + (let ((h (org-element-property :inside-header babel-call))) + (and h (format "[%s]" h))) + (concat "(" (org-element-property :arguments babel-call) ")") + (let ((h (org-element-property :end-header babel-call))) + (and h (concat " " h))))) + + +;;;; Clock + +(defun org-element-clock-parser (limit) + "Parse a clock. + +LIMIT bounds the search. + +Return a list whose CAR is `clock' and CDR is a plist containing +`:status', `:value', `:time', `:begin', `:end', `:post-blank' and +`:post-affiliated' as keywords." + (save-excursion + (let* ((case-fold-search nil) + (begin (point)) + (value (progn (search-forward org-clock-string (line-end-position) t) + (skip-chars-forward " \t") + (org-element-timestamp-parser))) + (duration (and (search-forward " => " (line-end-position) t) + (progn (skip-chars-forward " \t") + (looking-at "\\(\\S-+\\)[ \t]*$")) + (org-match-string-no-properties 1))) + (status (if duration 'closed 'running)) + (post-blank (let ((before-blank (progn (forward-line) (point)))) + (skip-chars-forward " \r\t\n" limit) + (skip-chars-backward " \t") + (unless (bolp) (end-of-line)) + (count-lines before-blank (point)))) + (end (point))) + (list 'clock + (list :status status + :value value + :duration duration + :begin begin + :end end + :post-blank post-blank + :post-affiliated begin))))) + +(defun org-element-clock-interpreter (clock contents) + "Interpret CLOCK element as Org syntax. +CONTENTS is nil." + (concat org-clock-string " " + (org-element-timestamp-interpreter + (org-element-property :value clock) nil) + (let ((duration (org-element-property :duration clock))) + (and duration + (concat " => " + (apply 'format + "%2s:%02s" + (org-split-string duration ":"))))))) + + +;;;; Comment + +(defun org-element-comment-parser (limit affiliated) + "Parse a comment. + +LIMIT bounds the search. AFFILIATED is a list of which CAR is +the buffer position at the beginning of the first affiliated +keyword and CDR is a plist of affiliated keywords along with +their value. + +Return a list whose CAR is `comment' and CDR is a plist +containing `:begin', `:end', `:value', `:post-blank', +`:post-affiliated' keywords. + +Assume point is at comment beginning." + (save-excursion + (let* ((begin (car affiliated)) + (post-affiliated (point)) + (value (prog2 (looking-at "[ \t]*# ?") + (buffer-substring-no-properties + (match-end 0) (line-end-position)) + (forward-line))) + (com-end + ;; Get comments ending. + (progn + (while (and (< (point) limit) (looking-at "[ \t]*#\\( \\|$\\)")) + ;; Accumulate lines without leading hash and first + ;; whitespace. + (setq value + (concat value + "\n" + (buffer-substring-no-properties + (match-end 0) (line-end-position)))) + (forward-line)) + (point))) + (end (progn (goto-char com-end) + (skip-chars-forward " \r\t\n" limit) + (if (eobp) (point) (line-beginning-position))))) + (list 'comment + (nconc + (list :begin begin + :end end + :value value + :post-blank (count-lines com-end end) + :post-affiliated post-affiliated) + (cdr affiliated)))))) + +(defun org-element-comment-interpreter (comment contents) + "Interpret COMMENT element as Org syntax. +CONTENTS is nil." + (replace-regexp-in-string "^" "# " (org-element-property :value comment))) + + +;;;; Comment Block + +(defun org-element-comment-block-parser (limit affiliated) + "Parse an export block. + +LIMIT bounds the search. AFFILIATED is a list of which CAR is +the buffer position at the beginning of the first affiliated +keyword and CDR is a plist of affiliated keywords along with +their value. + +Return a list whose CAR is `comment-block' and CDR is a plist +containing `:begin', `:end', `:value', `:post-blank' and +`:post-affiliated' keywords. + +Assume point is at comment block beginning." + (let ((case-fold-search t)) + (if (not (save-excursion + (re-search-forward "^[ \t]*#\\+END_COMMENT[ \t]*$" limit t))) + ;; Incomplete block: parse it as a paragraph. + (org-element-paragraph-parser limit affiliated) + (let ((contents-end (match-beginning 0))) + (save-excursion + (let* ((begin (car affiliated)) + (post-affiliated (point)) + (contents-begin (progn (forward-line) (point))) + (pos-before-blank (progn (goto-char contents-end) + (forward-line) + (point))) + (end (progn (skip-chars-forward " \r\t\n" limit) + (if (eobp) (point) (line-beginning-position)))) + (value (buffer-substring-no-properties + contents-begin contents-end))) + (list 'comment-block + (nconc + (list :begin begin + :end end + :value value + :post-blank (count-lines pos-before-blank end) + :post-affiliated post-affiliated) + (cdr affiliated))))))))) + +(defun org-element-comment-block-interpreter (comment-block contents) + "Interpret COMMENT-BLOCK element as Org syntax. +CONTENTS is nil." + (format "#+BEGIN_COMMENT\n%s#+END_COMMENT" + (org-element-normalize-string + (org-remove-indentation + (org-element-property :value comment-block))))) + + +;;;; Diary Sexp + +(defun org-element-diary-sexp-parser (limit affiliated) + "Parse a diary sexp. + +LIMIT bounds the search. AFFILIATED is a list of which CAR is +the buffer position at the beginning of the first affiliated +keyword and CDR is a plist of affiliated keywords along with +their value. + +Return a list whose CAR is `diary-sexp' and CDR is a plist +containing `:begin', `:end', `:value', `:post-blank' and +`:post-affiliated' keywords." + (save-excursion + (let ((begin (car affiliated)) + (post-affiliated (point)) + (value (progn (looking-at "\\(%%(.*\\)[ \t]*$") + (org-match-string-no-properties 1))) + (pos-before-blank (progn (forward-line) (point))) + (end (progn (skip-chars-forward " \r\t\n" limit) + (if (eobp) (point) (line-beginning-position))))) + (list 'diary-sexp + (nconc + (list :value value + :begin begin + :end end + :post-blank (count-lines pos-before-blank end) + :post-affiliated post-affiliated) + (cdr affiliated)))))) + +(defun org-element-diary-sexp-interpreter (diary-sexp contents) + "Interpret DIARY-SEXP as Org syntax. +CONTENTS is nil." + (org-element-property :value diary-sexp)) + + +;;;; Example Block + +(defun org-element-example-block-parser (limit affiliated) + "Parse an example block. + +LIMIT bounds the search. AFFILIATED is a list of which CAR is +the buffer position at the beginning of the first affiliated +keyword and CDR is a plist of affiliated keywords along with +their value. + +Return a list whose CAR is `example-block' and CDR is a plist +containing `:begin', `:end', `:number-lines', `:preserve-indent', +`:retain-labels', `:use-labels', `:label-fmt', `:switches', +`:value', `:post-blank' and `:post-affiliated' keywords." + (let ((case-fold-search t)) + (if (not (save-excursion + (re-search-forward "^[ \t]*#\\+END_EXAMPLE[ \t]*$" limit t))) + ;; Incomplete block: parse it as a paragraph. + (org-element-paragraph-parser limit affiliated) + (let ((contents-end (match-beginning 0))) + (save-excursion + (let* ((switches + (progn + (looking-at "^[ \t]*#\\+BEGIN_EXAMPLE\\(?: +\\(.*\\)\\)?") + (org-match-string-no-properties 1))) + ;; Switches analysis + (number-lines + (cond ((not switches) nil) + ((string-match "-n\\>" switches) 'new) + ((string-match "+n\\>" switches) 'continued))) + (preserve-indent + (and switches (string-match "-i\\>" switches))) + ;; Should labels be retained in (or stripped from) example + ;; blocks? + (retain-labels + (or (not switches) + (not (string-match "-r\\>" switches)) + (and number-lines (string-match "-k\\>" switches)))) + ;; What should code-references use - labels or + ;; line-numbers? + (use-labels + (or (not switches) + (and retain-labels + (not (string-match "-k\\>" switches))))) + (label-fmt + (and switches + (string-match "-l +\"\\([^\"\n]+\\)\"" switches) + (match-string 1 switches))) + ;; Standard block parsing. + (begin (car affiliated)) + (post-affiliated (point)) + (block-ind (progn (skip-chars-forward " \t") (current-column))) + (contents-begin (progn (forward-line) (point))) + (value (org-element-remove-indentation + (org-unescape-code-in-string + (buffer-substring-no-properties + contents-begin contents-end)) + block-ind)) + (pos-before-blank (progn (goto-char contents-end) + (forward-line) + (point))) + (end (progn (skip-chars-forward " \r\t\n" limit) + (if (eobp) (point) (line-beginning-position))))) + (list 'example-block + (nconc + (list :begin begin + :end end + :value value + :switches switches + :number-lines number-lines + :preserve-indent preserve-indent + :retain-labels retain-labels + :use-labels use-labels + :label-fmt label-fmt + :post-blank (count-lines pos-before-blank end) + :post-affiliated post-affiliated) + (cdr affiliated))))))))) + +(defun org-element-example-block-interpreter (example-block contents) + "Interpret EXAMPLE-BLOCK element as Org syntax. +CONTENTS is nil." + (let ((switches (org-element-property :switches example-block)) + (value (org-element-property :value example-block))) + (concat "#+BEGIN_EXAMPLE" (and switches (concat " " switches)) "\n" + (org-element-normalize-string + (org-escape-code-in-string + (if (or org-src-preserve-indentation + (org-element-property :preserve-indent example-block)) + value + (org-element-remove-indentation value)))) + "#+END_EXAMPLE"))) + + +;;;; Export Block + +(defun org-element-export-block-parser (limit affiliated) + "Parse an export block. + +LIMIT bounds the search. AFFILIATED is a list of which CAR is +the buffer position at the beginning of the first affiliated +keyword and CDR is a plist of affiliated keywords along with +their value. + +Return a list whose CAR is `export-block' and CDR is a plist +containing `:begin', `:end', `:type', `:value', `:post-blank' and +`:post-affiliated' keywords. + +Assume point is at export-block beginning." + (let* ((case-fold-search t) + (type (progn (looking-at "[ \t]*#\\+BEGIN_\\(\\S-+\\)") + (upcase (org-match-string-no-properties 1))))) + (if (not (save-excursion + (re-search-forward + (format "^[ \t]*#\\+END_%s[ \t]*$" type) limit t))) + ;; Incomplete block: parse it as a paragraph. + (org-element-paragraph-parser limit affiliated) + (let ((contents-end (match-beginning 0))) + (save-excursion + (let* ((begin (car affiliated)) + (post-affiliated (point)) + (contents-begin (progn (forward-line) (point))) + (pos-before-blank (progn (goto-char contents-end) + (forward-line) + (point))) + (end (progn (skip-chars-forward " \r\t\n" limit) + (if (eobp) (point) (line-beginning-position)))) + (value (buffer-substring-no-properties contents-begin + contents-end))) + (list 'export-block + (nconc + (list :begin begin + :end end + :type type + :value value + :post-blank (count-lines pos-before-blank end) + :post-affiliated post-affiliated) + (cdr affiliated))))))))) + +(defun org-element-export-block-interpreter (export-block contents) + "Interpret EXPORT-BLOCK element as Org syntax. +CONTENTS is nil." + (let ((type (org-element-property :type export-block))) + (concat (format "#+BEGIN_%s\n" type) + (org-element-property :value export-block) + (format "#+END_%s" type)))) + + +;;;; Fixed-width + +(defun org-element-fixed-width-parser (limit affiliated) + "Parse a fixed-width section. + +LIMIT bounds the search. AFFILIATED is a list of which CAR is +the buffer position at the beginning of the first affiliated +keyword and CDR is a plist of affiliated keywords along with +their value. + +Return a list whose CAR is `fixed-width' and CDR is a plist +containing `:begin', `:end', `:value', `:post-blank' and +`:post-affiliated' keywords. + +Assume point is at the beginning of the fixed-width area." + (save-excursion + (let* ((begin (car affiliated)) + (post-affiliated (point)) + value + (end-area + (progn + (while (and (< (point) limit) + (looking-at "[ \t]*:\\( \\|$\\)")) + ;; Accumulate text without starting colons. + (setq value + (concat value + (buffer-substring-no-properties + (match-end 0) (point-at-eol)) + "\n")) + (forward-line)) + (point))) + (end (progn (skip-chars-forward " \r\t\n" limit) + (if (eobp) (point) (line-beginning-position))))) + (list 'fixed-width + (nconc + (list :begin begin + :end end + :value value + :post-blank (count-lines end-area end) + :post-affiliated post-affiliated) + (cdr affiliated)))))) + +(defun org-element-fixed-width-interpreter (fixed-width contents) + "Interpret FIXED-WIDTH element as Org syntax. +CONTENTS is nil." + (let ((value (org-element-property :value fixed-width))) + (and value + (replace-regexp-in-string + "^" ": " + (if (string-match "\n\\'" value) (substring value 0 -1) value))))) + + +;;;; Horizontal Rule + +(defun org-element-horizontal-rule-parser (limit affiliated) + "Parse an horizontal rule. + +LIMIT bounds the search. AFFILIATED is a list of which CAR is +the buffer position at the beginning of the first affiliated +keyword and CDR is a plist of affiliated keywords along with +their value. + +Return a list whose CAR is `horizontal-rule' and CDR is a plist +containing `:begin', `:end', `:post-blank' and `:post-affiliated' +keywords." + (save-excursion + (let ((begin (car affiliated)) + (post-affiliated (point)) + (post-hr (progn (forward-line) (point))) + (end (progn (skip-chars-forward " \r\t\n" limit) + (if (eobp) (point) (line-beginning-position))))) + (list 'horizontal-rule + (nconc + (list :begin begin + :end end + :post-blank (count-lines post-hr end) + :post-affiliated post-affiliated) + (cdr affiliated)))))) + +(defun org-element-horizontal-rule-interpreter (horizontal-rule contents) + "Interpret HORIZONTAL-RULE element as Org syntax. +CONTENTS is nil." + "-----") + + +;;;; Keyword + +(defun org-element-keyword-parser (limit affiliated) + "Parse a keyword at point. + +LIMIT bounds the search. AFFILIATED is a list of which CAR is +the buffer position at the beginning of the first affiliated +keyword and CDR is a plist of affiliated keywords along with +their value. + +Return a list whose CAR is `keyword' and CDR is a plist +containing `:key', `:value', `:begin', `:end', `:post-blank' and +`:post-affiliated' keywords." + (save-excursion + ;; An orphaned affiliated keyword is considered as a regular + ;; keyword. In this case AFFILIATED is nil, so we take care of + ;; this corner case. + (let ((begin (or (car affiliated) (point))) + (post-affiliated (point)) + (key (progn (looking-at "[ \t]*#\\+\\(\\S-+*\\):") + (upcase (org-match-string-no-properties 1)))) + (value (org-trim (buffer-substring-no-properties + (match-end 0) (point-at-eol)))) + (pos-before-blank (progn (forward-line) (point))) + (end (progn (skip-chars-forward " \r\t\n" limit) + (if (eobp) (point) (line-beginning-position))))) + (list 'keyword + (nconc + (list :key key + :value value + :begin begin + :end end + :post-blank (count-lines pos-before-blank end) + :post-affiliated post-affiliated) + (cdr affiliated)))))) + +(defun org-element-keyword-interpreter (keyword contents) + "Interpret KEYWORD element as Org syntax. +CONTENTS is nil." + (format "#+%s: %s" + (org-element-property :key keyword) + (org-element-property :value keyword))) + + +;;;; Latex Environment + +(defconst org-element--latex-begin-environment + "^[ \t]*\\\\begin{\\([A-Za-z0-9*]+\\)}" + "Regexp matching the beginning of a LaTeX environment. +The environment is captured by the first group. + +See also `org-element--latex-end-environment'.") + +(defconst org-element--latex-end-environment + "\\\\end{%s}[ \t]*$" + "Format string matching the ending of a LaTeX environment. +See also `org-element--latex-begin-environment'.") + +(defun org-element-latex-environment-parser (limit affiliated) + "Parse a LaTeX environment. + +LIMIT bounds the search. AFFILIATED is a list of which CAR is +the buffer position at the beginning of the first affiliated +keyword and CDR is a plist of affiliated keywords along with +their value. + +Return a list whose CAR is `latex-environment' and CDR is a plist +containing `:begin', `:end', `:value', `:post-blank' and +`:post-affiliated' keywords. + +Assume point is at the beginning of the latex environment." + (save-excursion + (let ((case-fold-search t) + (code-begin (point))) + (looking-at org-element--latex-begin-environment) + (if (not (re-search-forward (format org-element--latex-end-environment + (regexp-quote (match-string 1))) + limit t)) + ;; Incomplete latex environment: parse it as a paragraph. + (org-element-paragraph-parser limit affiliated) + (let* ((code-end (progn (forward-line) (point))) + (begin (car affiliated)) + (value (buffer-substring-no-properties code-begin code-end)) + (end (progn (skip-chars-forward " \r\t\n" limit) + (if (eobp) (point) (line-beginning-position))))) + (list 'latex-environment + (nconc + (list :begin begin + :end end + :value value + :post-blank (count-lines code-end end) + :post-affiliated code-begin) + (cdr affiliated)))))))) + +(defun org-element-latex-environment-interpreter (latex-environment contents) + "Interpret LATEX-ENVIRONMENT element as Org syntax. +CONTENTS is nil." + (org-element-property :value latex-environment)) + + +;;;; Node Property + +(defun org-element-node-property-parser (limit) + "Parse a node-property at point. + +LIMIT bounds the search. + +Return a list whose CAR is `node-property' and CDR is a plist +containing `:key', `:value', `:begin', `:end', `:post-blank' and +`:post-affiliated' keywords." + (looking-at org-property-re) + (let ((case-fold-search t) + (begin (point)) + (key (org-match-string-no-properties 2)) + (value (org-match-string-no-properties 3)) + (end (save-excursion + (end-of-line) + (if (re-search-forward org-property-re limit t) + (line-beginning-position) + limit)))) + (list 'node-property + (list :key key + :value value + :begin begin + :end end + :post-blank 0 + :post-affiliated begin)))) + +(defun org-element-node-property-interpreter (node-property contents) + "Interpret NODE-PROPERTY element as Org syntax. +CONTENTS is nil." + (format org-property-format + (format ":%s:" (org-element-property :key node-property)) + (or (org-element-property :value node-property) ""))) + + +;;;; Paragraph + +(defun org-element-paragraph-parser (limit affiliated) + "Parse a paragraph. + +LIMIT bounds the search. AFFILIATED is a list of which CAR is +the buffer position at the beginning of the first affiliated +keyword and CDR is a plist of affiliated keywords along with +their value. + +Return a list whose CAR is `paragraph' and CDR is a plist +containing `:begin', `:end', `:contents-begin' and +`:contents-end', `:post-blank' and `:post-affiliated' keywords. + +Assume point is at the beginning of the paragraph." + (save-excursion + (let* ((begin (car affiliated)) + (contents-begin (point)) + (before-blank + (let ((case-fold-search t)) + (end-of-line) + ;; A matching `org-element-paragraph-separate' is not + ;; necessarily the end of the paragraph. In particular, + ;; drawers, blocks or LaTeX environments opening lines + ;; must be closed. Moreover keywords with a secondary + ;; value must belong to "dual keywords". + (while (not + (cond + ((not (and (re-search-forward + org-element-paragraph-separate limit 'move) + (progn (beginning-of-line) t)))) + ((looking-at org-drawer-regexp) + (save-excursion + (re-search-forward "^[ \t]*:END:[ \t]*$" limit t))) + ((looking-at "[ \t]*#\\+BEGIN_\\(\\S-+\\)") + (save-excursion + (re-search-forward + (format "^[ \t]*#\\+END_%s[ \t]*$" + (regexp-quote (match-string 1))) + limit t))) + ((looking-at org-element--latex-begin-environment) + (save-excursion + (re-search-forward + (format org-element--latex-end-environment + (regexp-quote (match-string 1))) + limit t))) + ((looking-at "[ \t]*#\\+\\(\\S-+\\)\\[.*\\]:") + (member-ignore-case (match-string 1) + org-element-dual-keywords)) + ;; Everything else is unambiguous. + (t))) + (end-of-line)) + (if (= (point) limit) limit + (goto-char (line-beginning-position))))) + (contents-end (save-excursion + (skip-chars-backward " \r\t\n" contents-begin) + (line-beginning-position 2))) + (end (progn (skip-chars-forward " \r\t\n" limit) + (if (eobp) (point) (line-beginning-position))))) + (list 'paragraph + (nconc + (list :begin begin + :end end + :contents-begin contents-begin + :contents-end contents-end + :post-blank (count-lines before-blank end) + :post-affiliated contents-begin) + (cdr affiliated)))))) + +(defun org-element-paragraph-interpreter (paragraph contents) + "Interpret PARAGRAPH element as Org syntax. +CONTENTS is the contents of the element." + contents) + + +;;;; Planning + +(defun org-element-planning-parser (limit) + "Parse a planning. + +LIMIT bounds the search. + +Return a list whose CAR is `planning' and CDR is a plist +containing `:closed', `:deadline', `:scheduled', `:begin', +`:end', `:post-blank' and `:post-affiliated' keywords." + (save-excursion + (let* ((case-fold-search nil) + (begin (point)) + (post-blank (let ((before-blank (progn (forward-line) (point)))) + (skip-chars-forward " \r\t\n" limit) + (skip-chars-backward " \t") + (unless (bolp) (end-of-line)) + (count-lines before-blank (point)))) + (end (point)) + closed deadline scheduled) + (goto-char begin) + (while (re-search-forward org-keyword-time-not-clock-regexp end t) + (goto-char (match-end 1)) + (skip-chars-forward " \t" end) + (let ((keyword (match-string 1)) + (time (org-element-timestamp-parser))) + (cond ((equal keyword org-closed-string) (setq closed time)) + ((equal keyword org-deadline-string) (setq deadline time)) + (t (setq scheduled time))))) + (list 'planning + (list :closed closed + :deadline deadline + :scheduled scheduled + :begin begin + :end end + :post-blank post-blank + :post-affiliated begin))))) + +(defun org-element-planning-interpreter (planning contents) + "Interpret PLANNING element as Org syntax. +CONTENTS is nil." + (mapconcat + 'identity + (delq nil + (list (let ((deadline (org-element-property :deadline planning))) + (when deadline + (concat org-deadline-string " " + (org-element-timestamp-interpreter deadline nil)))) + (let ((scheduled (org-element-property :scheduled planning))) + (when scheduled + (concat org-scheduled-string " " + (org-element-timestamp-interpreter scheduled nil)))) + (let ((closed (org-element-property :closed planning))) + (when closed + (concat org-closed-string " " + (org-element-timestamp-interpreter closed nil)))))) + " ")) + + +;;;; Src Block + +(defun org-element-src-block-parser (limit affiliated) + "Parse a src block. + +LIMIT bounds the search. AFFILIATED is a list of which CAR is +the buffer position at the beginning of the first affiliated +keyword and CDR is a plist of affiliated keywords along with +their value. + +Return a list whose CAR is `src-block' and CDR is a plist +containing `:language', `:switches', `:parameters', `:begin', +`:end', `:number-lines', `:retain-labels', `:use-labels', +`:label-fmt', `:preserve-indent', `:value', `:post-blank' and +`:post-affiliated' keywords. + +Assume point is at the beginning of the block." + (let ((case-fold-search t)) + (if (not (save-excursion (re-search-forward "^[ \t]*#\\+END_SRC[ \t]*$" + limit t))) + ;; Incomplete block: parse it as a paragraph. + (org-element-paragraph-parser limit affiliated) + (let ((contents-end (match-beginning 0))) + (save-excursion + (let* ((begin (car affiliated)) + (post-affiliated (point)) + ;; Get language as a string. + (language + (progn + (looking-at + (concat "^[ \t]*#\\+BEGIN_SRC" + "\\(?: +\\(\\S-+\\)\\)?" + "\\(\\(?: +\\(?:-l \".*?\"\\|[-+][A-Za-z]\\)\\)+\\)?" + "\\(.*\\)[ \t]*$")) + (org-match-string-no-properties 1))) + ;; Get switches. + (switches (org-match-string-no-properties 2)) + ;; Get parameters. + (parameters (org-match-string-no-properties 3)) + ;; Switches analysis + (number-lines + (cond ((not switches) nil) + ((string-match "-n\\>" switches) 'new) + ((string-match "+n\\>" switches) 'continued))) + (preserve-indent (and switches + (string-match "-i\\>" switches))) + (label-fmt + (and switches + (string-match "-l +\"\\([^\"\n]+\\)\"" switches) + (match-string 1 switches))) + ;; Should labels be retained in (or stripped from) + ;; src blocks? + (retain-labels + (or (not switches) + (not (string-match "-r\\>" switches)) + (and number-lines (string-match "-k\\>" switches)))) + ;; What should code-references use - labels or + ;; line-numbers? + (use-labels + (or (not switches) + (and retain-labels + (not (string-match "-k\\>" switches))))) + ;; Indentation. + (block-ind (progn (skip-chars-forward " \t") (current-column))) + ;; Retrieve code. + (value (org-element-remove-indentation + (org-unescape-code-in-string + (buffer-substring-no-properties + (progn (forward-line) (point)) contents-end)) + block-ind)) + (pos-before-blank (progn (goto-char contents-end) + (forward-line) + (point))) + ;; Get position after ending blank lines. + (end (progn (skip-chars-forward " \r\t\n" limit) + (if (eobp) (point) (line-beginning-position))))) + (list 'src-block + (nconc + (list :language language + :switches (and (org-string-nw-p switches) + (org-trim switches)) + :parameters (and (org-string-nw-p parameters) + (org-trim parameters)) + :begin begin + :end end + :number-lines number-lines + :preserve-indent preserve-indent + :retain-labels retain-labels + :use-labels use-labels + :label-fmt label-fmt + :value value + :post-blank (count-lines pos-before-blank end) + :post-affiliated post-affiliated) + (cdr affiliated))))))))) + +(defun org-element-src-block-interpreter (src-block contents) + "Interpret SRC-BLOCK element as Org syntax. +CONTENTS is nil." + (let ((lang (org-element-property :language src-block)) + (switches (org-element-property :switches src-block)) + (params (org-element-property :parameters src-block)) + (value + (let ((val (org-element-property :value src-block))) + (cond + ((or org-src-preserve-indentation + (org-element-property :preserve-indent src-block)) + val) + ((zerop org-edit-src-content-indentation) val) + (t + (let ((ind (make-string org-edit-src-content-indentation ?\s))) + (replace-regexp-in-string + "\\(^\\)[ \t]*\\S-" ind val nil nil 1))))))) + (concat (format "#+BEGIN_SRC%s\n" + (concat (and lang (concat " " lang)) + (and switches (concat " " switches)) + (and params (concat " " params)))) + (org-element-normalize-string (org-escape-code-in-string value)) + "#+END_SRC"))) + + +;;;; Table + +(defun org-element-table-parser (limit affiliated) + "Parse a table at point. + +LIMIT bounds the search. AFFILIATED is a list of which CAR is +the buffer position at the beginning of the first affiliated +keyword and CDR is a plist of affiliated keywords along with +their value. + +Return a list whose CAR is `table' and CDR is a plist containing +`:begin', `:end', `:tblfm', `:type', `:contents-begin', +`:contents-end', `:value', `:post-blank' and `:post-affiliated' +keywords. + +Assume point is at the beginning of the table." + (save-excursion + (let* ((case-fold-search t) + (table-begin (point)) + (type (if (looking-at "[ \t]*|") 'org 'table.el)) + (end-re (format "^[ \t]*\\($\\|[^| \t%s]\\)" + (if (eq type 'org) "" "+"))) + (begin (car affiliated)) + (table-end + (if (re-search-forward end-re limit 'move) + (goto-char (match-beginning 0)) + (point))) + (tblfm (let (acc) + (while (looking-at "[ \t]*#\\+TBLFM: +\\(.*\\)[ \t]*$") + (push (org-match-string-no-properties 1) acc) + (forward-line)) + acc)) + (pos-before-blank (point)) + (end (progn (skip-chars-forward " \r\t\n" limit) + (if (eobp) (point) (line-beginning-position))))) + (list 'table + (nconc + (list :begin begin + :end end + :type type + :tblfm tblfm + ;; Only `org' tables have contents. `table.el' tables + ;; use a `:value' property to store raw table as + ;; a string. + :contents-begin (and (eq type 'org) table-begin) + :contents-end (and (eq type 'org) table-end) + :value (and (eq type 'table.el) + (buffer-substring-no-properties + table-begin table-end)) + :post-blank (count-lines pos-before-blank end) + :post-affiliated table-begin) + (cdr affiliated)))))) + +(defun org-element-table-interpreter (table contents) + "Interpret TABLE element as Org syntax. +CONTENTS is a string, if table's type is `org', or nil." + (if (eq (org-element-property :type table) 'table.el) + (org-remove-indentation (org-element-property :value table)) + (concat (with-temp-buffer (insert contents) + (org-table-align) + (buffer-string)) + (mapconcat (lambda (fm) (concat "#+TBLFM: " fm)) + (reverse (org-element-property :tblfm table)) + "\n")))) + + +;;;; Table Row + +(defun org-element-table-row-parser (limit) + "Parse table row at point. + +LIMIT bounds the search. + +Return a list whose CAR is `table-row' and CDR is a plist +containing `:begin', `:end', `:contents-begin', `:contents-end', +`:type', `:post-blank' and `:post-affiliated' keywords." + (save-excursion + (let* ((type (if (looking-at "^[ \t]*|-") 'rule 'standard)) + (begin (point)) + ;; A table rule has no contents. In that case, ensure + ;; CONTENTS-BEGIN matches CONTENTS-END. + (contents-begin (and (eq type 'standard) + (search-forward "|") + (point))) + (contents-end (and (eq type 'standard) + (progn + (end-of-line) + (skip-chars-backward " \t") + (point)))) + (end (line-beginning-position 2))) + (list 'table-row + (list :type type + :begin begin + :end end + :contents-begin contents-begin + :contents-end contents-end + :post-blank 0 + :post-affiliated begin))))) + +(defun org-element-table-row-interpreter (table-row contents) + "Interpret TABLE-ROW element as Org syntax. +CONTENTS is the contents of the table row." + (if (eq (org-element-property :type table-row) 'rule) "|-" + (concat "| " contents))) + + +;;;; Verse Block + +(defun org-element-verse-block-parser (limit affiliated) + "Parse a verse block. + +LIMIT bounds the search. AFFILIATED is a list of which CAR is +the buffer position at the beginning of the first affiliated +keyword and CDR is a plist of affiliated keywords along with +their value. + +Return a list whose CAR is `verse-block' and CDR is a plist +containing `:begin', `:end', `:contents-begin', `:contents-end', +`:post-blank' and `:post-affiliated' keywords. + +Assume point is at beginning of the block." + (let ((case-fold-search t)) + (if (not (save-excursion + (re-search-forward "^[ \t]*#\\+END_VERSE[ \t]*$" limit t))) + ;; Incomplete block: parse it as a paragraph. + (org-element-paragraph-parser limit affiliated) + (let ((contents-end (match-beginning 0))) + (save-excursion + (let* ((begin (car affiliated)) + (post-affiliated (point)) + (contents-begin (progn (forward-line) (point))) + (pos-before-blank (progn (goto-char contents-end) + (forward-line) + (point))) + (end (progn (skip-chars-forward " \r\t\n" limit) + (if (eobp) (point) (line-beginning-position))))) + (list 'verse-block + (nconc + (list :begin begin + :end end + :contents-begin contents-begin + :contents-end contents-end + :post-blank (count-lines pos-before-blank end) + :post-affiliated post-affiliated) + (cdr affiliated))))))))) + +(defun org-element-verse-block-interpreter (verse-block contents) + "Interpret VERSE-BLOCK element as Org syntax. +CONTENTS is verse block contents." + (format "#+BEGIN_VERSE\n%s#+END_VERSE" contents)) + + + +;;; Objects +;; +;; Unlike to elements, raw text can be found between objects. Hence, +;; `org-element--object-lex' is provided to find the next object in +;; buffer. +;; +;; Some object types (e.g., `italic') are recursive. Restrictions on +;; object types they can contain will be specified in +;; `org-element-object-restrictions'. +;; +;; Creating a new type of object requires to alter +;; `org-element--object-regexp' and `org-element--object-lex', add the +;; new type in `org-element-all-objects', and possibly add +;; restrictions in `org-element-object-restrictions'. + +;;;; Bold + +(defun org-element-bold-parser () + "Parse bold object at point, if any. + +When at a bold object, return a list whose car is `bold' and cdr +is a plist with `:begin', `:end', `:contents-begin' and +`:contents-end' and `:post-blank' keywords. Otherwise, return +nil. + +Assume point is at the first star marker." + (save-excursion + (unless (bolp) (backward-char 1)) + (when (looking-at org-emph-re) + (let ((begin (match-beginning 2)) + (contents-begin (match-beginning 4)) + (contents-end (match-end 4)) + (post-blank (progn (goto-char (match-end 2)) + (skip-chars-forward " \t"))) + (end (point))) + (list 'bold + (list :begin begin + :end end + :contents-begin contents-begin + :contents-end contents-end + :post-blank post-blank)))))) + +(defun org-element-bold-interpreter (bold contents) + "Interpret BOLD object as Org syntax. +CONTENTS is the contents of the object." + (format "*%s*" contents)) + + +;;;; Code + +(defun org-element-code-parser () + "Parse code object at point, if any. + +When at a code object, return a list whose car is `code' and cdr +is a plist with `:value', `:begin', `:end' and `:post-blank' +keywords. Otherwise, return nil. + +Assume point is at the first tilde marker." + (save-excursion + (unless (bolp) (backward-char 1)) + (when (looking-at org-emph-re) + (let ((begin (match-beginning 2)) + (value (org-match-string-no-properties 4)) + (post-blank (progn (goto-char (match-end 2)) + (skip-chars-forward " \t"))) + (end (point))) + (list 'code + (list :value value + :begin begin + :end end + :post-blank post-blank)))))) + +(defun org-element-code-interpreter (code contents) + "Interpret CODE object as Org syntax. +CONTENTS is nil." + (format "~%s~" (org-element-property :value code))) + + +;;;; Entity + +(defun org-element-entity-parser () + "Parse entity at point, if any. + +When at an entity, return a list whose car is `entity' and cdr +a plist with `:begin', `:end', `:latex', `:latex-math-p', +`:html', `:latin1', `:utf-8', `:ascii', `:use-brackets-p' and +`:post-blank' as keywords. Otherwise, return nil. + +Assume point is at the beginning of the entity." + (catch 'no-object + (when (looking-at "\\\\\\(?:\\(?1:_ +\\)\\|\\(?1:there4\\|sup[123]\\|frac[13][24]\\|[a-zA-Z]+\\)\\(?2:$\\|{}\\|[^[:alpha:]]\\)\\)") + (save-excursion + (let* ((value (or (org-entity-get (match-string 1)) + (throw 'no-object nil))) + (begin (match-beginning 0)) + (bracketsp (string= (match-string 2) "{}")) + (post-blank (progn (goto-char (match-end 1)) + (when bracketsp (forward-char 2)) + (skip-chars-forward " \t"))) + (end (point))) + (list 'entity + (list :name (car value) + :latex (nth 1 value) + :latex-math-p (nth 2 value) + :html (nth 3 value) + :ascii (nth 4 value) + :latin1 (nth 5 value) + :utf-8 (nth 6 value) + :begin begin + :end end + :use-brackets-p bracketsp + :post-blank post-blank))))))) + +(defun org-element-entity-interpreter (entity contents) + "Interpret ENTITY object as Org syntax. +CONTENTS is nil." + (concat "\\" + (org-element-property :name entity) + (when (org-element-property :use-brackets-p entity) "{}"))) + + +;;;; Export Snippet + +(defun org-element-export-snippet-parser () + "Parse export snippet at point. + +When at an export snippet, return a list whose car is +`export-snippet' and cdr a plist with `:begin', `:end', +`:back-end', `:value' and `:post-blank' as keywords. Otherwise, +return nil. + +Assume point is at the beginning of the snippet." + (save-excursion + (let (contents-end) + (when (and (looking-at "@@\\([-A-Za-z0-9]+\\):") + (setq contents-end + (save-match-data (goto-char (match-end 0)) + (re-search-forward "@@" nil t) + (match-beginning 0)))) + (let* ((begin (match-beginning 0)) + (back-end (org-match-string-no-properties 1)) + (value (buffer-substring-no-properties + (match-end 0) contents-end)) + (post-blank (skip-chars-forward " \t")) + (end (point))) + (list 'export-snippet + (list :back-end back-end + :value value + :begin begin + :end end + :post-blank post-blank))))))) + +(defun org-element-export-snippet-interpreter (export-snippet contents) + "Interpret EXPORT-SNIPPET object as Org syntax. +CONTENTS is nil." + (format "@@%s:%s@@" + (org-element-property :back-end export-snippet) + (org-element-property :value export-snippet))) + + +;;;; Footnote Reference + +(defun org-element-footnote-reference-parser () + "Parse footnote reference at point, if any. + +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 +`:post-blank' as keywords. Otherwise, return nil." + (when (looking-at org-footnote-re) + (let ((closing (with-syntax-table org-element--pair-square-table + (ignore-errors (scan-lists (point) 1 0))))) + (when closing + (save-excursion + (let* ((begin (point)) + (label + (or (org-match-string-no-properties 2) + (org-match-string-no-properties 3) + (and (match-string 1) + (concat "fn:" (org-match-string-no-properties 1))))) + (type (if (or (not label) (match-string 1)) 'inline 'standard)) + (inner-begin (match-end 0)) + (inner-end (1- closing)) + (post-blank (progn (goto-char closing) + (skip-chars-forward " \t"))) + (end (point))) + (list 'footnote-reference + (list :label label + :type type + :begin begin + :end end + :contents-begin (and (eq type 'inline) inner-begin) + :contents-end (and (eq type 'inline) inner-end) + :post-blank post-blank)))))))) + +(defun org-element-footnote-reference-interpreter (footnote-reference contents) + "Interpret FOOTNOTE-REFERENCE object as Org syntax. +CONTENTS is its definition, when inline, or nil." + (format "[%s]" + (concat (or (org-element-property :label footnote-reference) "fn:") + (and contents (concat ":" contents))))) + + +;;;; Inline Babel Call + +(defun org-element-inline-babel-call-parser () + "Parse inline babel call at point, if any. + +When at an inline babel call, return a list whose car is +`inline-babel-call' and cdr a plist with `:call', +`:inside-header', `:arguments', `:end-header', `:begin', `:end', +`:value' and `:post-blank' as keywords. Otherwise, return nil. + +Assume point is at the beginning of the babel call." + (save-excursion + (unless (bolp) (backward-char)) + (when (let ((case-fold-search t)) + (looking-at org-babel-inline-lob-one-liner-regexp)) + (let ((begin (match-end 1)) + (call (org-match-string-no-properties 2)) + (inside-header (org-string-nw-p (org-match-string-no-properties 4))) + (arguments (org-string-nw-p (org-match-string-no-properties 6))) + (end-header (org-string-nw-p (org-match-string-no-properties 8))) + (value (buffer-substring-no-properties (match-end 1) (match-end 0))) + (post-blank (progn (goto-char (match-end 0)) + (skip-chars-forward " \t"))) + (end (point))) + (list 'inline-babel-call + (list :call call + :inside-header inside-header + :arguments arguments + :end-header end-header + :begin begin + :end end + :value value + :post-blank post-blank)))))) + +(defun org-element-inline-babel-call-interpreter (inline-babel-call contents) + "Interpret INLINE-BABEL-CALL object as Org syntax. +CONTENTS is nil." + (concat "call_" + (org-element-property :call inline-babel-call) + (let ((h (org-element-property :inside-header inline-babel-call))) + (and h (format "[%s]" h))) + "(" (org-element-property :arguments inline-babel-call) ")" + (let ((h (org-element-property :end-header inline-babel-call))) + (and h (format "[%s]" h))))) + + +;;;; Inline Src Block + +(defun org-element-inline-src-block-parser () + "Parse inline source block at point, if any. + +When at an inline source block, return a list whose car is +`inline-src-block' and cdr a plist with `:begin', `:end', +`:language', `:value', `:parameters' and `:post-blank' as +keywords. Otherwise, return nil. + +Assume point is at the beginning of the inline src block." + (save-excursion + (unless (bolp) (backward-char)) + (when (looking-at org-babel-inline-src-block-regexp) + (let ((begin (match-beginning 1)) + (language (org-match-string-no-properties 2)) + (parameters (org-match-string-no-properties 4)) + (value (org-match-string-no-properties 5)) + (post-blank (progn (goto-char (match-end 0)) + (skip-chars-forward " \t"))) + (end (point))) + (list 'inline-src-block + (list :language language + :value value + :parameters parameters + :begin begin + :end end + :post-blank post-blank)))))) + +(defun org-element-inline-src-block-interpreter (inline-src-block contents) + "Interpret INLINE-SRC-BLOCK object as Org syntax. +CONTENTS is nil." + (let ((language (org-element-property :language inline-src-block)) + (arguments (org-element-property :parameters inline-src-block)) + (body (org-element-property :value inline-src-block))) + (format "src_%s%s{%s}" + language + (if arguments (format "[%s]" arguments) "") + body))) + +;;;; Italic + +(defun org-element-italic-parser () + "Parse italic object at point, if any. + +When at an italic object, return a list whose car is `italic' and +cdr is a plist with `:begin', `:end', `:contents-begin' and +`:contents-end' and `:post-blank' keywords. Otherwise, return +nil. + +Assume point is at the first slash marker." + (save-excursion + (unless (bolp) (backward-char 1)) + (when (looking-at org-emph-re) + (let ((begin (match-beginning 2)) + (contents-begin (match-beginning 4)) + (contents-end (match-end 4)) + (post-blank (progn (goto-char (match-end 2)) + (skip-chars-forward " \t"))) + (end (point))) + (list 'italic + (list :begin begin + :end end + :contents-begin contents-begin + :contents-end contents-end + :post-blank post-blank)))))) + +(defun org-element-italic-interpreter (italic contents) + "Interpret ITALIC object as Org syntax. +CONTENTS is the contents of the object." + (format "/%s/" contents)) + + +;;;; Latex Fragment + +(defun org-element-latex-fragment-parser () + "Parse LaTeX fragment at point, if any. + +When at a LaTeX fragment, return a list whose car is +`latex-fragment' and cdr a plist with `:value', `:begin', `:end', +and `:post-blank' as keywords. Otherwise, return nil. + +Assume point is at the beginning of the LaTeX fragment." + (catch 'no-object + (save-excursion + (let* ((begin (point)) + (after-fragment + (if (eq (char-after) ?$) + (if (eq (char-after (1+ (point))) ?$) + (search-forward "$$" nil t 2) + (and (not (eq (char-before) ?$)) + (search-forward "$" nil t 2) + (not (memq (char-before (match-beginning 0)) + '(?\s ?\t ?\n ?, ?.))) + (looking-at "\\(\\s.\\|\\s-\\|\\s(\\|\\s)\\|\\s\"\\|$\\)") + (point))) + (case (char-after (1+ (point))) + (?\( (search-forward "\\)" nil t)) + (?\[ (search-forward "\\]" nil t)) + (otherwise + ;; Macro. + (and (looking-at "\\\\[a-zA-Z]+\\*?\\(\\(\\[[^][\n{}]*\\]\\)\\|\\({[^{}\n]*}\\)\\)*") + (match-end 0)))))) + (post-blank (if (not after-fragment) (throw 'no-object nil) + (goto-char after-fragment) + (skip-chars-forward " \t"))) + (end (point))) + (list 'latex-fragment + (list :value (buffer-substring-no-properties begin after-fragment) + :begin begin + :end end + :post-blank post-blank)))))) + +(defun org-element-latex-fragment-interpreter (latex-fragment contents) + "Interpret LATEX-FRAGMENT object as Org syntax. +CONTENTS is nil." + (org-element-property :value latex-fragment)) + +;;;; Line Break + +(defun org-element-line-break-parser () + "Parse line break at point, if any. + +When at a line break, return a list whose car is `line-break', +and cdr a plist with `:begin', `:end' and `:post-blank' keywords. +Otherwise, return nil. + +Assume point is at the beginning of the line break." + (when (and (org-looking-at-p "\\\\\\\\[ \t]*$") + (not (eq (char-before) ?\\))) + (list 'line-break + (list :begin (point) + :end (line-beginning-position 2) + :post-blank 0)))) + +(defun org-element-line-break-interpreter (line-break contents) + "Interpret LINE-BREAK object as Org syntax. +CONTENTS is nil." + "\\\\\n") + + +;;;; Link + +(defun org-element-link-parser () + "Parse link at point, if any. + +When at a link, return a list whose car is `link' and cdr a plist +with `:type', `:path', `:raw-link', `:application', +`:search-option', `:begin', `:end', `:contents-begin', +`:contents-end' and `:post-blank' as keywords. Otherwise, return +nil. + +Assume point is at the beginning of the link." + (catch 'no-object + (let ((begin (point)) + end contents-begin contents-end link-end post-blank path type + raw-link link search-option application) + (cond + ;; Type 1: Text targeted from a radio target. + ((and org-target-link-regexp + (save-excursion (or (bolp) (backward-char)) + (looking-at org-target-link-regexp))) + (setq type "radio" + link-end (match-end 1) + path (org-match-string-no-properties 1) + contents-begin (match-beginning 1) + contents-end (match-end 1))) + ;; Type 2: Standard link, i.e. [[http://orgmode.org][homepage]] + ((looking-at org-bracket-link-regexp) + (setq contents-begin (match-beginning 3)) + (setq contents-end (match-end 3)) + (setq link-end (match-end 0)) + ;; RAW-LINK is the original link. Expand any + ;; abbreviation in it. + ;; + ;; Also treat any newline character and associated + ;; indentation as a single space character. This is not + ;; compatible with RFC 3986, which requires to ignore + ;; them altogether. However, doing so would require + ;; users to encode spaces on the fly when writing links + ;; (e.g., insert [[shell:ls%20*.org]] instead of + ;; [[shell:ls *.org]], which defeats Org's focus on + ;; simplicity. + (setq raw-link (org-link-expand-abbrev + (replace-regexp-in-string + "[ \t]*\n[ \t]*" " " + (org-match-string-no-properties 1)))) + ;; Determine TYPE of link and set PATH accordingly. According + ;; to RFC 3986, remove whitespaces from URI in external links. + ;; In internal ones, treat indentation as a single space. + (cond + ;; File type. + ((or (file-name-absolute-p raw-link) + (string-match "\\`\\.\\.?/" raw-link)) + (setq type "file") + (setq path raw-link)) + ;; Explicit type (http, irc, bbdb...). See `org-link-types'. + ((string-match org-link-types-re raw-link) + (setq type (match-string 1 raw-link)) + (setq path (substring raw-link (match-end 0)))) + ;; Id type: PATH is the id. + ((string-match "\\`id:\\([-a-f0-9]+\\)\\'" raw-link) + (setq type "id" path (match-string 1 raw-link))) + ;; Code-ref type: PATH is the name of the reference. + ((and (org-string-match-p "\\`(" raw-link) + (org-string-match-p ")\\'" raw-link)) + (setq type "coderef") + (setq path (substring raw-link 1 -1))) + ;; Custom-id type: PATH is the name of the custom id. + ((= (string-to-char raw-link) ?#) + (setq type "custom-id") + (setq path (substring raw-link 1))) + ;; Fuzzy type: Internal link either matches a target, an + ;; headline name or nothing. PATH is the target or + ;; headline's name. + (t + (setq type "fuzzy") + (setq path raw-link)))) + ;; Type 3: Plain link, e.g., http://orgmode.org + ((looking-at org-plain-link-re) + (setq raw-link (org-match-string-no-properties 0) + type (org-match-string-no-properties 1) + link-end (match-end 0) + path (org-match-string-no-properties 2))) + ;; Type 4: Angular link, e.g., . Unlike to + ;; bracket links, follow RFC 3986 and remove any extra + ;; whitespace in URI. + ((looking-at org-angle-link-re) + (setq type (org-match-string-no-properties 1)) + (setq link-end (match-end 0)) + (setq raw-link + (buffer-substring-no-properties + (match-beginning 1) (match-end 2))) + (setq path (replace-regexp-in-string + "[ \t]*\n[ \t]*" "" (org-match-string-no-properties 2)))) + (t (throw 'no-object nil))) + ;; In any case, deduce end point after trailing white space from + ;; LINK-END variable. + (save-excursion + (setq post-blank + (progn (goto-char link-end) (skip-chars-forward " \t"))) + (setq end (point))) + ;; Special "file" type link processing. Extract opening + ;; application and search option, if any. Also normalize URI. + (when (string-match "\\`file\\(?:\\+\\(.+\\)\\)?\\'" type) + (setq application (match-string 1 type) type "file") + (when (string-match "::\\(.*\\)\\'" path) + (setq search-option (match-string 1 path)) + (setq path (replace-match "" nil nil path))) + (setq path (replace-regexp-in-string "\\`///+" "/" path))) + ;; Translate link, if `org-link-translation-function' is set. + (let ((trans (and (functionp org-link-translation-function) + (funcall org-link-translation-function type path)))) + (when trans + (setq type (car trans)) + (setq path (cdr trans)))) + (list 'link + (list :type type + :path path + :raw-link (or raw-link path) + :application application + :search-option search-option + :begin begin + :end end + :contents-begin contents-begin + :contents-end contents-end + :post-blank post-blank))))) + +(defun org-element-link-interpreter (link contents) + "Interpret LINK object as Org syntax. +CONTENTS is the contents of the object, or nil." + (let ((type (org-element-property :type link)) + (path (org-element-property :path link))) + (if (string= type "radio") path + (format "[[%s]%s]" + (cond ((string= type "coderef") (format "(%s)" path)) + ((string= type "custom-id") (concat "#" path)) + ((string= type "file") + (let ((app (org-element-property :application link)) + (opt (org-element-property :search-option link))) + (concat type (and app (concat "+" app)) ":" + path + (and opt (concat "::" opt))))) + ((string= type "fuzzy") path) + (t (concat type ":" path))) + (if contents (format "[%s]" contents) ""))))) + + +;;;; Macro + +(defun org-element-macro-parser () + "Parse macro at point, if any. + +When at a macro, return a list whose car is `macro' and cdr +a plist with `:key', `:args', `:begin', `:end', `:value' and +`:post-blank' as keywords. Otherwise, return nil. + +Assume point is at the macro." + (save-excursion + (when (looking-at "{{{\\([a-zA-Z][-a-zA-Z0-9_]*\\)\\(([ \t\n]*\\([^\000]*?\\))\\)?}}}") + (let ((begin (point)) + (key (downcase (org-match-string-no-properties 1))) + (value (org-match-string-no-properties 0)) + (post-blank (progn (goto-char (match-end 0)) + (skip-chars-forward " \t"))) + (end (point)) + (args (let ((args (org-match-string-no-properties 3))) + (and args (org-macro-extract-arguments args))))) + (list 'macro + (list :key key + :value value + :args args + :begin begin + :end end + :post-blank post-blank)))))) + +(defun org-element-macro-interpreter (macro contents) + "Interpret MACRO object as Org syntax. +CONTENTS is nil." + (org-element-property :value macro)) + + +;;;; Radio-target + +(defun org-element-radio-target-parser () + "Parse radio target at point, if any. + +When at a radio target, return a list whose car is `radio-target' +and cdr a plist with `:begin', `:end', `:contents-begin', +`:contents-end', `:value' and `:post-blank' as keywords. +Otherwise, return nil. + +Assume point is at the radio target." + (save-excursion + (when (looking-at org-radio-target-regexp) + (let ((begin (point)) + (contents-begin (match-beginning 1)) + (contents-end (match-end 1)) + (value (org-match-string-no-properties 1)) + (post-blank (progn (goto-char (match-end 0)) + (skip-chars-forward " \t"))) + (end (point))) + (list 'radio-target + (list :begin begin + :end end + :contents-begin contents-begin + :contents-end contents-end + :post-blank post-blank + :value value)))))) + +(defun org-element-radio-target-interpreter (target contents) + "Interpret TARGET object as Org syntax. +CONTENTS is the contents of the object." + (concat "<<<" contents ">>>")) + + +;;;; Statistics Cookie + +(defun org-element-statistics-cookie-parser () + "Parse statistics cookie at point, if any. + +When at a statistics cookie, return a list whose car is +`statistics-cookie', and cdr a plist with `:begin', `:end', +`:value' and `:post-blank' keywords. Otherwise, return nil. + +Assume point is at the beginning of the statistics-cookie." + (save-excursion + (when (looking-at "\\[[0-9]*\\(%\\|/[0-9]*\\)\\]") + (let* ((begin (point)) + (value (buffer-substring-no-properties + (match-beginning 0) (match-end 0))) + (post-blank (progn (goto-char (match-end 0)) + (skip-chars-forward " \t"))) + (end (point))) + (list 'statistics-cookie + (list :begin begin + :end end + :value value + :post-blank post-blank)))))) + +(defun org-element-statistics-cookie-interpreter (statistics-cookie contents) + "Interpret STATISTICS-COOKIE object as Org syntax. +CONTENTS is nil." + (org-element-property :value statistics-cookie)) + + +;;;; Strike-Through + +(defun org-element-strike-through-parser () + "Parse strike-through object at point, if any. + +When at a strike-through object, return a list whose car is +`strike-through' and cdr is a plist with `:begin', `:end', +`:contents-begin' and `:contents-end' and `:post-blank' keywords. +Otherwise, return nil. + +Assume point is at the first plus sign marker." + (save-excursion + (unless (bolp) (backward-char 1)) + (when (looking-at org-emph-re) + (let ((begin (match-beginning 2)) + (contents-begin (match-beginning 4)) + (contents-end (match-end 4)) + (post-blank (progn (goto-char (match-end 2)) + (skip-chars-forward " \t"))) + (end (point))) + (list 'strike-through + (list :begin begin + :end end + :contents-begin contents-begin + :contents-end contents-end + :post-blank post-blank)))))) + +(defun org-element-strike-through-interpreter (strike-through contents) + "Interpret STRIKE-THROUGH object as Org syntax. +CONTENTS is the contents of the object." + (format "+%s+" contents)) + + +;;;; Subscript + +(defun org-element-subscript-parser () + "Parse subscript at point, if any. + +When at a subscript object, return a list whose car is +`subscript' and cdr a plist with `:begin', `:end', +`:contents-begin', `:contents-end', `:use-brackets-p' and +`:post-blank' as keywords. Otherwise, return nil. + +Assume point is at the underscore." + (save-excursion + (unless (bolp) (backward-char)) + (when (looking-at org-match-substring-regexp) + (let ((bracketsp (match-beginning 4)) + (begin (match-beginning 2)) + (contents-begin (or (match-beginning 4) + (match-beginning 3))) + (contents-end (or (match-end 4) (match-end 3))) + (post-blank (progn (goto-char (match-end 0)) + (skip-chars-forward " \t"))) + (end (point))) + (list 'subscript + (list :begin begin + :end end + :use-brackets-p bracketsp + :contents-begin contents-begin + :contents-end contents-end + :post-blank post-blank)))))) + +(defun org-element-subscript-interpreter (subscript contents) + "Interpret SUBSCRIPT object as Org syntax. +CONTENTS is the contents of the object." + (format + (if (org-element-property :use-brackets-p subscript) "_{%s}" "_%s") + contents)) + + +;;;; Superscript + +(defun org-element-superscript-parser () + "Parse superscript at point, if any. + +When at a superscript object, return a list whose car is +`superscript' and cdr a plist with `:begin', `:end', +`:contents-begin', `:contents-end', `:use-brackets-p' and +`:post-blank' as keywords. Otherwise, return nil. + +Assume point is at the caret." + (save-excursion + (unless (bolp) (backward-char)) + (when (looking-at org-match-substring-regexp) + (let ((bracketsp (match-beginning 4)) + (begin (match-beginning 2)) + (contents-begin (or (match-beginning 4) + (match-beginning 3))) + (contents-end (or (match-end 4) (match-end 3))) + (post-blank (progn (goto-char (match-end 0)) + (skip-chars-forward " \t"))) + (end (point))) + (list 'superscript + (list :begin begin + :end end + :use-brackets-p bracketsp + :contents-begin contents-begin + :contents-end contents-end + :post-blank post-blank)))))) + +(defun org-element-superscript-interpreter (superscript contents) + "Interpret SUPERSCRIPT object as Org syntax. +CONTENTS is the contents of the object." + (format + (if (org-element-property :use-brackets-p superscript) "^{%s}" "^%s") + contents)) + + +;;;; Table Cell + +(defun org-element-table-cell-parser () + "Parse table cell at point. +Return a list whose car is `table-cell' and cdr is a plist +containing `:begin', `:end', `:contents-begin', `:contents-end' +and `:post-blank' keywords." + (looking-at "[ \t]*\\(.*?\\)[ \t]*\\(?:|\\|$\\)") + (let* ((begin (match-beginning 0)) + (end (match-end 0)) + (contents-begin (match-beginning 1)) + (contents-end (match-end 1))) + (list 'table-cell + (list :begin begin + :end end + :contents-begin contents-begin + :contents-end contents-end + :post-blank 0)))) + +(defun org-element-table-cell-interpreter (table-cell contents) + "Interpret TABLE-CELL element as Org syntax. +CONTENTS is the contents of the cell, or nil." + (concat " " contents " |")) + + +;;;; Target + +(defun org-element-target-parser () + "Parse target at point, if any. + +When at a target, return a list whose car is `target' and cdr +a plist with `:begin', `:end', `:value' and `:post-blank' as +keywords. Otherwise, return nil. + +Assume point is at the target." + (save-excursion + (when (looking-at org-target-regexp) + (let ((begin (point)) + (value (org-match-string-no-properties 1)) + (post-blank (progn (goto-char (match-end 0)) + (skip-chars-forward " \t"))) + (end (point))) + (list 'target + (list :begin begin + :end end + :value value + :post-blank post-blank)))))) + +(defun org-element-target-interpreter (target contents) + "Interpret TARGET object as Org syntax. +CONTENTS is nil." + (format "<<%s>>" (org-element-property :value target))) + + +;;;; Timestamp + +(defconst org-element--timestamp-regexp + (concat org-ts-regexp-both + "\\|" + "\\(?:<[0-9]+-[0-9]+-[0-9]+[^>\n]+?\\+[0-9]+[dwmy]>\\)" + "\\|" + "\\(?:<%%\\(?:([^>\n]+)\\)>\\)") + "Regexp matching any timestamp type object.") + +(defun org-element-timestamp-parser () + "Parse time stamp at point, if any. + +When at a time stamp, return a list whose car is `timestamp', and +cdr a plist with `:type', `:raw-value', `:year-start', +`:month-start', `:day-start', `:hour-start', `:minute-start', +`:year-end', `:month-end', `:day-end', `:hour-end', +`:minute-end', `:repeater-type', `:repeater-value', +`:repeater-unit', `:warning-type', `:warning-value', +`:warning-unit', `:begin', `:end' and `:post-blank' keywords. +Otherwise, return nil. + +Assume point is at the beginning of the timestamp." + (when (org-looking-at-p org-element--timestamp-regexp) + (save-excursion + (let* ((begin (point)) + (activep (eq (char-after) ?<)) + (raw-value + (progn + (looking-at "\\([<[]\\(%%\\)?.*?\\)[]>]\\(?:--\\([<[].*?[]>]\\)\\)?") + (match-string-no-properties 0))) + (date-start (match-string-no-properties 1)) + (date-end (match-string 3)) + (diaryp (match-beginning 2)) + (post-blank (progn (goto-char (match-end 0)) + (skip-chars-forward " \t"))) + (end (point)) + (time-range + (and (not diaryp) + (string-match + "[012]?[0-9]:[0-5][0-9]\\(-\\([012]?[0-9]\\):\\([0-5][0-9]\\)\\)" + date-start) + (cons (string-to-number (match-string 2 date-start)) + (string-to-number (match-string 3 date-start))))) + (type (cond (diaryp 'diary) + ((and activep (or date-end time-range)) 'active-range) + (activep 'active) + ((or date-end time-range) 'inactive-range) + (t 'inactive))) + (repeater-props + (and (not diaryp) + (string-match "\\([.+]?\\+\\)\\([0-9]+\\)\\([hdwmy]\\)" + raw-value) + (list + :repeater-type + (let ((type (match-string 1 raw-value))) + (cond ((equal "++" type) 'catch-up) + ((equal ".+" type) 'restart) + (t 'cumulate))) + :repeater-value (string-to-number (match-string 2 raw-value)) + :repeater-unit + (case (string-to-char (match-string 3 raw-value)) + (?h 'hour) (?d 'day) (?w 'week) (?m 'month) (t 'year))))) + (warning-props + (and (not diaryp) + (string-match "\\(-\\)?-\\([0-9]+\\)\\([hdwmy]\\)" raw-value) + (list + :warning-type (if (match-string 1 raw-value) 'first 'all) + :warning-value (string-to-number (match-string 2 raw-value)) + :warning-unit + (case (string-to-char (match-string 3 raw-value)) + (?h 'hour) (?d 'day) (?w 'week) (?m 'month) (t 'year))))) + year-start month-start day-start hour-start minute-start year-end + month-end day-end hour-end minute-end) + ;; Parse date-start. + (unless diaryp + (let ((date (org-parse-time-string date-start t))) + (setq year-start (nth 5 date) + month-start (nth 4 date) + day-start (nth 3 date) + hour-start (nth 2 date) + minute-start (nth 1 date)))) + ;; Compute date-end. It can be provided directly in time-stamp, + ;; or extracted from time range. Otherwise, it defaults to the + ;; same values as date-start. + (unless diaryp + (let ((date (and date-end (org-parse-time-string date-end t)))) + (setq year-end (or (nth 5 date) year-start) + month-end (or (nth 4 date) month-start) + day-end (or (nth 3 date) day-start) + hour-end (or (nth 2 date) (car time-range) hour-start) + minute-end (or (nth 1 date) (cdr time-range) minute-start)))) + (list 'timestamp + (nconc (list :type type + :raw-value raw-value + :year-start year-start + :month-start month-start + :day-start day-start + :hour-start hour-start + :minute-start minute-start + :year-end year-end + :month-end month-end + :day-end day-end + :hour-end hour-end + :minute-end minute-end + :begin begin + :end end + :post-blank post-blank) + repeater-props + warning-props)))))) + +(defun org-element-timestamp-interpreter (timestamp contents) + "Interpret TIMESTAMP object as Org syntax. +CONTENTS is nil." + (let* ((repeat-string + (concat + (case (org-element-property :repeater-type timestamp) + (cumulate "+") (catch-up "++") (restart ".+")) + (let ((val (org-element-property :repeater-value timestamp))) + (and val (number-to-string val))) + (case (org-element-property :repeater-unit timestamp) + (hour "h") (day "d") (week "w") (month "m") (year "y")))) + (warning-string + (concat + (case (org-element-property :warning-type timestamp) + (first "--") + (all "-")) + (let ((val (org-element-property :warning-value timestamp))) + (and val (number-to-string val))) + (case (org-element-property :warning-unit timestamp) + (hour "h") (day "d") (week "w") (month "m") (year "y")))) + (build-ts-string + ;; Build an Org timestamp string from TIME. ACTIVEP is + ;; non-nil when time stamp is active. If WITH-TIME-P is + ;; non-nil, add a time part. HOUR-END and MINUTE-END + ;; specify a time range in the timestamp. REPEAT-STRING is + ;; the repeater string, if any. + (lambda (time activep &optional with-time-p hour-end minute-end) + (let ((ts (format-time-string + (funcall (if with-time-p 'cdr 'car) + org-time-stamp-formats) + time))) + (when (and hour-end minute-end) + (string-match "[012]?[0-9]:[0-5][0-9]" ts) + (setq ts + (replace-match + (format "\\&-%02d:%02d" hour-end minute-end) + nil nil ts))) + (unless activep (setq ts (format "[%s]" (substring ts 1 -1)))) + (dolist (s (list repeat-string warning-string)) + (when (org-string-nw-p s) + (setq ts (concat (substring ts 0 -1) + " " + s + (substring ts -1))))) + ;; Return value. + ts))) + (type (org-element-property :type timestamp))) + (case type + ((active inactive) + (let* ((minute-start (org-element-property :minute-start timestamp)) + (minute-end (org-element-property :minute-end timestamp)) + (hour-start (org-element-property :hour-start timestamp)) + (hour-end (org-element-property :hour-end timestamp)) + (time-range-p (and hour-start hour-end minute-start minute-end + (or (/= hour-start hour-end) + (/= minute-start minute-end))))) + (funcall + build-ts-string + (encode-time 0 + (or minute-start 0) + (or hour-start 0) + (org-element-property :day-start timestamp) + (org-element-property :month-start timestamp) + (org-element-property :year-start timestamp)) + (eq type 'active) + (and hour-start minute-start) + (and time-range-p hour-end) + (and time-range-p minute-end)))) + ((active-range inactive-range) + (let ((minute-start (org-element-property :minute-start timestamp)) + (minute-end (org-element-property :minute-end timestamp)) + (hour-start (org-element-property :hour-start timestamp)) + (hour-end (org-element-property :hour-end timestamp))) + (concat + (funcall + build-ts-string (encode-time + 0 + (or minute-start 0) + (or hour-start 0) + (org-element-property :day-start timestamp) + (org-element-property :month-start timestamp) + (org-element-property :year-start timestamp)) + (eq type 'active-range) + (and hour-start minute-start)) + "--" + (funcall build-ts-string + (encode-time 0 + (or minute-end 0) + (or hour-end 0) + (org-element-property :day-end timestamp) + (org-element-property :month-end timestamp) + (org-element-property :year-end timestamp)) + (eq type 'active-range) + (and hour-end minute-end))))) + (otherwise (org-element-property :raw-value timestamp))))) + + +;;;; Underline + +(defun org-element-underline-parser () + "Parse underline object at point, if any. + +When at an underline object, return a list whose car is +`underline' and cdr is a plist with `:begin', `:end', +`:contents-begin' and `:contents-end' and `:post-blank' keywords. +Otherwise, return nil. + +Assume point is at the first underscore marker." + (save-excursion + (unless (bolp) (backward-char 1)) + (when (looking-at org-emph-re) + (let ((begin (match-beginning 2)) + (contents-begin (match-beginning 4)) + (contents-end (match-end 4)) + (post-blank (progn (goto-char (match-end 2)) + (skip-chars-forward " \t"))) + (end (point))) + (list 'underline + (list :begin begin + :end end + :contents-begin contents-begin + :contents-end contents-end + :post-blank post-blank)))))) + +(defun org-element-underline-interpreter (underline contents) + "Interpret UNDERLINE object as Org syntax. +CONTENTS is the contents of the object." + (format "_%s_" contents)) + + +;;;; Verbatim + +(defun org-element-verbatim-parser () + "Parse verbatim object at point, if any. + +When at a verbatim object, return a list whose car is `verbatim' +and cdr is a plist with `:value', `:begin', `:end' and +`:post-blank' keywords. Otherwise, return nil. + +Assume point is at the first equal sign marker." + (save-excursion + (unless (bolp) (backward-char 1)) + (when (looking-at org-emph-re) + (let ((begin (match-beginning 2)) + (value (org-match-string-no-properties 4)) + (post-blank (progn (goto-char (match-end 2)) + (skip-chars-forward " \t"))) + (end (point))) + (list 'verbatim + (list :value value + :begin begin + :end end + :post-blank post-blank)))))) + +(defun org-element-verbatim-interpreter (verbatim contents) + "Interpret VERBATIM object as Org syntax. +CONTENTS is nil." + (format "=%s=" (org-element-property :value verbatim))) + + + +;;; Parsing Element Starting At Point +;; +;; `org-element--current-element' is the core function of this section. +;; It returns the Lisp representation of the element starting at +;; point. +;; +;; `org-element--current-element' makes use of special modes. They +;; are activated for fixed element chaining (e.g., `plain-list' > +;; `item') or fixed conditional element chaining (e.g., `headline' > +;; `section'). Special modes are: `first-section', `item', +;; `node-property', `section' and `table-row'. + +(defun org-element--current-element (limit &optional granularity mode structure) + "Parse the element starting at point. + +Return value is a list like (TYPE PROPS) where TYPE is the type +of the element and PROPS a plist of properties associated to the +element. + +Possible types are defined in `org-element-all-elements'. + +LIMIT bounds the search. + +Optional argument GRANULARITY determines the depth of the +recursion. Allowed values are `headline', `greater-element', +`element', `object' or nil. When it is broader than `object' (or +nil), secondary values will not be parsed, since they only +contain objects. + +Optional argument MODE, when non-nil, can be either +`first-section', `section', `planning', `item', `node-property' +and `table-row'. + +If STRUCTURE isn't provided but MODE is set to `item', it will be +computed. + +This function assumes point is always at the beginning of the +element it has to parse." + (save-excursion + (let ((case-fold-search t) + ;; Determine if parsing depth allows for secondary strings + ;; parsing. It only applies to elements referenced in + ;; `org-element-secondary-value-alist'. + (raw-secondary-p (and granularity (not (eq granularity 'object))))) + (cond + ;; Item. + ((eq mode 'item) + (org-element-item-parser limit structure raw-secondary-p)) + ;; Table Row. + ((eq mode 'table-row) (org-element-table-row-parser limit)) + ;; Node Property. + ((eq mode 'node-property) (org-element-node-property-parser limit)) + ;; Headline. + ((org-with-limited-levels (org-at-heading-p)) + (org-element-headline-parser limit raw-secondary-p)) + ;; Sections (must be checked after headline). + ((eq mode 'section) (org-element-section-parser limit)) + ((eq mode 'first-section) + (org-element-section-parser + (or (save-excursion (org-with-limited-levels (outline-next-heading))) + limit))) + ;; Planning. + ((and (eq mode 'planning) (looking-at org-planning-line-re)) + (org-element-planning-parser limit)) + ;; Property drawer. + ((and (memq mode '(planning property-drawer)) + (looking-at org-property-drawer-re)) + (org-element-property-drawer-parser limit)) + ;; When not at bol, point is at the beginning of an item or + ;; a footnote definition: next item is always a paragraph. + ((not (bolp)) (org-element-paragraph-parser limit (list (point)))) + ;; Clock. + ((looking-at org-clock-line-re) (org-element-clock-parser limit)) + ;; Inlinetask. + ((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))) + (cond + ;; Jumping over affiliated keywords put point off-limits. + ;; Parse them as regular keywords. + ((and (cdr affiliated) (>= (point) limit)) + (goto-char (car affiliated)) + (org-element-keyword-parser limit nil)) + ;; LaTeX Environment. + ((looking-at org-element--latex-begin-environment) + (org-element-latex-environment-parser limit affiliated)) + ;; Drawer and Property Drawer. + ((looking-at org-drawer-regexp) + (org-element-drawer-parser limit affiliated)) + ;; Fixed Width + ((looking-at "[ \t]*:\\( \\|$\\)") + (org-element-fixed-width-parser limit affiliated)) + ;; Inline Comments, Blocks, Babel Calls, Dynamic Blocks and + ;; Keywords. + ((looking-at "[ \t]*#") + (goto-char (match-end 0)) + (cond ((looking-at "\\(?: \\|$\\)") + (beginning-of-line) + (org-element-comment-parser limit affiliated)) + ((looking-at "\\+BEGIN_\\(\\S-+\\)") + (beginning-of-line) + (let ((parser (assoc (upcase (match-string 1)) + org-element-block-name-alist))) + (if parser (funcall (cdr parser) limit affiliated) + (org-element-special-block-parser limit affiliated)))) + ((looking-at "\\+CALL:") + (beginning-of-line) + (org-element-babel-call-parser limit affiliated)) + ((looking-at "\\+BEGIN:? ") + (beginning-of-line) + (org-element-dynamic-block-parser limit affiliated)) + ((looking-at "\\+\\S-+:") + (beginning-of-line) + (org-element-keyword-parser limit affiliated)) + (t + (beginning-of-line) + (org-element-paragraph-parser limit affiliated)))) + ;; Footnote Definition. + ((looking-at org-footnote-definition-re) + (org-element-footnote-definition-parser limit affiliated)) + ;; Horizontal Rule. + ((looking-at "[ \t]*-\\{5,\\}[ \t]*$") + (org-element-horizontal-rule-parser limit affiliated)) + ;; Diary Sexp. + ((looking-at "%%(") + (org-element-diary-sexp-parser limit affiliated)) + ;; Table. + ((looking-at "[ \t]*\\(|\\|\\+\\(-+\\+\\)+[ \t]*$\\)") + (org-element-table-parser limit affiliated)) + ;; List. + ((looking-at (org-item-re)) + (org-element-plain-list-parser + limit affiliated + (or structure (org-element--list-struct limit)))) + ;; Default element: Paragraph. + (t (org-element-paragraph-parser limit affiliated))))))))) + + +;; Most elements can have affiliated keywords. When looking for an +;; element beginning, we want to move before them, as they belong to +;; that element, and, in the meantime, collect information they give +;; into appropriate properties. Hence the following function. + +(defun org-element--collect-affiliated-keywords (limit) + "Collect affiliated keywords from point down to LIMIT. + +Return a list whose CAR is the position at the first of them and +CDR a plist of keywords and values and move point to the +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." + (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)) + output) + (while (and (< (point) limit) (looking-at org-element--affiliated-re)) + (let* ((raw-kwd (upcase (match-string 1))) + ;; Apply translation to RAW-KWD. From there, KWD is + ;; the official keyword. + (kwd (or (cdr (assoc raw-kwd + org-element-keyword-translation-alist)) + raw-kwd)) + ;; 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)) + (dual-value + (and dualp + (let ((sec (org-match-string-no-properties 2))) + (if (or (not sec) (not parsedp)) sec + (save-match-data + (org-element--parse-objects + (match-beginning 2) (match-end 2) nil restrict)))))) + ;; 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 + (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. + (string-match "^ATTR_" kwd)) + (setq value (cons value (plist-get output kwd-sym)))) + ;; Eventually store the new value in OUTPUT. + (setq output (plist-put output kwd-sym value)) + ;; Move to next keyword. + (forward-line))) + ;; If affiliated keywords are orphaned: move back to first one. + ;; They will be parsed as a paragraph. + (when (looking-at "[ \t]*$") (goto-char origin) (setq output nil)) + ;; Return value. + (cons origin output)))) + + + +;;; The Org Parser +;; +;; The two major functions here are `org-element-parse-buffer', which +;; parses Org syntax inside the current buffer, taking into account +;; region, narrowing, or even visibility if specified, and +;; `org-element-parse-secondary-string', which parses objects within +;; a given string. +;; +;; The (almost) almighty `org-element-map' allows applying a function +;; on elements or objects matching some type, and accumulating the +;; resulting values. In an export situation, it also skips unneeded +;; parts of the parse tree. + +(defun org-element-parse-buffer (&optional granularity visible-only) + "Recursively parse the buffer and return structure. +If narrowing is in effect, only parse the visible part of the +buffer. + +Optional argument GRANULARITY determines the depth of the +recursion. It can be set to the following symbols: + +`headline' Only parse headlines. +`greater-element' Don't recurse into greater elements excepted + headlines and sections. Thus, elements + parsed are the top-level ones. +`element' Parse everything but objects and plain text. +`object' Parse the complete buffer (default). + +When VISIBLE-ONLY is non-nil, don't parse contents of hidden +elements. + +An element or an objects is represented as a list with the +pattern (TYPE PROPERTIES CONTENTS), where : + + TYPE is a symbol describing the element or object. See + `org-element-all-elements' and `org-element-all-objects' for an + exhaustive list of such symbols. One can retrieve it with + `org-element-type' function. + + PROPERTIES is the list of attributes attached to the element or + object, as a plist. Although most of them are specific to the + element or object type, all types share `:begin', `:end', + `:post-blank' and `:parent' properties, which respectively + refer to buffer position where the element or object starts, + ends, the number of white spaces or blank lines after it, and + the element or object containing it. Properties values can be + obtained by using `org-element-property' function. + + CONTENTS is a list of elements, objects or raw strings + contained in the current element or object, when applicable. + One can access them with `org-element-contents' function. + +The Org buffer has `org-data' as type and nil as properties. +`org-element-map' function can be used to find specific elements +or objects within the parse tree. + +This function assumes that current major mode is `org-mode'." + (save-excursion + (goto-char (point-min)) + (org-skip-whitespace) + (org-element--parse-elements + (point-at-bol) (point-max) + ;; Start in `first-section' mode so text before the first + ;; headline belongs to a section. + 'first-section nil granularity visible-only (list 'org-data nil)))) + +(defun org-element-parse-secondary-string (string restriction &optional parent) + "Recursively parse objects in STRING and return structure. + +RESTRICTION is a symbol limiting the object types that will be +looked after. + +Optional argument PARENT, when non-nil, is the element or object +containing the secondary string. It is used to set correctly +`:parent' property within the string. + +If STRING is the empty string or nil, return nil." + (cond + ((not string) nil) + ((equal string "") nil) + (t (let ((local-variables (buffer-local-variables))) + (with-temp-buffer + (dolist (v local-variables) + (ignore-errors + (if (symbolp v) (makunbound v) + (org-set-local (car v) (cdr v))))) + (insert string) + (restore-buffer-modified-p nil) + (let ((data (org-element--parse-objects + (point-min) (point-max) nil restriction))) + (when parent + (dolist (o data) (org-element-put-property o :parent parent))) + data)))))) + +(defun org-element-map + (data types fun &optional info first-match no-recursion with-affiliated) + "Map a function on selected elements or objects. + +DATA is a parse tree, an element, an object, a string, or a list +of such constructs. TYPES is a symbol or list of symbols of +elements or objects types (see `org-element-all-elements' and +`org-element-all-objects' for a complete list of types). FUN is +the function called on the matching element or object. It has to +accept one argument: the element or object itself. + +When optional argument INFO is non-nil, it should be a plist +holding export options. In that case, parts of the parse tree +not exportable according to that property list will be skipped. + +When optional argument FIRST-MATCH is non-nil, stop at the first +match for which FUN doesn't return nil, and return that value. + +Optional argument NO-RECURSION is a symbol or a list of symbols +representing elements or objects types. `org-element-map' won't +enter any recursive element or object whose type belongs to that +list. Though, FUN can still be applied on them. + +When optional argument WITH-AFFILIATED is non-nil, FUN will also +apply to matching objects within parsed affiliated keywords (see +`org-element-parsed-keywords'). + +Nil values returned from FUN do not appear in the results. + + +Examples: +--------- + +Assuming TREE is a variable containing an Org buffer parse tree, +the following example will return a flat list of all `src-block' +and `example-block' elements in it: + + (org-element-map tree \\='(example-block src-block) #\\='identity) + +The following snippet will find the first headline with a level +of 1 and a \"phone\" tag, and will return its beginning position: + + (org-element-map tree \\='headline + (lambda (hl) + (and (= (org-element-property :level hl) 1) + (member \"phone\" (org-element-property :tags hl)) + (org-element-property :begin hl))) + nil t) + +The next example will return a flat list of all `plain-list' type +elements in TREE that are not a sub-list themselves: + + (org-element-map tree \\='plain-list #\\='identity nil nil \\='plain-list) + +Eventually, this example will return a flat list of all `bold' +type objects containing a `latex-snippet' type object, even +looking into captions: + + (org-element-map tree \\='bold + (lambda (b) + (and (org-element-map b \\='latex-snippet #\\='identity nil t) b)) + nil nil nil t)" + ;; Ensure TYPES and NO-RECURSION are a list, even of one element. + (let* ((types (if (listp types) types (list types))) + (no-recursion (if (listp no-recursion) no-recursion + (list no-recursion))) + ;; Recursion depth is determined by --CATEGORY. + (--category + (catch 'found + (let ((category 'greater-elements) + (all-objects (cons 'plain-text org-element-all-objects))) + (dolist (type types category) + (cond ((memq type all-objects) + ;; If one object is found, the function has to + ;; recurse into every object. + (throw 'found 'objects)) + ((not (memq type org-element-greater-elements)) + ;; If one regular element is found, the + ;; function has to recurse, at least, into + ;; every element it encounters. + (and (not (eq category 'elements)) + (setq category 'elements)))))))) + --acc + --walk-tree + (--walk-tree + (lambda (--data) + ;; Recursively walk DATA. INFO, if non-nil, is a plist + ;; holding contextual information. + (let ((--type (org-element-type --data))) + (cond + ((not --data)) + ;; Ignored element in an export context. + ((and info (memq --data (plist-get info :ignore-list)))) + ;; List of elements or objects. + ((not --type) (mapc --walk-tree --data)) + ;; Unconditionally enter parse trees. + ((eq --type 'org-data) + (mapc --walk-tree (org-element-contents --data))) + (t + ;; Check if TYPE is matching among TYPES. If so, + ;; apply FUN to --DATA and accumulate return value + ;; into --ACC (or exit if FIRST-MATCH is non-nil). + (when (memq --type types) + (let ((result (funcall fun --data))) + (cond ((not result)) + (first-match (throw '--map-first-match result)) + (t (push result --acc))))) + ;; If --DATA has a secondary string that can contain + ;; objects with their type among TYPES, look into it. + (when (and (eq --category 'objects) (not (stringp --data))) + (dolist (p (cdr (assq --type + org-element-secondary-value-alist))) + (funcall --walk-tree (org-element-property p --data)))) + ;; If --DATA has any parsed affiliated keywords and + ;; WITH-AFFILIATED is non-nil, look for objects in + ;; them. + (when (and with-affiliated + (eq --category 'objects) + (memq --type org-element-all-elements)) + (dolist (kwd-pair org-element--parsed-properties-alist) + (let ((kwd (car kwd-pair)) + (value (org-element-property (cdr kwd-pair) --data))) + ;; Pay attention to the type of parsed keyword. + ;; In particular, preserve order for multiple + ;; keywords. + (cond + ((not value)) + ((member kwd org-element-dual-keywords) + (if (member kwd org-element-multiple-keywords) + (dolist (line (reverse value)) + (funcall --walk-tree (cdr line)) + (funcall --walk-tree (car line))) + (funcall --walk-tree (cdr value)) + (funcall --walk-tree (car value)))) + ((member kwd org-element-multiple-keywords) + (mapc --walk-tree (reverse value))) + (t (funcall --walk-tree value)))))) + ;; Determine if a recursion into --DATA is possible. + (cond + ;; --TYPE is explicitly removed from recursion. + ((memq --type no-recursion)) + ;; --DATA has no contents. + ((not (org-element-contents --data))) + ;; Looking for greater elements but --DATA is simply + ;; an element or an object. + ((and (eq --category 'greater-elements) + (not (memq --type org-element-greater-elements)))) + ;; Looking for elements but --DATA is an object. + ((and (eq --category 'elements) + (memq --type org-element-all-objects))) + ;; In any other case, map contents. + (t (mapc --walk-tree (org-element-contents --data)))))))))) + (catch '--map-first-match + (funcall --walk-tree data) + ;; Return value in a proper order. + (nreverse --acc)))) +(put 'org-element-map 'lisp-indent-function 2) + +;; The following functions are internal parts of the parser. +;; +;; The first one, `org-element--parse-elements' acts at the element's +;; level. +;; +;; The second one, `org-element--parse-objects' applies on all objects +;; of a paragraph or a secondary string. It calls +;; `org-element--object-lex' to find the next object in the current +;; container. + +(defsubst org-element--next-mode (type parentp) + "Return next special mode according to TYPE, or nil. +TYPE is a symbol representing the type of an element or object +containing next element if PARENTP is non-nil, or before it +otherwise. Modes can be either `first-section', `item', +`node-property', `planning', `property-drawer', `section', +`table-row' or nil." + (if parentp + (case type + (headline 'section) + (inlinetask 'planning) + (plain-list 'item) + (property-drawer 'node-property) + (section 'planning) + (table 'table-row)) + (case type + (item 'item) + (node-property 'node-property) + (planning 'property-drawer) + (table-row 'table-row)))) + +(defun org-element--parse-elements + (beg end mode structure granularity visible-only acc) + "Parse elements between BEG and END positions. + +MODE prioritizes some elements over the others. It can be set to +`first-section', `section', `planning', `item', `node-property' +or `table-row'. + +When value is `item', STRUCTURE will be used as the current list +structure. + +GRANULARITY determines the depth of the recursion. See +`org-element-parse-buffer' for more information. + +When VISIBLE-ONLY is non-nil, don't parse contents of hidden +elements. + +Elements are accumulated into ACC." + (save-excursion + (goto-char beg) + ;; Visible only: skip invisible parts at the beginning of the + ;; element. + (when (and visible-only (org-invisible-p2)) + (goto-char (min (1+ (org-find-visible)) end))) + ;; When parsing only headlines, skip any text before first one. + (when (and (eq granularity 'headline) (not (org-at-heading-p))) + (org-with-limited-levels (outline-next-heading))) + ;; Main loop start. + (while (< (point) end) + ;; Find current element's type and parse it accordingly to + ;; its category. + (let* ((element (org-element--current-element + end granularity mode structure)) + (type (org-element-type element)) + (cbeg (org-element-property :contents-begin element))) + (goto-char (org-element-property :end element)) + ;; Visible only: skip invisible parts between siblings. + (when (and visible-only (org-invisible-p2)) + (goto-char (min (1+ (org-find-visible)) end))) + ;; Fill ELEMENT contents by side-effect. + (cond + ;; If element has no contents, don't modify it. + ((not cbeg)) + ;; Greater element: parse it between `contents-begin' and + ;; `contents-end'. Make sure GRANULARITY allows the + ;; recursion, or ELEMENT is a headline, in which case going + ;; inside is mandatory, in order to get sub-level headings. + ((and (memq type org-element-greater-elements) + (or (memq granularity '(element object nil)) + (and (eq granularity 'greater-element) + (eq type 'section)) + (eq type 'headline))) + (org-element--parse-elements + cbeg (org-element-property :contents-end element) + ;; Possibly switch to a special mode. + (org-element--next-mode type t) + (and (memq type '(item plain-list)) + (org-element-property :structure element)) + granularity visible-only element)) + ;; ELEMENT has contents. Parse objects inside, if + ;; GRANULARITY allows it. + ((memq granularity '(object nil)) + (org-element--parse-objects + cbeg (org-element-property :contents-end element) element + (org-element-restriction type)))) + (org-element-adopt-elements acc element) + ;; Update mode. + (setq mode (org-element--next-mode type nil)))) + ;; Return result. + acc)) + +(defun org-element--object-lex (restriction) + "Return next object in current buffer or nil. +RESTRICTION is a list of object types, as symbols, that should be +looked after. This function assumes that the buffer is narrowed +to an appropriate container (e.g., a paragraph)." + (if (memq 'table-cell restriction) (org-element-table-cell-parser) + (save-excursion + (let ((limit (and org-target-link-regexp + (save-excursion + (or (bolp) (backward-char)) + (re-search-forward org-target-link-regexp nil t)) + (match-beginning 1))) + found) + (while (and (not found) + (re-search-forward org-element--object-regexp limit t)) + (goto-char (match-beginning 0)) + (let ((result (match-string 0))) + (setq found + (cond + ((eq (compare-strings result nil nil "call_" nil nil t) t) + (and (memq 'inline-babel-call restriction) + (org-element-inline-babel-call-parser))) + ((eq (compare-strings result nil nil "src_" nil nil t) t) + (and (memq 'inline-src-block restriction) + (org-element-inline-src-block-parser))) + (t + (case (char-after) + (?^ (and (memq 'superscript restriction) + (org-element-superscript-parser))) + (?_ (or (and (memq 'subscript restriction) + (org-element-subscript-parser)) + (and (memq 'underline restriction) + (org-element-underline-parser)))) + (?* (and (memq 'bold restriction) + (org-element-bold-parser))) + (?/ (and (memq 'italic restriction) + (org-element-italic-parser))) + (?~ (and (memq 'code restriction) + (org-element-code-parser))) + (?= (and (memq 'verbatim restriction) + (org-element-verbatim-parser))) + (?+ (and (memq 'strike-through restriction) + (org-element-strike-through-parser))) + (?@ (and (memq 'export-snippet restriction) + (org-element-export-snippet-parser))) + (?{ (and (memq 'macro restriction) + (org-element-macro-parser))) + (?$ (and (memq 'latex-fragment restriction) + (org-element-latex-fragment-parser))) + (?< + (if (eq (aref result 1) ?<) + (or (and (memq 'radio-target restriction) + (org-element-radio-target-parser)) + (and (memq 'target restriction) + (org-element-target-parser))) + (or (and (memq 'timestamp restriction) + (org-element-timestamp-parser)) + (and (memq 'link restriction) + (org-element-link-parser))))) + (?\\ + (if (eq (aref result 1) ?\\) + (and (memq 'line-break restriction) + (org-element-line-break-parser)) + (or (and (memq 'entity restriction) + (org-element-entity-parser)) + (and (memq 'latex-fragment restriction) + (org-element-latex-fragment-parser))))) + (?\[ + (if (eq (aref result 1) ?\[) + (and (memq 'link restriction) + (org-element-link-parser)) + (or (and (memq 'footnote-reference restriction) + (org-element-footnote-reference-parser)) + (and (memq 'timestamp restriction) + (org-element-timestamp-parser)) + (and (memq 'statistics-cookie restriction) + (org-element-statistics-cookie-parser))))) + ;; This is probably a plain link. + (otherwise (and (or (memq 'link restriction) + (memq 'plain-link restriction)) + (org-element-link-parser))))))) + (or (eobp) (forward-char)))) + (cond (found) + ;; Radio link. + ((and limit (memq 'link restriction)) + (goto-char limit) (org-element-link-parser))))))) + +(defun org-element--parse-objects (beg end acc restriction) + "Parse objects between BEG and END and return recursive structure. + +Objects are accumulated in ACC. + +RESTRICTION is a list of object successors which are allowed in +the current object." + (save-excursion + (save-restriction + (narrow-to-region beg end) + (goto-char (point-min)) + (let (next-object) + (while (and (not (eobp)) + (setq next-object (org-element--object-lex restriction))) + ;; 1. Text before any object. Untabify it. + (let ((obj-beg (org-element-property :begin next-object))) + (unless (= (point) obj-beg) + (setq acc + (org-element-adopt-elements + acc + (replace-regexp-in-string + "\t" (make-string tab-width ? ) + (buffer-substring-no-properties (point) obj-beg)))))) + ;; 2. Object... + (let ((obj-end (org-element-property :end next-object)) + (cont-beg (org-element-property :contents-begin next-object))) + ;; Fill contents of NEXT-OBJECT by side-effect, if it has + ;; a recursive type. + (when (and cont-beg + (memq (car next-object) org-element-recursive-objects)) + (org-element--parse-objects + cont-beg (org-element-property :contents-end next-object) + next-object (org-element-restriction next-object))) + (setq acc (org-element-adopt-elements acc next-object)) + (goto-char obj-end)))) + ;; 3. Text after last object. Untabify it. + (unless (eobp) + (setq acc + (org-element-adopt-elements + acc + (replace-regexp-in-string + "\t" (make-string tab-width ? ) + (buffer-substring-no-properties (point) end))))) + ;; Result. + acc))) + + + +;;; Towards A Bijective Process +;; +;; The parse tree obtained with `org-element-parse-buffer' is really +;; a snapshot of the corresponding Org buffer. Therefore, it can be +;; interpreted and expanded into a string with canonical Org syntax. +;; Hence `org-element-interpret-data'. +;; +;; The function relies internally on +;; `org-element--interpret-affiliated-keywords'. + +;;;###autoload +(defun org-element-interpret-data (data) + "Interpret DATA as Org syntax. +DATA is a parse tree, an element, an object or a secondary string +to interpret. Return Org syntax as a string." + (org-element--interpret-data-1 data nil)) + +(defun org-element--interpret-data-1 (data parent) + "Interpret DATA as Org syntax. + +DATA is a parse tree, an element, an object or a secondary string +to interpret. PARENT is used for recursive calls. It contains +the element or object containing data, or nil. + +Return Org syntax as a string." + (let* ((type (org-element-type data)) + ;; Find interpreter for current object or element. If it + ;; doesn't exist (e.g. this is a pseudo object or element), + ;; return contents, if any. + (interpret + (let ((fun (intern (format "org-element-%s-interpreter" type)))) + (if (fboundp fun) fun (lambda (data contents) contents)))) + (results + (cond + ;; Secondary string. + ((not type) + (mapconcat + (lambda (obj) (org-element--interpret-data-1 obj parent)) data "")) + ;; Full Org document. + ((eq type 'org-data) + (mapconcat (lambda (obj) (org-element--interpret-data-1 obj parent)) + (org-element-contents data) "")) + ;; Plain text: return it. + ((stringp data) data) + ;; Element or object without contents. + ((not (org-element-contents data)) (funcall interpret data nil)) + ;; Element or object with contents. + (t + (funcall interpret data + ;; Recursively interpret contents. + (mapconcat + (lambda (obj) (org-element--interpret-data-1 obj data)) + (org-element-contents + (if (not (memq type '(paragraph verse-block))) + data + ;; Fix indentation of elements containing + ;; objects. We ignore `table-row' elements + ;; as they are one line long anyway. + (org-element-normalize-contents + data + ;; When normalizing first paragraph of an + ;; item or a footnote-definition, ignore + ;; first line's indentation. + (and (eq type 'paragraph) + (equal data (car (org-element-contents parent))) + (memq (org-element-type parent) + '(footnote-definition item)))))) + "")))))) + (if (memq type '(org-data plain-text nil)) results + ;; Build white spaces. If no `:post-blank' property is + ;; specified, assume its value is 0. + (let ((post-blank (or (org-element-property :post-blank data) 0))) + (if (or (memq type org-element-all-objects) + (and parent + (let ((type (org-element-type parent))) + (or (not type) + (memq type org-element-object-containers))))) + (concat results (make-string post-blank ?\s)) + (concat + (org-element--interpret-affiliated-keywords data) + (org-element-normalize-string results) + (make-string post-blank ?\n))))))) + +(defun org-element--interpret-affiliated-keywords (element) + "Return ELEMENT's affiliated keywords as Org syntax. +If there is no affiliated keyword, return the empty string." + (let ((keyword-to-org + (function + (lambda (key value) + (let (dual) + (when (member key org-element-dual-keywords) + (setq dual (cdr value) value (car value))) + (concat "#+" key + (and dual + (format "[%s]" (org-element-interpret-data dual))) + ": " + (if (member key org-element-parsed-keywords) + (org-element-interpret-data value) + value) + "\n")))))) + (mapconcat + (lambda (prop) + (let ((value (org-element-property prop element)) + (keyword (upcase (substring (symbol-name prop) 1)))) + (when value + (if (or (member keyword org-element-multiple-keywords) + ;; All attribute keywords can have multiple lines. + (string-match "^ATTR_" keyword)) + (mapconcat (lambda (line) (funcall keyword-to-org keyword line)) + (reverse value) + "") + (funcall keyword-to-org keyword value))))) + ;; List all ELEMENT's properties matching an attribute line or an + ;; affiliated keyword, but ignore translated keywords since they + ;; cannot belong to the property list. + (loop for prop in (nth 1 element) by 'cddr + when (let ((keyword (upcase (substring (symbol-name prop) 1)))) + (or (string-match "^ATTR_" keyword) + (and + (member keyword org-element-affiliated-keywords) + (not (assoc keyword + org-element-keyword-translation-alist))))) + collect prop) + ""))) + +;; Because interpretation of the parse tree must return the same +;; number of blank lines between elements and the same number of white +;; space after objects, some special care must be given to white +;; spaces. +;; +;; The first function, `org-element-normalize-string', ensures any +;; string different from the empty string will end with a single +;; newline character. +;; +;; The second function, `org-element-normalize-contents', removes +;; global indentation from the contents of the current element. + +(defun org-element-normalize-string (s) + "Ensure string S ends with a single newline character. + +If S isn't a string return it unchanged. If S is the empty +string, return it. Otherwise, return a new string with a single +newline character at its end." + (cond + ((not (stringp s)) s) + ((string= "" s) "") + (t (and (string-match "\\(\n[ \t]*\\)*\\'" s) + (replace-match "\n" nil nil s))))) + +(defun org-element-normalize-contents (element &optional ignore-first) + "Normalize plain text in ELEMENT's contents. + +ELEMENT must only contain plain text and objects. + +If optional argument IGNORE-FIRST is non-nil, ignore first line's +indentation to compute maximal common indentation. + +Return the normalized element that is element with global +indentation removed from its contents. The function assumes that +indentation is not done with TAB characters." + (let* ((min-ind most-positive-fixnum) + find-min-ind ; For byte-compiler. + (find-min-ind + ;; Return minimal common indentation within BLOB. This is + ;; done by walking recursively BLOB and updating MIN-IND + ;; along the way. FIRST-FLAG is non-nil when the next + ;; object is expected to be a string that doesn't start with + ;; a newline character. It happens for strings at the + ;; beginnings of the contents or right after a line break. + (lambda (blob first-flag) + (dolist (object (org-element-contents blob)) + (when first-flag + (setq first-flag nil) + ;; Objects cannot start with spaces: in this case, + ;; indentation is 0. + (if (not (stringp object)) (throw 'zero (setq min-ind 0)) + (string-match "\\` *" object) + (let ((len (match-end 0))) + ;; An indentation of zero means no string will be + ;; modified. Quit the process. + (if (zerop len) (throw 'zero (setq min-ind 0)) + (setq min-ind (min len min-ind)))))) + (cond + ((stringp object) + (dolist (line (cdr (org-split-string object " *\n"))) + (unless (string= line "") + (setq min-ind (min (org-get-indentation line) min-ind))))) + ((eq (org-element-type object) 'line-break) (setq first-flag t)) + ((memq (org-element-type object) org-element-recursive-objects) + (funcall find-min-ind object first-flag))))))) + ;; Find minimal indentation in ELEMENT. + (catch 'zero (funcall find-min-ind element (not ignore-first))) + (if (or (zerop min-ind) (= min-ind most-positive-fixnum)) element + ;; Build ELEMENT back, replacing each string with the same + ;; string minus common indentation. + (let* (build ; For byte compiler. + (build + (lambda (blob first-flag) + ;; Return BLOB with all its strings indentation + ;; shortened from MIN-IND white spaces. FIRST-FLAG is + ;; non-nil when the next object is expected to be + ;; a string that doesn't start with a newline + ;; character. + (setcdr (cdr blob) + (mapcar + (lambda (object) + (when first-flag + (setq first-flag nil) + (when (stringp object) + (setq object + (replace-regexp-in-string + (format "\\` \\{%d\\}" min-ind) + "" object)))) + (cond + ((stringp object) + (replace-regexp-in-string + (format "\n \\{%d\\}" min-ind) "\n" object)) + ((memq (org-element-type object) + org-element-recursive-objects) + (funcall build object first-flag)) + ((eq (org-element-type object) 'line-break) + (setq first-flag t) + object) + (t object))) + (org-element-contents blob))) + blob))) + (funcall build element (not ignore-first)))))) + + + +;;; Cache +;; +;; Implement a caching mechanism for `org-element-at-point' and +;; `org-element-context', which see. +;; +;; A single public function is provided: `org-element-cache-reset'. +;; +;; Cache is enabled by default, but can be disabled globally with +;; `org-element-use-cache'. `org-element-cache-sync-idle-time', +;; org-element-cache-sync-duration' and `org-element-cache-sync-break' +;; can be tweaked to control caching behaviour. +;; +;; Internally, parsed elements are stored in an AVL tree, +;; `org-element--cache'. This tree is updated lazily: whenever +;; a change happens to the buffer, a synchronization request is +;; registered in `org-element--cache-sync-requests' (see +;; `org-element--cache-submit-request'). During idle time, requests +;; are processed by `org-element--cache-sync'. Synchronization also +;; happens when an element is required from the cache. In this case, +;; the process stops as soon as the needed element is up-to-date. +;; +;; A synchronization request can only apply on a synchronized part of +;; the cache. Therefore, the cache is updated at least to the +;; location where the new request applies. Thus, requests are ordered +;; from left to right and all elements starting before the first +;; request are correct. This property is used by functions like +;; `org-element--cache-find' to retrieve elements in the part of the +;; cache that can be trusted. +;; +;; A request applies to every element, starting from its original +;; location (or key, see below). When a request is processed, it +;; moves forward and may collide the next one. In this case, both +;; requests are merged into a new one that starts from that element. +;; As a consequence, the whole synchronization complexity does not +;; depend on the number of pending requests, but on the number of +;; elements the very first request will be applied on. +;; +;; Elements cannot be accessed through their beginning position, which +;; may or may not be up-to-date. Instead, each element in the tree is +;; associated to a key, obtained with `org-element--cache-key'. This +;; mechanism is robust enough to preserve total order among elements +;; even when the tree is only partially synchronized. +;; +;; Objects contained in an element are stored in a hash table, +;; `org-element--cache-objects'. + + +(defvar org-element-use-cache t + "Non nil when Org parser should cache its results. +This is mostly for debugging purpose.") + +(defvar org-element-cache-sync-idle-time 0.6 + "Length, in seconds, of idle time before syncing cache.") + +(defvar org-element-cache-sync-duration (seconds-to-time 0.04) + "Maximum duration, as a time value, for a cache synchronization. +If the synchronization is not over after this delay, the process +pauses and resumes after `org-element-cache-sync-break' +seconds.") + +(defvar org-element-cache-sync-break (seconds-to-time 0.3) + "Duration, as a time value, of the pause between synchronizations. +See `org-element-cache-sync-duration' for more information.") + + +;;;; Data Structure + +(defvar org-element--cache nil + "AVL tree used to cache elements. +Each node of the tree contains an element. Comparison is done +with `org-element--cache-compare'. This cache is used in +`org-element-at-point'.") + +(defvar org-element--cache-objects nil + "Hash table used as to cache objects. +Key is an element, as returned by `org-element-at-point', and +value is an alist where each association is: + + \(PARENT COMPLETEP . OBJECTS) + +where PARENT is an element or object, COMPLETEP is a boolean, +non-nil when all direct children of parent are already cached and +OBJECTS is a list of such children, as objects, from farthest to +closest. + +In the following example, \\alpha, bold object and \\beta are +contained within a paragraph + + \\alpha *\\beta* + +If the paragraph is completely parsed, OBJECTS-DATA will be + + \((PARAGRAPH t BOLD-OBJECT ENTITY-OBJECT) + \(BOLD-OBJECT t ENTITY-OBJECT)) + +whereas in a partially parsed paragraph, it could be + + \((PARAGRAPH nil ENTITY-OBJECT)) + +This cache is used in `org-element-context'.") + +(defvar org-element--cache-sync-requests nil + "List of pending synchronization requests. + +A request is a vector with the following pattern: + + \[NEXT BEG END OFFSET PARENT PHASE] + +Processing a synchronization request consists of three phases: + + 0. Delete modified elements, + 1. Fill missing area in cache, + 2. Shift positions and re-parent elements after the changes. + +During phase 0, NEXT is the key of the first element to be +removed, BEG and END is buffer position delimiting the +modifications. Elements starting between them (inclusive) are +removed. So are elements whose parent is removed. PARENT, when +non-nil, is the parent of the first element to be removed. + +During phase 1, NEXT is the key of the next known element in +cache and BEG its beginning position. Parse buffer between that +element and the one before it in order to determine the parent of +the next element. Set PARENT to the element containing NEXT. + +During phase 2, NEXT is the key of the next element to shift in +the parse tree. All elements starting from this one have their +properties relatives to buffer positions shifted by integer +OFFSET and, if they belong to element PARENT, are adopted by it. + +PHASE specifies the phase number, as an integer.") + +(defvar org-element--cache-sync-timer nil + "Timer used for cache synchronization.") + +(defvar org-element--cache-sync-keys nil + "Hash table used to store keys during synchronization. +See `org-element--cache-key' for more information.") + +(defsubst org-element--cache-key (element) + "Return a unique key for ELEMENT in cache tree. + +Keys are used to keep a total order among elements in the cache. +Comparison is done with `org-element--cache-key-less-p'. + +When no synchronization is taking place, a key is simply the +beginning position of the element, or that position plus one in +the case of an first item (respectively row) in +a list (respectively a table). + +During a synchronization, the key is the one the element had when +the cache was synchronized for the last time. Elements added to +cache during the synchronization get a new key generated with +`org-element--cache-generate-key'. + +Such keys are stored in `org-element--cache-sync-keys'. The hash +table is cleared once the synchronization is complete." + (or (gethash element org-element--cache-sync-keys) + (let* ((begin (org-element-property :begin element)) + ;; Increase beginning position of items (respectively + ;; table rows) by one, so the first item can get + ;; a different key from its parent list (respectively + ;; table). + (key (if (memq (org-element-type element) '(item table-row)) + (1+ begin) + begin))) + (if org-element--cache-sync-requests + (puthash element key org-element--cache-sync-keys) + key)))) + +(defun org-element--cache-generate-key (lower upper) + "Generate a key between LOWER and UPPER. + +LOWER and UPPER are integers or lists, possibly empty. + +If LOWER and UPPER are equals, return LOWER. Otherwise, return +a unique key, as an integer or a list of integers, according to +the following rules: + + - LOWER and UPPER are compared level-wise until values differ. + + - If, at a given level, LOWER and UPPER differ from more than + 2, the new key shares all the levels above with LOWER and + gets a new level. Its value is the mean between LOWER and + UPPER: + + \(1 2) + (1 4) --> (1 3) + + - If LOWER has no value to compare with, it is assumed that its + value is `most-negative-fixnum'. E.g., + + \(1 1) + (1 1 2) + + is equivalent to + + \(1 1 m) + (1 1 2) + + where m is `most-negative-fixnum'. Likewise, if UPPER is + short of levels, the current value is `most-positive-fixnum'. + + - If they differ from only one, the new key inherits from + current LOWER level and fork it at the next level. E.g., + + \(2 1) + (3 3) + + is equivalent to + + \(2 1) + (2 M) + + where M is `most-positive-fixnum'. + + - If the key is only one level long, it is returned as an + integer: + + \(1 2) + (3 2) --> 2 + +When they are not equals, the function assumes that LOWER is +lesser than UPPER, per `org-element--cache-key-less-p'." + (if (equal lower upper) lower + (let ((lower (if (integerp lower) (list lower) lower)) + (upper (if (integerp upper) (list upper) upper)) + skip-upper key) + (catch 'exit + (while t + (let ((min (or (car lower) most-negative-fixnum)) + (max (cond (skip-upper most-positive-fixnum) + ((car upper)) + (t most-positive-fixnum)))) + (if (< (1+ min) max) + (let ((mean (+ (ash min -1) (ash max -1) (logand min max 1)))) + (throw 'exit (if key (nreverse (cons mean key)) mean))) + (when (and (< min max) (not skip-upper)) + ;; When at a given level, LOWER and UPPER differ from + ;; 1, ignore UPPER altogether. Instead create a key + ;; between LOWER and the greatest key with the same + ;; prefix as LOWER so far. + (setq skip-upper t)) + (push min key) + (setq lower (cdr lower) upper (cdr upper))))))))) + +(defsubst org-element--cache-key-less-p (a b) + "Non-nil if key A is less than key B. +A and B are either integers or lists of integers, as returned by +`org-element--cache-key'." + (if (integerp a) (if (integerp b) (< a b) (<= a (car b))) + (if (integerp b) (< (car a) b) + (catch 'exit + (while (and a b) + (cond ((car-less-than-car a b) (throw 'exit t)) + ((car-less-than-car b a) (throw 'exit nil)) + (t (setq a (cdr a) b (cdr b))))) + ;; If A is empty, either keys are equal (B is also empty) and + ;; we return nil, or A is lesser than B (B is longer) and we + ;; return a non-nil value. + ;; + ;; If A is not empty, B is necessarily empty and A is greater + ;; than B (A is longer). Therefore, return nil. + (and (null a) b))))) + +(defun org-element--cache-compare (a b) + "Non-nil when element A is located before element B." + (org-element--cache-key-less-p (org-element--cache-key a) + (org-element--cache-key b))) + +(defsubst org-element--cache-root () + "Return root value in cache. +This function assumes `org-element--cache' is a valid AVL tree." + (avl-tree--node-left (avl-tree--dummyroot org-element--cache))) + + +;;;; Tools + +(defsubst org-element--cache-active-p () + "Non-nil when cache is active in current buffer." + (and org-element-use-cache + org-element--cache + (derived-mode-p 'org-mode))) + +(defun org-element--cache-find (pos &optional side) + "Find element in cache starting at POS or before. + +POS refers to a buffer position. + +When optional argument SIDE is non-nil, the function checks for +elements starting at or past POS instead. If SIDE is `both', the +function returns a cons cell where car is the first element +starting at or before POS and cdr the first element starting +after POS. + +The function can only find elements in the synchronized part of +the cache." + (let ((limit (and org-element--cache-sync-requests + (aref (car org-element--cache-sync-requests) 0))) + (node (org-element--cache-root)) + lower upper) + (while node + (let* ((element (avl-tree--node-data node)) + (begin (org-element-property :begin element))) + (cond + ((and limit + (not (org-element--cache-key-less-p + (org-element--cache-key element) limit))) + (setq node (avl-tree--node-left node))) + ((> begin pos) + (setq upper element + node (avl-tree--node-left node))) + ((< begin pos) + (setq lower element + node (avl-tree--node-right node))) + ;; We found an element in cache starting at POS. If `side' + ;; is `both' we also want the next one in order to generate + ;; a key in-between. + ;; + ;; If the element is the first row or item in a table or + ;; a plain list, we always return the table or the plain + ;; list. + ;; + ;; In any other case, we return the element found. + ((eq side 'both) + (setq lower element) + (setq node (avl-tree--node-right node))) + ((and (memq (org-element-type element) '(item table-row)) + (let ((parent (org-element-property :parent element))) + (and (= (org-element-property :begin element) + (org-element-property :contents-begin parent)) + (setq node nil + lower parent + upper parent))))) + (t + (setq node nil + lower element + upper element))))) + (case side + (both (cons lower upper)) + ((nil) lower) + (otherwise upper)))) + +(defun org-element--cache-put (element &optional data) + "Store ELEMENT in current buffer's cache, if allowed. +When optional argument DATA is non-nil, assume is it object data +relative to ELEMENT and store it in the objects cache." + (cond ((not (org-element--cache-active-p)) nil) + ((not data) + (when org-element--cache-sync-requests + ;; During synchronization, first build an appropriate key + ;; for the new element so `avl-tree-enter' can insert it at + ;; the right spot in the cache. + (let ((keys (org-element--cache-find + (org-element-property :begin element) 'both))) + (puthash element + (org-element--cache-generate-key + (and (car keys) (org-element--cache-key (car keys))) + (cond ((cdr keys) (org-element--cache-key (cdr keys))) + (org-element--cache-sync-requests + (aref (car org-element--cache-sync-requests) 0)))) + org-element--cache-sync-keys))) + (avl-tree-enter org-element--cache element)) + ;; Headlines are not stored in cache, so objects in titles are + ;; not stored either. + ((eq (org-element-type element) 'headline) nil) + (t (puthash element data org-element--cache-objects)))) + +(defsubst org-element--cache-remove (element) + "Remove ELEMENT from cache. +Assume ELEMENT belongs to cache and that a cache is active." + (avl-tree-delete org-element--cache element) + (remhash element org-element--cache-objects)) + + +;;;; Synchronization + +(defsubst org-element--cache-set-timer (buffer) + "Set idle timer for cache synchronization in BUFFER." + (when org-element--cache-sync-timer + (cancel-timer org-element--cache-sync-timer)) + (setq org-element--cache-sync-timer + (run-with-idle-timer + (let ((idle (current-idle-time))) + (if idle (time-add idle org-element-cache-sync-break) + org-element-cache-sync-idle-time)) + nil + #'org-element--cache-sync + buffer))) + +(defsubst org-element--cache-interrupt-p (time-limit) + "Non-nil when synchronization process should be interrupted. +TIME-LIMIT is a time value or nil." + (and time-limit + (or (input-pending-p) + (time-less-p time-limit (current-time))))) + +(defsubst org-element--cache-shift-positions (element offset &optional props) + "Shift ELEMENT properties relative to buffer positions by OFFSET. + +Properties containing buffer positions are `:begin', `:end', +`:contents-begin', `:contents-end' and `:structure'. When +optional argument PROPS is a list of keywords, only shift +properties provided in that list. + +Properties are modified by side-effect." + (let ((properties (nth 1 element))) + ;; Shift `:structure' property for the first plain list only: it + ;; is the only one that really matters and it prevents from + ;; shifting it more than once. + (when (and (or (not props) (memq :structure props)) + (eq (org-element-type element) 'plain-list) + (not (eq (org-element-type (plist-get properties :parent)) + 'item))) + (dolist (item (plist-get properties :structure)) + (incf (car item) offset) + (incf (nth 6 item) offset))) + (dolist (key '(:begin :contents-begin :contents-end :end :post-affiliated)) + (let ((value (and (or (not props) (memq key props)) + (plist-get properties key)))) + (and value (plist-put properties key (+ offset value))))))) + +(defun org-element--cache-sync (buffer &optional threshold future-change) + "Synchronize cache with recent modification in BUFFER. + +When optional argument THRESHOLD is non-nil, do the +synchronization for all elements starting before or at threshold, +then exit. Otherwise, synchronize cache for as long as +`org-element-cache-sync-duration' or until Emacs leaves idle +state. + +FUTURE-CHANGE, when non-nil, is a buffer position where changes +not registered yet in the cache are going to happen. It is used +in `org-element--cache-submit-request', where cache is partially +updated before current modification are actually submitted." + (when (buffer-live-p buffer) + (with-current-buffer buffer + (let ((inhibit-quit t) request next) + (when org-element--cache-sync-timer + (cancel-timer org-element--cache-sync-timer)) + (catch 'interrupt + (while org-element--cache-sync-requests + (setq request (car org-element--cache-sync-requests) + next (nth 1 org-element--cache-sync-requests)) + (org-element--cache-process-request + request + (and next (aref next 0)) + threshold + (and (not threshold) + (time-add (current-time) + org-element-cache-sync-duration)) + future-change) + ;; Request processed. Merge current and next offsets and + ;; transfer ending position. + (when next + (incf (aref next 3) (aref request 3)) + (aset next 2 (aref request 2))) + (setq org-element--cache-sync-requests + (cdr org-element--cache-sync-requests)))) + ;; If more requests are awaiting, set idle timer accordingly. + ;; Otherwise, reset keys. + (if org-element--cache-sync-requests + (org-element--cache-set-timer buffer) + (clrhash org-element--cache-sync-keys)))))) + +(defun org-element--cache-process-request + (request next threshold time-limit future-change) + "Process synchronization REQUEST for all entries before NEXT. + +REQUEST is a vector, built by `org-element--cache-submit-request'. + +NEXT is a cache key, as returned by `org-element--cache-key'. + +When non-nil, THRESHOLD is a buffer position. Synchronization +stops as soon as a shifted element begins after it. + +When non-nil, TIME-LIMIT is a time value. Synchronization stops +after this time or when Emacs exits idle state. + +When non-nil, FUTURE-CHANGE is a buffer position where changes +not registered yet in the cache are going to happen. See +`org-element--cache-submit-request' for more information. + +Throw `interrupt' if the process stops before completing the +request." + (catch 'quit + (when (= (aref request 5) 0) + ;; Phase 0. + ;; + ;; Delete all elements starting after BEG, but not after buffer + ;; position END or past element with key NEXT. Also delete + ;; elements contained within a previously removed element + ;; (stored in `last-container'). + ;; + ;; At each iteration, we start again at tree root since + ;; a deletion modifies structure of the balanced tree. + (catch 'end-phase + (while t + (when (org-element--cache-interrupt-p time-limit) + (throw 'interrupt nil)) + ;; Find first element in cache with key BEG or after it. + (let ((beg (aref request 0)) + (end (aref request 2)) + (node (org-element--cache-root)) + data data-key last-container) + (while node + (let* ((element (avl-tree--node-data node)) + (key (org-element--cache-key element))) + (cond + ((org-element--cache-key-less-p key beg) + (setq node (avl-tree--node-right node))) + ((org-element--cache-key-less-p beg key) + (setq data element + data-key key + node (avl-tree--node-left node))) + (t (setq data element + data-key key + node nil))))) + (if data + (let ((pos (org-element-property :begin data))) + (if (if (or (not next) + (org-element--cache-key-less-p data-key next)) + (<= pos end) + (and last-container + (let ((up data)) + (while (and up (not (eq up last-container))) + (setq up (org-element-property :parent up))) + up))) + (progn (when (and (not last-container) + (> (org-element-property :end data) + end)) + (setq last-container data)) + (org-element--cache-remove data)) + (aset request 0 data-key) + (aset request 1 pos) + (aset request 5 1) + (throw 'end-phase nil))) + ;; No element starting after modifications left in + ;; cache: further processing is futile. + (throw 'quit t)))))) + (when (= (aref request 5) 1) + ;; Phase 1. + ;; + ;; Phase 0 left a hole in the cache. Some elements after it + ;; could have parents within. For example, in the following + ;; buffer: + ;; + ;; - item + ;; + ;; + ;; Paragraph1 + ;; + ;; Paragraph2 + ;; + ;; if we remove a blank line between "item" and "Paragraph1", + ;; everything down to "Paragraph2" is removed from cache. But + ;; the paragraph now belongs to the list, and its `:parent' + ;; property no longer is accurate. + ;; + ;; Therefore we need to parse again elements in the hole, or at + ;; least in its last section, so that we can re-parent + ;; subsequent elements, during phase 2. + ;; + ;; Note that we only need to get the parent from the first + ;; element in cache after the hole. + ;; + ;; When next key is lesser or equal to the current one, delegate + ;; phase 1 processing to next request in order to preserve key + ;; order among requests. + (let ((key (aref request 0))) + (when (and next (not (org-element--cache-key-less-p key next))) + (let ((next-request (nth 1 org-element--cache-sync-requests))) + (aset next-request 0 key) + (aset next-request 1 (aref request 1)) + (aset next-request 5 1)) + (throw 'quit t))) + ;; Next element will start at its beginning position plus + ;; offset, since it hasn't been shifted yet. Therefore, LIMIT + ;; contains the real beginning position of the first element to + ;; shift and re-parent. + (let ((limit (+ (aref request 1) (aref request 3)))) + (cond ((and threshold (> limit threshold)) (throw 'interrupt nil)) + ((and future-change (>= limit future-change)) + ;; Changes are going to happen around this element and + ;; they will trigger another phase 1 request. Skip the + ;; current one. + (aset request 5 2)) + (t + (let ((parent (org-element--parse-to limit t time-limit))) + (aset request 4 parent) + (aset request 5 2)))))) + ;; Phase 2. + ;; + ;; Shift all elements starting from key START, but before NEXT, by + ;; OFFSET, and re-parent them when appropriate. + ;; + ;; Elements are modified by side-effect so the tree structure + ;; remains intact. + ;; + ;; Once THRESHOLD, if any, is reached, or once there is an input + ;; pending, exit. Before leaving, the current synchronization + ;; request is updated. + (let ((start (aref request 0)) + (offset (aref request 3)) + (parent (aref request 4)) + (node (org-element--cache-root)) + (stack (list nil)) + (leftp t) + exit-flag) + ;; No re-parenting nor shifting planned: request is over. + (when (and (not parent) (zerop offset)) (throw 'quit t)) + (while node + (let* ((data (avl-tree--node-data node)) + (key (org-element--cache-key data))) + (if (and leftp (avl-tree--node-left node) + (not (org-element--cache-key-less-p key start))) + (progn (push node stack) + (setq node (avl-tree--node-left node))) + (unless (org-element--cache-key-less-p key start) + ;; We reached NEXT. Request is complete. + (when (equal key next) (throw 'quit t)) + ;; Handle interruption request. Update current request. + (when (or exit-flag (org-element--cache-interrupt-p time-limit)) + (aset request 0 key) + (aset request 4 parent) + (throw 'interrupt nil)) + ;; Shift element. + (unless (zerop offset) + (org-element--cache-shift-positions data offset) + ;; Shift associated objects data, if any. + (dolist (object-data (gethash data org-element--cache-objects)) + (dolist (object (cddr object-data)) + (org-element--cache-shift-positions object offset)))) + (let ((begin (org-element-property :begin data))) + ;; Update PARENT and re-parent DATA, only when + ;; necessary. Propagate new structures for lists. + (while (and parent + (<= (org-element-property :end parent) begin)) + (setq parent (org-element-property :parent parent))) + (cond ((and (not parent) (zerop offset)) (throw 'quit nil)) + ((and parent + (let ((p (org-element-property :parent data))) + (or (not p) + (< (org-element-property :begin p) + (org-element-property :begin parent))))) + (org-element-put-property data :parent parent) + (let ((s (org-element-property :structure parent))) + (when (and s (org-element-property :structure data)) + (org-element-put-property data :structure s))))) + ;; Cache is up-to-date past THRESHOLD. Request + ;; interruption. + (when (and threshold (> begin threshold)) (setq exit-flag t)))) + (setq node (if (setq leftp (avl-tree--node-right node)) + (avl-tree--node-right node) + (pop stack)))))) + ;; We reached end of tree: synchronization complete. + t))) + +(defun org-element--parse-to (pos &optional syncp time-limit) + "Parse elements in current section, down to POS. + +Start parsing from the closest between the last known element in +cache or headline above. Return the smallest element containing +POS. + +When optional argument SYNCP is non-nil, return the parent of the +element containing POS instead. In that case, it is also +possible to provide TIME-LIMIT, which is a time value specifying +when the parsing should stop. The function throws `interrupt' if +the process stopped before finding the expected result." + (catch 'exit + (org-with-wide-buffer + (goto-char pos) + (let* ((cached (and (org-element--cache-active-p) + (org-element--cache-find pos nil))) + (begin (org-element-property :begin cached)) + element next mode) + (cond + ;; Nothing in cache before point: start parsing from first + ;; element following headline above, or first element in + ;; buffer. + ((not cached) + (when (org-with-limited-levels (outline-previous-heading)) + (setq mode 'planning) + (forward-line)) + (skip-chars-forward " \r\t\n") + (beginning-of-line)) + ;; Cache returned exact match: return it. + ((= pos begin) + (throw 'exit (if syncp (org-element-property :parent cached) cached))) + ;; There's a headline between cached value and POS: cached + ;; value is invalid. Start parsing from first element + ;; following the headline. + ((re-search-backward + (org-with-limited-levels org-outline-regexp-bol) begin t) + (forward-line) + (skip-chars-forward " \r\t\n") + (beginning-of-line) + (setq mode 'planning)) + ;; Check if CACHED or any of its ancestors contain point. + ;; + ;; If there is such an element, we inspect it in order to know + ;; if we return it or if we need to parse its contents. + ;; Otherwise, we just start parsing from current location, + ;; which is right after the top-most element containing + ;; CACHED. + ;; + ;; As a special case, if POS is at the end of the buffer, we + ;; want to return the innermost element ending there. + ;; + ;; Also, if we find an ancestor and discover that we need to + ;; parse its contents, make sure we don't start from + ;; `:contents-begin', as we would otherwise go past CACHED + ;; again. Instead, in that situation, we will resume parsing + ;; from NEXT, which is located after CACHED or its higher + ;; ancestor not containing point. + (t + (let ((up cached) + (pos (if (= (point-max) pos) (1- pos) pos))) + (goto-char (or (org-element-property :contents-begin cached) begin)) + (while (let ((end (org-element-property :end up))) + (and (<= end pos) + (goto-char end) + (setq up (org-element-property :parent up))))) + (cond ((not up)) + ((eobp) (setq element up)) + (t (setq element up next (point))))))) + ;; Parse successively each element until we reach POS. + (let ((end (or (org-element-property :end element) + (save-excursion + (org-with-limited-levels (outline-next-heading)) + (point)))) + (parent element)) + (while t + (when syncp + (cond ((= (point) pos) (throw 'exit parent)) + ((org-element--cache-interrupt-p time-limit) + (throw 'interrupt nil)))) + (unless element + (setq element (org-element--current-element + end 'element mode + (org-element-property :structure parent))) + (org-element-put-property element :parent parent) + (org-element--cache-put element)) + (let ((elem-end (org-element-property :end element)) + (type (org-element-type element))) + (cond + ;; Skip any element ending before point. Also skip + ;; element ending at point (unless it is also the end of + ;; buffer) since we're sure that another element begins + ;; after it. + ((and (<= elem-end pos) (/= (point-max) elem-end)) + (goto-char elem-end) + (setq mode (org-element--next-mode type nil))) + ;; A non-greater element contains point: return it. + ((not (memq type org-element-greater-elements)) + (throw 'exit element)) + ;; Otherwise, we have to decide if ELEMENT really + ;; contains POS. In that case we start parsing from + ;; contents' beginning. + ;; + ;; If POS is at contents' beginning but it is also at + ;; the beginning of the first item in a list or a table. + ;; In that case, we need to create an anchor for that + ;; list or table, so return it. + ;; + ;; Also, if POS is at the end of the buffer, no element + ;; can start after it, but more than one may end there. + ;; Arbitrarily, we choose to return the innermost of + ;; such elements. + ((let ((cbeg (org-element-property :contents-begin element)) + (cend (org-element-property :contents-end element))) + (when (or syncp + (and cbeg cend + (or (< cbeg pos) + (and (= cbeg pos) + (not (memq type '(plain-list table))))) + (or (> cend pos) + (and (= cend pos) (= (point-max) pos))))) + (goto-char (or next cbeg)) + (setq next nil + mode (org-element--next-mode type t) + parent element + end cend)))) + ;; Otherwise, return ELEMENT as it is the smallest + ;; element containing POS. + (t (throw 'exit element)))) + (setq element nil))))))) + + +;;;; Staging Buffer Changes + +(defconst org-element--cache-sensitive-re + (concat + org-outline-regexp-bol "\\|" + "\\\\end{[A-Za-z0-9*]+}[ \t]*$" "\\|" + "^[ \t]*\\(?:" + "#\\+\\(?:BEGIN[:_]\\|END\\(?:_\\|:?[ \t]*$\\)\\)" "\\|" + "\\\\begin{[A-Za-z0-9*]+}" "\\|" + ":\\(?:\\w\\|[-_]\\)+:[ \t]*$" + "\\)") + "Regexp matching a sensitive line, structure wise. +A sensitive line is a headline, inlinetask, block, drawer, or +latex-environment boundary. When such a line is modified, +structure changes in the document may propagate in the whole +section, possibly making cache invalid.") + +(defvar org-element--cache-change-warning nil + "Non-nil when a sensitive line is about to be changed. +It is a symbol among nil, t and `headline'.") + +(defun org-element--cache-before-change (beg end) + "Request extension of area going to be modified if needed. +BEG and END are the beginning and end of the range of changed +text. See `before-change-functions' for more information." + (when (org-element--cache-active-p) + (org-with-wide-buffer + (goto-char beg) + (beginning-of-line) + (let ((bottom (save-excursion (goto-char end) (line-end-position)))) + (setq org-element--cache-change-warning + (save-match-data + (if (and (org-with-limited-levels (org-at-heading-p)) + (= (line-end-position) bottom)) + 'headline + (let ((case-fold-search t)) + (re-search-forward + org-element--cache-sensitive-re bottom t))))))))) + +(defun org-element--cache-after-change (beg end pre) + "Update buffer modifications for current buffer. +BEG and END are the beginning and end of the range of changed +text, and the length in bytes of the pre-change text replaced by +that range. See `after-change-functions' for more information." + (when (org-element--cache-active-p) + (org-with-wide-buffer + (goto-char beg) + (beginning-of-line) + (save-match-data + (let ((top (point)) + (bottom (save-excursion (goto-char end) (line-end-position)))) + ;; Determine if modified area needs to be extended, according + ;; to both previous and current state. We make a special + ;; case for headline editing: if a headline is modified but + ;; not removed, do not extend. + (when (case org-element--cache-change-warning + ((t) t) + (headline + (not (and (org-with-limited-levels (org-at-heading-p)) + (= (line-end-position) bottom)))) + (otherwise + (let ((case-fold-search t)) + (re-search-forward + org-element--cache-sensitive-re bottom t)))) + ;; Effectively extend modified area. + (org-with-limited-levels + (setq top (progn (goto-char top) + (when (outline-previous-heading) (forward-line)) + (point))) + (setq bottom (progn (goto-char bottom) + (if (outline-next-heading) (1- (point)) + (point)))))) + ;; Store synchronization request. + (let ((offset (- end beg pre))) + (org-element--cache-submit-request top (- bottom offset) offset))))) + ;; Activate a timer to process the request during idle time. + (org-element--cache-set-timer (current-buffer)))) + +(defun org-element--cache-for-removal (beg end offset) + "Return first element to remove from cache. + +BEG and END are buffer positions delimiting buffer modifications. +OFFSET is the size of the changes. + +Returned element is usually the first element in cache containing +any position between BEG and END. As an exception, greater +elements around the changes that are robust to contents +modifications are preserved and updated according to the +changes." + (let* ((elements (org-element--cache-find (1- beg) 'both)) + (before (car elements)) + (after (cdr elements))) + (if (not before) after + (let ((up before) + (robust-flag t)) + (while up + (if (let ((type (org-element-type up))) + (and (or (memq type '(center-block dynamic-block quote-block + special-block)) + ;; Drawers named "PROPERTIES" are probably + ;; a properties drawer being edited. Force + ;; parsing to check if editing is over. + (and (eq type 'drawer) + (not (string= + (org-element-property :drawer-name up) + "PROPERTIES")))) + (let ((cbeg (org-element-property :contents-begin up))) + (and cbeg + (<= cbeg beg) + (> (org-element-property :contents-end up) end))))) + ;; UP is a robust greater element containing changes. + ;; We only need to extend its ending boundaries. + (org-element--cache-shift-positions + up offset '(:contents-end :end)) + (setq before up) + (when robust-flag (setq robust-flag nil))) + (setq up (org-element-property :parent up))) + ;; We're at top level element containing ELEMENT: if it's + ;; altered by buffer modifications, it is first element in + ;; cache to be removed. Otherwise, that first element is the + ;; following one. + ;; + ;; As a special case, do not remove BEFORE if it is a robust + ;; container for current changes. + (if (or (< (org-element-property :end before) beg) robust-flag) after + before))))) + +(defun org-element--cache-submit-request (beg end offset) + "Submit a new cache synchronization request for current buffer. +BEG and END are buffer positions delimiting the minimal area +where cache data should be removed. OFFSET is the size of the +change, as an integer." + (let ((next (car org-element--cache-sync-requests)) + delete-to delete-from) + (if (and next + (zerop (aref next 5)) + (> (setq delete-to (+ (aref next 2) (aref next 3))) end) + (<= (setq delete-from (aref next 1)) end)) + ;; Current changes can be merged with first sync request: we + ;; can save a partial cache synchronization. + (progn + (incf (aref next 3) offset) + ;; If last change happened within area to be removed, extend + ;; boundaries of robust parents, if any. Otherwise, find + ;; first element to remove and update request accordingly. + (if (> beg delete-from) + (let ((up (aref next 4))) + (while up + (org-element--cache-shift-positions + up offset '(:contents-end :end)) + (setq up (org-element-property :parent up)))) + (let ((first (org-element--cache-for-removal beg delete-to offset))) + (when first + (aset next 0 (org-element--cache-key first)) + (aset next 1 (org-element-property :begin first)) + (aset next 4 (org-element-property :parent first)))))) + ;; Ensure cache is correct up to END. Also make sure that NEXT, + ;; if any, is no longer a 0-phase request, thus ensuring that + ;; phases are properly ordered. We need to provide OFFSET as + ;; optional parameter since current modifications are not known + ;; yet to the otherwise correct part of the cache (i.e, before + ;; the first request). + (when next (org-element--cache-sync (current-buffer) end beg)) + (let ((first (org-element--cache-for-removal beg end offset))) + (if first + (push (let ((beg (org-element-property :begin first)) + (key (org-element--cache-key first))) + (cond + ;; When changes happen before the first known + ;; element, re-parent and shift the rest of the + ;; cache. + ((> beg end) (vector key beg nil offset nil 1)) + ;; Otherwise, we find the first non robust + ;; element containing END. All elements between + ;; FIRST and this one are to be removed. + ((let ((first-end (org-element-property :end first))) + (and (> first-end end) + (vector key beg first-end offset first 0)))) + (t + (let* ((element (org-element--cache-find end)) + (end (org-element-property :end element)) + (up element)) + (while (and (setq up (org-element-property :parent up)) + (>= (org-element-property :begin up) beg)) + (setq end (org-element-property :end up) + element up)) + (vector key beg end offset element 0))))) + org-element--cache-sync-requests) + ;; No element to remove. No need to re-parent either. + ;; Simply shift additional elements, if any, by OFFSET. + (when org-element--cache-sync-requests + (incf (aref (car org-element--cache-sync-requests) 3) offset))))))) + + +;;;; Public Functions + +;;;###autoload +(defun org-element-cache-reset (&optional all) + "Reset cache in current buffer. +When optional argument ALL is non-nil, reset cache in all Org +buffers." + (interactive "P") + (dolist (buffer (if all (buffer-list) (list (current-buffer)))) + (with-current-buffer buffer + (when (and org-element-use-cache (derived-mode-p 'org-mode)) + (org-set-local 'org-element--cache + (avl-tree-create #'org-element--cache-compare)) + (org-set-local 'org-element--cache-objects (make-hash-table :test #'eq)) + (org-set-local 'org-element--cache-sync-keys + (make-hash-table :weakness 'key :test #'eq)) + (org-set-local 'org-element--cache-change-warning nil) + (org-set-local 'org-element--cache-sync-requests nil) + (org-set-local 'org-element--cache-sync-timer nil) + (add-hook 'before-change-functions + #'org-element--cache-before-change nil t) + (add-hook 'after-change-functions + #'org-element--cache-after-change nil t))))) + +;;;###autoload +(defun org-element-cache-refresh (pos) + "Refresh cache at position POS." + (when (org-element--cache-active-p) + (org-element--cache-sync (current-buffer) pos) + (org-element--cache-submit-request pos pos 0) + (org-element--cache-set-timer (current-buffer)))) + + + +;;; The Toolbox +;; +;; The first move is to implement a way to obtain the smallest element +;; containing point. This is the job of `org-element-at-point'. It +;; basically jumps back to the beginning of section containing point +;; and proceed, one element after the other, with +;; `org-element--current-element' until the container is found. Note: +;; When using `org-element-at-point', secondary values are never +;; parsed since the function focuses on elements, not on objects. +;; +;; At a deeper level, `org-element-context' lists all elements and +;; objects containing point. +;; +;; `org-element-nested-p' and `org-element-swap-A-B' may be used +;; internally by navigation and manipulation tools. + + +;;;###autoload +(defun org-element-at-point () + "Determine closest element around point. + +Return value is a list like (TYPE PROPS) where TYPE is the type +of the element and PROPS a plist of properties associated to the +element. + +Possible types are defined in `org-element-all-elements'. +Properties depend on element or object type, but always include +`:begin', `:end', `:parent' and `:post-blank' properties. + +As a special case, if point is at the very beginning of the first +item in a list or sub-list, returned element will be that list +instead of the item. Likewise, if point is at the beginning of +the first row of a table, returned element will be the table +instead of the first row. + +When point is at the end of the buffer, return the innermost +element ending there." + (org-with-wide-buffer + (let ((origin (point))) + (end-of-line) + (skip-chars-backward " \r\t\n") + (cond + ;; Within blank lines at the beginning of buffer, return nil. + ((bobp) nil) + ;; Within blank lines right after a headline, return that + ;; headline. + ((org-with-limited-levels (org-at-heading-p)) + (beginning-of-line) + (org-element-headline-parser (point-max) t)) + ;; Otherwise parse until we find element containing ORIGIN. + (t + (when (org-element--cache-active-p) + (if (not org-element--cache) (org-element-cache-reset) + (org-element--cache-sync (current-buffer) origin))) + (org-element--parse-to origin)))))) + +;;;###autoload +(defun org-element-context (&optional element) + "Return smallest element or object around point. + +Return value is a list like (TYPE PROPS) where TYPE is the type +of the element or object and PROPS a plist of properties +associated to it. + +Possible types are defined in `org-element-all-elements' and +`org-element-all-objects'. Properties depend on element or +object type, but always include `:begin', `:end', `:parent' and +`:post-blank'. + +As a special case, if point is right after an object and not at +the beginning of any other object, return that object. + +Optional argument ELEMENT, when non-nil, is the closest element +containing point, as returned by `org-element-at-point'. +Providing it allows for quicker computation." + (catch 'objects-forbidden + (org-with-wide-buffer + (let* ((pos (point)) + (element (or element (org-element-at-point))) + (type (org-element-type element)) + (post (org-element-property :post-affiliated element))) + ;; If point is inside an element containing objects or + ;; a secondary string, narrow buffer to the container and + ;; proceed with parsing. Otherwise, return ELEMENT. + (cond + ;; At a parsed affiliated keyword, check if we're inside main + ;; or dual value. + ((and post (< pos post)) + (beginning-of-line) + (let ((case-fold-search t)) (looking-at org-element--affiliated-re)) + (cond + ((not (member-ignore-case (match-string 1) + org-element-parsed-keywords)) + (throw 'objects-forbidden element)) + ((< (match-end 0) pos) + (narrow-to-region (match-end 0) (line-end-position))) + ((and (match-beginning 2) + (>= pos (match-beginning 2)) + (< pos (match-end 2))) + (narrow-to-region (match-beginning 2) (match-end 2))) + (t (throw 'objects-forbidden element))) + ;; Also change type to retrieve correct restrictions. + (setq type 'keyword)) + ;; At an item, objects can only be located within tag, if any. + ((eq type 'item) + (let ((tag (org-element-property :tag element))) + (if (or (not tag) (/= (line-beginning-position) post)) + (throw 'objects-forbidden element) + (beginning-of-line) + (search-forward tag (line-end-position)) + (goto-char (match-beginning 0)) + (if (and (>= pos (point)) (< pos (match-end 0))) + (narrow-to-region (point) (match-end 0)) + (throw 'objects-forbidden element))))) + ;; At an headline or inlinetask, objects are in title. + ((memq type '(headline inlinetask)) + (goto-char (org-element-property :begin element)) + (looking-at org-complex-heading-regexp) + (let ((end (match-end 4))) + (if (not end) (throw 'objects-forbidden element) + (goto-char (match-beginning 4)) + (when (let (case-fold-search) (looking-at org-comment-string)) + (goto-char (match-end 0))) + (if (>= (point) end) (throw 'objects-forbidden element) + (narrow-to-region (point) end))))) + ;; At a paragraph, a table-row or a verse block, objects are + ;; located within their contents. + ((memq type '(paragraph table-row verse-block)) + (let ((cbeg (org-element-property :contents-begin element)) + (cend (org-element-property :contents-end element))) + ;; CBEG is nil for table rules. + (if (and cbeg cend (>= pos cbeg) + (or (< pos cend) (and (= pos cend) (eobp)))) + (narrow-to-region cbeg cend) + (throw 'objects-forbidden element)))) + ;; At a planning line, if point is at a timestamp, return it, + ;; otherwise, return element. + ((eq type 'planning) + (dolist (p '(:closed :deadline :scheduled)) + (let ((timestamp (org-element-property p element))) + (when (and timestamp + (<= (org-element-property :begin timestamp) pos) + (> (org-element-property :end timestamp) pos)) + (throw 'objects-forbidden timestamp)))) + ;; All other locations cannot contain objects: bail out. + (throw 'objects-forbidden element)) + (t (throw 'objects-forbidden element))) + (goto-char (point-min)) + (let ((restriction (org-element-restriction type)) + (parent element) + (cache (cond ((not (org-element--cache-active-p)) nil) + (org-element--cache-objects + (gethash element org-element--cache-objects)) + (t (org-element-cache-reset) nil))) + next object-data last) + (prog1 + (catch 'exit + (while t + ;; When entering PARENT for the first time, get list + ;; of objects within known so far. Store it in + ;; OBJECT-DATA. + (unless next + (let ((data (assq parent cache))) + (if data (setq object-data data) + (push (setq object-data (list parent nil)) cache)))) + ;; Find NEXT object for analysis. + (catch 'found + ;; If NEXT is non-nil, we already exhausted the + ;; cache so we can parse buffer to find the object + ;; after it. + (if next (setq next (org-element--object-lex restriction)) + ;; Otherwise, check if cache can help us. + (let ((objects (cddr object-data)) + (completep (nth 1 object-data))) + (cond + ((and (not objects) completep) (throw 'exit parent)) + ((not objects) + (setq next (org-element--object-lex restriction))) + (t + (let ((cache-limit + (org-element-property :end (car objects)))) + (if (>= cache-limit pos) + ;; Cache contains the information needed. + (dolist (object objects (throw 'exit parent)) + (when (<= (org-element-property :begin object) + pos) + (if (>= (org-element-property :end object) + pos) + (throw 'found (setq next object)) + (throw 'exit parent)))) + (goto-char cache-limit) + (setq next + (org-element--object-lex restriction)))))))) + ;; If we have a new object to analyze, store it in + ;; cache. Otherwise record that there is nothing + ;; more to parse in this element at this depth. + (if next + (progn (org-element-put-property next :parent parent) + (push next (cddr object-data))) + (setcar (cdr object-data) t))) + ;; Process NEXT, if any, in order to know if we need + ;; to skip it, return it or move into it. + (if (or (not next) (> (org-element-property :begin next) pos)) + (throw 'exit (or last parent)) + (let ((end (org-element-property :end next)) + (cbeg (org-element-property :contents-begin next)) + (cend (org-element-property :contents-end next))) + (cond + ;; Skip objects ending before point. Also skip + ;; objects ending at point unless it is also the + ;; end of buffer, since we want to return the + ;; innermost object. + ((and (<= end pos) (/= (point-max) end)) + (goto-char end) + ;; For convenience, when object ends at POS, + ;; without any space, store it in LAST, as we + ;; will return it if no object starts here. + (when (and (= end pos) + (not (memq (char-before) '(?\s ?\t)))) + (setq last next))) + ;; If POS is within a container object, move + ;; into that object. + ((and cbeg cend + (>= pos cbeg) + (or (< pos cend) + ;; At contents' end, if there is no + ;; space before point, also move into + ;; object, for consistency with + ;; convenience feature above. + (and (= pos cend) + (or (= (point-max) pos) + (not (memq (char-before pos) + '(?\s ?\t))))))) + (goto-char cbeg) + (narrow-to-region (point) cend) + (setq parent next + restriction (org-element-restriction next) + next nil + object-data nil)) + ;; Otherwise, return NEXT. + (t (throw 'exit next))))))) + ;; Store results in cache, if applicable. + (org-element--cache-put element cache))))))) + +(defun org-element-lineage (blob &optional types with-self) + "List all ancestors of a given element or object. + +BLOB is an object or element. + +When optional argument TYPES is a list of symbols, return the +first element or object in the lineage whose type belongs to that +list. + +When optional argument WITH-SELF is non-nil, lineage includes +BLOB itself as the first element, and TYPES, if provided, also +apply to it. + +When BLOB is obtained through `org-element-context' or +`org-element-at-point', only ancestors from its section can be +found. There is no such limitation when BLOB belongs to a full +parse tree." + (let ((up (if with-self blob (org-element-property :parent blob))) + ancestors) + (while (and up (not (memq (org-element-type up) types))) + (unless types (push up ancestors)) + (setq up (org-element-property :parent up))) + (if types up (nreverse ancestors)))) + +(defun org-element-nested-p (elem-A elem-B) + "Non-nil when elements ELEM-A and ELEM-B are nested." + (let ((beg-A (org-element-property :begin elem-A)) + (beg-B (org-element-property :begin elem-B)) + (end-A (org-element-property :end elem-A)) + (end-B (org-element-property :end elem-B))) + (or (and (>= beg-A beg-B) (<= end-A end-B)) + (and (>= beg-B beg-A) (<= end-B end-A))))) + +(defun org-element-swap-A-B (elem-A elem-B) + "Swap elements ELEM-A and ELEM-B. +Assume ELEM-B is after ELEM-A in the buffer. Leave point at the +end of ELEM-A." + (goto-char (org-element-property :begin elem-A)) + ;; There are two special cases when an element doesn't start at bol: + ;; the first paragraph in an item or in a footnote definition. + (let ((specialp (not (bolp)))) + ;; Only a paragraph without any affiliated keyword can be moved at + ;; ELEM-A position in such a situation. Note that the case of + ;; a footnote definition is impossible: it cannot contain two + ;; paragraphs in a row because it cannot contain a blank line. + (if (and specialp + (or (not (eq (org-element-type elem-B) 'paragraph)) + (/= (org-element-property :begin elem-B) + (org-element-property :contents-begin elem-B)))) + (error "Cannot swap elements")) + ;; In a special situation, ELEM-A will have no indentation. We'll + ;; give it ELEM-B's (which will in, in turn, have no indentation). + (let* ((ind-B (when specialp + (goto-char (org-element-property :begin elem-B)) + (org-get-indentation))) + (beg-A (org-element-property :begin elem-A)) + (end-A (save-excursion + (goto-char (org-element-property :end elem-A)) + (skip-chars-backward " \r\t\n") + (point-at-eol))) + (beg-B (org-element-property :begin elem-B)) + (end-B (save-excursion + (goto-char (org-element-property :end elem-B)) + (skip-chars-backward " \r\t\n") + (point-at-eol))) + ;; Store inner overlays responsible for visibility status. + ;; We also need to store their boundaries as they will be + ;; removed from buffer. + (overlays + (cons + (delq nil + (mapcar (lambda (o) + (and (>= (overlay-start o) beg-A) + (<= (overlay-end o) end-A) + (list o (overlay-start o) (overlay-end o)))) + (overlays-in beg-A end-A))) + (delq nil + (mapcar (lambda (o) + (and (>= (overlay-start o) beg-B) + (<= (overlay-end o) end-B) + (list o (overlay-start o) (overlay-end o)))) + (overlays-in beg-B end-B))))) + ;; Get contents. + (body-A (buffer-substring beg-A end-A)) + (body-B (delete-and-extract-region beg-B end-B))) + (goto-char beg-B) + (when specialp + (setq body-B (replace-regexp-in-string "\\`[ \t]*" "" body-B)) + (org-indent-to-column ind-B)) + (insert body-A) + ;; Restore ex ELEM-A overlays. + (let ((offset (- beg-B beg-A))) + (dolist (o (car overlays)) + (move-overlay (car o) (+ (nth 1 o) offset) (+ (nth 2 o) offset))) + (goto-char beg-A) + (delete-region beg-A end-A) + (insert body-B) + ;; Restore ex ELEM-B overlays. + (dolist (o (cdr overlays)) + (move-overlay (car o) (- (nth 1 o) offset) (- (nth 2 o) offset)))) + (goto-char (org-element-property :end elem-B))))) + +(defun org-element-remove-indentation (s &optional n) + "Remove maximum common indentation in string S and return it. +When optional argument N is a positive integer, remove exactly +that much characters from indentation, if possible, or return +S as-is otherwise. Unlike to `org-remove-indentation', this +function doesn't call `untabify' on S." + (catch 'exit + (with-temp-buffer + (insert s) + (goto-char (point-min)) + ;; Find maximum common indentation, if not specified. + (setq n (or n + (let ((min-ind (point-max))) + (save-excursion + (while (re-search-forward "^[ \t]*\\S-" nil t) + (let ((ind (1- (current-column)))) + (if (zerop ind) (throw 'exit s) + (setq min-ind (min min-ind ind)))))) + min-ind))) + (if (zerop n) s + ;; Remove exactly N indentation, but give up if not possible. + (while (not (eobp)) + (let ((ind (progn (skip-chars-forward " \t") (current-column)))) + (cond ((eolp) (delete-region (line-beginning-position) (point))) + ((< ind n) (throw 'exit s)) + (t (org-indent-line-to (- ind n)))) + (forward-line))) + (buffer-string))))) + + + +(provide 'org-element) + +;; Local variables: +;; generated-autoload-file: "org-loaddefs.el" +;; End: + +;;; org-element.el ends here diff --git a/elpa/org-20160215/org-entities.el b/elpa/org-20160215/org-entities.el new file mode 100644 index 00000000..89c59629 --- /dev/null +++ b/elpa/org-20160215/org-entities.el @@ -0,0 +1,611 @@ +;;; org-entities.el --- Support for special entities in Org-mode + +;; Copyright (C) 2010-2016 Free Software Foundation, Inc. + +;; Author: Carsten Dominik , +;; Ulf Stegemann +;; Keywords: outlines, calendar, wp +;; Homepage: http://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 . +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: + +;;; Code: + +(declare-function org-toggle-pretty-entities "org" ()) +(declare-function org-table-align "org-table" ()) + +(eval-when-compile + (require 'cl)) + +(defgroup org-entities nil + "Options concerning entities in Org-mode." + :tag "Org Entities" + :group 'org) + +(defun org-entities--user-safe-p (v) + "Non-nil if V is a safe value for `org-entities-user'." + (or (null v) + (and (listp v) + (= (length v) 7) + (stringp (nth 0 v)) + (stringp (nth 1 v)) + (booleanp (nth 2 v)) + (stringp (nth 3 v)) + (stringp (nth 4 v)) + (stringp (nth 5 v)) + (stringp (nth 6 v))))) + +(defcustom org-entities-user nil + "User-defined entities used in Org-mode to produce special characters. +Each entry in this list is a list of strings. It associates the name +of the entity that can be inserted into an Org file as \\name with the +appropriate replacements for the different export backends. The order +of the fields is the following + +name As a string, without the leading backslash. +LaTeX replacement In ready LaTeX, no further processing will take place. +LaTeX mathp Either t or nil. When t this entity needs to be in + math mode. +HTML replacement In ready HTML, no further processing will take place. + Usually this will be an &...; entity. +ASCII replacement Plain ASCII, no extensions. +Latin1 replacement Use the special characters available in latin1. +utf-8 replacement Use the special characters available in utf-8. + +If you define new entities here that require specific LaTeX +packages to be loaded, add these packages to `org-latex-packages-alist'." + :group 'org-entities + :version "24.1" + :type '(repeat + (list + (string :tag "name ") + (string :tag "LaTeX ") + (boolean :tag "Require LaTeX math?") + (string :tag "HTML ") + (string :tag "ASCII ") + (string :tag "Latin1") + (string :tag "utf-8 "))) + :safe #'org-entities--user-safe-p) + +(defconst org-entities + (append + '("* Letters" + "** Latin" + ("Agrave" "\\`{A}" nil "À" "A" "À" "À") + ("agrave" "\\`{a}" nil "à" "a" "à" "à") + ("Aacute" "\\'{A}" nil "Á" "A" "Á" "Á") + ("aacute" "\\'{a}" nil "á" "a" "á" "á") + ("Acirc" "\\^{A}" nil "Â" "A" "Â" "Â") + ("acirc" "\\^{a}" nil "â" "a" "â" "â") + ("Atilde" "\\~{A}" nil "Ã" "A" "Ã" "Ã") + ("atilde" "\\~{a}" nil "ã" "a" "ã" "ã") + ("Auml" "\\\"{A}" nil "Ä" "Ae" "Ä" "Ä") + ("auml" "\\\"{a}" nil "ä" "ae" "ä" "ä") + ("Aring" "\\AA{}" nil "Å" "A" "Å" "Å") + ("AA" "\\AA{}" nil "Å" "A" "Å" "Å") + ("aring" "\\aa{}" nil "å" "a" "Ã¥" "Ã¥") + ("AElig" "\\AE{}" nil "Æ" "AE" "Æ" "Æ") + ("aelig" "\\ae{}" nil "æ" "ae" "æ" "æ") + ("Ccedil" "\\c{C}" nil "Ç" "C" "Ç" "Ç") + ("ccedil" "\\c{c}" nil "ç" "c" "ç" "ç") + ("Egrave" "\\`{E}" nil "È" "E" "È" "È") + ("egrave" "\\`{e}" nil "è" "e" "è" "è") + ("Eacute" "\\'{E}" nil "É" "E" "É" "É") + ("eacute" "\\'{e}" nil "é" "e" "é" "é") + ("Ecirc" "\\^{E}" nil "Ê" "E" "Ê" "Ê") + ("ecirc" "\\^{e}" nil "ê" "e" "ê" "ê") + ("Euml" "\\\"{E}" nil "Ë" "E" "Ë" "Ë") + ("euml" "\\\"{e}" nil "ë" "e" "ë" "ë") + ("Igrave" "\\`{I}" nil "Ì" "I" "Ì" "Ì") + ("igrave" "\\`{i}" nil "ì" "i" "ì" "ì") + ("Iacute" "\\'{I}" nil "Í" "I" "Í" "Í") + ("iacute" "\\'{i}" nil "í" "i" "í" "í") + ("Icirc" "\\^{I}" nil "Î" "I" "Î" "Î") + ("icirc" "\\^{i}" nil "î" "i" "î" "î") + ("Iuml" "\\\"{I}" nil "Ï" "I" "Ï" "Ï") + ("iuml" "\\\"{i}" nil "ï" "i" "ï" "ï") + ("Ntilde" "\\~{N}" nil "Ñ" "N" "Ñ" "Ñ") + ("ntilde" "\\~{n}" nil "ñ" "n" "ñ" "ñ") + ("Ograve" "\\`{O}" nil "Ò" "O" "Ò" "Ò") + ("ograve" "\\`{o}" nil "ò" "o" "ò" "ò") + ("Oacute" "\\'{O}" nil "Ó" "O" "Ó" "Ó") + ("oacute" "\\'{o}" nil "ó" "o" "ó" "ó") + ("Ocirc" "\\^{O}" nil "Ô" "O" "Ô" "Ô") + ("ocirc" "\\^{o}" nil "ô" "o" "ô" "ô") + ("Otilde" "\\~{O}" nil "Õ" "O" "Õ" "Õ") + ("otilde" "\\~{o}" nil "õ" "o" "õ" "õ") + ("Ouml" "\\\"{O}" nil "Ö" "Oe" "Ö" "Ö") + ("ouml" "\\\"{o}" nil "ö" "oe" "ö" "ö") + ("Oslash" "\\O" nil "Ø" "O" "Ø" "Ø") + ("oslash" "\\o{}" nil "ø" "o" "ø" "ø") + ("OElig" "\\OE{}" nil "Œ" "OE" "OE" "Œ") + ("oelig" "\\oe{}" nil "œ" "oe" "oe" "œ") + ("Scaron" "\\v{S}" nil "Š" "S" "S" "Å ") + ("scaron" "\\v{s}" nil "š" "s" "s" "Å¡") + ("szlig" "\\ss{}" nil "ß" "ss" "ß" "ß") + ("Ugrave" "\\`{U}" nil "Ù" "U" "Ù" "Ù") + ("ugrave" "\\`{u}" nil "ù" "u" "ù" "ù") + ("Uacute" "\\'{U}" nil "Ú" "U" "Ú" "Ú") + ("uacute" "\\'{u}" nil "ú" "u" "ú" "ú") + ("Ucirc" "\\^{U}" nil "Û" "U" "Û" "Û") + ("ucirc" "\\^{u}" nil "û" "u" "û" "û") + ("Uuml" "\\\"{U}" nil "Ü" "Ue" "Ü" "Ü") + ("uuml" "\\\"{u}" nil "ü" "ue" "ü" "ü") + ("Yacute" "\\'{Y}" nil "Ý" "Y" "Ý" "Ý") + ("yacute" "\\'{y}" nil "ý" "y" "ý" "ý") + ("Yuml" "\\\"{Y}" nil "Ÿ" "Y" "Y" "Ÿ") + ("yuml" "\\\"{y}" nil "ÿ" "y" "ÿ" "ÿ") + + "** Latin (special face)" + ("fnof" "\\textit{f}" nil "ƒ" "f" "f" "ƒ") + ("real" "\\Re" t "ℜ" "R" "R" "ℜ") + ("image" "\\Im" t "ℑ" "I" "I" "ℑ") + ("weierp" "\\wp" t "℘" "P" "P" "℘") + ("ell" "\\ell" t "ℓ" "ell" "ell" "ℓ") + ("imath" "\\imath" t "ı" "[dotless i]" "dotless i" "ı") + ("jmath" "\\jmath" t "ȷ" "[dotless j]" "dotless j" "È·") + + "** Greek" + ("Alpha" "A" nil "Α" "Alpha" "Alpha" "Α") + ("alpha" "\\alpha" t "α" "alpha" "alpha" "α") + ("Beta" "B" nil "Β" "Beta" "Beta" "Β") + ("beta" "\\beta" t "β" "beta" "beta" "β") + ("Gamma" "\\Gamma" t "Γ" "Gamma" "Gamma" "Γ") + ("gamma" "\\gamma" t "γ" "gamma" "gamma" "γ") + ("Delta" "\\Delta" t "Δ" "Delta" "Gamma" "Δ") + ("delta" "\\delta" t "δ" "delta" "delta" "δ") + ("Epsilon" "E" nil "Ε" "Epsilon" "Epsilon" "Ε") + ("epsilon" "\\epsilon" t "ε" "epsilon" "epsilon" "ε") + ("varepsilon" "\\varepsilon" t "ε" "varepsilon" "varepsilon" "ε") + ("Zeta" "Z" nil "Ζ" "Zeta" "Zeta" "Ζ") + ("zeta" "\\zeta" t "ζ" "zeta" "zeta" "ζ") + ("Eta" "H" nil "Η" "Eta" "Eta" "Η") + ("eta" "\\eta" t "η" "eta" "eta" "η") + ("Theta" "\\Theta" t "Θ" "Theta" "Theta" "Θ") + ("theta" "\\theta" t "θ" "theta" "theta" "θ") + ("thetasym" "\\vartheta" t "ϑ" "theta" "theta" "ϑ") + ("vartheta" "\\vartheta" t "ϑ" "theta" "theta" "ϑ") + ("Iota" "I" nil "Ι" "Iota" "Iota" "Ι") + ("iota" "\\iota" t "ι" "iota" "iota" "ι") + ("Kappa" "K" nil "Κ" "Kappa" "Kappa" "Κ") + ("kappa" "\\kappa" t "κ" "kappa" "kappa" "κ") + ("Lambda" "\\Lambda" t "Λ" "Lambda" "Lambda" "Λ") + ("lambda" "\\lambda" t "λ" "lambda" "lambda" "λ") + ("Mu" "M" nil "Μ" "Mu" "Mu" "Μ") + ("mu" "\\mu" t "μ" "mu" "mu" "μ") + ("nu" "\\nu" t "ν" "nu" "nu" "ν") + ("Nu" "N" nil "Ν" "Nu" "Nu" "Ν") + ("Xi" "\\Xi" t "Ξ" "Xi" "Xi" "Ξ") + ("xi" "\\xi" t "ξ" "xi" "xi" "ξ") + ("Omicron" "O" nil "Ο" "Omicron" "Omicron" "Ο") + ("omicron" "\\textit{o}" nil "ο" "omicron" "omicron" "ο") + ("Pi" "\\Pi" t "Π" "Pi" "Pi" "Π") + ("pi" "\\pi" t "π" "pi" "pi" "π") + ("Rho" "P" nil "Ρ" "Rho" "Rho" "Ρ") + ("rho" "\\rho" t "ρ" "rho" "rho" "ρ") + ("Sigma" "\\Sigma" t "Σ" "Sigma" "Sigma" "Σ") + ("sigma" "\\sigma" t "σ" "sigma" "sigma" "σ") + ("sigmaf" "\\varsigma" t "ς" "sigmaf" "sigmaf" "ς") + ("varsigma" "\\varsigma" t "ς" "varsigma" "varsigma" "ς") + ("Tau" "T" nil "Τ" "Tau" "Tau" "Τ") + ("Upsilon" "\\Upsilon" t "Υ" "Upsilon" "Upsilon" "Î¥") + ("upsih" "\\Upsilon" t "ϒ" "upsilon" "upsilon" "ϒ") + ("upsilon" "\\upsilon" t "υ" "upsilon" "upsilon" "υ") + ("Phi" "\\Phi" t "Φ" "Phi" "Phi" "Φ") + ("phi" "\\phi" t "φ" "phi" "phi" "φ") + ("varphi" "\\varphi" t "ϕ" "varphi" "varphi" "ɸ") + ("Chi" "X" nil "Χ" "Chi" "Chi" "Χ") + ("chi" "\\chi" t "χ" "chi" "chi" "χ") + ("acutex" "\\acute x" t "´x" "'x" "'x" "𝑥́") + ("Psi" "\\Psi" t "Ψ" "Psi" "Psi" "Ψ") + ("psi" "\\psi" t "ψ" "psi" "psi" "ψ") + ("tau" "\\tau" t "τ" "tau" "tau" "τ") + ("Omega" "\\Omega" t "Ω" "Omega" "Omega" "Ω") + ("omega" "\\omega" t "ω" "omega" "omega" "ω") + ("piv" "\\varpi" t "ϖ" "omega-pi" "omega-pi" "ϖ") + ("varpi" "\\varpi" t "ϖ" "omega-pi" "omega-pi" "ϖ") + ("partial" "\\partial" t "∂" "[partial differential]" "[partial differential]" "∂") + + "** Hebrew" + ("alefsym" "\\aleph" t "ℵ" "aleph" "aleph" "ℵ") + ("aleph" "\\aleph" t "ℵ" "aleph" "aleph" "ℵ") + ("gimel" "\\gimel" t "ℷ" "gimel" "gimel" "ℷ") + ("beth" "\\beth" t "ℶ" "beth" "beth" "ב") + ("dalet" "\\daleth" t "ℸ" "dalet" "dalet" "ד") + + "** Dead languages" + ("ETH" "\\DH{}" nil "Ð" "D" "Ð" "Ð") + ("eth" "\\dh{}" nil "ð" "dh" "ð" "ð") + ("THORN" "\\TH{}" nil "Þ" "TH" "Þ" "Þ") + ("thorn" "\\th{}" nil "þ" "th" "þ" "þ") + + "* Punctuation" + "** Dots and Marks" + ("dots" "\\dots{}" nil "…" "..." "..." "…") + ("cdots" "\\cdots{}" t "⋯" "..." "..." "⋯") + ("hellip" "\\dots{}" nil "…" "..." "..." "…") + ("middot" "\\textperiodcentered{}" nil "·" "." "·" "·") + ("iexcl" "!`" nil "¡" "!" "¡" "¡") + ("iquest" "?`" nil "¿" "?" "¿" "¿") + + "** Dash-like" + ("shy" "\\-" nil "­" "" "" "") + ("ndash" "--" nil "–" "-" "-" "–") + ("mdash" "---" nil "—" "--" "--" "—") + + "** Quotations" + ("quot" "\\textquotedbl{}" nil """ "\"" "\"" "\"") + ("acute" "\\textasciiacute{}" nil "´" "'" "´" "´") + ("ldquo" "\\textquotedblleft{}" nil "“" "\"" "\"" "“") + ("rdquo" "\\textquotedblright{}" nil "”" "\"" "\"" "”") + ("bdquo" "\\quotedblbase{}" nil "„" "\"" "\"" "„") + ("lsquo" "\\textquoteleft{}" nil "‘" "`" "`" "‘") + ("rsquo" "\\textquoteright{}" nil "’" "'" "'" "’") + ("sbquo" "\\quotesinglbase{}" nil "‚" "," "," "‚") + ("laquo" "\\guillemotleft{}" nil "«" "<<" "«" "«") + ("raquo" "\\guillemotright{}" nil "»" ">>" "»" "»") + ("lsaquo" "\\guilsinglleft{}" nil "‹" "<" "<" "‹") + ("rsaquo" "\\guilsinglright{}" nil "›" ">" ">" "›") + + "* Other" + "** Misc. (often used)" + ("circ" "\\^{}" nil "ˆ" "^" "^" "ˆ") + ("vert" "\\vert{}" t "|" "|" "|" "|") + ("brvbar" "\\textbrokenbar{}" nil "¦" "|" "¦" "¦") + ("S" "\\S" nil "§" "paragraph" "§" "§") + ("sect" "\\S" nil "§" "paragraph" "§" "§") + ("amp" "\\&" nil "&" "&" "&" "&") + ("lt" "\\textless{}" nil "<" "<" "<" "<") + ("gt" "\\textgreater{}" nil ">" ">" ">" ">") + ("tilde" "\\textasciitilde{}" nil "~" "~" "~" "~") + ("slash" "/" nil "/" "/" "/" "/") + ("plus" "+" nil "+" "+" "+" "+") + ("under" "\\_" nil "_" "_" "_" "_") + ("equal" "=" nil "=" "=" "=" "=") + ("asciicirc" "\\textasciicircum{}" nil "^" "^" "^" "^") + ("dagger" "\\textdagger{}" nil "†" "[dagger]" "[dagger]" "†") + ("dag" "\\dag{}" nil "†" "[dagger]" "[dagger]" "†") + ("Dagger" "\\textdaggerdbl{}" nil "‡" "[doubledagger]" "[doubledagger]" "‡") + ("ddag" "\\ddag{}" nil "‡" "[doubledagger]" "[doubledagger]" "‡") + + "** Whitespace" + ("nbsp" "~" nil " " " " " " " ") + ("ensp" "\\hspace*{.5em}" nil " " " " " " " ") + ("emsp" "\\hspace*{1em}" nil " " " " " " " ") + ("thinsp" "\\hspace*{.2em}" nil " " " " " " " ") + + "** Currency" + ("curren" "\\textcurrency{}" nil "¤" "curr." "¤" "¤") + ("cent" "\\textcent{}" nil "¢" "cent" "¢" "¢") + ("pound" "\\pounds{}" nil "£" "pound" "£" "£") + ("yen" "\\textyen{}" nil "¥" "yen" "Â¥" "Â¥") + ("euro" "\\texteuro{}" nil "€" "EUR" "EUR" "€") + ("EUR" "\\texteuro{}" nil "€" "EUR" "EUR" "€") + + "** Property Marks" + ("copy" "\\textcopyright{}" nil "©" "(c)" "©" "©") + ("reg" "\\textregistered{}" nil "®" "(r)" "®" "®") + ("trade" "\\texttrademark{}" nil "™" "TM" "TM" "™") + + "** Science et al." + ("minus" "\\minus" t "−" "-" "-" "−") + ("pm" "\\textpm{}" nil "±" "+-" "±" "±") + ("plusmn" "\\textpm{}" nil "±" "+-" "±" "±") + ("times" "\\texttimes{}" nil "×" "*" "×" "×") + ("frasl" "/" nil "⁄" "/" "/" "⁄") + ("colon" "\\colon" t ":" ":" ":" ":") + ("div" "\\textdiv{}" nil "÷" "/" "÷" "÷") + ("frac12" "\\textonehalf{}" nil "½" "1/2" "½" "½") + ("frac14" "\\textonequarter{}" nil "¼" "1/4" "¼" "¼") + ("frac34" "\\textthreequarters{}" nil "¾" "3/4" "¾" "¾") + ("permil" "\\textperthousand{}" nil "‰" "per thousand" "per thousand" "‰") + ("sup1" "\\textonesuperior{}" nil "¹" "^1" "¹" "¹") + ("sup2" "\\texttwosuperior{}" nil "²" "^2" "²" "²") + ("sup3" "\\textthreesuperior{}" nil "³" "^3" "³" "³") + ("radic" "\\sqrt{\\,}" t "√" "[square root]" "[square root]" "√") + ("sum" "\\sum" t "∑" "[sum]" "[sum]" "∑") + ("prod" "\\prod" t "∏" "[product]" "[n-ary product]" "∏") + ("micro" "\\textmu{}" nil "µ" "micro" "µ" "µ") + ("macr" "\\textasciimacron{}" nil "¯" "[macron]" "¯" "¯") + ("deg" "\\textdegree{}" nil "°" "degree" "°" "°") + ("prime" "\\prime" t "′" "'" "'" "′") + ("Prime" "\\prime{}\\prime" t "″" "''" "''" "″") + ("infin" "\\infty" t "∞" "[infinity]" "[infinity]" "∞") + ("infty" "\\infty" t "∞" "[infinity]" "[infinity]" "∞") + ("prop" "\\propto" t "∝" "[proportional to]" "[proportional to]" "∝") + ("propto" "\\propto" t "∝" "[proportional to]" "[proportional to]" "∝") + ("not" "\\textlnot{}" nil "¬" "[angled dash]" "¬" "¬") + ("neg" "\\neg{}" t "¬" "[angled dash]" "¬" "¬") + ("land" "\\land" t "∧" "[logical and]" "[logical and]" "∧") + ("wedge" "\\wedge" t "∧" "[logical and]" "[logical and]" "∧") + ("lor" "\\lor" t "∨" "[logical or]" "[logical or]" "∨") + ("vee" "\\vee" t "∨" "[logical or]" "[logical or]" "∨") + ("cap" "\\cap" t "∩" "[intersection]" "[intersection]" "∩") + ("cup" "\\cup" t "∪" "[union]" "[union]" "∪") + ("smile" "\\smile" t "⌣" "[cup product]" "[cup product]" "⌣") + ("frown" "\\frown" t "⌢" "[Cap product]" "[cap product]" "⌢") + ("int" "\\int" t "∫" "[integral]" "[integral]" "∫") + ("therefore" "\\therefore" t "∴" "[therefore]" "[therefore]" "∴") + ("there4" "\\therefore" t "∴" "[therefore]" "[therefore]" "∴") + ("because" "\\because" t "∵" "[because]" "[because]" "∵") + ("sim" "\\sim" t "∼" "~" "~" "∼") + ("cong" "\\cong" t "≅" "[approx. equal to]" "[approx. equal to]" "≅") + ("simeq" "\\simeq" t "≅" "[approx. equal to]" "[approx. equal to]" "≅") + ("asymp" "\\asymp" t "≈" "[almost equal to]" "[almost equal to]" "≈") + ("approx" "\\approx" t "≈" "[almost equal to]" "[almost equal to]" "≈") + ("ne" "\\ne" t "≠" "[not equal to]" "[not equal to]" "≠") + ("neq" "\\neq" t "≠" "[not equal to]" "[not equal to]" "≠") + ("equiv" "\\equiv" t "≡" "[identical to]" "[identical to]" "≡") + + ("triangleq" "\\triangleq" t "≜" "[defined to]" "[defined to]" "≜") + ("le" "\\le" t "≤" "<=" "<=" "≤") + ("leq" "\\le" t "≤" "<=" "<=" "≤") + ("ge" "\\ge" t "≥" ">=" ">=" "≥") + ("geq" "\\ge" t "≥" ">=" ">=" "≥") + ("lessgtr" "\\lessgtr" t "≶" "[less than or greater than]" "[less than or greater than]" "≶") + ("lesseqgtr" "\\lesseqgtr" t "⋚" "[less than or equal or greater than or equal]" "[less than or equal or greater than or equal]" "⋚") + ("ll" "\\ll" t "≪" "<<" "<<" "≪") + ("Ll" "\\lll" t "⋘" "<<<" "<<<" "⋘") + ("lll" "\\lll" t "⋘" "<<<" "<<<" "⋘") + ("gg" "\\gg" t "≫" ">>" ">>" "≫") + ("Gg" "\\ggg" t "⋙" ">>>" ">>>" "⋙") + ("ggg" "\\ggg" t "⋙" ">>>" ">>>" "⋙") + ("prec" "\\prec" t "≺" "[precedes]" "[precedes]" "≺") + ("preceq" "\\preceq" t "≼" "[precedes or equal]" "[precedes or equal]" "≼") + ("preccurlyeq" "\\preccurlyeq" t "≼" "[precedes or equal]" "[precedes or equal]" "≼") + ("succ" "\\succ" t "≻" "[succeeds]" "[succeeds]" "≻") + ("succeq" "\\succeq" t "≽" "[succeeds or equal]" "[succeeds or equal]" "≽") + ("succcurlyeq" "\\succcurlyeq" t "≽" "[succeeds or equal]" "[succeeds or equal]" "≽") + ("sub" "\\subset" t "⊂" "[subset of]" "[subset of]" "⊂") + ("subset" "\\subset" t "⊂" "[subset of]" "[subset of]" "⊂") + ("sup" "\\supset" t "⊃" "[superset of]" "[superset of]" "⊃") + ("supset" "\\supset" t "⊃" "[superset of]" "[superset of]" "⊃") + ("nsub" "\\not\\subset" t "⊄" "[not a subset of]" "[not a subset of" "⊄") + ("sube" "\\subseteq" t "⊆" "[subset of or equal to]" "[subset of or equal to]" "⊆") + ("nsup" "\\not\\supset" t "⊅" "[not a superset of]" "[not a superset of]" "⊅") + ("supe" "\\supseteq" t "⊇" "[superset of or equal to]" "[superset of or equal to]" "⊇") + ("setminus" "\\setminus" t "∖" "\" "\" "â§µ") + ("forall" "\\forall" t "∀" "[for all]" "[for all]" "∀") + ("exist" "\\exists" t "∃" "[there exists]" "[there exists]" "∃") + ("exists" "\\exists" t "∃" "[there exists]" "[there exists]" "∃") + ("nexist" "\\nexists" t "∃" "[there does not exists]" "[there does not exists]" "∄") + ("nexists" "\\nexists" t "∃" "[there does not exists]" "[there does not exists]" "∄") + ("empty" "\\empty" t "∅" "[empty set]" "[empty set]" "∅") + ("emptyset" "\\emptyset" t "∅" "[empty set]" "[empty set]" "∅") + ("isin" "\\in" t "∈" "[element of]" "[element of]" "∈") + ("in" "\\in" t "∈" "[element of]" "[element of]" "∈") + ("notin" "\\notin" t "∉" "[not an element of]" "[not an element of]" "∉") + ("ni" "\\ni" t "∋" "[contains as member]" "[contains as member]" "∋") + ("nabla" "\\nabla" t "∇" "[nabla]" "[nabla]" "∇") + ("ang" "\\angle" t "∠" "[angle]" "[angle]" "∠") + ("angle" "\\angle" t "∠" "[angle]" "[angle]" "∠") + ("perp" "\\perp" t "⊥" "[up tack]" "[up tack]" "⊥") + ("parallel" "\\parallel" t "∥" "||" "||" "∥") + ("sdot" "\\cdot" t "⋅" "[dot]" "[dot]" "⋅") + ("cdot" "\\cdot" t "⋅" "[dot]" "[dot]" "⋅") + ("lceil" "\\lceil" t "⌈" "[left ceiling]" "[left ceiling]" "⌈") + ("rceil" "\\rceil" t "⌉" "[right ceiling]" "[right ceiling]" "⌉") + ("lfloor" "\\lfloor" t "⌊" "[left floor]" "[left floor]" "⌊") + ("rfloor" "\\rfloor" t "⌋" "[right floor]" "[right floor]" "⌋") + ("lang" "\\langle" t "⟨" "<" "<" "⟨") + ("rang" "\\rangle" t "⟩" ">" ">" "⟩") + ("langle" "\\langle" t "⟨" "<" "<" "⟨") + ("rangle" "\\rangle" t "⟩" ">" ">" "⟩") + ("hbar" "\\hbar" t "ℏ" "hbar" "hbar" "ℏ") + ("mho" "\\mho" t "℧" "mho" "mho" "℧") + + "** Arrows" + ("larr" "\\leftarrow" t "←" "<-" "<-" "←") + ("leftarrow" "\\leftarrow" t "←" "<-" "<-" "←") + ("gets" "\\gets" t "←" "<-" "<-" "←") + ("lArr" "\\Leftarrow" t "⇐" "<=" "<=" "⇐") + ("Leftarrow" "\\Leftarrow" t "⇐" "<=" "<=" "⇐") + ("uarr" "\\uparrow" t "↑" "[uparrow]" "[uparrow]" "↑") + ("uparrow" "\\uparrow" t "↑" "[uparrow]" "[uparrow]" "↑") + ("uArr" "\\Uparrow" t "⇑" "[dbluparrow]" "[dbluparrow]" "⇑") + ("Uparrow" "\\Uparrow" t "⇑" "[dbluparrow]" "[dbluparrow]" "⇑") + ("rarr" "\\rightarrow" t "→" "->" "->" "→") + ("to" "\\to" t "→" "->" "->" "→") + ("rightarrow" "\\rightarrow" t "→" "->" "->" "→") + ("rArr" "\\Rightarrow" t "⇒" "=>" "=>" "⇒") + ("Rightarrow" "\\Rightarrow" t "⇒" "=>" "=>" "⇒") + ("darr" "\\downarrow" t "↓" "[downarrow]" "[downarrow]" "↓") + ("downarrow" "\\downarrow" t "↓" "[downarrow]" "[downarrow]" "↓") + ("dArr" "\\Downarrow" t "⇓" "[dbldownarrow]" "[dbldownarrow]" "⇓") + ("Downarrow" "\\Downarrow" t "⇓" "[dbldownarrow]" "[dbldownarrow]" "⇓") + ("harr" "\\leftrightarrow" t "↔" "<->" "<->" "↔") + ("leftrightarrow" "\\leftrightarrow" t "↔" "<->" "<->" "↔") + ("hArr" "\\Leftrightarrow" t "⇔" "<=>" "<=>" "⇔") + ("Leftrightarrow" "\\Leftrightarrow" t "⇔" "<=>" "<=>" "⇔") + ("crarr" "\\hookleftarrow" t "↵" "<-'" "<-'" "↵") + ("hookleftarrow" "\\hookleftarrow" t "↵" "<-'" "<-'" "↵") + + "** Function names" + ("arccos" "\\arccos" t "arccos" "arccos" "arccos" "arccos") + ("arcsin" "\\arcsin" t "arcsin" "arcsin" "arcsin" "arcsin") + ("arctan" "\\arctan" t "arctan" "arctan" "arctan" "arctan") + ("arg" "\\arg" t "arg" "arg" "arg" "arg") + ("cos" "\\cos" t "cos" "cos" "cos" "cos") + ("cosh" "\\cosh" t "cosh" "cosh" "cosh" "cosh") + ("cot" "\\cot" t "cot" "cot" "cot" "cot") + ("coth" "\\coth" t "coth" "coth" "coth" "coth") + ("csc" "\\csc" t "csc" "csc" "csc" "csc") + ("deg" "\\deg" t "°" "deg" "deg" "deg") + ("det" "\\det" t "det" "det" "det" "det") + ("dim" "\\dim" t "dim" "dim" "dim" "dim") + ("exp" "\\exp" t "exp" "exp" "exp" "exp") + ("gcd" "\\gcd" t "gcd" "gcd" "gcd" "gcd") + ("hom" "\\hom" t "hom" "hom" "hom" "hom") + ("inf" "\\inf" t "inf" "inf" "inf" "inf") + ("ker" "\\ker" t "ker" "ker" "ker" "ker") + ("lg" "\\lg" t "lg" "lg" "lg" "lg") + ("lim" "\\lim" t "lim" "lim" "lim" "lim") + ("liminf" "\\liminf" t "liminf" "liminf" "liminf" "liminf") + ("limsup" "\\limsup" t "limsup" "limsup" "limsup" "limsup") + ("ln" "\\ln" t "ln" "ln" "ln" "ln") + ("log" "\\log" t "log" "log" "log" "log") + ("max" "\\max" t "max" "max" "max" "max") + ("min" "\\min" t "min" "min" "min" "min") + ("Pr" "\\Pr" t "Pr" "Pr" "Pr" "Pr") + ("sec" "\\sec" t "sec" "sec" "sec" "sec") + ("sin" "\\sin" t "sin" "sin" "sin" "sin") + ("sinh" "\\sinh" t "sinh" "sinh" "sinh" "sinh") + ("sup" "\\sup" t "⊃" "sup" "sup" "sup") + ("tan" "\\tan" t "tan" "tan" "tan" "tan") + ("tanh" "\\tanh" t "tanh" "tanh" "tanh" "tanh") + + "** Signs & Symbols" + ("bull" "\\textbullet{}" nil "•" "*" "*" "•") + ("bullet" "\\textbullet{}" nil "•" "*" "*" "•") + ("star" "\\star" t "*" "*" "*" "⋆") + ("lowast" "\\ast" t "∗" "*" "*" "∗") + ("ast" "\\ast" t "∗" "*" "*" "*") + ("odot" "\\odot" t "o" "[circled dot]" "[circled dot]" "ʘ") + ("oplus" "\\oplus" t "⊕" "[circled plus]" "[circled plus]" "⊕") + ("otimes" "\\otimes" t "⊗" "[circled times]" "[circled times]" "⊗") + ("check" "\\checkmark" t "✓" "[checkmark]" "[checkmark]" "✓") + ("checkmark" "\\checkmark" t "✓" "[checkmark]" "[checkmark]" "✓") + + "** Miscellaneous (seldom used)" + ("para" "\\P{}" nil "¶" "[pilcrow]" "¶" "¶") + ("ordf" "\\textordfeminine{}" nil "ª" "_a_" "ª" "ª") + ("ordm" "\\textordmasculine{}" nil "º" "_o_" "º" "º") + ("cedil" "\\c{}" nil "¸" "[cedilla]" "¸" "¸") + ("oline" "\\overline{~}" t "‾" "[overline]" "¯" "‾") + ("uml" "\\textasciidieresis{}" nil "¨" "[diaeresis]" "¨" "¨") + ("zwnj" "\\/{}" nil "‌" "" "" "‌") + ("zwj" "" nil "‍" "" "" "‍") + ("lrm" "" nil "‎" "" "" "‎") + ("rlm" "" nil "‏" "" "" "‏") + + "** Smilies" + ("smiley" "\\ddot\\smile" t "☺" ":-)" ":-)" "☺") + ("blacksmile" "\\ddot\\smile" t "☻" ":-)" ":-)" "☻") + ("sad" "\\ddot\\frown" t "☹" ":-(" ":-(" "☹") + ("frowny" "\\ddot\\frown" t "☹" ":-(" ":-(" "☹") + + "** Suits" + ("clubs" "\\clubsuit" t "♣" "[clubs]" "[clubs]" "♣") + ("clubsuit" "\\clubsuit" t "♣" "[clubs]" "[clubs]" "♣") + ("spades" "\\spadesuit" t "♠" "[spades]" "[spades]" "♠") + ("spadesuit" "\\spadesuit" t "♠" "[spades]" "[spades]" "♠") + ("hearts" "\\heartsuit" t "♥" "[hearts]" "[hearts]" "♥") + ("heartsuit" "\\heartsuit" t "♥" "[hearts]" "[hearts]" "♥") + ("diams" "\\diamondsuit" t "♦" "[diamonds]" "[diamonds]" "◆") + ("diamondsuit" "\\diamondsuit" t "♦" "[diamonds]" "[diamonds]" "◆") + ("diamond" "\\diamondsuit" t "⋄" "[diamond]" "[diamond]" "◆") + ("Diamond" "\\diamondsuit" t "⋄" "[diamond]" "[diamond]" "◆") + ("loz" "\\lozenge" t "◊" "[lozenge]" "[lozenge]" "â§«")) + ;; Add "\_ "-entity family for spaces. + (let (space-entities html-spaces (entity "_")) + (dotimes (n 20 (nreverse space-entities)) + (let ((n (+ 1 n)) + (spaces (make-string n ?\s))) + (push (list (setq entity (concat entity " ")) + (format "\\hspace*{%sem}" (* n .5)) + nil + (setq html-spaces (concat " " html-spaces)) + spaces + spaces + (make-string n ?\x2002)) + space-entities))))) + "Default entities used in Org mode to produce special characters. +For details see `org-entities-user'.") + +(defsubst org-entity-get (name) + "Get the proper association for NAME from the entity lists. +This first checks the user list, then the built-in list." + (or (assoc name org-entities-user) + (assoc name org-entities))) + +;; Helpfunctions to create a table for orgmode.org/worg/org-symbols.org + +(defun org-entities-create-table () + "Create an Org mode table with all entities." + (interactive) + (let ((pos (point)) e latex mathp html latin utf8 name ascii) + (insert "|Name|LaTeX code|LaTeX|HTML code |HTML|ASCII|Latin1|UTF-8\n|-\n") + (mapc (lambda (e) (when (listp e) + (setq name (car e) + latex (nth 1 e) + mathp (nth 2 e) + html (nth 3 e) + ascii (nth 4 e) + latin (nth 5 e) + utf8 (nth 6 e)) + (if (equal ascii "|") (setq ascii "\\vert")) + (if (equal latin "|") (setq latin "\\vert")) + (if (equal utf8 "|") (setq utf8 "\\vert")) + (if (equal ascii "=>") (setq ascii "= >")) + (if (equal latin "=>") (setq latin "= >")) + (insert "|" name + "|" (format "=%s=" latex) + "|" (format (if mathp "$%s$" "$\\mbox{%s}$") + latex) + "|" (format "=%s=" html) "|" html + "|" ascii "|" latin "|" utf8 + "|\n"))) + org-entities) + (goto-char pos) + (org-table-align))) + +(defvar org-pretty-entities) ;; declare defcustom from org +(defun org-entities-help () + "Create a Help buffer with all available entities." + (interactive) + (with-output-to-temp-buffer "*Org Entity Help*" + (princ "Org-mode entities\n=================\n\n") + (let ((ll (append '("* User-defined additions (variable org-entities-user)") + org-entities-user + org-entities)) + e latex mathp html latin utf8 name ascii + (lastwasstring t) + (head (concat + "\n" + " Symbol Org entity LaTeX code HTML code\n" + " -----------------------------------------------------------\n"))) + (while ll + (setq e (pop ll)) + (if (stringp e) + (progn + (princ e) + (princ "\n") + (setq lastwasstring t)) + (if lastwasstring (princ head)) + (setq lastwasstring nil) + (setq name (car e) + latex (nth 1 e) + html (nth 3 e) + utf8 (nth 6 e)) + (princ (format " %-8s \\%-16s %-22s %-13s\n" + utf8 name latex html)))))) + (with-current-buffer "*Org Entity Help*" + (org-mode) + (when org-pretty-entities + (org-toggle-pretty-entities))) + (select-window (get-buffer-window "*Org Entity Help*"))) + + +(provide 'org-entities) + +;; Local variables: +;; coding: utf-8 +;; End: + +;;; org-entities.el ends here diff --git a/elpa/org-20150629/org-eshell.el b/elpa/org-20160215/org-eshell.el similarity index 97% rename from elpa/org-20150629/org-eshell.el rename to elpa/org-20160215/org-eshell.el index 1256bc37..9c1c4a1b 100644 --- a/elpa/org-20150629/org-eshell.el +++ b/elpa/org-20160215/org-eshell.el @@ -1,6 +1,6 @@ ;;; org-eshell.el - Support for links to working directories in eshell -;; Copyright (C) 2011-2014 Free Software Foundation, Inc. +;; Copyright (C) 2011-2016 Free Software Foundation, Inc. ;; Author: Konrad Hinsen diff --git a/elpa/org-20150629/org-faces.el b/elpa/org-20160215/org-faces.el similarity index 93% rename from elpa/org-20150629/org-faces.el rename to elpa/org-20160215/org-faces.el index f8625f12..941a6042 100644 --- a/elpa/org-20150629/org-faces.el +++ b/elpa/org-20160215/org-faces.el @@ -1,6 +1,6 @@ ;;; org-faces.el --- Face definitions for Org-mode. -;; Copyright (C) 2004-2014 Free Software Foundation, Inc. +;; Copyright (C) 2004-2016 Free Software Foundation, Inc. ;; Author: Carsten Dominik ;; Keywords: outlines, hypermedia, calendar, wp @@ -31,19 +31,6 @@ (require 'org-macs) (require 'org-compat) -(defun org-copy-face (old-face new-face docstring &rest attributes) - (unless (facep new-face) - (if (fboundp 'set-face-attribute) - (progn - (make-face new-face) - (set-face-attribute new-face nil :inherit old-face) - (apply 'set-face-attribute new-face nil attributes) - (set-face-doc-string new-face docstring)) - (copy-face old-face new-face) - (if (fboundp 'set-face-doc-string) - (set-face-doc-string new-face docstring))))) -(put 'org-copy-face 'lisp-indent-function 2) - (when (featurep 'xemacs) (put 'mode-line 'face-alias 'modeline)) @@ -427,12 +414,15 @@ determines if it is a foreground or a background color." "Face for checkboxes." :group 'org-faces) +(defface org-checkbox-statistics-todo + '((t (:inherit org-todo))) + "Face used for unfinished checkbox statistics." + :group 'org-faces) -(org-copy-face 'org-todo 'org-checkbox-statistics-todo - "Face used for unfinished checkbox statistics.") - -(org-copy-face 'org-done 'org-checkbox-statistics-done - "Face used for finished checkbox statistics.") +(defface org-checkbox-statistics-done + '((t (:inherit org-done))) + "Face used for finished checkbox statistics." + :group 'org-faces) (defcustom org-tag-faces nil "Faces for specific tags. @@ -491,7 +481,7 @@ changes." (defface org-meta-line (org-compatible-face 'font-lock-comment-face nil) - "Face for meta lines startin with \"#+\"." + "Face for meta lines starting with \"#+\"." :group 'org-faces :version "22.1") @@ -537,14 +527,15 @@ follows a #+DATE:, #+AUTHOR: or #+EMAIL: keyword." :group 'org-faces :version "22.1") -(defface org-block-background '((t ())) - "Face used for the source block background.") - -(org-copy-face 'org-meta-line 'org-block-begin-line - "Face used for the line delimiting the begin of source blocks.") +(defface org-block-begin-line + '((t (:inherit org-meta-line))) + "Face used for the line delimiting the begin of source blocks." + :group 'org-faces) -(org-copy-face 'org-meta-line 'org-block-end-line - "Face used for the line delimiting the end of source blocks.") +(defface org-block-end-line + '((t (:inherit org-block-begin-line))) + "Face used for the line delimiting the end of source blocks." + :group 'org-faces) (defface org-verbatim (org-compatible-face 'shadow @@ -560,10 +551,15 @@ follows a #+DATE:, #+AUTHOR: or #+EMAIL: keyword." :group 'org-faces :version "22.1") -(org-copy-face 'org-block 'org-quote - "Face for #+BEGIN_QUOTE ... #+END_QUOTE blocks.") -(org-copy-face 'org-block 'org-verse - "Face for #+BEGIN_VERSE ... #+END_VERSE blocks.") +(defface org-quote + '((t (:inherit org-block))) + "Face for #+BEGIN_QUOTE ... #+END_QUOTE blocks." + :group 'org-faces) + +(defface org-verse + '((t (:inherit org-block))) + "Face for #+BEGIN_VERSE ... #+END_VERSE blocks." + :group 'org-faces) (defcustom org-fontify-quote-and-verse-blocks nil "Non-nil means, add a special face to #+begin_quote and #+begin_verse block. @@ -576,13 +572,13 @@ content of these blocks will still be treated as Org syntax." (defface org-clock-overlay ;; copied from secondary-selection (org-compatible-face nil '((((class color) (min-colors 88) (background light)) - (:background "yellow1")) + (:background "LightGray" :foreground "black")) (((class color) (min-colors 88) (background dark)) - (:background "SkyBlue4")) + (:background "SkyBlue4" :foreground "white")) (((class color) (min-colors 16) (background light)) - (:background "yellow")) + (:background "gray" :foreground "black")) (((class color) (min-colors 16) (background dark)) - (:background "SkyBlue4")) + (:background "SkyBlue4" :foreground "white")) (((class color) (min-colors 8)) (:background "cyan" :foreground "black")) (t (:inverse-video t)))) @@ -600,21 +596,28 @@ content of these blocks will still be treated as Org syntax." "Face used in agenda for captions and dates." :group 'org-faces) -(org-copy-face 'org-agenda-structure 'org-agenda-date - "Face used in agenda for normal days.") +(defface org-agenda-date + '((t (:inherit org-agenda-structure))) + "Face used in agenda for normal days." + :group 'org-faces) -(org-copy-face 'org-agenda-date 'org-agenda-date-today +(defface org-agenda-date-today + '((t (:inherit org-agenda-date :weight bold :italic t))) "Face used in agenda for today." - :weight 'bold :italic 't) + :group 'org-faces) -(org-copy-face 'secondary-selection 'org-agenda-clocking - "Face marking the current clock item in the agenda.") +(defface org-agenda-clocking + '((t (:inherit secondary-selection))) + "Face marking the current clock item in the agenda." + :group 'org-faces) -(org-copy-face 'org-agenda-date 'org-agenda-date-weekend +(defface org-agenda-date-weekend + '((t (:inherit org-agenda-date :weight bold))) "Face used in agenda for weekend days. -See the variable `org-agenda-weekend-days' for a definition of which days -belong to the weekend." - :weight 'bold) + +See the variable `org-agenda-weekend-days' for a definition of +which days belong to the weekend." + :group 'org-faces) (defface org-scheduled (org-compatible-face nil @@ -666,7 +669,7 @@ belong to the weekend." (0.0 . default)) "Faces for showing deadlines in the agenda. This is a list of cons cells. The cdr of each cell is a face to be used, -and it can also just be like '(:foreground \"yellow\"). +and it can also just be like \\='(:foreground \"yellow\"). Each car is a fraction of the head-warning time that must have passed for this the face in the cdr to be used for display. The numbers must be given in descending order. The head-warning time is normally taken @@ -719,8 +722,10 @@ month and 365.24 days for a year)." "Face used for time grids." :group 'org-faces) -(org-copy-face 'org-time-grid 'org-agenda-current-time - "Face used to show the current time in the time grid.") +(defface org-agenda-current-time + '((t (:inherit org-time-grid))) + "Face used to show the current time in the time grid." + :group 'org-faces) (defface org-agenda-diary (org-compatible-face 'default nil) @@ -791,11 +796,15 @@ level org-n-level-faces" :version "24.4" :package-version '(Org . "8.0")) -(org-copy-face 'mode-line 'org-mode-line-clock - "Face used for clock display in mode line.") -(org-copy-face 'mode-line 'org-mode-line-clock-overrun +(defface org-mode-line-clock + '((t (:inherit mode-line))) + "Face used for clock display in mode line." + :group 'org-faces) + +(defface org-mode-line-clock-overrun + '((t (:inherit mode-line :background "red"))) "Face used for clock display for overrun tasks in mode line." - :background "red") + :group 'org-faces) (provide 'org-faces) diff --git a/elpa/org-20150629/org-feed.el b/elpa/org-20160215/org-feed.el similarity index 97% rename from elpa/org-20150629/org-feed.el rename to elpa/org-20160215/org-feed.el index 6e680718..0600f637 100644 --- a/elpa/org-20150629/org-feed.el +++ b/elpa/org-20160215/org-feed.el @@ -1,6 +1,6 @@ ;;; org-feed.el --- Add RSS feed items to Org files ;; -;; Copyright (C) 2009-2014 Free Software Foundation, Inc. +;; Copyright (C) 2009-2016 Free Software Foundation, Inc. ;; ;; Author: Carsten Dominik ;; Keywords: outlines, hypermedia, calendar, wp @@ -24,7 +24,7 @@ ;; ;;; Commentary: ;; -;; This module allows to create and change entries in an Org-mode +;; This module allows entries to be created and changed in an Org-mode ;; file triggered by items in an RSS feed. The basic functionality is ;; geared toward simply adding new items found in a feed as outline nodes ;; to an Org file. Using hooks, arbitrary actions can be triggered for @@ -116,7 +116,9 @@ to create inbox items in Org. Each entry is a list with the following items: name a custom name for this feed URL the Feed URL -file the target Org file where entries should be listed +file the target Org file where entries should be listed, when + nil the target becomes the current buffer (may be an + indirect buffer) each time the feed update is invoked headline the headline under which entries should be listed Additional arguments can be given using keyword-value pairs. Many of these @@ -215,10 +217,7 @@ Here are the keyword-value pair allows in `org-feed-alist'. (defcustom org-feed-drawer "FEEDSTATUS" "The name of the drawer for feed status information. Each feed may also specify its own drawer name using the `:drawer' -parameter in `org-feed-alist'. -Note that in order to make these drawers behave like drawers, they must -be added to the variable `org-drawers' or configured with a #+DRAWERS -line." +parameter in `org-feed-alist'." :group 'org-feed :type '(string :tag "Drawer Name")) @@ -299,7 +298,8 @@ it can be a list structured like an entry in `org-feed-alist'." (catch 'exit (let ((name (car feed)) (url (nth 1 feed)) - (file (nth 2 feed)) + (file (or (nth 2 feed) (buffer-file-name (or (buffer-base-buffer) + (current-buffer))))) (headline (nth 3 feed)) (filter (nth 1 (memq :filter feed))) (formatter (nth 1 (memq :formatter feed))) @@ -406,8 +406,8 @@ it can be a list structured like an entry in `org-feed-alist'." ;; Normalize the visibility of the inbox tree (goto-char inbox-pos) - (hide-subtree) - (show-children) + (outline-hide-subtree) + (outline-show-children) (org-cycle-hide-drawers 'children) ;; Hooks and messages @@ -604,6 +604,7 @@ Assumes headers are indeed present!" "Parse BUFFER for RSS feed entries. Returns a list of entries, with each entry a property list, containing the properties `:guid' and `:item-full-text'." + (require 'xml) (let ((case-fold-search t) entries beg end item guid entry) (with-current-buffer buffer @@ -615,7 +616,7 @@ containing the properties `:guid' and `:item-full-text'." (match-beginning 0))) (setq item (buffer-substring beg end) guid (if (string-match ".*?>\\(.*?\\)" item) - (org-match-string-no-properties 1 item))) + (xml-substitute-special (org-match-string-no-properties 1 item)))) (setq entry (list :guid guid :item-full-text item)) (push entry entries) (widen) @@ -690,7 +691,8 @@ formatted as a string, not the original XML data." (xml-node-children content))))) (t (setq entry (plist-put entry :description - (format "Unknown '%s' content." type))))))) + (format-message + "Unknown `%s' content." type))))))) entry)) (provide 'org-feed) diff --git a/elpa/org-20150629/org-footnote.el b/elpa/org-20160215/org-footnote.el similarity index 59% rename from elpa/org-20150629/org-footnote.el rename to elpa/org-20160215/org-footnote.el index c8b8c2ea..800b5dfc 100644 --- a/elpa/org-20150629/org-footnote.el +++ b/elpa/org-20160215/org-footnote.el @@ -1,6 +1,6 @@ ;;; org-footnote.el --- Footnote support in Org and elsewhere ;; -;; Copyright (C) 2009-2014 Free Software Foundation, Inc. +;; Copyright (C) 2009-2016 Free Software Foundation, Inc. ;; ;; Author: Carsten Dominik ;; Keywords: outlines, hypermedia, calendar, wp @@ -38,32 +38,39 @@ (require 'org-compat) (declare-function message-point-in-header-p "message" ()) +(declare-function org-at-comment-p "org" ()) +(declare-function org-at-heading-p "org" (&optional ignored)) (declare-function org-back-over-empty-lines "org" ()) (declare-function org-back-to-heading "org" (&optional invisible-ok)) (declare-function org-combine-plists "org" (&rest plists)) +(declare-function org-edit-footnote-reference "org-src" ()) +(declare-function org-element-context "org-element" (&optional element)) +(declare-function org-element-property "org-element" (property element)) +(declare-function org-element-type "org-element" (element)) (declare-function org-end-of-subtree "org" (&optional invisible-ok to-heading)) (declare-function org-fill-paragraph "org" (&optional justify)) (declare-function org-icompleting-read "org" (&rest args)) (declare-function org-id-uuid "org-id" ()) (declare-function org-in-block-p "org" (names)) -(declare-function org-in-commented-line "org" ()) -(declare-function org-in-indented-comment-line "org" ()) (declare-function org-in-regexp "org" (re &optional nlines visually)) (declare-function org-in-verbatim-emphasis "org" ()) (declare-function org-inside-LaTeX-fragment-p "org" ()) (declare-function org-inside-latex-macro-p "org" ()) (declare-function org-mark-ring-push "org" (&optional pos buffer)) (declare-function org-show-context "org" (&optional key)) -(declare-function org-trim "org" (s)) (declare-function org-skip-whitespace "org" ()) -(declare-function outline-next-heading "outline") (declare-function org-skip-whitespace "org" ()) +(declare-function org-trim "org" (s)) +(declare-function outline-next-heading "outline") -(defvar org-outline-regexp-bol) ; defined in org.el -(defvar org-odd-levels-only) ; defined in org.el -(defvar org-bracket-link-regexp) ; defined in org.el (defvar message-cite-prefix-regexp) ; defined in message.el (defvar message-signature-separator) ; defined in message.el +(defvar org-bracket-link-regexp) ; defined in org.el +(defvar org-complex-heading-regexp) ; defined in org.el +(defvar org-element-all-elements) ; defined in org-element.el +(defvar org-element-all-objects) ; defined in org-element.el +(defvar org-odd-levels-only) ; defined in org.el +(defvar org-outline-regexp-bol) ; defined in org.el (defconst org-footnote-re ;; Only [1]-like footnotes are closed in this regexp, as footnotes @@ -106,8 +113,18 @@ the notes. However, by hand you may place definitions *anywhere*. If this is a string, during export, all subtrees starting with -this heading will be ignored." +this heading will be ignored. + +If you don't use the customize interface to change this variable, +you will need to run the following command after the change: + + \\[universal-argument] \\[org-element-cache-reset]" :group 'org-footnote + :initialize 'custom-initialize-default + :set (lambda (var val) + (set var val) + (when (fboundp 'org-element-cache-reset) + (org-element-cache-reset 'all))) :type '(choice (string :tag "Collect footnotes under heading") (const :tag "Define footnotes locally" nil))) @@ -182,8 +199,7 @@ extracted will be filled again." (defun org-footnote-in-valid-context-p () "Is point in a context where footnotes are allowed?" (save-match-data - (not (or (org-in-commented-line) - (org-in-indented-comment-line) + (not (or (org-at-comment-p) (org-inside-LaTeX-fragment-p) ;; Avoid literal example. (org-in-verbatim-emphasis) @@ -330,36 +346,56 @@ If no footnote is found, return nil." (defun org-footnote-get-definition (label) "Return label, boundaries and definition of the footnote LABEL." (let* ((label (regexp-quote (org-footnote-normalize-label label))) - (re (format "^\\[%s\\]\\|.\\[%s:" label label)) - pos) - (save-excursion - (save-restriction - (when (or (re-search-forward re nil t) - (and (goto-char (point-min)) - (re-search-forward re nil t)) - (and (progn (widen) t) - (goto-char (point-min)) - (re-search-forward re nil t))) - (let ((refp (org-footnote-at-reference-p))) - (cond - ((and (nth 3 refp) refp)) - ((org-footnote-at-definition-p))))))))) - -(defun org-footnote-goto-definition (label) + (re (format "^\\[%s\\]\\|.\\[%s:" label label))) + (org-with-wide-buffer + (goto-char (point-min)) + (catch 'found + (while (re-search-forward re nil t) + (let* ((datum (progn (backward-char) (org-element-context))) + (type (org-element-type datum))) + (when (memq type '(footnote-definition footnote-reference)) + (throw 'found + (list + label + (org-element-property :begin datum) + (org-element-property :end datum) + (let ((cbeg (org-element-property :contents-begin datum))) + (if (not cbeg) "" + (replace-regexp-in-string + "[ \t\n]*\\'" + "" + (buffer-substring-no-properties + cbeg + (org-element-property :contents-end datum)))))))))) + nil)))) + +(defun org-footnote-goto-definition (label &optional location) "Move point to the definition of the footnote LABEL. -Return a non-nil value when a definition has been found." + +LOCATION, when non-nil specifies the buffer position of the +definition. + +Throw an error if there is no definition or if it cannot be +reached from current narrowed part of buffer. Return a non-nil +value if point was successfully moved." (interactive "sLabel: ") - (org-mark-ring-push) - (let ((def (org-footnote-get-definition label))) - (if (not def) - (error "Cannot find definition of footnote %s" label) - (goto-char (nth 1 def)) - (looking-at (format "\\[%s\\]\\|\\[%s:" label label)) - (goto-char (match-end 0)) - (org-show-context 'link-search) - (when (derived-mode-p 'org-mode) - (message "Edit definition and go back with `C-c &' or, if unique, with `C-c C-c'.")) - t))) + (let ((def-start (or location (nth 1 (org-footnote-get-definition label))))) + (cond + ((not def-start) + (user-error "Cannot find definition of footnote %s" label)) + ((or (> def-start (point-max)) (< def-start (point-min))) + (user-error "Definition is outside narrowed part of buffer"))) + (org-mark-ring-push) + (goto-char def-start) + (looking-at (format "\\[%s[]:] ?" label)) + (goto-char (match-end 0)) + (org-show-context 'link-search) + (when (derived-mode-p 'org-mode) + (message + (substitute-command-keys + "Edit definition and go back with `\\[org-mark-ring-goto]' or, if \ +unique, with `\\[org-ctrl-c-ctrl-c]'."))) + t)) (defun org-footnote-goto-previous-reference (label) "Find the first closest (to point) reference of footnote with label LABEL." @@ -436,79 +472,137 @@ buffer." (incf cnt)) (format fmt cnt))) +(defun org-footnote--allow-reference-p () + "Non-nil when a footnote reference can be inserted at point." + ;; XXX: This is similar to `org-footnote-in-valid-context-p' but + ;; more accurate and usually faster, except in some corner cases. + ;; It may replace it after doing proper benchmarks as it would be + ;; used in fontification. + (unless (bolp) + (let* ((context (org-element-context)) + (type (org-element-type context))) + (cond + ;; No footnote reference in attributes. + ((let ((post (org-element-property :post-affiliated context))) + (and post (< (point) post))) + nil) + ;; Paragraphs and blank lines at top of document are fine. + ((memq type '(nil paragraph))) + ;; So are contents of verse blocks. + ((eq type 'verse-block) + (and (>= (point) (org-element-property :contents-begin context)) + (< (point) (org-element-property :contents-end context)))) + ;; In an headline or inlinetask, point must be either on the + ;; heading itself or on the blank lines below. + ((memq type '(headline inlinetask)) + (or (not (org-at-heading-p)) + (and (save-excursion (beginning-of-line) + (and (let ((case-fold-search t)) + (not (looking-at "\\*+ END[ \t]*$"))) + (looking-at org-complex-heading-regexp))) + (match-beginning 4) + (>= (point) (match-beginning 4)) + (or (not (match-beginning 5)) + (< (point) (match-beginning 5)))))) + ;; White spaces after an object or blank lines after an element + ;; are OK. + ((>= (point) + (save-excursion (goto-char (org-element-property :end context)) + (skip-chars-backward " \r\t\n") + (if (memq type org-element-all-objects) (point) + (1+ (line-beginning-position 2)))))) + ;; Other elements are invalid. + ((memq type org-element-all-elements) nil) + ;; Just before object is fine. + ((= (point) (org-element-property :begin context))) + ;; Within recursive object too, but not in a link. + ((eq type 'link) nil) + ((let ((cbeg (org-element-property :contents-begin context)) + (cend (org-element-property :contents-end context))) + (and cbeg (>= (point) cbeg) (<= (point) cend)))))))) + (defun org-footnote-new () "Insert a new footnote. This command prompts for a label. If this is a label referencing an existing label, only insert the label. If the footnote label is empty or new, let the user edit the definition of the footnote." (interactive) - (unless (org-footnote-in-valid-context-p) - (error "Cannot insert a footnote here")) - (let* ((lbls (and (not (equal org-footnote-auto-label 'random)) - (org-footnote-all-labels))) - (propose (and (not (equal org-footnote-auto-label 'random)) - (org-footnote-unique-label lbls))) + (unless (org-footnote--allow-reference-p) + (user-error "Cannot insert a footnote here")) + (let* ((all (org-footnote-all-labels)) (label (org-footnote-normalize-label - (cond - ((member org-footnote-auto-label '(t plain)) - propose) - ((equal org-footnote-auto-label 'random) - (require 'org-id) - (substring (org-id-uuid) 0 8)) - (t - (org-icompleting-read - "Label (leave empty for anonymous): " - (mapcar 'list lbls) nil nil - (if (eq org-footnote-auto-label 'confirm) propose nil))))))) - (cond - ((bolp) (error "Cannot create a footnote reference at left margin")) - ((not label) - (insert "[fn:: ]") - (backward-char 1)) - ((member label lbls) - (insert "[" label "]") - (message "New reference to existing note")) - (org-footnote-define-inline - (insert "[" label ": ]") - (backward-char 1) - (org-footnote-auto-adjust-maybe)) - (t - (insert "[" label "]") - (org-footnote-create-definition label) - (org-footnote-auto-adjust-maybe))))) - -(defvar org-blank-before-new-entry) ; silence byte-compiler + (if (eq org-footnote-auto-label 'random) + (format "fn:%x" (random most-positive-fixnum)) + (let ((propose (org-footnote-unique-label all))) + (if (memq org-footnote-auto-label '(t plain)) propose + (org-icompleting-read + "Label (leave empty for anonymous): " + (mapcar #'list all) nil nil + (and (eq org-footnote-auto-label 'confirm) propose)))))))) + (cond ((not label) + (insert "[fn::]") + (backward-char 1)) + ((member label all) + (insert "[" label "]") + (message "New reference to existing note")) + (org-footnote-define-inline + (insert "[" label ":]") + (backward-char 1) + (org-footnote-auto-adjust-maybe)) + (t + (insert "[" label "]") + (let ((p (org-footnote-create-definition label))) + ;; `org-footnote-goto-definition' needs to be called + ;; after `org-footnote-auto-adjust-maybe'. Otherwise + ;; both label and location of the definition are lost. + ;; On the contrary, it needs to be called before + ;; `org-edit-footnote-reference' so that the remote + ;; editing buffer can display the correct label. + (if (ignore-errors (org-footnote-goto-definition label p)) + (org-footnote-auto-adjust-maybe) + ;; Definition was created outside current scope: edit + ;; it remotely. + (org-footnote-auto-adjust-maybe) + (org-edit-footnote-reference))))))) + +(defvar org-blank-before-new-entry) ; Silence byte-compiler. (defun org-footnote-create-definition (label) - "Start the definition of a footnote with label LABEL." - (interactive "sLabel: ") + "Start the definition of a footnote with label LABEL. +Return buffer position at the beginning of the definition. In an +Org buffer, this function doesn't move point." (let ((label (org-footnote-normalize-label label)) - electric-indent-mode) ;; Prevent wrong indentation + electric-indent-mode) ; Prevent wrong indentation. (cond - ;; In an Org file. + ;; In an Org document. ((derived-mode-p 'org-mode) ;; If `org-footnote-section' is defined, find it, or create it ;; at the end of the buffer. - (when org-footnote-section - (goto-char (point-min)) - (let ((re (concat "^\\*+[ \t]+" org-footnote-section "[ \t]*$"))) - (unless (or (re-search-forward re nil t) - (and (progn (widen) t) - (re-search-forward re nil t))) - (goto-char (point-max)) - (skip-chars-backward " \t\r\n") - (unless (bolp) (newline)) - ;; Insert new section. Separate it from the previous one - ;; with a blank line, unless `org-blank-before-new-entry' - ;; explicitly says no. - (when (and (cdr (assq 'heading org-blank-before-new-entry)) - (zerop (save-excursion (org-back-over-empty-lines)))) - (insert "\n")) - (insert "* " org-footnote-section "\n")))) - ;; Move to the end of this entry (which may be - ;; `org-footnote-section' or the current one). - (org-footnote-goto-local-insertion-point) - (org-show-context 'link-search)) + (org-with-wide-buffer + (cond + ((not org-footnote-section) + (org-footnote--goto-local-insertion-point)) + ((save-excursion + (goto-char (point-min)) + (re-search-forward + (concat "^\\*+[ \t]+" (regexp-quote org-footnote-section) "[ \t]*$") + nil t)) + (goto-char (match-end 0)) + (forward-line) + (unless (bolp) (insert "\n"))) + (t + (goto-char (point-max)) + (unless (bolp) (insert "\n")) + ;; Insert new section. Separate it from the previous one + ;; with a blank line, unless `org-blank-before-new-entry' + ;; explicitly says no. + (when (and (cdr (assq 'heading org-blank-before-new-entry)) + (zerop (save-excursion (org-back-over-empty-lines)))) + (insert "\n")) + (insert "* " org-footnote-section "\n"))) + (when (zerop (org-back-over-empty-lines)) (insert "\n")) + (insert "[" label "] \n") + (line-beginning-position 0))) (t ;; In a non-Org file. Search for footnote tag, or create it if ;; specified (at the end of buffer, or before signature if in @@ -543,16 +637,11 @@ or new, let the user edit the definition of the footnote." (skip-chars-backward " \t\r\n") (delete-region (point) max) (unless (bolp) (newline)) - (set-marker max nil)))) - ;; Insert footnote label. - (when (zerop (org-back-over-empty-lines)) (newline)) - (insert "[" label "] \n") - (backward-char) - ;; Only notify user about next possible action when in an Org - ;; buffer, as the bindings may have different meanings otherwise. - (when (derived-mode-p 'org-mode) - (message - "Edit definition and go back with `C-c &' or, if unique, with `C-c C-c'.")))) + (set-marker max nil)) + (when (zerop (org-back-over-empty-lines)) (insert "\n")) + (insert "[" label "] \n") + (backward-char) + (line-beginning-position))))) ;;;###autoload (defun org-footnote-action (&optional special) @@ -564,38 +653,55 @@ When at a definition, jump to the references if they exist, offer to create them otherwise. When neither at definition or reference, create a new footnote, -interactively. +interactively if possible. -With prefix arg SPECIAL, offer additional commands in a menu." +With prefix arg SPECIAL, or when no footnote can be created, +offer additional commands in a menu." (interactive "P") - (let (tmp c) + (let* ((context (and (not special) (org-element-context))) + (type (org-element-type context))) (cond - (special - (message "Footnotes: [s]ort | [r]enumber fn:N | [S]=r+s |->[n]umeric | [d]elete") - (setq c (read-char-exclusive)) - (cond - ((eq c ?s) (org-footnote-normalize 'sort)) - ((eq c ?r) (org-footnote-renumber-fn:N)) - ((eq c ?S) - (org-footnote-renumber-fn:N) - (org-footnote-normalize 'sort)) - ((eq c ?n) (org-footnote-normalize)) - ((eq c ?d) (org-footnote-delete)) - (t (error "No such footnote command %c" c)))) - ((setq tmp (org-footnote-at-reference-p)) - (cond - ;; Anonymous footnote: move point at the beginning of its - ;; definition. - ((not (car tmp)) - (goto-char (nth 1 tmp)) - (forward-char 5)) - ;; A definition exists: move to it. - ((ignore-errors (org-footnote-goto-definition (car tmp)))) - ;; No definition exists: offer to create it. - ((yes-or-no-p (format "No definition for %s. Create one? " (car tmp))) - (org-footnote-create-definition (car tmp))))) - ((setq tmp (org-footnote-at-definition-p)) - (org-footnote-goto-previous-reference (car tmp))) + ;; On white space after element, insert a new footnote. + ((and context + (> (point) + (save-excursion + (goto-char (org-element-property :end context)) + (skip-chars-backward " \t") + (point)))) + (org-footnote-new)) + ((eq type 'footnote-reference) + (let ((label (org-element-property :label context))) + (cond + ;; Anonymous footnote: move point at the beginning of its + ;; definition. + ((not label) + (goto-char (org-element-property :contents-begin context))) + ;; Check if a definition exists: then move to it. + ((let ((p (nth 1 (org-footnote-get-definition label)))) + (when p (org-footnote-goto-definition label p)))) + ;; No definition exists: offer to create it. + ((yes-or-no-p (format "No definition for %s. Create one? " label)) + (let ((p (org-footnote-create-definition label))) + (or (ignore-errors (org-footnote-goto-definition label p)) + ;; Since definition was created outside current scope, + ;; edit it remotely. + (org-edit-footnote-reference))))))) + ((eq type 'footnote-definition) + (org-footnote-goto-previous-reference + (org-element-property :label context))) + ((or special (not (org-footnote--allow-reference-p))) + (message "Footnotes: [s]ort | [r]enumber fn:N | [S]=r+s | \ +->[n]umeric | [d]elete") + (let ((c (read-char-exclusive))) + (cond + ((eq c ?s) (org-footnote-normalize 'sort)) + ((eq c ?r) (org-footnote-renumber-fn:N)) + ((eq c ?S) + (org-footnote-renumber-fn:N) + (org-footnote-normalize 'sort)) + ((eq c ?n) (org-footnote-normalize)) + ((eq c ?d) (org-footnote-delete)) + (t (error "No such footnote command %c" c))))) (t (org-footnote-new))))) ;;;###autoload @@ -622,163 +728,162 @@ referenced sequence." (concat "\\*" (if nstars (format "\\{1,%d\\} " nstars) "+ "))) (count 0) ins-point ref ref-table) - (save-excursion - ;; 1. Find every footnote reference, extract the definition, and - ;; collect that data in REF-TABLE. If SORT-ONLY is nil, also - ;; normalize references. - (goto-char (point-min)) - (while (setq ref (org-footnote-get-next-reference)) - (let* ((lbl (car ref)) - (pos (nth 1 ref)) - ;; When footnote isn't anonymous, check if it's label - ;; (REF) is already stored in REF-TABLE. In that case, - ;; extract number used to identify it (MARKER). If - ;; footnote is unknown, increment the global counter - ;; (COUNT) to create an unused identifier. - (a (and lbl (assoc lbl ref-table))) - (marker (or (nth 1 a) (incf count))) - ;; Is the reference inline or pointing to an inline - ;; footnote? - (inlinep (or (stringp (nth 3 ref)) (nth 3 a)))) - ;; Replace footnote reference with [MARKER]. Maybe fill - ;; paragraph once done. If SORT-ONLY is non-nil, only move - ;; to the end of reference found to avoid matching it twice. - (if sort-only (goto-char (nth 2 ref)) - (delete-region (nth 1 ref) (nth 2 ref)) - (goto-char (nth 1 ref)) - (insert (format "[%d]" marker)) - (and inlinep - org-footnote-fill-after-inline-note-extraction - (org-fill-paragraph))) - ;; Add label (REF), identifier (MARKER), definition (DEF) - ;; type (INLINEP) and position (POS) to REF-TABLE if data - ;; was unknown. - (unless a - (let ((def (or (nth 3 ref) ; Inline definition. - (nth 3 (org-footnote-get-definition lbl))))) - (push (list lbl marker def - ;; Reference beginning position is a marker - ;; to preserve it during further buffer - ;; modifications. - inlinep (copy-marker pos)) ref-table))))) - ;; 2. Find and remove the footnote section, if any. Also - ;; determine where footnotes shall be inserted (INS-POINT). - (cond - ((and org-footnote-section (derived-mode-p 'org-mode)) - (goto-char (point-min)) - (if (re-search-forward - (concat "^\\*[ \t]+" (regexp-quote org-footnote-section) - "[ \t]*$") nil t) - (delete-region (match-beginning 0) (org-end-of-subtree t t))) - ;; A new footnote section is inserted by default at the end of - ;; the buffer. - (goto-char (point-max)) - (skip-chars-backward " \r\t\n") - (forward-line) - (unless (bolp) (newline))) - ;; No footnote section set: Footnotes will be added at the end - ;; of the section containing their first reference. - ((derived-mode-p 'org-mode)) - (t - ;; Remove any left-over tag in the buffer, if one is set up. - (when org-footnote-tag-for-non-org-mode-files - (let ((tag (concat "^" (regexp-quote - org-footnote-tag-for-non-org-mode-files) - "[ \t]*$"))) - (goto-char (point-min)) - (while (re-search-forward tag nil t) - (replace-match "") - (delete-region (point) (progn (forward-line) (point)))))) - ;; In Message mode, ensure footnotes are inserted before the - ;; signature. - (if (and (derived-mode-p 'message-mode) - (goto-char (point-max)) - (re-search-backward message-signature-separator nil t)) - (beginning-of-line) - (goto-char (point-max))))) - (setq ins-point (point-marker)) - ;; 3. Clean-up REF-TABLE. - (setq ref-table - (delq nil - (mapcar - (lambda (x) - (cond - ;; When only sorting, ignore inline footnotes. - ;; Also clear position marker. - ((and sort-only (nth 3 x)) - (set-marker (nth 4 x) nil) nil) - ;; No definition available: provide one. - ((not (nth 2 x)) - (append - (list (car x) (nth 1 x) - (format "DEFINITION NOT FOUND: %s" (car x))) - (nthcdr 3 x))) - (t x))) - ref-table))) - (setq ref-table (nreverse ref-table)) - ;; 4. Remove left-over definitions in the buffer. - (mapc (lambda (x) - (unless (nth 3 x) (org-footnote-delete-definitions (car x)))) - ref-table) - ;; 5. Insert the footnotes again in the buffer, at the - ;; appropriate spot. - (goto-char ins-point) - (cond - ;; No footnote: exit. - ((not ref-table)) - ;; Cases when footnotes should be inserted in one place. - ((or (not (derived-mode-p 'org-mode)) org-footnote-section) - ;; Insert again the section title, if any. Ensure that title, - ;; or the subsequent footnotes, will be separated by a blank - ;; lines from the rest of the document. In an Org buffer, - ;; separate section with a blank line, unless explicitly - ;; stated in `org-blank-before-new-entry'. - (if (not (derived-mode-p 'org-mode)) - (progn (skip-chars-backward " \t\n\r") - (delete-region (point) ins-point) - (unless (bolp) (newline)) - (when org-footnote-tag-for-non-org-mode-files - (insert "\n" org-footnote-tag-for-non-org-mode-files "\n"))) - (when (and (cdr (assq 'heading org-blank-before-new-entry)) - (zerop (save-excursion (org-back-over-empty-lines)))) - (insert "\n")) - (insert "* " org-footnote-section "\n")) - (set-marker ins-point nil) - ;; Insert the footnotes, separated by a blank line. - (insert - (mapconcat - (lambda (x) - ;; Clean markers. - (set-marker (nth 4 x) nil) - (format "\n[%s] %s" (nth (if sort-only 0 1) x) (nth 2 x))) - ref-table "\n")) - (unless (eobp) (insert "\n\n"))) - ;; Each footnote definition has to be inserted at the end of - ;; the section where its first reference belongs. - (t - (mapc + (org-with-wide-buffer + ;; 1. Find every footnote reference, extract the definition, and + ;; collect that data in REF-TABLE. If SORT-ONLY is nil, also + ;; normalize references. + (goto-char (point-min)) + (while (setq ref (org-footnote-get-next-reference)) + (let* ((lbl (car ref)) + (pos (nth 1 ref)) + ;; When footnote isn't anonymous, check if it's label + ;; (REF) is already stored in REF-TABLE. In that case, + ;; extract number used to identify it (MARKER). If + ;; footnote is unknown, increment the global counter + ;; (COUNT) to create an unused identifier. + (a (and lbl (assoc lbl ref-table))) + (marker (or (nth 1 a) (incf count))) + ;; Is the reference inline or pointing to an inline + ;; footnote? + (inlinep (or (stringp (nth 3 ref)) (nth 3 a)))) + ;; Replace footnote reference with [MARKER]. Maybe fill + ;; paragraph once done. If SORT-ONLY is non-nil, only move + ;; to the end of reference found to avoid matching it twice. + (if sort-only (goto-char (nth 2 ref)) + (delete-region (nth 1 ref) (nth 2 ref)) + (goto-char (nth 1 ref)) + (insert (format "[%d]" marker)) + (and inlinep + org-footnote-fill-after-inline-note-extraction + (org-fill-paragraph))) + ;; Add label (REF), identifier (MARKER), definition (DEF) + ;; type (INLINEP) and position (POS) to REF-TABLE if data was + ;; unknown. + (unless a + (let ((def (or (nth 3 ref) ; Inline definition. + (nth 3 (org-footnote-get-definition lbl))))) + (push (list lbl marker def + ;; Reference beginning position is a marker + ;; to preserve it during further buffer + ;; modifications. + inlinep (copy-marker pos)) ref-table))))) + ;; 2. Find and remove the footnote section, if any. Also + ;; determine where footnotes shall be inserted (INS-POINT). + (cond + ((and org-footnote-section (derived-mode-p 'org-mode)) + (goto-char (point-min)) + (if (re-search-forward + (concat "^\\*[ \t]+" (regexp-quote org-footnote-section) + "[ \t]*$") nil t) + (delete-region (match-beginning 0) (org-end-of-subtree t t))) + ;; A new footnote section is inserted by default at the end of + ;; the buffer. + (goto-char (point-max)) + (skip-chars-backward " \r\t\n") + (forward-line) + (unless (bolp) (newline))) + ;; No footnote section set: Footnotes will be added at the end + ;; of the section containing their first reference. + ((derived-mode-p 'org-mode)) + (t + ;; Remove any left-over tag in the buffer, if one is set up. + (when org-footnote-tag-for-non-org-mode-files + (let ((tag (concat "^" (regexp-quote + org-footnote-tag-for-non-org-mode-files) + "[ \t]*$"))) + (goto-char (point-min)) + (while (re-search-forward tag nil t) + (replace-match "") + (delete-region (point) (progn (forward-line) (point)))))) + ;; In Message mode, ensure footnotes are inserted before the + ;; signature. + (if (and (derived-mode-p 'message-mode) + (goto-char (point-max)) + (re-search-backward message-signature-separator nil t)) + (beginning-of-line) + (goto-char (point-max))))) + (setq ins-point (point-marker)) + ;; 3. Clean-up REF-TABLE. + (setq ref-table + (delq nil + (mapcar + (lambda (x) + (cond + ;; When only sorting, ignore inline footnotes. + ;; Also clear position marker. + ((and sort-only (nth 3 x)) + (set-marker (nth 4 x) nil) nil) + ;; No definition available: provide one. + ((not (nth 2 x)) + (append + (list (car x) (nth 1 x) + (format "DEFINITION NOT FOUND: %s" (car x))) + (nthcdr 3 x))) + (t x))) + ref-table))) + (setq ref-table (nreverse ref-table)) + ;; 4. Remove left-over definitions in the buffer. + (dolist (x ref-table) + (unless (nth 3 x) (org-footnote-delete-definitions (car x)))) + ;; 5. Insert the footnotes again in the buffer, at the + ;; appropriate spot. + (goto-char ins-point) + (cond + ;; No footnote: exit. + ((not ref-table)) + ;; Cases when footnotes should be inserted in one place. + ((or (not (derived-mode-p 'org-mode)) org-footnote-section) + ;; Insert again the section title, if any. Ensure that title, + ;; or the subsequent footnotes, will be separated by a blank + ;; lines from the rest of the document. In an Org buffer, + ;; separate section with a blank line, unless explicitly stated + ;; in `org-blank-before-new-entry'. + (if (not (derived-mode-p 'org-mode)) + (progn (skip-chars-backward " \t\n\r") + (delete-region (point) ins-point) + (unless (bolp) (newline)) + (when org-footnote-tag-for-non-org-mode-files + (insert "\n" org-footnote-tag-for-non-org-mode-files "\n"))) + (when (and (cdr (assq 'heading org-blank-before-new-entry)) + (zerop (save-excursion (org-back-over-empty-lines)))) + (insert "\n")) + (insert "* " org-footnote-section "\n")) + (set-marker ins-point nil) + ;; Insert the footnotes, separated by a blank line. + (insert + (mapconcat (lambda (x) - (let ((pos (nth 4 x))) - (goto-char pos) - ;; Clean marker. - (set-marker pos nil)) - (org-footnote-goto-local-insertion-point) - (insert (format "\n[%s] %s\n" - (if sort-only (car x) (nth 1 x)) - (nth 2 x)))) - ref-table)))))) - -(defun org-footnote-goto-local-insertion-point () - "Find insertion point for footnote, just before next outline heading." + ;; Clean markers. + (set-marker (nth 4 x) nil) + (format "\n[%s] %s" (nth (if sort-only 0 1) x) (nth 2 x))) + ref-table "\n")) + (unless (eobp) (insert "\n\n"))) + ;; Each footnote definition has to be inserted at the end of the + ;; section where its first reference belongs. + (t + (dolist (x ref-table) + (let ((pos (nth 4 x))) + (goto-char pos) + ;; Clean marker. + (set-marker pos nil)) + (org-footnote--goto-local-insertion-point) + (insert (format "\n[%s] %s\n" + (nth (if sort-only 0 1) x) + (nth 2 x))))))))) + +(defun org-footnote--goto-local-insertion-point () + "Find insertion point for footnote, just before next outline heading. +Assume insertion point is within currently accessible part of the buffer." (org-with-limited-levels (outline-next-heading)) - (or (bolp) (newline)) - (beginning-of-line 0) - (while (and (not (bobp)) (= (char-after) ?#)) - (beginning-of-line 0)) - (if (let ((case-fold-search t)) (looking-at "[ \t]*#\\+tblfm:")) (beginning-of-line 2)) - (end-of-line 1) - (skip-chars-backward "\n\r\t ") - (forward-line)) + ;; Skip file local variables. See `modify-file-local-variable'. + (when (eobp) + (let ((case-fold-search t)) + (re-search-backward "^[ \t]*# +Local Variables:" + (max (- (point-max) 3000) (point-min)) + t))) + (skip-chars-backward " \t\n") + (forward-line) + (unless (bolp) (insert "\n"))) (defun org-footnote-delete-references (label) "Delete every reference to footnote LABEL. diff --git a/elpa/org-20150629/org-gnus.el b/elpa/org-20160215/org-gnus.el similarity index 96% rename from elpa/org-20150629/org-gnus.el rename to elpa/org-20160215/org-gnus.el index 785b577f..a574c0f0 100644 --- a/elpa/org-20150629/org-gnus.el +++ b/elpa/org-20160215/org-gnus.el @@ -1,6 +1,6 @@ ;;; org-gnus.el --- Support for links to Gnus groups and messages from within Org-mode -;; Copyright (C) 2004-2014 Free Software Foundation, Inc. +;; Copyright (C) 2004-2016 Free Software Foundation, Inc. ;; Author: Carsten Dominik ;; Tassilo Horn @@ -36,11 +36,13 @@ (eval-when-compile (require 'gnus-sum)) ;; Declare external functions and variables + (declare-function message-fetch-field "message" (header &optional not-all)) (declare-function message-narrow-to-head-1 "message" nil) (declare-function nnimap-group-overview-filename "nnimap" (group server)) -;; The following line suppresses a compiler warning stemming from gnus-sum.el (declare-function gnus-summary-last-subject "gnus-sum" nil) +(declare-function nnvirtual-map-article "nnvirtual" (article)) + ;; Customization variables (org-defvaralias 'org-usenet-links-prefer-google 'org-gnus-prefer-web-links) @@ -60,7 +62,7 @@ Normally, this translation is done by querying the IMAP server, which is usually very fast. Unfortunately, some (maybe badly configured) IMAP servers don't support this operation quickly. So if following a link to a Gnus article takes ages, try setting -this variable to `t'." +this variable to t." :group 'org-link-store :version "24.1" :type 'boolean) @@ -170,6 +172,10 @@ If `org-store-link' was called with a prefix arg the meaning of (subject (copy-sequence (mail-header-subject header))) (to (cdr (assq 'To (mail-header-extra header)))) newsgroups x-no-archive desc link) + (when (eq (car (gnus-find-method-for-group gnus-newsgroup-name)) + 'nnvirtual) + (setq group (car (nnvirtual-map-article + (gnus-summary-article-number))))) ;; Remove text properties of subject string to avoid Emacs bug ;; #3506 (set-text-properties 0 (length subject) nil subject) @@ -249,10 +255,8 @@ If `org-store-link' was called with a prefix arg the meaning of (require 'gnus) (funcall (cdr (assq 'gnus org-link-frame-setup))) (if gnus-other-frame-object (select-frame gnus-other-frame-object)) - (when group - (setq group (org-no-properties group))) - (when article - (setq article (org-no-properties article))) + (setq group (org-no-properties group)) + (setq article (org-no-properties article)) (cond ((and group article) (gnus-activate-group group) (condition-case nil @@ -291,7 +295,7 @@ If `org-store-link' was called with a prefix arg the meaning of (group (gnus-group-jump-to-group group)))) (defun org-gnus-no-new-news () - "Like `M-x gnus' but doesn't check for new news." + "Like `\\[gnus]' but doesn't check for new news." (if (not (gnus-alive-p)) (if org-gnus-no-server (gnus-no-server) (gnus)))) (provide 'org-gnus) diff --git a/elpa/org-20150629/org-habit.el b/elpa/org-20160215/org-habit.el similarity index 87% rename from elpa/org-20150629/org-habit.el rename to elpa/org-20160215/org-habit.el index 60137568..25bc1606 100644 --- a/elpa/org-20150629/org-habit.el +++ b/elpa/org-20160215/org-habit.el @@ -1,6 +1,6 @@ ;;; org-habit.el --- The habit tracking code for Org-mode -;; Copyright (C) 2009-2014 Free Software Foundation, Inc. +;; Copyright (C) 2009-2016 Free Software Foundation, Inc. ;; Author: John Wiegley ;; Keywords: outlines, hypermedia, calendar, wp @@ -165,6 +165,7 @@ Returns a list with the following elements: 2: Optional deadline (nil if not present) 3: If deadline, the repeater for the deadline, otherwise nil 4: A list of all the past dates this todo was mark closed + 5: Repeater type as a string This list represents a \"habit\" for the rest of this module." (save-excursion @@ -174,15 +175,17 @@ This list represents a \"habit\" for the rest of this module." (scheduled-repeat (org-get-repeat org-scheduled-string)) (end (org-entry-end-position)) (habit-entry (org-no-properties (nth 4 (org-heading-components)))) - closed-dates deadline dr-days sr-days) + closed-dates deadline dr-days sr-days sr-type) (if scheduled (setq scheduled (time-to-days scheduled)) (error "Habit %s has no scheduled date" habit-entry)) (unless scheduled-repeat (error - "Habit '%s' has no scheduled repeat period or has an incorrect one" + "Habit `%s' has no scheduled repeat period or has an incorrect one" habit-entry)) - (setq sr-days (org-habit-duration-to-days scheduled-repeat)) + (setq sr-days (org-habit-duration-to-days scheduled-repeat) + sr-type (progn (string-match "[\\.+]?\\+" scheduled-repeat) + (org-match-string-no-properties 0 scheduled-repeat))) (unless (> sr-days 0) (error "Habit %s scheduled repeat period is less than 1d" habit-entry)) (when (string-match "/\\([0-9]+[dwmy]\\)" scheduled-repeat) @@ -197,17 +200,33 @@ This list represents a \"habit\" for the rest of this module." (reversed org-log-states-order-reversed) (search (if reversed 're-search-forward 're-search-backward)) (limit (if reversed end (point))) - (count 0)) + (count 0) + (re (format + "^[ \t]*-[ \t]+\\(?:State \"%s\".*%s%s\\)" + (regexp-opt org-done-keywords) + org-ts-regexp-inactive + (let ((value (cdr (assq 'done org-log-note-headings)))) + (if (not value) "" + (concat "\\|" + (org-replace-escapes + (regexp-quote value) + `(("%d" . ,org-ts-regexp-inactive) + ("%D" . ,org-ts-regexp) + ("%s" . "\"\\S-+\"") + ("%S" . "\"\\S-+\"") + ("%t" . ,org-ts-regexp-inactive) + ("%T" . ,org-ts-regexp) + ("%u" . ".*?") + ("%U" . ".*?"))))))))) (unless reversed (goto-char end)) - (while (and (< count maxdays) - (funcall search (format "- State \"%s\".*\\[\\([^]]+\\)\\]" - (regexp-opt org-done-keywords)) - limit t)) + (while (and (< count maxdays) (funcall search re limit t)) (push (time-to-days - (org-time-string-to-time (match-string-no-properties 1))) + (org-time-string-to-time + (or (org-match-string-no-properties 1) + (org-match-string-no-properties 2)))) closed-dates) (setq count (1+ count)))) - (list scheduled sr-days deadline dr-days closed-dates)))) + (list scheduled sr-days deadline dr-days closed-dates sr-type)))) (defsubst org-habit-scheduled (habit) (nth 0 habit)) @@ -225,6 +244,8 @@ This list represents a \"habit\" for the rest of this module." (org-habit-scheduled-repeat habit))) (defsubst org-habit-done-dates (habit) (nth 4 habit)) +(defsubst org-habit-repeat-type (habit) + (nth 5 habit)) (defsubst org-habit-get-priority (habit &optional moment) "Determine the relative priority of a habit. @@ -311,10 +332,27 @@ current time." (not (< scheduled now))) '(org-habit-clear-face . org-habit-clear-future-face) (org-habit-get-faces - habit start (and in-the-past-p - (if last-done-date - (+ last-done-date s-repeat) - scheduled)) + habit start + (and in-the-past-p last-done-date + ;; Compute scheduled time for habit at the + ;; time START was current. + (let ((type (org-habit-repeat-type habit))) + (cond + ((equal type ".+") + (+ last-done-date s-repeat)) + ((equal type "+") + ;; Since LAST-DONE-DATE, each done + ;; mark shifted scheduled date by + ;; S-REPEAT. + (- scheduled (* (length done-dates) s-repeat))) + (t + ;; Scheduled time was the first time + ;; past LAST-DONE-STATE which can jump + ;; to current SCHEDULED time by + ;; S-REPEAT hops. + (- scheduled + (* (/ (- scheduled last-done-date) s-repeat) + s-repeat)))))) donep))) markedp face) (if donep diff --git a/elpa/org-20150629/org-id.el b/elpa/org-20160215/org-id.el similarity index 99% rename from elpa/org-20150629/org-id.el rename to elpa/org-20160215/org-id.el index fdd0ff00..107ac39a 100644 --- a/elpa/org-20150629/org-id.el +++ b/elpa/org-20160215/org-id.el @@ -1,6 +1,6 @@ ;;; org-id.el --- Global identifiers for Org-mode entries ;; -;; Copyright (C) 2008-2014 Free Software Foundation, Inc. +;; Copyright (C) 2008-2016 Free Software Foundation, Inc. ;; ;; Author: Carsten Dominik ;; Keywords: outlines, hypermedia, calendar, wp @@ -87,6 +87,7 @@ 'org-link-to-org-use-id 'org-id-link-to-org-use-id "24.3") (defcustom org-id-link-to-org-use-id nil "Non-nil means storing a link to an Org file will use entry IDs. +\\\ The variable can have the following values: @@ -101,7 +102,7 @@ create-if-interactive call `org-capture' that automatically and preemptively creates a link. If you do want to get an ID link in a capture template to an entry not having an ID, create it first by explicitly creating - a link to it, using `C-c C-l' first. + a link to it, using `\\[org-insert-link]' first. create-if-interactive-and-no-custom-id Like create-if-interactive, but do not create an ID if there is diff --git a/elpa/org-20150629/org-indent.el b/elpa/org-20160215/org-indent.el similarity index 71% rename from elpa/org-20150629/org-indent.el rename to elpa/org-20160215/org-indent.el index fa5f0608..83c5aac0 100644 --- a/elpa/org-20150629/org-indent.el +++ b/elpa/org-20160215/org-indent.el @@ -1,5 +1,5 @@ ;;; org-indent.el --- Dynamic indentation for Org-mode -;; Copyright (C) 2009-2014 Free Software Foundation, Inc. +;; Copyright (C) 2009-2016 Free Software Foundation, Inc. ;; ;; Author: Carsten Dominik ;; Keywords: outlines, hypermedia, calendar, wp @@ -52,20 +52,6 @@ :tag "Org Indent" :group 'org) -(defconst org-indent-max 40 - "Maximum indentation in characters.") -(defconst org-indent-max-levels 20 - "Maximum added level through virtual indentation, in characters. - -It is computed by multiplying `org-indent-indentation-per-level' -minus one by actual level of the headline minus one.") - -(defvar org-indent-strings nil - "Vector with all indentation strings. -It will be set in `org-indent-initialize'.") -(defvar org-indent-stars nil - "Vector with all indentation star strings. -It will be set in `org-indent-initialize'.") (defvar org-indent-inlinetask-first-star (org-add-props "*" '(face org-warning)) "First star of inline tasks, with correct face.") (defvar org-indent-agent-timer nil @@ -92,15 +78,12 @@ This is used locally in each buffer being initialized.") It is modified by `org-indent-notify-modified-headline'.") -(defcustom org-indent-boundary-char ?\ ; comment to protect space char +(defcustom org-indent-boundary-char ?\s "The end of the virtual indentation strings, a single-character string. The default is just a space, but if you wish, you can use \"|\" or so. This can be useful on a terminal window - under a windowing system, -it may be prettier to customize the org-indent face." +it may be prettier to customize the `org-indent' face." :group 'org-indent - :set (lambda (var val) - (set var val) - (and org-indent-strings (org-indent-initialize))) :type 'character) (defcustom org-indent-mode-turns-off-org-adapt-indentation t @@ -121,30 +104,12 @@ turn on `org-hide-leading-stars'." :group 'org-indent :type 'integer) -(defface org-indent - (org-compatible-face nil nil) +(defface org-indent '((t (:inherit org-hide))) "Face for outline indentation. The default is to make it look like whitespace. But you may find it useful to make it ever so slightly different." :group 'org-faces) -(defun org-indent-initialize () - "Initialize the indentation strings." - (setq org-indent-strings (make-vector (1+ org-indent-max) nil)) - (setq org-indent-stars (make-vector (1+ org-indent-max) nil)) - (aset org-indent-strings 0 nil) - (aset org-indent-stars 0 nil) - (loop for i from 1 to org-indent-max do - (aset org-indent-strings i - (org-add-props - (concat (make-string (1- i) ?\ ) - (char-to-string org-indent-boundary-char)) - nil 'face 'org-indent))) - (loop for i from 1 to org-indent-max-levels do - (aset org-indent-stars i - (org-add-props (make-string i ?*) - nil 'face 'org-hide)))) - (defsubst org-indent-remove-properties (beg end) "Remove indentations between BEG and END." (org-with-silent-modifications @@ -174,7 +139,6 @@ during idle time." (org-indent-mode ;; mode was turned on. (org-set-local 'indent-tabs-mode nil) - (or org-indent-strings (org-indent-initialize)) (org-set-local 'org-indent-initial-marker (copy-marker 1)) (when org-indent-mode-turns-off-org-adapt-indentation (org-set-local 'org-adapt-indentation nil)) @@ -281,34 +245,41 @@ a time value." (setq org-indent-agentized-buffers (delq buffer org-indent-agentized-buffers)))))))) -(defsubst org-indent-set-line-properties (l w h) +(defun org-indent-set-line-properties (level indentation &optional heading) "Set prefix properties on current line an move to next one. -Prefix properties `line-prefix' and `wrap-prefix' in current line -are set to, respectively, length L and W. - -If H is non-nil, `line-prefix' will be starred. If H is -`inline', the first star will have `org-warning' face. - -Assume point is at beginning of line." - (let ((line (cond - ((eq 'inline h) - (let ((stars (aref org-indent-stars - (min l org-indent-max-levels)))) - (and stars - (if (org-bound-and-true-p org-inlinetask-show-first-star) - (concat org-indent-inlinetask-first-star - (substring stars 1)) - stars)))) - (h (aref org-indent-stars - (min l org-indent-max-levels))) - (t (aref org-indent-strings - (min l org-indent-max))))) - (wrap (aref org-indent-strings (min w org-indent-max)))) +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 +have `org-warning' face." + (let* ((stars (if (<= level 1) "" + (make-string (* (1- org-indent-indentation-per-level) + (1- level)) + ?*))) + (line + (cond + ((and (org-bound-and-true-p org-inlinetask-show-first-star) + (eq heading 'inlinetask)) + (concat org-indent-inlinetask-first-star + (org-add-props (substring stars 1) nil 'face 'org-hide))) + (heading (org-add-props stars nil 'face 'org-hide)) + (t (concat (org-add-props (concat stars (make-string level ?*)) + nil 'face 'org-indent) + (and (> level 0) + (char-to-string org-indent-boundary-char)))))) + (wrap + (org-add-props + (concat stars + (make-string level ?*) + (if heading " " + (make-string (+ indentation (min level 1)) ?\s))) + nil 'face 'org-indent))) ;; Add properties down to the next line to indent empty lines. - (add-text-properties (point) (min (1+ (point-at-eol)) (point-max)) + (add-text-properties (line-beginning-position) (line-beginning-position 2) `(line-prefix ,line wrap-prefix ,wrap))) - (forward-line 1)) + (forward-line)) (defun org-indent-add-properties (beg end &optional delay) "Add indentation properties between BEG and END. @@ -322,26 +293,14 @@ stopped." (org-with-wide-buffer (goto-char beg) (beginning-of-line) - ;; 1. Initialize prefix at BEG. This is done by storing two - ;; variables: INLINE-PF and PF, representing respectively - ;; length of current `line-prefix' when line is inside an - ;; inline task or not. + ;; Initialize prefix at BEG, according to current entry's level. (let* ((case-fold-search t) (limited-re (org-get-limited-outline-regexp)) - (added-ind-per-lvl (abs (1- org-indent-indentation-per-level))) - (pf (save-excursion - (and (ignore-errors (let ((outline-regexp limited-re)) - (org-back-to-heading t))) - (+ (* org-indent-indentation-per-level - (- (match-end 0) (match-beginning 0) 2)) 2)))) - (pf-inline (and (featurep 'org-inlinetask) - (org-inlinetask-in-task-p) - (+ (* org-indent-indentation-per-level - (1- (org-inlinetask-get-task-level))) 2))) + (level (or (org-current-level) 0)) (time-limit (and delay (time-add (current-time) delay)))) - ;; 2. For each line, set `line-prefix' and `wrap-prefix' - ;; properties depending on the type of line (headline, - ;; inline task, item or other). + ;; For each line, set `line-prefix' and `wrap-prefix' + ;; properties depending on the type of line (headline, inline + ;; task, item or other). (org-with-silent-modifications (while (and (<= (point) end) (not (eobp))) (cond @@ -354,38 +313,23 @@ stopped." ((and delay (time-less-p time-limit (current-time))) (setq org-indent-agent-resume-timer (run-with-idle-timer - (time-add (current-idle-time) - org-indent-agent-resume-delay) + (time-add (current-idle-time) org-indent-agent-resume-delay) nil #'org-indent-initialize-agent)) (throw 'interrupt (point))) ;; Headline or inline task. ((looking-at org-outline-regexp) (let* ((nstars (- (match-end 0) (match-beginning 0) 1)) - (line (* added-ind-per-lvl (1- nstars))) - (wrap (+ line (1+ nstars)))) - (cond - ;; Headline: new value for PF. - ((looking-at limited-re) - (org-indent-set-line-properties line wrap t) - (setq pf wrap)) - ;; End of inline task: PF-INLINE is now nil. - ((looking-at "\\*+ end[ \t]*$") - (org-indent-set-line-properties line wrap 'inline) - (setq pf-inline nil)) - ;; Start of inline task. Determine if it contains - ;; text, or if it is only one line long. Set - ;; PF-INLINE accordingly. - (t (org-indent-set-line-properties line wrap 'inline) - (setq pf-inline (and (org-inlinetask-in-task-p) wrap)))))) + (type (or (org-looking-at-p limited-re) 'inlinetask))) + (org-indent-set-line-properties nstars 0 type) + ;; At an headline, define new value for LEVEL. + (unless (eq type 'inlinetask) (setq level nstars)))) ;; List item: `wrap-prefix' is set where body starts. ((org-at-item-p) - (let* ((line (or pf-inline pf 0)) - (wrap (+ (org-list-item-body-column (point)) line))) - (org-indent-set-line-properties line wrap nil))) - ;; Normal line: use PF-INLINE, PF or nil as prefixes. - (t (let* ((line (or pf-inline pf 0)) - (wrap (+ line (org-get-indentation)))) - (org-indent-set-line-properties line wrap nil)))))))))) + (org-indent-set-line-properties + level (org-list-item-body-column (point)))) + ;; Regular line. + (t + (org-indent-set-line-properties level (org-get-indentation)))))))))) (defun org-indent-notify-modified-headline (beg end) "Set `org-indent-modified-headline-flag' depending on context. @@ -398,11 +342,12 @@ Flag will be non-nil if command is going to modify or delete an headline." (when org-indent-mode (setq org-indent-modified-headline-flag - (save-excursion - (goto-char beg) - (save-match-data - (or (and (org-at-heading-p) (< beg (match-end 0))) - (re-search-forward org-outline-regexp-bol end t))))))) + (org-with-wide-buffer + (goto-char beg) + (save-match-data + (or (and (org-at-heading-p) (< beg (match-end 0))) + (re-search-forward + (org-with-limited-levels org-outline-regexp-bol) end t))))))) (defun org-indent-refresh-maybe (beg end dummy) "Refresh indentation properties in an adequate portion of buffer. @@ -414,19 +359,21 @@ This function is meant to be called by `after-change-functions'." (save-match-data ;; If a headline was modified or inserted, set properties until ;; next headline. - (if (or org-indent-modified-headline-flag - (save-excursion - (goto-char beg) - (beginning-of-line) - (re-search-forward org-outline-regexp-bol end t))) - (let ((end (save-excursion - (goto-char end) - (org-with-limited-levels (outline-next-heading)) - (point)))) - (setq org-indent-modified-headline-flag nil) - (org-indent-add-properties beg end)) - ;; Otherwise, only set properties on modified area. - (org-indent-add-properties beg end))))) + (org-with-wide-buffer + (if (or org-indent-modified-headline-flag + (save-excursion + (goto-char beg) + (beginning-of-line) + (re-search-forward + (org-with-limited-levels org-outline-regexp-bol) end t))) + (let ((end (save-excursion + (goto-char end) + (org-with-limited-levels (outline-next-heading)) + (point)))) + (setq org-indent-modified-headline-flag nil) + (org-indent-add-properties beg end)) + ;; Otherwise, only set properties on modified area. + (org-indent-add-properties beg end)))))) (provide 'org-indent) diff --git a/elpa/org-20150629/org-info.el b/elpa/org-20160215/org-info.el similarity index 68% rename from elpa/org-20150629/org-info.el rename to elpa/org-20160215/org-info.el index 8a2d7176..270c19f7 100644 --- a/elpa/org-20150629/org-info.el +++ b/elpa/org-20160215/org-info.el @@ -1,6 +1,6 @@ ;;; org-info.el --- Support for links to Info nodes from within Org-Mode -;; Copyright (C) 2004-2014 Free Software Foundation, Inc. +;; Copyright (C) 2004-2016 Free Software Foundation, Inc. ;; Author: Carsten Dominik ;; Keywords: outlines, hypermedia, calendar, wp @@ -40,7 +40,7 @@ (defvar Info-current-node) ;; Install the link type -(org-add-link-type "info" 'org-info-open) +(org-add-link-type "info" 'org-info-open 'org-info-export) (add-hook 'org-store-link-functions 'org-info-store-link) ;; Implementation @@ -67,12 +67,32 @@ "Follow an Info file and node link specified by NAME." (if (or (string-match "\\(.*\\)[#:]:?\\(.*\\)" name) (string-match "\\(.*\\)" name)) - (progn + (let ((filename (match-string 1 name)) + (nodename-or-index (or (match-string 2 name) "Top"))) (require 'info) - (if (match-string 2 name) ; If there isn't a node, choose "Top" - (Info-find-node (match-string 1 name) (match-string 2 name)) - (Info-find-node (match-string 1 name) "Top"))) - (message "Could not open: %s" name))) + ;; If nodename-or-index is invalid node name, then look it up + ;; in the index. + (condition-case nil + (Info-find-node filename nodename-or-index) + (user-error (Info-find-node filename "Top") + (condition-case nil + (Info-index nodename-or-index) + (user-error "Could not find '%s' node or index entry" + nodename-or-index))))) + (user-error "Could not open: %s" name))) + +(defun org-info-export (path desc format) + "Export an info link. +See `org-add-link-type' for details about PATH, DESC and FORMAT." + (when (eq format 'html) + (or (string-match "\\(.*\\)[#:]:?\\(.*\\)" path) + (string-match "\\(.*\\)" path)) + (let ((filename (match-string 1 path)) + (node (or (match-string 2 path) "Top"))) + (format "%s" + filename + (replace-regexp-in-string " " "-" node) + (or desc path))))) (provide 'org-info) diff --git a/elpa/org-20150629/org-inlinetask.el b/elpa/org-20160215/org-inlinetask.el similarity index 93% rename from elpa/org-20150629/org-inlinetask.el rename to elpa/org-20160215/org-inlinetask.el index de4267c8..26d2e3dd 100644 --- a/elpa/org-20150629/org-inlinetask.el +++ b/elpa/org-20160215/org-inlinetask.el @@ -1,6 +1,6 @@ ;;; org-inlinetask.el --- Tasks independent of outline hierarchy -;; Copyright (C) 2009-2014 Free Software Foundation, Inc. +;; Copyright (C) 2009-2016 Free Software Foundation, Inc. ;; ;; Author: Carsten Dominik ;; Keywords: outlines, hypermedia, calendar, wp @@ -108,7 +108,6 @@ When nil, the first star is not shown." (defvar org-odd-levels-only) (defvar org-keyword-time-regexp) -(defvar org-drawer-regexp) (defvar org-complex-heading-regexp) (defvar org-property-end-re) @@ -315,19 +314,36 @@ If the task has an end part, also demote it." ;; Nothing to show/hide. ((= end start)) ;; Inlinetask was folded: expand it. - ((get-char-property (1+ start) 'invisible) + ((eq (get-char-property (1+ start) 'invisible) 'outline) (outline-flag-region start end nil) (org-cycle-hide-drawers 'children)) (t (outline-flag-region start end t))))) +(defun org-inlinetask-hide-tasks (state) + "Hide inline tasks in buffer when STATE is `contents' or `children'. +This function is meant to be used in `org-cycle-hook'." + (case state + (contents + (let ((regexp (org-inlinetask-outline-regexp))) + (save-excursion + (goto-char (point-min)) + (while (re-search-forward regexp nil t) + (org-inlinetask-toggle-visibility) + (org-inlinetask-goto-end))))) + (children + (save-excursion + (while (and (outline-next-heading) (org-inlinetask-at-task-p)) + (org-inlinetask-toggle-visibility) + (org-inlinetask-goto-end)))))) + (defun org-inlinetask-remove-END-maybe () "Remove an END line when present." (when (looking-at (format "\\([ \t]*\n\\)*\\*\\{%d,\\}[ \t]+END[ \t]*$" org-inlinetask-min-level)) (replace-match ""))) -(eval-after-load "org" - '(add-hook 'org-font-lock-hook 'org-inlinetask-fontify)) +(add-hook 'org-font-lock-hook 'org-inlinetask-fontify) +(add-hook 'org-cycle-hook 'org-inlinetask-hide-tasks) (provide 'org-inlinetask) diff --git a/elpa/org-20150629/org-install.el b/elpa/org-20160215/org-install.el similarity index 100% rename from elpa/org-20150629/org-install.el rename to elpa/org-20160215/org-install.el diff --git a/elpa/org-20150629/org-irc.el b/elpa/org-20160215/org-irc.el similarity index 98% rename from elpa/org-20150629/org-irc.el rename to elpa/org-20160215/org-irc.el index 8f9761b3..333c4b1a 100644 --- a/elpa/org-20150629/org-irc.el +++ b/elpa/org-20160215/org-irc.el @@ -1,6 +1,6 @@ ;;; org-irc.el --- Store links to IRC sessions ;; -;; Copyright (C) 2008-2014 Free Software Foundation, Inc. +;; Copyright (C) 2008-2016 Free Software Foundation, Inc. ;; ;; Author: Philip Jackson ;; Keywords: erc, irc, link, org @@ -108,7 +108,7 @@ attributes that are found." (defun org-irc-ellipsify-description (string &optional after) "Remove unnecessary white space from STRING and add ellipses if necessary. Strip starting and ending white space from STRING and replace any -chars that the value AFTER with '...'" +chars that the value AFTER with `...'" (let* ((after (number-to-string (or after 30))) (replace-map (list (cons "^[ \t]*" "") (cons "[ \t]*$" "") @@ -172,7 +172,7 @@ the session itself." (org-store-link-props :type "irc" :link (concat "irc:/" link-text) - :description (concat "irc session '" link-text "'") + :description (concat "irc session `" link-text "'") :server (car (car link)) :port (or (string-to-number (cadr (pop link))) erc-default-port) :nick (pop link)) diff --git a/elpa/org-20160215/org-lint.el b/elpa/org-20160215/org-lint.el new file mode 100644 index 00000000..37d05edc --- /dev/null +++ b/elpa/org-20160215/org-lint.el @@ -0,0 +1,1151 @@ +;;; org-lint.el --- Linting for Org documents -*- lexical-binding: t; -*- + +;; Copyright (C) 2015 Free Software Foundation + +;; Author: Nicolas Goaziou +;; 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 . + +;;; Commentary: + +;; This library implements linting for Org syntax. The sole public +;; function is `org-lint', which see. + +;; Internally, the library defines a new structure: +;; `org-lint-checker', with the following slots: + +;; - NAME: Unique check identifier, as a non-nil symbol that doesn't +;; start with an hyphen. +;; +;; The check is done calling the function `org-lint-NAME' with one +;; mandatory argument, the parse tree describing the current Org +;; buffer. Such function calls are wrapped within +;; a `save-excursion' and point is always at `point-min'. Its +;; return value has to be an alist (POSITION MESSAGE) when +;; POSITION refer to the buffer position of the error, as an +;; integer, and MESSAGE is a string describing the error. + +;; - DESCRIPTION: Summary about the check, as a string. + +;; - CATEGORIES: Categories relative to the check, as a list of +;; symbol. They are used for filtering when calling `org-lint'. +;; Checkers not explicitly associated to a category are collected +;; in the `default' one. + +;; - TRUST: The trust level one can have in the check. It is either +;; `low' or `high', depending on the heuristics implemented and +;; the nature of the check. This has an indicative value only and +;; is displayed along reports. + +;; All checks have to be listed in `org-lint--checkers'. + +;; Results are displayed in a special "*Org Lint*" buffer with +;; a dedicated major mode, derived from `tabulated-list-mode'. +;; +;; In addition to the usual key-bindings inherited from it, "C-j" and +;; "TAB" display problematic line reported under point whereas "RET" +;; jumps to it. Also, "h" hides all reports similar to the current +;; one. Additionally, "i" removes them from subsequent reports. + +;; Checks currently implemented are: + +;; - duplicate CUSTOM_ID properties +;; - duplicate NAME values +;; - duplicate targets +;; - duplicate footnote definitions +;; - orphaned affiliated keywords +;; - obsolete affiliated keywords +;; - missing language in src blocks +;; - invalid Babel call blocks +;; - NAME values with a colon +;; - deprecated Babel header properties +;; - wrong header arguments in src blocks +;; - misuse of CATEGORY keyword +;; - "coderef" links with unknown destination +;; - "custom-id" links with unknown destination +;; - "fuzzy" links with unknown destination +;; - "id" links with unknown destination +;; - links to non-existent local files +;; - SETUPFILE keywords with non-existent file parameter +;; - INCLUDE keywords with wrong link parameter +;; - unknown items in OPTIONS keyword +;; - spurious macro arguments or invalid macro templates +;; - special properties in properties drawer +;; - obsolete syntax for PROPERTIES drawers +;; - missing definition for footnote references +;; - missing reference for footnote definitions +;; - non-footnote definitions in footnote section +;; - probable invalid keywords +;; - invalid blocks +;; - misplaced planning info line +;; - incomplete drawers +;; - indented diary-sexps +;; - obsolete QUOTE section + + +;;; Code: + +(require 'cl-lib) +(require 'org-element) +(require 'org-macro) +(require 'ox) +(require 'ob) + + +;;; Checkers + +(cl-defstruct (org-lint-checker (:copier nil)) + (name 'missing-checker-name) + (description "") + (categories '(default)) + (trust 'high)) ; `low' or `high' + +(defun org-lint-missing-checker-name (_) + (error + "`A checker has no `:name' property. Please verify `org-lint--checkers'")) + +(defconst org-lint--checkers + (list + (make-org-lint-checker + :name 'duplicate-custom-id + :description "Report duplicates CUSTOM_ID properties" + :categories '(link)) + (make-org-lint-checker + :name 'duplicate-name + :description "Report duplicate NAME values" + :categories '(babel link)) + (make-org-lint-checker + :name 'duplicate-target + :description "Report duplicate targets" + :categories '(link)) + (make-org-lint-checker + :name 'duplicate-footnote-definition + :description "Report duplicate footnote definitions" + :categories '(footnote)) + (make-org-lint-checker + :name 'orphaned-affiliated-keywords + :description "Report orphaned affiliated keywords" + :trust 'low) + (make-org-lint-checker + :name 'obsolete-affiliated-keywords + :description "Report obsolete affiliated keywords" + :categories '(obsolete)) + (make-org-lint-checker + :name 'deprecated-header-syntax + :description "Report deprecated Babel header syntax" + :categories '(babel obsolete) + :trust 'low) + (make-org-lint-checker + :name 'missing-language-in-src-block + :description "Report missing language in src blocks" + :categories '(babel)) + (make-org-lint-checker + :name 'invalid-babel-call-block + :description "Report invalid Babel call blocks" + :categories '(babel)) + (make-org-lint-checker + :name 'colon-in-name + :description "Report NAME values with a colon" + :categories '(babel)) + (make-org-lint-checker + :name 'wrong-header-argument + :description "Report wrong babel headers" + :categories '(babel)) + (make-org-lint-checker + :name 'wrong-header-value + :description "Report invalid value in babel headers" + :categories '(babel) + :trust 'low) + (make-org-lint-checker + :name 'deprecated-category-setup + :description "Report misuse of CATEGORY keyword" + :categories '(obsolete)) + (make-org-lint-checker + :name 'invalid-coderef-link + :description "Report \"coderef\" links with unknown destination" + :categories '(link)) + (make-org-lint-checker + :name 'invalid-custom-id-link + :description "Report \"custom-id\" links with unknown destination" + :categories '(link)) + (make-org-lint-checker + :name 'invalid-fuzzy-link + :description "Report \"fuzzy\" links with unknown destination" + :categories '(link)) + (make-org-lint-checker + :name 'invalid-id-link + :description "Report \"id\" links with unknown destination" + :categories '(link)) + (make-org-lint-checker + :name 'link-to-local-file + :description "Report links to non-existent local files" + :categories '(link) + :trust 'low) + (make-org-lint-checker + :name 'non-existent-setupfile-parameter + :description "Report SETUPFILE keywords with non-existent file parameter" + :trust 'low) + (make-org-lint-checker + :name 'wrong-include-link-parameter + :description "Report INCLUDE keywords with misleading link parameter" + :categories '(export) + :trust 'low) + (make-org-lint-checker + :name 'unknown-options-item + :description "Report unknown items in OPTIONS keyword" + :categories '(export) + :trust 'low) + (make-org-lint-checker + :name 'invalid-macro-argument-and-template + :description "Report spurious macro arguments or invalid macro templates" + :categories '(export) + :trust 'low) + (make-org-lint-checker + :name 'special-property-in-properties-drawer + :description "Report special properties in properties drawers" + :categories '(properties)) + (make-org-lint-checker + :name 'obsolete-properties-drawer + :description "Report obsolete syntax for properties drawers" + :categories '(obsolete properties)) + (make-org-lint-checker + :name 'undefined-footnote-reference + :description "Report missing definition for footnote references" + :categories '(footnote)) + (make-org-lint-checker + :name 'unreferenced-footnote-definition + :description "Report missing reference for footnote definitions" + :categories '(footnote)) + (make-org-lint-checker + :name 'extraneous-element-in-footnote-section + :description "Report non-footnote definitions in footnote section" + :categories '(footnote)) + (make-org-lint-checker + :name 'invalid-keyword-syntax + :description "Report probable invalid keywords" + :trust 'low) + (make-org-lint-checker + :name 'invalid-block + :description "Report invalid blocks" + :trust 'low) + (make-org-lint-checker + :name 'misplaced-planning-info + :description "Report misplaced planning info line" + :trust 'low) + (make-org-lint-checker + :name 'incomplete-drawer + :description "Report probable incomplete drawers" + :trust 'low) + (make-org-lint-checker + :name 'indented-diary-sexp + :description "Report probable indented diary-sexps" + :trust 'low) + (make-org-lint-checker + :name 'quote-section + :description "Report obsolete QUOTE section" + :categories '(obsolete) + :trust 'low)) + "List of all available checkers.") + +(defun org-lint--collect-duplicates + (ast type extract-key extract-position build-message) + "Helper function to collect duplicates in parse tree AST. + +EXTRACT-KEY is a function extracting key. It is called with +a single argument: the element or object. Comparison is done +with `equal'. + +EXTRACT-POSITION is a function returning position for the report. +It is called with two arguments, the object or element, and the +key. + +BUILD-MESSAGE is a function creating the report message. It is +called with one argument, the key used for comparison." + (let* (keys + originals + reports + (make-report + (lambda (position value) + (push (list position (funcall build-message value)) reports)))) + (org-element-map ast type + (lambda (datum) + (let ((key (funcall extract-key datum))) + (cond + ((not key)) + ((assoc key keys) (cl-pushnew (assoc key keys) originals) + (funcall make-report (funcall extract-position datum key) key)) + (t (push (cons key (funcall extract-position datum key)) keys)))))) + (dolist (e originals reports) (funcall make-report (cdr e) (car e))))) + +(defun org-lint-duplicate-custom-id (ast) + (org-lint--collect-duplicates + ast + 'node-property + (lambda (property) + (and (eq (compare-strings "CUSTOM_ID" nil nil + (org-element-property :key property) nil nil + t) + t) + (org-element-property :value property))) + (lambda (property _) (org-element-property :begin property)) + (lambda (key) (format "Duplicate CUSTOM_ID property \"%s\"" key)))) + +(defun org-lint-duplicate-name (ast) + (org-lint--collect-duplicates + ast + org-element-all-elements + (lambda (datum) (org-element-property :name datum)) + (lambda (datum name) + (goto-char (org-element-property :begin datum)) + (re-search-forward + (format "^[ \t]*#\\+[A-Za-z]+: +%s *$" (regexp-quote name))) + (match-beginning 0)) + (lambda (key) (format "Duplicate NAME \"%s\"" key)))) + +(defun org-lint-duplicate-target (ast) + (org-lint--collect-duplicates + ast + 'target + (lambda (target) (org-split-string (org-element-property :value target))) + (lambda (target _) (org-element-property :begin target)) + (lambda (key) + (format "Duplicate target <<%s>>" (mapconcat #'identity key " "))))) + +(defun org-lint-duplicate-footnote-definition (ast) + (org-lint--collect-duplicates + ast + 'footnote-definition + (lambda (definition) (org-element-property :label definition)) + (lambda (definition _) (org-element-property :post-affiliated definition)) + (lambda (key) (format "Duplicate footnote definition \"%s\"" key)))) + +(defun org-lint-orphaned-affiliated-keywords (ast) + ;; Ignore orphan RESULTS keywords, which could be generated from + ;; a source block returning no value. + (let ((keywords (cl-set-difference org-element-affiliated-keywords + '("RESULT" "RESULTS") + :test #'equal))) + (org-element-map ast 'keyword + (lambda (k) + (let ((key (org-element-property :key k))) + (and (or (let ((case-fold-search t)) + (org-string-match-p "\\`ATTR_[-_A-Za-z0-9]+\\'" key)) + (member key keywords)) + (list (org-element-property :post-affiliated k) + (format "Orphaned affiliated keyword: \"%s\"" key)))))))) + +(defun org-lint-obsolete-affiliated-keywords (_) + (let ((regexp (format "^[ \t]*#\\+%s:" + (regexp-opt '("DATA" "LABEL" "RESNAME" "SOURCE" + "SRCNAME" "TBLNAME" "RESULT" "HEADERS") + t))) + reports) + (while (re-search-forward regexp nil t) + (let ((key (upcase (org-match-string-no-properties 1)))) + (when (< (point) + (org-element-property :post-affiliated (org-element-at-point))) + (push + (list (line-beginning-position) + (format + "Obsolete affiliated keyword: \"%s\". Use \"%s\" instead" + key + (pcase key + ("HEADERS" "HEADER") + ("RESULT" "RESULTS") + (_ "NAME")))) + reports)))) + reports)) + +(defun org-lint-deprecated-header-syntax (ast) + (let* ((deprecated-babel-properties + (mapcar (lambda (arg) (symbol-name (car arg))) + org-babel-common-header-args-w-values)) + (deprecated-re + (format "\\`%s[ \t]" (regexp-opt deprecated-babel-properties t)))) + (org-element-map ast '(keyword node-property) + (lambda (datum) + (let ((key (org-element-property :key datum))) + (pcase (org-element-type datum) + (`keyword + (let ((value (org-element-property :value datum))) + (and (string= key "PROPERTY") + (string-match deprecated-re value) + (list (org-element-property :begin datum) + (format "Deprecated syntax for \"%s\". \ +Use header-args instead" + (org-match-string-no-properties 1 value)))))) + (`node-property + (and (member-ignore-case key deprecated-babel-properties) + (list + (org-element-property :begin datum) + (format "Deprecated syntax for \"%s\". \ +Use :header-args: instead" + key)))))))))) + +(defun org-lint-missing-language-in-src-block (ast) + (org-element-map ast 'src-block + (lambda (b) + (unless (org-element-property :language b) + (list (org-element-property :post-affiliated b) + "Missing language in source block"))))) + +(defun org-lint-invalid-babel-call-block (ast) + (org-element-map ast 'babel-call + (lambda (b) + (cond + ((not (org-element-property :call b)) + (list (org-element-property :post-affiliated b) + "Invalid syntax in babel call block")) + ((let ((h (org-element-property :end-header b))) + (and h (org-string-match-p "\\`\\[.*\\]\\'" h))) + (list + (org-element-property :post-affiliated b) + "Babel call's end header must not be wrapped within brackets")))))) + +(defun org-lint-deprecated-category-setup (ast) + (org-element-map ast 'keyword + (let (category-flag) + (lambda (k) + (cond + ((not (string= (org-element-property :key k) "CATEGORY")) nil) + (category-flag + (list (org-element-property :post-affiliated k) + "Spurious CATEGORY keyword. Set :CATEGORY: property instead")) + (t (setf category-flag t) nil)))))) + +(defun org-lint-invalid-coderef-link (ast) + (let ((info (list :parse-tree ast))) + (org-element-map ast 'link + (lambda (link) + (let ((ref (org-element-property :path link))) + (and (equal (org-element-property :type link) "coderef") + (not (ignore-errors (org-export-resolve-coderef ref info))) + (list (org-element-property :begin link) + (format "Unknown coderef \"%s\"" ref)))))))) + +(defun org-lint-invalid-custom-id-link (ast) + (let ((info (list :parse-tree ast))) + (org-element-map ast 'link + (lambda (link) + (and (equal (org-element-property :type link) "custom-id") + (not (ignore-errors (org-export-resolve-id-link link info))) + (list (org-element-property :begin link) + (format "Unknown custom ID \"%s\"" + (org-element-property :path link)))))))) + +(defun org-lint-invalid-fuzzy-link (ast) + (let ((info (list :parse-tree ast))) + (org-element-map ast 'link + (lambda (link) + (and (equal (org-element-property :type link) "fuzzy") + (not (ignore-errors (org-export-resolve-fuzzy-link link info))) + (list (org-element-property :begin link) + (format "Unknown fuzzy location \"%s\"" + (let ((path (org-element-property :path link))) + (if (string-prefix-p "*" path) + (substring path 1) + path))))))))) + +(defun org-lint-invalid-id-link (ast) + (org-element-map ast 'link + (lambda (link) + (let ((id (org-element-property :path link))) + (and (equal (org-element-property :type link) "id") + (not (org-id-find id)) + (list (org-element-property :begin link) + (format "Unknown ID \"%s\"" id))))))) + +(defun org-lint-special-property-in-properties-drawer (ast) + (org-element-map ast 'node-property + (lambda (p) + (let ((key (org-element-property :key p))) + (and (member-ignore-case key org-special-properties) + (list (org-element-property :begin p) + (format + "Special property \"%s\" found in a properties drawer" + key))))))) + +(defun org-lint-obsolete-properties-drawer (ast) + (org-element-map ast 'drawer + (lambda (d) + (when (equal (org-element-property :drawer-name d) "PROPERTIES") + (let ((section (org-element-lineage d '(section)))) + (unless (org-element-map section 'property-drawer #'identity nil t) + (list (org-element-property :post-affiliated d) + (if (save-excursion + (goto-char (org-element-property :post-affiliated d)) + (forward-line -1) + (or (org-at-heading-p) (org-at-planning-p))) + "Incorrect contents for PROPERTIES drawer" + "Incorrect location for PROPERTIES drawer")))))))) + +(defun org-lint-link-to-local-file (ast) + (org-element-map ast 'link + (lambda (l) + (when (equal (org-element-property :type l) "file") + (let ((file (org-link-unescape (org-element-property :path l)))) + (and (not (file-remote-p file)) + (not (file-exists-p file)) + (list (org-element-property :begin l) + (format (if (org-element-lineage l '(link)) + "Link to non-existent image file \"%s\"\ + in link description" + "Link to non-existent local file \"%s\"") + file)))))))) + +(defun org-lint-non-existent-setupfile-parameter (ast) + (org-element-map ast 'keyword + (lambda (k) + (when (equal (org-element-property :key k) "SETUPFILE") + (let ((file (org-remove-double-quotes + (org-element-property :value k)))) + (and (not (file-remote-p file)) + (not (file-exists-p file)) + (list (org-element-property :begin k) + (format "Non-existent setup file \"%s\"" file)))))))) + +(defun org-lint-wrong-include-link-parameter (ast) + (org-element-map ast 'keyword + (lambda (k) + (when (equal (org-element-property :key k) "INCLUDE") + (let* ((value (org-element-property :value k)) + (path + (and (string-match "^\\(\".+\"\\|\\S-+\\)[ \t]*" value) + (save-match-data + (org-remove-double-quotes (match-string 1 value)))))) + (if (not path) + (list (org-element-property :post-affiliated k) + "Missing location argument in INCLUDE keyword") + (let* ((file (org-string-nw-p + (if (string-match "::\\(.*\\)\\'" path) + (substring path 0 (match-beginning 0)) + path))) + (search (and (not (equal file path)) + (org-string-nw-p (match-string 1 path))))) + (if (and file + (not (file-remote-p file)) + (not (file-exists-p file))) + (list (org-element-property :post-affiliated k) + "Non-existent file argument in INCLUDE keyword") + (let* ((visiting (if file (find-buffer-visiting file) + (current-buffer))) + (buffer (or visiting (find-file-noselect file)))) + (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))))) + (list (org-element-property :post-affiliated k) + (format + "Invalid search part \"%s\" in INCLUDE keyword" + search)))) + (unless visiting (kill-buffer buffer)))))))))))) + +(defun org-lint-unknown-options-item (ast) + (let ((allowed (delq nil + (append + (mapcar (lambda (o) (nth 2 o)) org-export-options-alist) + (cl-mapcan + (lambda (b) + (mapcar (lambda (o) (nth 2 o)) + (org-export-backend-options b))) + org-export-registered-backends)))) + reports) + (org-element-map ast 'keyword + (lambda (k) + (when (string= (org-element-property :key k) "OPTIONS") + (let ((value (org-element-property :value k)) + (start 0)) + (while (string-match "\\(.+?\\):\\((.*?)\\|\\S-*\\)[ \t]*" + value + start) + (setf start (match-end 0)) + (let ((item (match-string 1 value))) + (unless (member item allowed) + (push (list (org-element-property :post-affiliated k) + (format "Unknown OPTIONS item \"%s\"" item)) + reports)))))))) + reports)) + +(defun org-lint-invalid-macro-argument-and-template (ast) + (let ((extract-placeholders + (lambda (template) + (let ((start 0) + args) + (while (string-match "\\$\\([1-9][0-9]*\\)" template start) + (setf start (match-end 0)) + (push (string-to-number (match-string 1 template)) args)) + (sort (org-uniquify args) #'<)))) + reports) + ;; Check arguments for macro templates. + (org-element-map ast 'keyword + (lambda (k) + (when (string= (org-element-property :key k) "MACRO") + (let* ((value (org-element-property :value k)) + (name (and (string-match "^\\S-+" value) + (match-string 0 value))) + (template (and name + (org-trim (substring value (match-end 0)))))) + (cond + ((not name) + (push (list (org-element-property :post-affiliated k) + "Missing name in MACRO keyword") + reports)) + ((not (org-string-nw-p template)) + (push (list (org-element-property :post-affiliated k) + "Missing template in macro \"%s\"" name) + reports)) + (t + (unless (let ((args (funcall extract-placeholders template))) + (equal (number-sequence 1 (or (org-last args) 0)) args)) + (push (list (org-element-property :post-affiliated k) + (format "Unused placeholders in macro \"%s\"" + name)) + reports)))))))) + ;; Check arguments for macros. + (org-macro-initialize-templates) + (let ((templates (append + (mapcar (lambda (m) (cons m "$1")) + '("author" "date" "email" "title" "results")) + org-macro-templates))) + (org-element-map ast 'macro + (lambda (macro) + (let* ((name (org-element-property :key macro)) + (template (cdr (assoc-string name templates t)))) + (if (not template) + (push (list (org-element-property :begin macro) + (format "Undefined macro \"%s\"" name)) + reports) + (let ((arg-numbers (funcall extract-placeholders template))) + (when arg-numbers + (let ((spurious-args + (nthcdr (apply #'max arg-numbers) + (org-element-property :args macro)))) + (when spurious-args + (push + (list (org-element-property :begin macro) + (format "Unused argument%s in macro \"%s\": %s" + (if (> (length spurious-args) 1) "s" "") + name + (mapconcat (lambda (a) (format "\"%s\"" a)) + spurious-args + ", "))) + reports)))))))))) + reports)) + +(defun org-lint-undefined-footnote-reference (ast) + (let ((definitions (org-element-map ast 'footnote-definition + (lambda (f) (org-element-property :label f))))) + (org-element-map ast 'footnote-reference + (lambda (f) + (let ((label (org-element-property :label f))) + (and label + (not (member label definitions)) + (list (org-element-property :begin f) + (format "Missing definition for footnote [%s]" + label)))))))) + +(defun org-lint-unreferenced-footnote-definition (ast) + (let ((references (org-element-map ast 'footnote-reference + (lambda (f) (org-element-property :label f))))) + (org-element-map ast 'footnote-definition + (lambda (f) + (let ((label (org-element-property :label f))) + (and label + (not (member label references)) + (list (org-element-property :post-affiliated f) + (format "No reference for footnote definition [%s]" + label)))))))) + +(defun org-lint-colon-in-name (ast) + (org-element-map ast org-element-all-elements + (lambda (e) + (let ((name (org-element-property :name e))) + (and name + (org-string-match-p ":" name) + (list (progn + (goto-char (org-element-property :begin e)) + (re-search-forward + (format "^[ \t]*#\\+\\w+: +%s *$" (regexp-quote name))) + (match-beginning 0)) + (format + "Name \"%s\" contains a colon; Babel cannot use it as input" + name))))))) + +(defun org-lint-misplaced-planning-info (_) + (let ((case-fold-search t) + reports) + (while (re-search-forward org-planning-line-re nil t) + (unless (memq (org-element-type (org-element-at-point)) + '(comment-block example-block export-block planning + src-block verse-block)) + (push (list (line-beginning-position) "Misplaced planning info line") + reports))) + reports)) + +(defun org-lint-incomplete-drawer (_) + (let (reports) + (while (re-search-forward org-drawer-regexp nil t) + (let ((name (org-trim (org-match-string-no-properties 0))) + (element (org-element-at-point))) + (pcase (org-element-type element) + ((or `drawer `property-drawer) + (goto-char (org-element-property :end element)) + nil) + ((or `comment-block `example-block `export-block `src-block + `verse-block) + nil) + (_ + (push (list (line-beginning-position) + (format "Possible incomplete drawer \"%s\"" name)) + reports))))) + reports)) + +(defun org-lint-indented-diary-sexp (_) + (let (reports) + (while (re-search-forward "^[ \t]+%%(" nil t) + (unless (memq (org-element-type (org-element-at-point)) + '(comment-block diary-sexp example-block export-block + src-block verse-block)) + (push (list (line-beginning-position) "Possible indented diary-sexp") + reports))) + reports)) + +(defun org-lint-invalid-block (_) + (let ((case-fold-search t) + (regexp "^[ \t]*#\\+\\(BEGIN\\|END\\)\\(?::\\|_[^[:space:]]*\\)?[ \t]*") + reports) + (while (re-search-forward regexp nil t) + (let ((name (org-trim (buffer-substring-no-properties + (line-beginning-position) (line-end-position))))) + (cond + ((and (string-prefix-p "END" (match-string 1) t) + (not (eolp))) + (push (list (line-beginning-position) + (format "Invalid block closing line \"%s\"" name)) + reports)) + ((not (memq (org-element-type (org-element-at-point)) + '(center-block comment-block dynamic-block example-block + export-block quote-block special-block + src-block verse-block))) + (push (list (line-beginning-position) + (format "Possible incomplete block \"%s\"" + name)) + reports))))) + reports)) + +(defun org-lint-invalid-keyword-syntax (_) + (let ((regexp "^[ \t]*#\\+\\([^[:space:]:]*\\)\\(?: \\|$\\)") + (exception-re + (format "[ \t]*#\\+%s\\(\\[.*\\]\\)?:\\(?: \\|$\\)" + (regexp-opt org-element-dual-keywords))) + reports) + (while (re-search-forward regexp nil t) + (let ((name (org-match-string-no-properties 1))) + (unless (or (string-prefix-p "BEGIN" name t) + (string-prefix-p "END" name t) + (save-excursion + (beginning-of-line) + (let ((case-fold-search t)) (looking-at exception-re)))) + (push (list (match-beginning 0) + (format "Possible missing colon in keyword \"%s\"" name)) + reports)))) + reports)) + +(defun org-lint-extraneous-element-in-footnote-section (ast) + (org-element-map ast 'headline + (lambda (h) + (and (org-element-property :footnote-section-p h) + (org-element-map (org-element-contents h) + (cl-remove-if + (lambda (e) + (memq e '(comment comment-block footnote-definition + property-drawer section))) + org-element-all-elements) + (lambda (e) + (not (and (eq (org-element-type e) 'headline) + (org-element-property :commentedp e)))) + nil t '(footnote-definition property-drawer)) + (list (org-element-property :begin h) + "Extraneous elements in footnote section"))))) + +(defun org-lint-quote-section (ast) + (org-element-map ast '(headline inlinetask) + (lambda (h) + (let ((title (org-element-property :raw-value h))) + (and (or (string-prefix-p "QUOTE " title) + (string-prefix-p (concat org-comment-string " QUOTE ") title)) + (list (org-element-property :begin h) + "Deprecated QUOTE section")))))) + +(defun org-lint-wrong-header-argument (ast) + (let* ((reports) + (verify + (lambda (datum language headers) + (let ((allowed + ;; If LANGUAGE is specified, restrict allowed + ;; headers to both LANGUAGE-specific and default + ;; ones. Otherwise, accept headers from any loaded + ;; language. + (append + org-babel-header-arg-names + (cl-mapcan + (lambda (l) + (let ((v (intern (format "org-babel-header-args:%s" l)))) + (and (boundp v) (mapcar #'car (symbol-value v))))) + (if language (list language) + (mapcar #'car org-babel-load-languages)))))) + (dolist (header headers) + (let ((h (symbol-name (car header))) + (p (or (org-element-property :post-affiliated datum) + (org-element-property :begin datum)))) + (cond + ((not (string-prefix-p ":" h)) + (push + (list p + (format "Missing colon in header argument \"%s\"" h)) + reports)) + ((assoc-string (substring h 1) allowed)) + (t (push (list p (format "Unknown header argument \"%s\"" h)) + reports))))))))) + (org-element-map ast '(babel-call inline-babel-call inline-src-block keyword + node-property src-block) + (lambda (datum) + (pcase (org-element-type datum) + ((or `babel-call `inline-babel-call) + (funcall verify + datum + nil + (cl-mapcan #'org-babel-parse-header-arguments + (list + (org-element-property :inside-header datum) + (org-element-property :end-header datum))))) + (`inline-src-block + (funcall verify + datum + (org-element-property :language datum) + (org-babel-parse-header-arguments + (org-element-property :parameters datum)))) + (`keyword + (when (string= (org-element-property :key datum) "PROPERTY") + (let ((value (org-element-property :value datum))) + (when (string-match "\\`header-args\\(?::\\(\\S-+\\)\\)?\\+? *" + value) + (funcall verify + datum + (match-string 1 value) + (org-babel-parse-header-arguments + (substring value (match-end 0)))))))) + (`node-property + (let ((key (org-element-property :key datum))) + (when (let ((case-fold-search t)) + (string-match "\\`HEADER-ARGS\\(?::\\(\\S-+\\)\\)?\\+?" + key)) + (funcall verify + datum + (match-string 1 key) + (org-babel-parse-header-arguments + (org-element-property :value datum)))))) + (`src-block + (funcall verify + datum + (org-element-property :language datum) + (cl-mapcan #'org-babel-parse-header-arguments + (cons (org-element-property :parameters datum) + (org-element-property :header datum)))))))) + reports)) + +(defun org-lint-wrong-header-value (ast) + (let (reports) + (org-element-map ast + '(babel-call inline-babel-call inline-src-block src-block) + (lambda (datum) + (let* ((type (org-element-type datum)) + (language (org-element-property :language datum)) + (allowed-header-values + (append (and language + (let ((v (intern (concat "org-babel-header-args:" + language)))) + (and (boundp v) (symbol-value v)))) + org-babel-common-header-args-w-values)) + (datum-header-values + (apply + #'org-babel-merge-params + org-babel-default-header-args + (and language + (let ((v (intern (concat "org-babel-default-header-args:" + language)))) + (and (boundp v) (symbol-value v)))) + (append + (list (and (memq type '(babel-call inline-babel-call)) + org-babel-default-lob-header-args)) + (progn (goto-char (org-element-property :begin datum)) + (org-babel-params-from-properties language)) + (list + (org-babel-parse-header-arguments + (org-trim + (pcase type + (`src-block + (mapconcat + #'identity + (cons (org-element-property :parameters datum) + (org-element-property :header datum)) + " ")) + (`inline-src-block + (or (org-element-property :parameters datum) "")) + (_ + (concat + (org-element-property :inside-header datum) + " " + (org-element-property :end-header datum))))))))))) + (dolist (header datum-header-values) + (let ((allowed-values + (cdr (assoc-string (substring (symbol-name (car header)) 1) + allowed-header-values)))) + (unless (memq allowed-values '(:any nil)) + (let ((values (cdr header)) + groups-alist) + (dolist (v (if (stringp values) (org-split-string values) + (list values))) + (let ((valid-value nil)) + (catch 'exit + (dolist (group allowed-values) + (cond + ((not (funcall + (if (stringp v) #'assoc-string #'assoc) + v group)) + (when (memq :any group) + (setf valid-value t) + (push (cons group v) groups-alist))) + ((assq group groups-alist) + (push + (list + (or (org-element-property :post-affiliated datum) + (org-element-property :begin datum)) + (format + "Forbidden combination in header \"%s\": %s, %s" + (car header) + (cdr (assq group groups-alist)) + v)) + reports) + (throw 'exit nil)) + (t (push (cons group v) groups-alist) + (setf valid-value t)))) + (unless valid-value + (push + (list + (or (org-element-property :post-affiliated datum) + (org-element-property :begin datum)) + (format "Unknown value \"%s\" for header \"%s\"" + v + (car header))) + reports)))))))))))) + reports)) + + +;;; Reports UI + +(defvar org-lint--report-mode-map + (let ((map (make-sparse-keymap))) + (set-keymap-parent map tabulated-list-mode-map) + (define-key map (kbd "RET") 'org-lint--jump-to-source) + (define-key map (kbd "TAB") 'org-lint--show-source) + (define-key map (kbd "C-j") 'org-lint--show-source) + (define-key map (kbd "h") 'org-lint--hide-checker) + (define-key map (kbd "i") 'org-lint--ignore-checker) + map) + "Local keymap for `org-lint--report-mode' buffers.") + +(define-derived-mode org-lint--report-mode tabulated-list-mode "OrgLint" + "Major mode used to display reports emitted during linting. +\\{org-lint--report-mode-map}" + (setf tabulated-list-format + `[("Line" 6 + (lambda (a b) + (< (string-to-number (aref (cadr a) 0)) + (string-to-number (aref (cadr b) 0)))) + :right-align t) + ("Trust" 5 t) + ("Warning" 0 t)]) + (tabulated-list-init-header)) + +(defun org-lint--generate-reports (buffer checkers) + "Generate linting report for BUFFER. + +CHECKERS is the list of checkers used. + +Return an alist (ID [LINE TRUST DESCRIPTION CHECKER]), suitable +for `tabulated-list-printer'." + (with-current-buffer buffer + (save-excursion + (goto-char (point-min)) + (let ((ast (org-element-parse-buffer)) + (id 0) + (last-line 1) + (last-pos 1)) + ;; Insert unique ID for each report. Replace buffer positions + ;; with line numbers. + (mapcar + (lambda (report) + (list + (incf id) + (apply #'vector + (cons + (progn + (goto-char (car report)) + (beginning-of-line) + (prog1 (number-to-string + (incf last-line (count-lines last-pos (point)))) + (setf last-pos (point)))) + (cdr report))))) + ;; Insert trust level in generated reports. Also sort them + ;; by buffer position in order to optimize lines computation. + (sort (cl-mapcan + (lambda (c) + (let ((trust (symbol-name (org-lint-checker-trust c)))) + (mapcar + (lambda (report) + (list (car report) trust (nth 1 report) c)) + (save-excursion + (funcall + (intern (format "org-lint-%s" + (org-lint-checker-name c))) + ast))))) + checkers) + #'car-less-than-car)))))) + +(defvar-local org-lint--source-buffer nil + "Source buffer associated to current report buffer.") + +(defvar-local org-lint--local-checkers nil + "List of checkers used to build current report.") + +(defun org-lint--refresh-reports () + (setq tabulated-list-entries + (org-lint--generate-reports org-lint--source-buffer + org-lint--local-checkers)) + (tabulated-list-print)) + +(defun org-lint--current-line () + "Return current report line, as a number." + (string-to-number (aref (tabulated-list-get-entry) 0))) + +(defun org-lint--current-checker (&optional entry) + "Return current report checker. +When optional argument ENTRY is non-nil, use this entry instead +of current one." + (aref (if entry (nth 1 entry) (tabulated-list-get-entry)) 3)) + +(defun org-lint--display-reports (source checkers) + "Display linting reports for buffer SOURCE. +CHECKERS is the list of checkers used." + (let ((buffer (get-buffer-create "*Org Lint*"))) + (with-current-buffer buffer + (org-lint--report-mode) + (setf org-lint--source-buffer source) + (setf org-lint--local-checkers checkers) + (org-lint--refresh-reports) + (tabulated-list-print) + (add-hook 'tabulated-list-revert-hook #'org-lint--refresh-reports nil t)) + (pop-to-buffer buffer))) + +(defun org-lint--jump-to-source () + "Move to source line that generated the report at point." + (interactive) + (let ((l (org-lint--current-line))) + (switch-to-buffer-other-window org-lint--source-buffer) + (org-goto-line l) + (org-show-set-visibility 'local) + (recenter))) + +(defun org-lint--show-source () + "Show source line that generated the report at point." + (interactive) + (let ((buffer (current-buffer))) + (org-lint--jump-to-source) + (switch-to-buffer-other-window buffer))) + +(defun org-lint--hide-checker () + "Hide all reports from checker that generated the report at point." + (interactive) + (let ((c (org-lint--current-checker))) + (setf tabulated-list-entries + (cl-remove-if (lambda (e) (equal c (org-lint--current-checker e))) + tabulated-list-entries)) + (tabulated-list-print))) + +(defun org-lint--ignore-checker () + "Ignore all reports from checker that generated the report at point. +Checker will also be ignored in all subsequent reports." + (interactive) + (setf org-lint--local-checkers + (remove (org-lint--current-checker) org-lint--local-checkers)) + (org-lint--hide-checker)) + + +;;; Public function + +;;;###autoload +(defun org-lint (&optional arg) + "Check current Org buffer for syntax mistakes. + +By default, run all checkers. With a single prefix ARG \ +\\[universal-argument], +select one category of checkers only. With a double prefix +\\[universal-argument] \\[universal-argument], select one precise \ +checker by its name. + +ARG can also be a list of checker names, as symbols, to run." + (interactive "P") + (unless (derived-mode-p 'org-mode) (user-error "Not in an Org buffer")) + (when (org-called-interactively-p) + (message "Org linting process starting...")) + (let ((checkers + (pcase arg + (`nil org-lint--checkers) + (`(4) + (let ((category + (completing-read + "Checker category: " + (mapcar #'org-lint-checker-categories org-lint--checkers) + nil t))) + (cl-remove-if-not + (lambda (c) + (assoc-string (org-lint-checker-categories c) category)) + org-lint--checkers))) + (`(16) + (list + (let ((name (completing-read + "Checker name: " + (mapcar #'org-lint-checker-name org-lint--checkers) + nil t))) + (catch 'exit + (dolist (c org-lint--checkers) + (when (string= (org-lint-checker-name c) name) + (throw 'exit c))))))) + ((pred consp) + (cl-remove-if-not (lambda (c) (memq (org-lint-checker-name c) arg)) + org-lint--checkers)) + (_ (user-error "Invalid argument `%S' for `org-lint'" arg))))) + (if (not (org-called-interactively-p)) + (org-lint--generate-reports (current-buffer) checkers) + (org-lint--display-reports (current-buffer) checkers) + (message "Org linting process completed")))) + + +(provide 'org-lint) +;;; org-lint.el ends here diff --git a/elpa/org-20150629/org-list.el b/elpa/org-20160215/org-list.el similarity index 91% rename from elpa/org-20150629/org-list.el rename to elpa/org-20160215/org-list.el index 342265c8..d264451a 100644 --- a/elpa/org-20150629/org-list.el +++ b/elpa/org-20160215/org-list.el @@ -1,6 +1,6 @@ ;;; org-list.el --- Plain lists for Org-mode ;; -;; Copyright (C) 2004-2014 Free Software Foundation, Inc. +;; Copyright (C) 2004-2016 Free Software Foundation, Inc. ;; ;; Author: Carsten Dominik ;; Bastien Guerry @@ -88,36 +88,43 @@ (defvar org-closed-string) (defvar org-deadline-string) (defvar org-description-max-indent) -(defvar org-drawers) (defvar org-odd-levels-only) (defvar org-scheduled-string) (defvar org-ts-regexp) (defvar org-ts-regexp-both) +(defvar org-drawer-regexp) -(declare-function outline-invisible-p "outline" (&optional pos)) -(declare-function outline-flag-region "outline" (from to flag)) -(declare-function outline-next-heading "outline" ()) -(declare-function outline-previous-heading "outline" ()) - -(declare-function org-at-heading-p "org" (&optional ignored)) -(declare-function org-before-first-heading-p "org" ()) +(declare-function org-at-heading-p "org" (&optional invisible-ok)) (declare-function org-back-to-heading "org" (&optional invisible-ok)) +(declare-function org-before-first-heading-p "org" ()) (declare-function org-combine-plists "org" (&rest plists)) (declare-function org-count "org" (cl-item cl-seq)) (declare-function org-current-level "org" ()) +(declare-function org-element-at-point "org-element" ()) +(declare-function org-element-context "org-element" (&optional element)) +(declare-function org-element-lineage "org-element" + (blob &optional types with-self)) +(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-export-string-as "ox" + (string backend &optional body-only ext-plist)) (declare-function org-fix-tags-on-the-fly "org" ()) (declare-function org-get-indentation "org" (&optional line)) (declare-function org-icompleting-read "org" (&rest args)) (declare-function org-in-block-p "org" (names)) (declare-function org-in-regexp "org" (re &optional nlines visually)) +(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-outline-regexp "org-inlinetask" ()) (declare-function org-level-increment "org" ()) (declare-function org-narrow-to-subtree "org" ()) -(declare-function org-at-heading-p "org" (&optional invisible-ok)) (declare-function org-previous-line-empty-p "org" ()) -(declare-function org-remove-if "org" (predicate seq)) (declare-function org-reduced-level "org" (L)) +(declare-function org-remove-if "org" (predicate seq)) (declare-function org-show-subtree "org" ()) (declare-function org-sort-remove-invisible "org" (S)) (declare-function org-time-string-to-seconds "org" (s)) @@ -125,15 +132,10 @@ (declare-function org-timer-item "org-timer" (&optional arg)) (declare-function org-trim "org" (s)) (declare-function org-uniquify "org" (list)) - -(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-outline-regexp "org-inlinetask" ()) - -(declare-function org-export-string-as "ox" - (string backend &optional body-only ext-plist)) - +(declare-function outline-flag-region "outline" (from to flag)) +(declare-function outline-invisible-p "outline" (&optional pos)) +(declare-function outline-next-heading "outline" ()) +(declare-function outline-previous-heading "outline" ()) @@ -174,7 +176,7 @@ to the bullet that should be used when this item is demoted. For example, (setq org-list-demote-modify-bullet - '((\"+\" . \"-\") (\"-\" . \"+\") (\"*\" . \"+\"))) + \\='((\"+\" . \"-\") (\"-\" . \"+\") (\"*\" . \"+\"))) will make @@ -211,11 +213,19 @@ into (defcustom org-plain-list-ordered-item-terminator t "The character that makes a line with leading number an ordered list item. -Valid values are ?. and ?\). To get both terminators, use t." +Valid values are ?. and ?\). To get both terminators, use t. + +This variable needs to be set before org.el is loaded. If you +need to make a change while Emacs is running, use the customize +interface or run the following code after updating it: + + \\[org-element-update-syntax]" :group 'org-plain-lists :type '(choice (const :tag "dot like in \"2.\"" ?.) (const :tag "paren like in \"2)\"" ?\)) - (const :tag "both" t))) + (const :tag "both" t)) + :set (lambda (var val) (set var val) + (when (featurep 'org-element) (org-element-update-syntax)))) (define-obsolete-variable-alias 'org-alphabetical-lists 'org-list-allow-alphabetical "24.4") ; Since 8.0 @@ -230,13 +240,12 @@ This variable needs to be set before org.el is loaded. If you need to make a change while Emacs is running, use the customize interface or run the following code after updating it: - \(when (featurep 'org-element) (load \"org-element\" t t))" + \\[org-element-update-syntax]" :group 'org-plain-lists :version "24.1" :type 'boolean - :set (lambda (var val) - (when (featurep 'org-element) (load "org-element" t t)) - (set var val))) + :set (lambda (var val) (set var val) + (when (featurep 'org-element) (org-element-update-syntax)))) (defcustom org-list-two-spaces-after-bullet-regexp nil "A regular expression matching bullets that should have 2 spaces after them. @@ -430,9 +439,6 @@ group 4: description tag") (let* ((case-fold-search t) (context (org-list-context)) (lim-up (car context)) - (drawers-re (concat "^[ \t]*:\\(" - (mapconcat #'regexp-quote org-drawers "\\|") - "\\):[ \t]*$")) (inlinetask-re (and (featurep 'org-inlinetask) (org-inlinetask-outline-regexp))) (item-re (org-item-re)) @@ -476,7 +482,7 @@ group 4: description tag") ((and (looking-at "^[ \t]*#\\+end_") (re-search-backward "^[ \t]*#\\+begin_" lim-up t))) ((and (looking-at "^[ \t]*:END:") - (re-search-backward drawers-re lim-up t)) + (re-search-backward org-drawer-regexp lim-up t)) (beginning-of-line)) ((and inlinetask-re (looking-at inlinetask-re)) (org-inlinetask-goto-beginning) @@ -547,11 +553,7 @@ Contexts `block' and `invalid' refer to `org-list-forbidden-blocks'." (lim-down (or (save-excursion (outline-next-heading)) (point-max)))) ;; Is point inside a drawer? (let ((end-re "^[ \t]*:END:") - ;; Can't use org-drawers-regexp as this function might - ;; be called in buffers not in Org mode. - (beg-re (concat "^[ \t]*:\\(" - (mapconcat #'regexp-quote org-drawers "\\|") - "\\):[ \t]*$"))) + (beg-re org-drawer-regexp)) (when (save-excursion (and (not (looking-at beg-re)) (not (looking-at end-re)) @@ -620,11 +622,11 @@ point-at-bol: will get the following structure: -\(\(1 0 \"- \" nil \"[X]\" nil 97\) - \(18 2 \"1. \" nil nil nil 34\) - \(34 2 \"5. \" \"5\" nil nil 55\) - \(97 0 \"- \" nil nil nil 131\) - \(109 2 \"+ \" nil nil \"tag\" 131\) + ((1 0 \"- \" nil \"[X]\" nil 97) + (18 2 \"1. \" nil nil nil 34) + (34 2 \"5. \" \"5\" nil nil 55) + (97 0 \"- \" nil nil nil 131) + (109 2 \"+ \" nil nil \"tag\" 131)) Assume point is at an item." (save-excursion @@ -635,9 +637,6 @@ Assume point is at an item." (lim-down (nth 1 context)) (text-min-ind 10000) (item-re (org-item-re)) - (drawers-re (concat "^[ \t]*:\\(" - (mapconcat #'regexp-quote org-drawers "\\|") - "\\):[ \t]*$")) (inlinetask-re (and (featurep 'org-inlinetask) (org-inlinetask-outline-regexp))) (beg-cell (cons (point) (org-get-indentation))) @@ -700,7 +699,7 @@ Assume point is at an item." ((and (looking-at "^[ \t]*#\\+end_") (re-search-backward "^[ \t]*#\\+begin_" lim-up t))) ((and (looking-at "^[ \t]*:END:") - (re-search-backward drawers-re lim-up t)) + (re-search-backward org-drawer-regexp lim-up t)) (beginning-of-line)) ((and inlinetask-re (looking-at inlinetask-re)) (org-inlinetask-goto-beginning) @@ -766,7 +765,7 @@ Assume point is at an item." (cond ((and (looking-at "^[ \t]*#\\+begin_") (re-search-forward "^[ \t]*#\\+end_" lim-down t))) - ((and (looking-at drawers-re) + ((and (looking-at org-drawer-regexp) (re-search-forward "^[ \t]*:END:" lim-down t)))) (forward-line 1)))))) (setq struct (append itm-lst (cdr (nreverse itm-lst-2))) @@ -1137,13 +1136,20 @@ This function modifies STRUCT." ;; Store overlays responsible for visibility status. We ;; also need to store their boundaries as they will be ;; removed from buffer. - (overlays (cons - (mapcar (lambda (ov) - (list ov (overlay-start ov) (overlay-end ov))) - (overlays-in beg-A end-A)) - (mapcar (lambda (ov) - (list ov (overlay-start ov) (overlay-end ov))) - (overlays-in beg-B end-B))))) + (overlays + (cons + (delq nil + (mapcar (lambda (o) + (and (>= (overlay-start o) beg-A) + (<= (overlay-end o) end-A) + (list o (overlay-start o) (overlay-end o)))) + (overlays-in beg-A end-A))) + (delq nil + (mapcar (lambda (o) + (and (>= (overlay-start o) beg-B) + (<= (overlay-end o) end-B) + (list o (overlay-start o) (overlay-end o)))) + (overlays-in beg-B end-B)))))) ;; 1. Move effectively items in buffer. (goto-char beg-A) (delete-region beg-A end-B-no-blank) @@ -1154,42 +1160,39 @@ This function modifies STRUCT." ;; as empty spaces are not moved there. In others words, ;; item BEG-A will end with whitespaces that were at the end ;; of BEG-B and the same applies to BEG-B. - (mapc (lambda (e) - (let ((pos (car e))) - (cond - ((< pos beg-A)) - ((memq pos sub-A) - (let ((end-e (nth 6 e))) - (setcar e (+ pos (- end-B-no-blank end-A-no-blank))) - (setcar (nthcdr 6 e) - (+ end-e (- end-B-no-blank end-A-no-blank))) - (when (= end-e end-A) (setcar (nthcdr 6 e) end-B)))) - ((memq pos sub-B) - (let ((end-e (nth 6 e))) - (setcar e (- (+ pos beg-A) beg-B)) - (setcar (nthcdr 6 e) (+ end-e (- beg-A beg-B))) - (when (= end-e end-B) - (setcar (nthcdr 6 e) - (+ beg-A size-B (- end-A end-A-no-blank)))))) - ((< pos beg-B) - (let ((end-e (nth 6 e))) - (setcar e (+ pos (- size-B size-A))) - (setcar (nthcdr 6 e) (+ end-e (- size-B size-A)))))))) - struct) - (setq struct (sort struct (lambda (e1 e2) (< (car e1) (car e2))))) + (dolist (e struct) + (let ((pos (car e))) + (cond + ((< pos beg-A)) + ((memq pos sub-A) + (let ((end-e (nth 6 e))) + (setcar e (+ pos (- end-B-no-blank end-A-no-blank))) + (setcar (nthcdr 6 e) + (+ end-e (- end-B-no-blank end-A-no-blank))) + (when (= end-e end-A) (setcar (nthcdr 6 e) end-B)))) + ((memq pos sub-B) + (let ((end-e (nth 6 e))) + (setcar e (- (+ pos beg-A) beg-B)) + (setcar (nthcdr 6 e) (+ end-e (- beg-A beg-B))) + (when (= end-e end-B) + (setcar (nthcdr 6 e) + (+ beg-A size-B (- end-A end-A-no-blank)))))) + ((< pos beg-B) + (let ((end-e (nth 6 e))) + (setcar e (+ pos (- size-B size-A))) + (setcar (nthcdr 6 e) (+ end-e (- size-B size-A)))))))) + (setq struct (sort struct #'car-less-than-car)) ;; Restore visibility status, by moving overlays to their new ;; position. - (mapc (lambda (ov) - (move-overlay - (car ov) - (+ (nth 1 ov) (- (+ beg-B (- size-B size-A)) beg-A)) - (+ (nth 2 ov) (- (+ beg-B (- size-B size-A)) beg-A)))) - (car overlays)) - (mapc (lambda (ov) - (move-overlay (car ov) - (+ (nth 1 ov) (- beg-A beg-B)) - (+ (nth 2 ov) (- beg-A beg-B)))) - (cdr overlays)) + (dolist (ov (car overlays)) + (move-overlay + (car ov) + (+ (nth 1 ov) (- (+ beg-B (- size-B size-A)) beg-A)) + (+ (nth 2 ov) (- (+ beg-B (- size-B size-A)) beg-A)))) + (dolist (ov (cdr overlays)) + (move-overlay (car ov) + (+ (nth 1 ov) (- beg-A beg-B)) + (+ (nth 2 ov) (- beg-A beg-B)))) ;; Return structure. struct))) @@ -1272,12 +1275,16 @@ This function modifies STRUCT." (beforep (progn (looking-at org-list-full-item-re) - ;; Do not count tag in a non-descriptive list. - (<= pos (if (and (match-beginning 4) - (save-match-data - (string-match "[.)]" (match-string 1)))) - (match-beginning 4) - (match-end 0))))) + (<= pos + (cond + ((not (match-beginning 4)) (match-end 0)) + ;; Ignore tag in a non-descriptive list. + ((save-match-data (string-match "[.)]" (match-string 1))) + (match-beginning 4)) + (t (save-excursion + (goto-char (match-end 4)) + (skip-chars-forward " \t") + (point))))))) (split-line-p (org-get-alist-option org-M-RET-may-split-line 'item)) (blank-nb (org-list-separating-blank-lines-number pos struct prevs)) @@ -1473,8 +1480,10 @@ This function returns, destructively, the new list structure." (point-at-eol))))) (t dest))) (org-M-RET-may-split-line nil) - ;; Store visibility. - (visibility (overlays-in item item-end))) + ;; Store inner overlays (to preserve visibility). + (overlays (org-remove-if (lambda (o) (or (< (overlay-start o) item) + (> (overlay-end o) item))) + (overlays-in item item-end)))) (cond ((eq dest 'delete) (org-list-delete-item item struct)) ((eq dest 'kill) @@ -1509,13 +1518,12 @@ This function returns, destructively, the new list structure." new-end (+ end shift))))))) moved-items)) - (lambda (e1 e2) (< (car e1) (car e2)))))) - ;; 2. Restore visibility. - (mapc (lambda (ov) - (move-overlay ov - (+ (overlay-start ov) (- (point) item)) - (+ (overlay-end ov) (- (point) item)))) - visibility) + #'car-less-than-car))) + ;; 2. Restore inner overlays. + (dolist (o overlays) + (move-overlay o + (+ (overlay-start o) (- (point) item)) + (+ (overlay-end o) (- (point) item)))) ;; 3. Eventually delete extra copy of the item and clean marker. (prog1 (org-list-delete-item (marker-position item) struct) (move-marker item nil))) @@ -1861,10 +1869,9 @@ Initial position of cursor is restored after the changes." (item-re (org-item-re)) (shift-body-ind (function - ;; Shift the indentation between END and BEG by DELTA. If - ;; MAX-IND is non-nil, ensure that no line will be indented - ;; more than that number. Start from the line before END. - (lambda (end beg delta max-ind) + ;; Shift the indentation between END and BEG by DELTA. + ;; Start from the line before END. + (lambda (end beg delta) (goto-char end) (skip-chars-backward " \r\t\n") (beginning-of-line) @@ -1877,9 +1884,7 @@ Initial position of cursor is restored after the changes." (org-inlinetask-goto-beginning)) ;; Shift only non-empty lines. ((org-looking-at-p "^[ \t]*\\S-") - (let ((i (org-get-indentation))) - (org-indent-line-to - (if max-ind (min (+ i delta) max-ind) (+ i delta)))))) + (org-indent-line-to (+ (org-get-indentation) delta)))) (forward-line -1))))) (modify-item (function @@ -1934,37 +1939,53 @@ Initial position of cursor is restored after the changes." ;; belongs to: it is the last item (ITEM-UP), whose ;; ending is further than the position we're ;; interested in. - (let ((item-up (assoc-default end-pos acc-end '>))) + (let ((item-up (assoc-default end-pos acc-end #'>))) (push (cons end-pos item-up) end-list))) (push (cons end-pos pos) acc-end))) ;; 2. Slice the items into parts that should be shifted by the ;; same amount of indentation. Each slice follow the pattern - ;; (END BEG DELTA MAX-IND-OR-NIL). Slices are returned in - ;; reverse order. + ;; (END BEG DELTA). Slices are returned in reverse order. (setq all-ends (sort (append (mapcar #'car itm-shift) (org-uniquify (mapcar #'car end-list))) - '<)) + #'<) + acc-end (nreverse acc-end)) (while (cdr all-ends) (let* ((up (pop all-ends)) (down (car all-ends)) (itemp (assq up struct)) - (item (if itemp up (cdr (assq up end-list)))) - (ind (cdr (assq item itm-shift))) - ;; If we're not at an item, there's a child of the item - ;; point belongs to above. Make sure this slice isn't - ;; moved within that child by specifying a maximum - ;; indentation. - (max-ind (and (not itemp) - (+ (org-list-get-ind item struct) - (length (org-list-get-bullet item struct)) - org-list-indent-offset)))) - (push (list down up ind max-ind) sliced-struct))) + (delta + (if itemp (cdr (assq up itm-shift)) + ;; If we're not at an item, there's a child of the + ;; item point belongs to above. Make sure the less + ;; indented line in this slice has the same column + ;; as that child. + (let* ((child (cdr (assq up acc-end))) + (ind (org-list-get-ind child struct)) + (min-ind most-positive-fixnum)) + (save-excursion + (goto-char up) + (while (< (point) down) + ;; Ignore empty lines. Also ignore blocks and + ;; drawers contents. + (unless (org-looking-at-p "[ \t]*$") + (setq min-ind (min (org-get-indentation) min-ind)) + (cond + ((and (looking-at "#\\+BEGIN\\(:\\|_\\S-+\\)") + (re-search-forward + (format "^[ \t]*#\\+END%s[ \t]*$" + (match-string 1)) + down t))) + ((and (looking-at org-drawer-regexp) + (re-search-forward "^[ \t]*:END:[ \t]*$" + down t))))) + (forward-line))) + (- ind min-ind))))) + (push (list down up delta) sliced-struct))) ;; 3. Shift each slice in buffer, provided delta isn't 0, from ;; end to beginning. Take a special action when beginning is ;; at item bullet. (dolist (e sliced-struct) - (unless (and (zerop (nth 2 e)) (not (nth 3 e))) - (apply shift-body-ind e)) + (unless (zerop (nth 2 e)) (apply shift-body-ind e)) (let* ((beg (nth 1 e)) (cell (assq beg struct))) (unless (or (not cell) (equal cell (assq beg old-struct))) @@ -2015,7 +2036,7 @@ previous item, plus ARGS extra arguments. FUNCTION is applied on items in reverse order. -As an example, \(org-apply-on-list \(lambda \(result\) \(1+ result\)\) 0\) +As an example, \(org-apply-on-list \(lambda \(result) \(1+ result)) 0) will return the number of items in the current list. Sublists of the list are skipped. Cursor is always at the @@ -2060,16 +2081,19 @@ Possible values are: `folded', `children' or `subtree'. See (defun org-list-item-body-column (item) "Return column at which body of ITEM should start." - (let (bpos bcol tpos tcol) - (save-excursion - (goto-char item) - (looking-at "[ \t]*\\(\\S-+\\)\\(.*[ \t]+::\\)?\\([ \t]+\\|$\\)") - (setq bpos (match-beginning 1) tpos (match-end 0) - bcol (progn (goto-char bpos) (current-column)) - tcol (progn (goto-char tpos) (current-column))) - (when (> tcol (+ bcol org-description-max-indent)) - (setq tcol (+ bcol 5)))) - tcol)) + (save-excursion + (goto-char item) + (looking-at "[ \t]*\\(\\S-+\\)\\(.*[ \t]+::\\)?\\([ \t]+\\|$\\)") + (if (match-beginning 2) + (let ((start (1+ (match-end 2))) + (ind (org-get-indentation))) + (if (> start (+ ind org-description-max-indent)) (+ ind 5) start)) + (+ (progn (goto-char (match-end 1)) (current-column)) + (if (and org-list-two-spaces-after-bullet-regexp + (org-string-match-p org-list-two-spaces-after-bullet-regexp + (match-string 1))) + 2 + 1))))) @@ -2325,9 +2349,6 @@ in subtree, ignoring drawers." block-item lim-up lim-down - (drawer-re (concat "^[ \t]*:\\(" - (mapconcat #'regexp-quote org-drawers "\\|") - "\\):[ \t]*$")) (keyword-re (concat "^[ \t]*\\<\\(" org-scheduled-string "\\|" org-deadline-string "\\|" org-closed-string @@ -2349,7 +2370,8 @@ in subtree, ignoring drawers." ;; time-stamps (scheduled, etc.). (let ((limit (save-excursion (outline-next-heading) (point)))) (forward-line 1) - (while (or (looking-at drawer-re) (looking-at keyword-re)) + (while (or (looking-at org-drawer-regexp) + (looking-at keyword-re)) (if (looking-at keyword-re) (forward-line 1) (re-search-forward "^[ \t]*:END:" limit nil))) @@ -2439,130 +2461,129 @@ in subtree, ignoring drawers." (defun org-update-checkbox-count (&optional all) "Update the checkbox statistics in the current section. + This will find all statistic cookies like [57%] and [6/12] and update them with the current numbers. With optional prefix argument ALL, do this for the whole buffer." (interactive "P") - (save-excursion - (let ((cookie-re "\\(\\(\\[[0-9]*%\\]\\)\\|\\(\\[[0-9]*/[0-9]*\\]\\)\\)") - (box-re "^[ \t]*\\([-+*]\\|\\([0-9]+\\|[A-Za-z]\\)[.)]\\)[ \t]+\\(?:\\[@\\(?:start:\\)?\\([0-9]+\\|[A-Za-z]\\)\\][ \t]*\\)?\\(\\[[- X]\\]\\)") + (org-with-wide-buffer + (let* ((cookie-re "\\(\\(\\[[0-9]*%\\]\\)\\|\\(\\[[0-9]*/[0-9]*\\]\\)\\)") + (box-re "^[ \t]*\\([-+*]\\|\\([0-9]+\\|[A-Za-z]\\)[.)]\\)[ \t]+\ +\\(?:\\[@\\(?:start:\\)?\\([0-9]+\\|[A-Za-z]\\)\\][ \t]*\\)?\\(\\[[- X]\\]\\)") (recursivep (or (not org-checkbox-hierarchical-statistics) (string-match "\\" (or (org-entry-get nil "COOKIE_DATA") "")))) - (bounds (if all - (cons (point-min) (point-max)) - (cons (or (ignore-errors (org-back-to-heading t) (point)) - (point-min)) - (save-excursion (outline-next-heading) (point))))) + (within-inlinetask (and (not all) + (featurep 'org-inlinetask) + (org-inlinetask-in-task-p))) + (end (cond (all (point-max)) + (within-inlinetask + (save-excursion (outline-next-heading) (point))) + (t (save-excursion + (org-with-limited-levels (outline-next-heading)) + (point))))) (count-boxes - (function - ;; Return number of checked boxes and boxes of all types - ;; in all structures in STRUCTS. If RECURSIVEP is - ;; non-nil, also count boxes in sub-lists. If ITEM is - ;; nil, count across the whole structure, else count only - ;; across subtree whose ancestor is ITEM. - (lambda (item structs recursivep) - (let ((c-on 0) (c-all 0)) - (mapc - (lambda (s) - (let* ((pre (org-list-prevs-alist s)) - (par (org-list-parents-alist s)) - (items - (cond - ((and recursivep item) (org-list-get-subtree item s)) - (recursivep (mapcar #'car s)) - (item (org-list-get-children item s par)) - (t (org-list-get-all-items - (org-list-get-top-point s) s pre)))) - (cookies (delq nil (mapcar - (lambda (e) - (org-list-get-checkbox e s)) - items)))) - (setq c-all (+ (length cookies) c-all) - c-on (+ (org-count "[X]" cookies) c-on)))) - structs) - (cons c-on c-all))))) - (backup-end 1) - cookies-list structs-bak) - (goto-char (car bounds)) - ;; 1. Build an alist for each cookie found within BOUNDS. The - ;; key will be position at beginning of cookie and values - ;; ending position, format of cookie, and a cell whose car is - ;; number of checked boxes to report, and cdr total number of - ;; boxes. - (while (re-search-forward cookie-re (cdr bounds) t) - (catch 'skip - (save-excursion - (push - (list - (match-beginning 1) ; cookie start - (match-end 1) ; cookie end - (match-string 2) ; percent? - (cond ; boxes count - ;; Cookie is at an heading, but specifically for todo, - ;; not for checkboxes: skip it. - ((and (org-at-heading-p) - (string-match "\\" - (downcase - (or (org-entry-get nil "COOKIE_DATA") "")))) - (throw 'skip nil)) - ;; Cookie is at an heading, but all lists before next - ;; heading already have been read. Use data collected - ;; in STRUCTS-BAK. This should only happen when - ;; heading has more than one cookie on it. - ((and (org-at-heading-p) - (<= (save-excursion (outline-next-heading) (point)) - backup-end)) - (funcall count-boxes nil structs-bak recursivep)) - ;; Cookie is at a fresh heading. Grab structure of - ;; every list containing a checkbox between point and - ;; next headline, and save them in STRUCTS-BAK. - ((org-at-heading-p) - (setq backup-end (save-excursion - (outline-next-heading) (point)) - structs-bak nil) - (while (org-list-search-forward box-re backup-end 'move) - (let* ((struct (org-list-struct)) - (bottom (org-list-get-bottom-point struct))) - (push struct structs-bak) - (goto-char bottom))) - (funcall count-boxes nil structs-bak recursivep)) - ;; Cookie is at an item, and we already have list - ;; structure stored in STRUCTS-BAK. - ((and (org-at-item-p) - (< (point-at-bol) backup-end) - ;; Only lists in no special context are stored. - (not (nth 2 (org-list-context)))) - (funcall count-boxes (point-at-bol) structs-bak recursivep)) - ;; Cookie is at an item, but we need to compute list - ;; structure. - ((org-at-item-p) - (let ((struct (org-list-struct))) - (setq backup-end (org-list-get-bottom-point struct) - structs-bak (list struct))) - (funcall count-boxes (point-at-bol) structs-bak recursivep)) - ;; Else, cookie found is at a wrong place. Skip it. - (t (throw 'skip nil)))) - cookies-list)))) - ;; 2. Apply alist to buffer, in reverse order so positions stay - ;; unchanged after cookie modifications. - (mapc (lambda (cookie) - (let* ((beg (car cookie)) - (end (nth 1 cookie)) - (percentp (nth 2 cookie)) - (checked (car (nth 3 cookie))) - (total (cdr (nth 3 cookie))) - (new (if percentp - (format "[%d%%]" (/ (* 100 checked) - (max 1 total))) - (format "[%d/%d]" checked total)))) - (goto-char beg) - (insert new) - (delete-region (point) (+ (point) (- end beg))) - (when org-auto-align-tags (org-fix-tags-on-the-fly)))) + (lambda (item structs recursivep) + ;; Return number of checked boxes and boxes of all types + ;; in all structures in STRUCTS. If RECURSIVEP is + ;; non-nil, also count boxes in sub-lists. If ITEM is + ;; nil, count across the whole structure, else count only + ;; across subtree whose ancestor is ITEM. + (let ((c-on 0) (c-all 0)) + (dolist (s structs (list c-on c-all)) + (let* ((pre (org-list-prevs-alist s)) + (par (org-list-parents-alist s)) + (items + (cond + ((and recursivep item) (org-list-get-subtree item s)) + (recursivep (mapcar #'car s)) + (item (org-list-get-children item s par)) + (t (org-list-get-all-items + (org-list-get-top-point s) s pre)))) + (cookies (delq nil (mapcar + (lambda (e) + (org-list-get-checkbox e s)) + items)))) + (incf c-all (length cookies)) + (incf c-on (org-count "[X]" cookies))))))) + cookies-list cache) + ;; Move to start. + (cond (all (goto-char (point-min))) + (within-inlinetask (org-back-to-heading t)) + (t (org-with-limited-levels (outline-previous-heading)))) + ;; Build an alist for each cookie found. The key is the position + ;; at beginning of cookie and values ending position, format of + ;; cookie, number of checked boxes to report and total number of + ;; boxes. + (while (re-search-forward cookie-re end t) + (let ((context (save-excursion (backward-char) + (save-match-data (org-element-context))))) + (when (eq (org-element-type context) 'statistics-cookie) + (push + (append + (list (match-beginning 1) (match-end 1) (match-end 2)) + (let* ((container + (org-element-lineage + context + '(drawer center-block dynamic-block inlinetask item + quote-block special-block verse-block))) + (beg (if container + (org-element-property :contents-begin container) + (save-excursion + (org-with-limited-levels + (outline-previous-heading)) + (point))))) + (or (cdr (assq beg cache)) + (save-excursion + (goto-char beg) + (let ((end + (if container + (org-element-property :contents-end container) + (save-excursion + (org-with-limited-levels (outline-next-heading)) + (point)))) + structs) + (while (re-search-forward box-re end t) + (let ((element (org-element-at-point))) + (when (eq (org-element-type element) 'item) + (push (org-element-property :structure element) + structs) + ;; Skip whole list since we have its + ;; structure anyway. + (while (setq element (org-element-lineage + element '(plain-list))) + (goto-char + (min (org-element-property :end element) + end)))))) + ;; Cache count for cookies applying to the same + ;; area. Then return it. + (let ((count + (funcall count-boxes + (and (eq (org-element-type container) + 'item) + (org-element-property + :begin container)) + structs + recursivep))) + (push (cons beg count) cache) + count)))))) cookies-list)))) + ;; Apply alist to buffer. + (dolist (cookie cookies-list) + (let* ((beg (car cookie)) + (end (nth 1 cookie)) + (percent (nth 2 cookie)) + (checked (nth 3 cookie)) + (total (nth 4 cookie))) + (goto-char beg) + (insert + (if percent (format "[%d%%]" (floor (* 100.0 checked) + (max 1 total))) + (format "[%d/%d]" checked total))) + (delete-region (point) (+ (point) (- end beg))) + (when org-auto-align-tags (org-fix-tags-on-the-fly))))))) (defun org-get-checkbox-statistics-face () "Select the face for checkbox statistics. @@ -2931,13 +2952,13 @@ For example, the following list: will be parsed as: -\(ordered - \(nil \"first item\" - \(unordered - \(nil \"sub-item one\"\) - \(nil \"[CBON] sub-item two\"\)\) - \"more text in first item\"\) - \(3 \"last item\"\)\) + (ordered + (nil \"first item\" + (unordered + (nil \"sub-item one\") + (nil \"[CBON] sub-item two\")) + \"more text in first item\") + (3 \"last item\")) Point is left at list end." (defvar parse-item) ;FIXME: Or use `cl-labels' or `letrec'. @@ -3056,7 +3077,7 @@ for this list." (unless (org-at-item-p) (error "Not at a list item")) (save-excursion (re-search-backward "#\\+ORGLST" nil t) - (unless (looking-at "#\\+ORGLST:[ \t]+SEND[ \t]+\\(\\S-+\\)[ \t]+\\(\\S-+\\)") + (unless (looking-at "\\(?:[ \t]\\)?#\\+ORGLST:[ \t]+SEND[ \t]+\\(\\S-+\\)[ \t]+\\(\\S-+\\)") (if maybe (throw 'exit nil) (error "Don't know how to transform this list")))) (let* ((name (match-string 1)) @@ -3196,13 +3217,13 @@ items." (when nobr (setq first (org-list-item-trim-br first))) ;; Insert descriptive term if TYPE is `descriptive'. (when (eq type 'descriptive) - (let* ((complete (string-match "^\\(.*\\)[ \t]+::" first)) + (let* ((complete + (string-match "^\\(.*\\)[ \t]+::[ \t]*" first)) (term (if complete (save-match-data (org-trim (match-string 1 first))) "???")) - (desc (if complete - (org-trim (substring first (match-end 0))) + (desc (if complete (substring first (match-end 0)) first))) (setq first (concat (eval dtstart) term (eval dtend) (eval ddstart) desc)))) diff --git a/elpa/org-20150629/org-loaddefs.el b/elpa/org-20160215/org-loaddefs.el similarity index 86% rename from elpa/org-20150629/org-loaddefs.el rename to elpa/org-20160215/org-loaddefs.el index 02e939a3..f6a7dd82 100644 --- a/elpa/org-20150629/org-loaddefs.el +++ b/elpa/org-20160215/org-loaddefs.el @@ -8,13 +8,13 @@ ;;;;;; org-babel-sha1-hash org-babel-execute-subtree org-babel-execute-buffer ;;;;;; org-babel-map-executables org-babel-map-call-lines org-babel-map-inline-src-blocks ;;;;;; org-babel-map-src-blocks org-babel-open-src-block-result -;;;;;; org-babel-switch-to-session-with-code org-babel-switch-to-session -;;;;;; org-babel-initiate-session org-babel-load-in-session org-babel-insert-header-arg -;;;;;; org-babel-check-src-block org-babel-expand-src-block org-babel-execute-src-block -;;;;;; org-babel-pop-to-session-maybe org-babel-load-in-session-maybe -;;;;;; org-babel-expand-src-block-maybe org-babel-view-src-block-info -;;;;;; org-babel-execute-maybe org-babel-execute-safely-maybe) "ob-core" -;;;;;; "ob-core.el" "09a8853df17caadea177348cda6471b9") +;;;;;; org-babel-do-in-edit-buffer org-babel-switch-to-session-with-code +;;;;;; org-babel-switch-to-session org-babel-initiate-session org-babel-load-in-session +;;;;;; org-babel-insert-header-arg org-babel-check-src-block org-babel-expand-src-block +;;;;;; org-babel-execute-src-block org-babel-pop-to-session-maybe +;;;;;; org-babel-load-in-session-maybe org-babel-expand-src-block-maybe +;;;;;; org-babel-view-src-block-info org-babel-execute-maybe org-babel-execute-safely-maybe) +;;;;;; "ob-core" "ob-core.el" "ee83b8920bd29f8ac10c08e0b4271f48") ;;; Generated autoloads from ob-core.el (autoload 'org-babel-execute-safely-maybe "ob-core" "\ @@ -78,7 +78,7 @@ Expand the current source code block. Expand according to the source code block's header arguments and pop open the results in a preview buffer. -\(fn &optional ARG INFO PARAMS)" t nil) +\(fn &optional _ARG INFO PARAMS)" t nil) (autoload 'org-babel-check-src-block "ob-core" "\ Check for misspelled header arguments in the current code block. @@ -88,7 +88,7 @@ Check for misspelled header arguments in the current code block. (autoload 'org-babel-insert-header-arg "ob-core" "\ Insert a header argument selecting from lists of common args and values. -\(fn)" t nil) +\(fn &optional HEADER-ARG VALUE)" t nil) (autoload 'org-babel-load-in-session "ob-core" "\ Load the body of the current source-code block. @@ -96,7 +96,7 @@ Evaluate the header arguments for the source block before entering the session. After loading the body this pops open the session. -\(fn &optional ARG INFO)" t nil) +\(fn &optional _ARG INFO)" t nil) (autoload 'org-babel-initiate-session "ob-core" "\ Initiate session for current code block. @@ -117,7 +117,13 @@ with a prefix argument then this is passed on to (autoload 'org-babel-switch-to-session-with-code "ob-core" "\ Switch to code buffer and display session. -\(fn &optional ARG INFO)" t nil) +\(fn &optional ARG _INFO)" t nil) + +(autoload 'org-babel-do-in-edit-buffer "ob-core" "\ +Evaluate BODY in edit buffer if there is a code block at point. +Return t if a code block was found at point, nil otherwise. + +\(fn &rest BODY)" nil (quote macro)) (autoload 'org-babel-open-src-block-result "ob-core" "\ If `point' is on a src block then open the results of the @@ -229,7 +235,7 @@ Mark current src block. ;;;*** ;;;### (autoloads (org-babel-describe-bindings) "ob-keys" "ob-keys.el" -;;;;;; "25a1e7a65f088c34d9576789abaaebc6") +;;;;;; "24762aeb15b93f86ba40d1649d47134a") ;;; Generated autoloads from ob-keys.el (autoload 'org-babel-describe-bindings "ob-keys" "\ @@ -240,7 +246,7 @@ Describe all keybindings behind `org-babel-key-prefix'. ;;;*** ;;;### (autoloads (org-babel-lob-get-info org-babel-lob-execute-maybe) -;;;;;; "ob-lob" "ob-lob.el" "6452edf7fff14c5ebb5c1cece08ba833") +;;;;;; "ob-lob" "ob-lob.el" "642d1791b061066c54b8ff95e332f856") ;;; Generated autoloads from ob-lob.el (autoload 'org-babel-lob-execute-maybe "ob-lob" "\ @@ -258,7 +264,7 @@ Return a Library of Babel function call as a string. ;;;*** ;;;### (autoloads (org-babel-tangle org-babel-tangle-file) "ob-tangle" -;;;;;; "ob-tangle.el" "1fc39a5a416a66ab63a506ccc0a122ff") +;;;;;; "ob-tangle.el" "3ba1e4bcd6d4b3c9293130baa1e76017") ;;; Generated autoloads from ob-tangle.el (autoload 'org-babel-tangle-file "ob-tangle" "\ @@ -292,7 +298,7 @@ used to limit the exported source code blocks by language. ;;;;;; org-search-view org-agenda-list org-batch-store-agenda-views ;;;;;; org-store-agenda-views org-batch-agenda-csv org-batch-agenda ;;;;;; org-agenda org-toggle-sticky-agenda) "org-agenda" "org-agenda.el" -;;;;;; (21903 33206)) +;;;;;; (22194 60218)) ;;; Generated autoloads from org-agenda.el (autoload 'org-toggle-sticky-agenda "org-agenda" "\ @@ -517,7 +523,7 @@ Do we have a reason to ignore this TODO entry because it has a time stamp? (autoload 'org-agenda-set-restriction-lock "org-agenda" "\ Set restriction lock for agenda, to current subtree or file. Restriction will be the file if TYPE is `file', or if type is the -universal prefix '(4), or if the cursor is before the first headline +universal prefix \\='(4), or if the cursor is before the first headline in the file. Otherwise, restriction will be to the current subtree. \(fn &optional TYPE)" t nil) @@ -544,9 +550,9 @@ calling the function returns nil. This function takes one argument: an entry from `org-agenda-get-day-entries'. FILTER can also be an alist with the car of each cell being -either 'headline or 'category. For example: +either `headline' or `category'. For example: - '((headline \"IMPORTANT\") + \\='((headline \"IMPORTANT\") (category \"Work\")) will only add headlines containing IMPORTANT or headlines @@ -568,7 +574,7 @@ to override `appt-message-warning-time'. ;;;### (autoloads (org-archive-subtree-default-with-confirmation ;;;;;; org-archive-subtree-default org-toggle-archive-tag org-archive-to-archive-sibling ;;;;;; org-archive-subtree org-add-archive-files) "org-archive" -;;;;;; "org-archive.el" "9a54b246691497eb10c911c2c12f9742") +;;;;;; "org-archive.el" "49615e9b6aa6314b77b090b118280556") ;;; Generated autoloads from org-archive.el (autoload 'org-add-archive-files "org-archive" "\ @@ -584,9 +590,11 @@ The archive can be a certain top-level heading in the current file, or in a different file. The tree will be moved to that location, the subtree heading be marked DONE, and the current time will be added. -When called with prefix argument FIND-DONE, find whole trees without any +When called with a single prefix argument FIND-DONE, find whole trees without any open TODO items and archive them (after getting confirmation from the user). -If the cursor is not at a headline when this command is called, try all level +When called with a double prefix argument, find whole trees with timestamps before +today and archive them (after getting confirmation from the user). +If the cursor is not at a headline when these commands are called, try all level 1 trees. If the cursor is on a headline, only try the direct children of this heading. @@ -621,7 +629,7 @@ This command is set with the variable `org-archive-default-command'. ;;;*** -;;;### (autoloads (org-attach) "org-attach" "org-attach.el" "5ca6eaa6ba7fa7c7eddc8d339f2a2170") +;;;### (autoloads (org-attach) "org-attach" "org-attach.el" "1e4c1afefe41ea28817861da7ea71ce6") ;;; Generated autoloads from org-attach.el (autoload 'org-attach "org-attach" "\ @@ -633,7 +641,7 @@ Shows a list of commands and prompts for another key to execute a command. ;;;*** ;;;### (autoloads (org-bbdb-anniversaries) "org-bbdb" "org-bbdb.el" -;;;;;; "5fed335fd36cec704d37da4b5f5d54a7") +;;;;;; "e782f707a5a0d3b8a8fd76825deb4111") ;;; Generated autoloads from org-bbdb.el (autoload 'org-bbdb-anniversaries "org-bbdb" "\ @@ -644,8 +652,8 @@ Extract anniversaries from BBDB for display in the agenda. ;;;*** ;;;### (autoloads (org-capture-import-remember-templates org-capture -;;;;;; org-capture-string) "org-capture" "org-capture.el" (21903 -;;;;;; 33206)) +;;;;;; org-capture-string) "org-capture" "org-capture.el" (22200 +;;;;;; 12002)) ;;; Generated autoloads from org-capture.el (autoload 'org-capture-string "org-capture" "\ @@ -692,7 +700,7 @@ Set `org-capture-templates' to be similar to `org-remember-templates'. ;;;;;; org-clock-remove-overlays org-clock-display org-clock-sum ;;;;;; org-clock-goto org-clock-cancel org-clock-out org-clock-in-last ;;;;;; org-clock-in org-resolve-clocks) "org-clock" "org-clock.el" -;;;;;; "4e11691598cd014eca5924ab851f839f") +;;;;;; "133b6d837d46606bf3b4f1753035bca8") ;;; Generated autoloads from org-clock.el (autoload 'org-resolve-clocks "org-clock" "\ @@ -756,16 +764,20 @@ each headline in the time range with point at the headline. Headlines for which HEADLINE-FILTER returns nil are excluded from the clock summation. PROPNAME lets you set a custom text property instead of :org-clock-minutes. -\(fn &optional TSTART TEND HEADLINE-FILTER PROPNAME)" t nil) +\(fn &optional TSTART TEND HEADLINE-FILTER PROPNAME)" nil nil) (autoload 'org-clock-display "org-clock" "\ Show subtree times in the entire buffer. -If TOTAL-ONLY is non-nil, only show the total time for the entire file -in the echo area. + +By default, show the total time for the range defined in +`org-clock-display-default-range'. With \\[universal-argument] prefix, show +the total time for today instead. With \\[universal-argument] \\[universal-argument] prefix, use +a custom range, entered at the prompt. With \\[universal-argument] \\[universal-argument] \\[universal-argument] +prefix, display the total time in the echo area. Use \\[org-clock-remove-overlays] to remove the subtree times. -\(fn &optional TOTAL-ONLY)" t nil) +\(fn &optional ARG)" t nil) (autoload 'org-clock-remove-overlays "org-clock" "\ Remove the occur highlights from the buffer. @@ -821,7 +833,7 @@ Otherwise, return nil. ;;;### (autoloads (org-agenda-columns org-insert-columns-dblock org-dblock-write:columnview ;;;;;; org-columns-number-to-string org-columns-compute org-columns ;;;;;; org-columns-get-format-and-top-level org-columns-remove-overlays) -;;;;;; "org-colview" "org-colview.el" (21903 33206)) +;;;;;; "org-colview" "org-colview.el" (22176 30266)) ;;; Generated autoloads from org-colview.el (autoload 'org-columns-remove-overlays "org-colview" "\ @@ -885,7 +897,7 @@ Turn on or update column view in the agenda. ;;;*** ;;;### (autoloads (org-check-version) "org-compat" "org-compat.el" -;;;;;; (21903 33206)) +;;;;;; (22193 39354)) ;;; Generated autoloads from org-compat.el (autoload 'org-check-version "org-compat" "\ @@ -896,7 +908,7 @@ Try very hard to provide sensible version strings. ;;;*** ;;;### (autoloads (org-datetree-find-date-create) "org-datetree" -;;;;;; "org-datetree.el" "448ccbc2749a60a5e276fc3c9a9c5605") +;;;;;; "org-datetree.el" "b568067e20b64b5dcfc50d0fe986fb9f") ;;; Generated autoloads from org-datetree.el (autoload 'org-datetree-find-date-create "org-datetree" "\ @@ -909,22 +921,34 @@ tree can be found. ;;;*** -;;;### (autoloads (org-element-context org-element-at-point org-element-interpret-data) -;;;;;; "org-element" "org-element.el" "e30bb4fe00f0e82056941112ae076340") +;;;### (autoloads (org-element-context org-element-at-point org-element-cache-refresh +;;;;;; org-element-cache-reset org-element-interpret-data org-element-update-syntax) +;;;;;; "org-element" "org-element.el" "54a3a77d31b0c99c7ce9827c94b05491") ;;; Generated autoloads from org-element.el +(autoload 'org-element-update-syntax "org-element" "\ +Update parser internals. + +\(fn)" t nil) + (autoload 'org-element-interpret-data "org-element" "\ Interpret DATA as Org syntax. - DATA is a parse tree, an element, an object or a secondary string -to interpret. +to interpret. Return Org syntax as a string. -Optional argument PARENT is used for recursive calls. It contains -the element or object containing data, or nil. +\(fn DATA)" nil nil) -Return Org syntax as a string. +(autoload 'org-element-cache-reset "org-element" "\ +Reset cache in current buffer. +When optional argument ALL is non-nil, reset cache in all Org +buffers. -\(fn DATA &optional PARENT)" nil nil) +\(fn &optional ALL)" t nil) + +(autoload 'org-element-cache-refresh "org-element" "\ +Refresh cache at position POS. + +\(fn POS)" nil nil) (autoload 'org-element-at-point "org-element" "\ Determine closest element around point. @@ -937,22 +961,19 @@ Possible types are defined in `org-element-all-elements'. Properties depend on element or object type, but always include `:begin', `:end', `:parent' and `:post-blank' properties. -As a special case, if point is at the very beginning of a list or -sub-list, returned element will be that list instead of the first -item. In the same way, if point is at the beginning of the first -row of a table, returned element will be the table instead of the -first row. +As a special case, if point is at the very beginning of the first +item in a list or sub-list, returned element will be that list +instead of the item. Likewise, if point is at the beginning of +the first row of a table, returned element will be the table +instead of the first row. -If optional argument KEEP-TRAIL is non-nil, the function returns -a list of elements leading to element at point. The list's CAR -is always the element at point. The following positions contain -element's siblings, then parents, siblings of parents, until the -first element of current section. +When point is at the end of the buffer, return the innermost +element ending there. -\(fn &optional KEEP-TRAIL)" nil nil) +\(fn)" nil nil) (autoload 'org-element-context "org-element" "\ -Return closest element or object around point. +Return smallest element or object around point. Return value is a list like (TYPE PROPS) where TYPE is the type of the element or object and PROPS a plist of properties @@ -963,6 +984,9 @@ Possible types are defined in `org-element-all-elements' and object type, but always include `:begin', `:end', `:parent' and `:post-blank'. +As a special case, if point is right after an object and not at +the beginning of any other object, return that object. + Optional argument ELEMENT, when non-nil, is the closest element containing point, as returned by `org-element-at-point'. Providing it allows for quicker computation. @@ -972,7 +996,7 @@ Providing it allows for quicker computation. ;;;*** ;;;### (autoloads (org-feed-show-raw-feed org-feed-goto-inbox org-feed-update -;;;;;; org-feed-update-all) "org-feed" "org-feed.el" "d29a33e181e81cddc70543c0ba8fdbe4") +;;;;;; org-feed-update-all) "org-feed" "org-feed.el" "d0f9ed4388a963a1ef1623799a68a0f0") ;;; Generated autoloads from org-feed.el (autoload 'org-feed-update-all "org-feed" "\ @@ -1000,7 +1024,7 @@ Show the raw feed buffer of a feed. ;;;*** ;;;### (autoloads (org-footnote-normalize org-footnote-action) "org-footnote" -;;;;;; "org-footnote.el" "9906c2a4ea425a7c96d7c1371b2e35f9") +;;;;;; "org-footnote.el" "9ceecddca334b14eed8100670d00bb8f") ;;; Generated autoloads from org-footnote.el (autoload 'org-footnote-action "org-footnote" "\ @@ -1012,9 +1036,10 @@ When at a definition, jump to the references if they exist, offer to create them otherwise. When neither at definition or reference, create a new footnote, -interactively. +interactively if possible. -With prefix arg SPECIAL, offer additional commands in a menu. +With prefix arg SPECIAL, or when no footnote can be created, +offer additional commands in a menu. \(fn &optional SPECIAL)" t nil) @@ -1034,7 +1059,7 @@ referenced sequence. ;;;### (autoloads (org-id-store-link org-id-find-id-file org-id-update-id-locations ;;;;;; org-id-new org-id-find org-id-goto org-id-get-with-outline-drilling ;;;;;; org-id-get-with-outline-path-completion org-id-get org-id-copy -;;;;;; org-id-get-create) "org-id" "org-id.el" "82e762bd5cca2e3d24252745fca306d7") +;;;;;; org-id-get-create) "org-id" "org-id.el" "aa9a9a641f5d77fb14a6ac89b1831168") ;;; Generated autoloads from org-id.el (autoload 'org-id-get-create "org-id" "\ @@ -1128,7 +1153,7 @@ Store a link to the current entry, using its ID. ;;;*** ;;;### (autoloads (org-indent-mode) "org-indent" "org-indent.el" -;;;;;; "3d658901e4f096f04688498e4a709eb5") +;;;;;; "da988e2c3b7826ad167376bcfd481df9") ;;; Generated autoloads from org-indent.el (autoload 'org-indent-mode "org-indent" "\ @@ -1145,7 +1170,7 @@ during idle time. ;;;*** -;;;### (autoloads (org-irc-store-link) "org-irc" "org-irc.el" "2432d5cd8271c05b0e8778cd26bf11ab") +;;;### (autoloads (org-irc-store-link) "org-irc" "org-irc.el" "844cf138fe188afd472820c355b395ae") ;;; Generated autoloads from org-irc.el (autoload 'org-irc-store-link "org-irc" "\ @@ -1153,10 +1178,26 @@ Dispatch to the appropriate function to store a link to an IRC session. \(fn)" nil nil) +;;;*** + +;;;### (autoloads (org-lint) "org-lint" "org-lint.el" (22106 38585)) +;;; Generated autoloads from org-lint.el + +(autoload 'org-lint "org-lint" "\ +Check current Org buffer for syntax mistakes. + +By default, run all checkers. With a single prefix ARG \\[universal-argument], +select one category of checkers only. With a double prefix +\\[universal-argument] \\[universal-argument], select one precise checker by its name. + +ARG can also be a list of checker names, as symbols, to run. + +\(fn &optional ARG)" t nil) + ;;;*** ;;;### (autoloads (org-load-noerror-mustsuffix) "org-macs" "org-macs.el" -;;;;;; (21903 33207)) +;;;;;; (22161 62906)) ;;; Generated autoloads from org-macs.el (autoload 'org-load-noerror-mustsuffix "org-macs" "\ @@ -1167,7 +1208,7 @@ Load FILE with optional arguments NOERROR and MUSTSUFFIX. Drop the MUSTSUFFIX a ;;;*** ;;;### (autoloads (org-mobile-pull org-mobile-push) "org-mobile" -;;;;;; "org-mobile.el" "13cb59aeb0c907454cbd127597d96ea2") +;;;;;; "org-mobile.el" "6fe291f3ef3fff1fbde9b1ec117c2d2a") ;;; Generated autoloads from org-mobile.el (autoload 'org-mobile-push "org-mobile" "\ @@ -1186,7 +1227,7 @@ agenda view showing the flagged items. ;;;*** -;;;### (autoloads (org-plot/gnuplot) "org-plot" "org-plot.el" "5fae0ed29ffaee8526d31b4634c56692") +;;;### (autoloads (org-plot/gnuplot) "org-plot" "org-plot.el" "e480cdf4e7d3e91e180354e60f40dd55") ;;; Generated autoloads from org-plot.el (autoload 'org-plot/gnuplot "org-plot" "\ @@ -1198,13 +1239,13 @@ line directly before or after the table. ;;;*** -;;;### (autoloads (orgtbl-to-orgtbl orgtbl-to-texinfo orgtbl-to-html -;;;;;; orgtbl-to-latex orgtbl-to-csv orgtbl-to-tsv orgtbl-to-generic -;;;;;; org-table-to-lisp orgtbl-mode org-table-toggle-formula-debugger +;;;### (autoloads (orgtbl-ascii-plot orgtbl-to-orgtbl orgtbl-to-texinfo +;;;;;; orgtbl-to-html orgtbl-to-latex orgtbl-to-csv orgtbl-to-tsv +;;;;;; orgtbl-to-generic org-table-to-lisp orgtbl-mode org-table-toggle-formula-debugger ;;;;;; org-table-toggle-coordinate-overlays org-table-edit-formulas ;;;;;; org-table-iterate-buffer-tables org-table-recalculate-buffer-tables -;;;;;; org-table-iterate org-table-recalculate org-table-set-constants -;;;;;; org-table-eval-formula org-table-maybe-recalculate-line org-table-rotate-recalc-marks +;;;;;; org-table-iterate org-table-recalculate org-table-eval-formula +;;;;;; org-table-maybe-recalculate-line org-table-analyze org-table-rotate-recalc-marks ;;;;;; org-table-maybe-eval-formula org-table-get-stored-formulas ;;;;;; org-table-sum org-table-edit-field org-table-wrap-region ;;;;;; org-table-convert org-table-paste-rectangle org-table-copy-region @@ -1219,7 +1260,7 @@ line directly before or after the table. ;;;;;; org-table-begin org-table-align org-table-export org-table-import ;;;;;; org-table-convert-region org-table-create org-table-create-or-convert-from-region ;;;;;; org-table-create-with-table\.el) "org-table" "org-table.el" -;;;;;; "9b6e8818ec6951cc97eba4e5d0822cef") +;;;;;; "e9359ea5b998c77257caa9b21313bf8a") ;;; Generated autoloads from org-table.el (autoload 'org-table-create-with-table\.el "org-table" "\ @@ -1253,9 +1294,11 @@ slightly, to make sure a beginning of line in the first line is included. SEPARATOR specifies the field separator in the lines. It can have the following values: -'(4) Use the comma as a field separator -'(16) Use a TAB as field separator +\(4) Use the comma as a field separator +\(16) Use a TAB as field separator +\(64) Prompt for a regular expression as field separator integer When a number, use that many spaces as field separator +regexp When a regular expression, use it to match the separator nil When nil, the command tries to be smart and figure out the separator in the following way: - when each line contains a TAB, assume TAB-separated material @@ -1296,13 +1339,17 @@ Align the table at point by aligning all vertical bars. (autoload 'org-table-begin "org-table" "\ Find the beginning of the table and return its position. -With argument TABLE-TYPE, go to the beginning of a table.el-type table. +With a non-nil optional argument TABLE-TYPE, return the beginning +of a table.el-type table. This function assumes point is on +a table. \(fn &optional TABLE-TYPE)" nil nil) (autoload 'org-table-end "org-table" "\ Find the end of the table and return its position. -With argument TABLE-TYPE, go to the end of a table.el-type table. +With a non-nil optional argument TABLE-TYPE, return the end of +a table.el-type table. This function assumes point is on +a table. \(fn &optional TABLE-TYPE)" nil nil) @@ -1331,16 +1378,22 @@ Before doing so, re-align the table if necessary. \(fn)" t nil) (autoload 'org-table-copy-down "org-table" "\ -Copy a field down in the current column. -If the field at the cursor is empty, copy into it 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. +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. In the case of a timestamp, increment by one day. +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. \(fn N)" t nil) @@ -1444,16 +1497,24 @@ 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). Sorting in reverse order is also possible. +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 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) where the capital letter indicate that sorting -should be done in reverse order. +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 either +a string or a number that should serve as the sorting key for that +row. It will then use COMPARE-FUNC to compare entries. If GETKEY-FUNC +is specified interactively, the comparison will be either a string or +numeric compare based on the type of the first key in the table. -\(fn WITH-CASE &optional SORTING-TYPE)" t nil) +\(fn WITH-CASE &optional SORTING-TYPE GETKEY-FUNC COMPARE-FUNC)" t nil) (autoload 'org-table-cut-region "org-table" "\ Copy region in table to the clipboard and blank all relevant fields. @@ -1497,7 +1558,7 @@ 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]' +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 @@ -1542,8 +1603,11 @@ If NLAST is a number, only the NLAST fields will actually be summed. (autoload 'org-table-get-stored-formulas "org-table" "\ Return an alist with the stored formulas directly after current table. +By default, only return active formulas, i.e., formulas located +on the first line after the table. However, if optional argument +LOCATION is a buffer position, consider the formulas there. -\(fn &optional NOERROR)" t nil) +\(fn &optional NOERROR LOCATION)" nil nil) (autoload 'org-table-maybe-eval-formula "org-table" "\ Check if the current field starts with \"=\" or \":=\". @@ -1562,6 +1626,23 @@ of the new mark. \(fn &optional NEWCHAR)" t nil) +(autoload 'org-table-analyze "org-table" "\ +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'. + +\(fn)" nil nil) + (autoload 'org-table-maybe-recalculate-line "org-table" "\ Recompute the current line if marked for it, and if we haven't just done it. @@ -1606,11 +1687,6 @@ not overwrite the stored one. \(fn &optional ARG EQUATION SUPPRESS-ALIGN SUPPRESS-CONST SUPPRESS-STORE SUPPRESS-ANALYSIS)" t nil) -(autoload 'org-table-set-constants "org-table" "\ -Set `org-table-formula-constants-local' in the current buffer. - -\(fn)" nil nil) - (autoload 'org-table-recalculate "org-table" "\ Recalculate the current table line by applying all stored formulas. With prefix arg ALL, do this for all lines in the table. @@ -1659,6 +1735,9 @@ The `org-mode' table editor as a minor mode for use in other modes. \(fn &optional ARG)" t nil) +(defvar orgtbl-exp-regexp "^\\([-+]?[0-9][0-9.]*\\)[eE]\\([-+]?[0-9]+\\)$" "\ +Regular expression matching exponentials as produced by calc.") + (autoload 'org-table-to-lisp "org-table" "\ Convert the table at point to a Lisp structure. The structure will be a list. Each item is either the symbol `hline' @@ -1669,68 +1748,105 @@ The table is taken from the parameter TXT, or from the buffer at point. (autoload 'orgtbl-to-generic "org-table" "\ Convert the orgtbl-mode TABLE to some other format. + This generic routine can be used for many standard cases. -TABLE is a list, each entry either the symbol `hline' for a horizontal -separator line, or a list of fields for that line. -PARAMS is a property list of parameters that can influence the conversion. -A third optional argument BACKEND can be used to convert the content of -the cells using a specific export back-end. -For the generic converter, some parameters are obligatory: you need to -specify either :lfmt, or all of (:lstart :lend :sep). +TABLE is a list, each entry either the symbol `hline' for +a horizontal separator line, or a list of fields for that +line. PARAMS is a property list of parameters that can +influence the conversion. Valid parameters are: -:splice When set to t, return only table body lines, don't wrap - them into :tstart and :tend. Default is nil. When :splice - is non-nil, this also means that the exporter should not look - for and interpret header and footer sections. +:backend, :raw + + Export back-end used as a basis to transcode elements of the + table, when no specific parameter applies to it. It is also + used to translate cells contents. You can prevent this by + setting :raw property to a non-nil value. + +:splice + + When non-nil, only convert rows, not the table itself. This is + equivalent to setting to the empty string both :tstart + and :tend, which see. + +:skip + + When set to an integer N, skip the first N lines of the table. + Horizontal separation lines do count for this parameter! + +:skipcols + + List of columns that should be skipped. If the table has + a column with calculation marks, that column is automatically + discarded beforehand. -:hline String to be inserted on horizontal separation lines. - May be nil to ignore hlines. +:hline -:sep Separator between two fields -:remove-nil-lines Do not include lines that evaluate to nil. + String to be inserted on horizontal separation lines. May be + nil to ignore these lines altogether. + +:sep + + Separator between two fields, as a string. Each in the following group may be either a string or a function of no arguments returning a string: -:tstart String to start the table. Ignored when :splice is t. -:tend String to end the table. Ignored when :splice is t. -:lstart String to start a new table line. -:llstart String to start the last table line, defaults to :lstart. -:lend String to end a table line -:llend String to end the last table line, defaults to :lend. - -Each in the following group may be a string, a function of one -argument (the field or line) returning a string, or a plist -mapping columns to either of the above: - -:lfmt Format for entire line, with enough %s to capture all fields. - If this is present, :lstart, :lend, and :sep are ignored. -:llfmt Format for the entire last line, defaults to :lfmt. -:fmt A format to be used to wrap the field, should contain - %s for the original field value. For example, to wrap - everything in dollars, you could use :fmt \"$%s$\". - This may also be a property list with column numbers and - formats. For example :fmt (2 \"$%s$\" 4 \"%s%%\") -:hlstart :hllstart :hlend :hllend :hlsep :hlfmt :hllfmt :hfmt - Same as above, specific for the header lines in the table. - All lines before the first hline are treated as header. - If any of these is not present, the data line value is used. +:tstart, :tend + + Strings to start and end the table. Ignored when :splice is t. + +:lstart, :lend + + Strings to start and end a new table line. + +:llstart, :llend + + Strings to start and end the last table line. Default, + respectively, to :lstart and :lend. + +Each in the following group may be a string or a function of one +argument (either the cells in the current row, as a list of +strings, or the current cell) returning a string: + +:lfmt + + Format string for an entire row, with enough %s to capture all + fields. When non-nil, :lstart, :lend, and :sep are ignored. + +:llfmt + + Format for the entire last line, defaults to :lfmt. + +:fmt + + A format to be used to wrap the field, should contain %s for + the original field value. For example, to wrap everything in + dollars, you could use :fmt \"$%s$\". This may also be + a property list with column numbers and format strings, or + functions, e.g., + + (:fmt (2 \"$%s$\" 4 (lambda (c) (format \"$%s$\" c)))) + +:hlstart :hllstart :hlend :hllend :hsep :hlfmt :hllfmt :hfmt + + Same as above, specific for the header lines in the table. + All lines before the first hline are treated as header. If + any of these is not present, the data line value is used. This may be either a string or a function of two arguments: -:efmt Use this format to print numbers with exponentials. - The format 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. :fmt will still be applied after :efmt. +:efmt -In addition to this, the parameters :skip and :skipcols are always handled -directly by `orgtbl-send-table'. See manual. + Use this format to print numbers with exponential. The format + 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 format strings or functions. + :fmt will still be applied after :efmt. -\(fn TABLE PARAMS &optional BACKEND)" nil nil) +\(fn TABLE PARAMS)" nil nil) (autoload 'orgtbl-to-tsv "org-table" "\ Convert the orgtbl-mode table to TAB separated material. @@ -1745,92 +1861,86 @@ This does take care of the proper quoting of fields with comma or quotes. (autoload 'orgtbl-to-latex "org-table" "\ Convert the orgtbl-mode TABLE to LaTeX. -TABLE is a list, each entry either the symbol `hline' for a horizontal -separator line, or a list of fields for that line. -PARAMS is a property list of parameters that can influence the conversion. -Supports all parameters from `orgtbl-to-generic'. Most important for -LaTeX are: -:splice When set to t, return only table body lines, don't wrap - them into a tabular environment. Default is nil. +TABLE is a list, each entry either the symbol `hline' for +a horizontal separator line, or a list of fields for that line. +PARAMS is a property list of parameters that can influence the +conversion. All parameters from `orgtbl-to-generic' are +supported. It is also possible to use the following ones: -:fmt A format to be used to wrap the field, should contain %s for the - original field value. For example, to wrap everything in dollars, - use :fmt \"$%s$\". This may also be a property list with column - numbers and formats. For example :fmt (2 \"$%s$\" 4 \"%s%%\") - The format may also be a function that formats its one argument. +:booktabs -:efmt Format for transforming numbers with exponentials. The format - should have %s twice for inserting mantissa and exponent, for - example \"%s\\\\times10^{%s}\". LaTeX default is \"%s\\\\,(%s)\". - This may also be a property list with column numbers and formats. - The format may also be a function that formats its two arguments. + When non-nil, use formal \"booktabs\" style. -:llend If you find too much space below the last line of a table, - pass a value of \"\" for :llend to suppress the final \\\\. +:environment -The general parameters :skip and :skipcols have already been applied when -this function is called. + Specify environment to use, as a string. If you use + \"longtable\", you may also want to specify :language property, + as a string, to get proper continuation strings. \(fn TABLE PARAMS)" nil nil) (autoload 'orgtbl-to-html "org-table" "\ Convert the orgtbl-mode TABLE to HTML. -TABLE is a list, each entry either the symbol `hline' for a horizontal -separator line, or a list of fields for that line. -PARAMS is a property list of parameters that can influence the conversion. -Currently this function recognizes the following parameters: -:splice When set to t, return only table body lines, don't wrap - them into a environment. Default is nil. +TABLE is a list, each entry either the symbol `hline' for +a horizontal separator line, or a list of fields for that line. +PARAMS is a property list of parameters that can influence the +conversion. All parameters from `orgtbl-to-generic' are +supported. It is also possible to use the following one: + +:attributes -The general parameters :skip and :skipcols have already been applied when -this function is called. The function does *not* use `orgtbl-to-generic', -so you cannot specify parameters for it. + Attributes and values, as a plist, which will be used in +
tag. \(fn TABLE PARAMS)" nil nil) (autoload 'orgtbl-to-texinfo "org-table" "\ -Convert the orgtbl-mode TABLE to TeXInfo. -TABLE is a list, each entry either the symbol `hline' for a horizontal -separator line, or a list of fields for that line. -PARAMS is a property list of parameters that can influence the conversion. -Supports all parameters from `orgtbl-to-generic'. Most important for -TeXInfo are: - -:splice nil/t When set to t, return only table body lines, don't wrap - them into a multitable environment. Default is nil. - -:fmt fmt A format to be used to wrap the field, should contain - %s for the original field value. For example, to wrap - everything in @kbd{}, you could use :fmt \"@kbd{%s}\". - This may also be a property list with column numbers and - formats. For example :fmt (2 \"@kbd{%s}\" 4 \"@code{%s}\"). - Each format also may be a function that formats its one - argument. - -:cf \"f1 f2..\" The column fractions for the table. By default these - are computed automatically from the width of the columns - under org-mode. - -The general parameters :skip and :skipcols have already been applied when -this function is called. +Convert the orgtbl-mode TABLE to Texinfo. + +TABLE is a list, each entry either the symbol `hline' for +a horizontal separator line, or a list of fields for that line. +PARAMS is a property list of parameters that can influence the +conversion. All parameters from `orgtbl-to-generic' are +supported. It is also possible to use the following one: + +:columns + + Column widths, as a string. When providing column fractions, + \"@columnfractions\" command can be omitted. \(fn TABLE PARAMS)" nil nil) (autoload 'orgtbl-to-orgtbl "org-table" "\ Convert the orgtbl-mode TABLE into another orgtbl-mode table. + +TABLE is a list, each entry either the symbol `hline' for +a horizontal separator line, or a list of fields for that line. +PARAMS is a property list of parameters that can influence the +conversion. All parameters from `orgtbl-to-generic' are +supported. + Useful when slicing one table into many. The :hline, :sep, -:lstart, and :lend provide orgtbl framing. The default nil :tstart -and :tend suppress strings without splicing; they can be set to -provide ORGTBL directives for the generated table. +:lstart, and :lend provide orgtbl framing. :tstart and :tend can +be set to provide ORGTBL directives for the generated table. \(fn TABLE PARAMS)" nil nil) +(autoload 'orgtbl-ascii-plot "org-table" "\ +Draw an ascii bar plot in a column. +With cursor in a column containing numerical values, this +function will draw a plot in a new column. +ASK, if given, is a numeric prefix to override the default 12 +characters width of the plot. ASK may also be the +\\[universal-argument] prefix, which will prompt for the width. + +\(fn &optional ASK)" t nil) + ;;;*** ;;;### (autoloads (org-timer-set-timer org-timer-item org-timer-change-times-in-region -;;;;;; org-timer org-timer-start) "org-timer" "org-timer.el" "54b0453041fa05a477a9da6054ed8b31") +;;;;;; org-timer org-timer-start) "org-timer" "org-timer.el" "96624173cc52bc1945ce7cb5940a7d2b") ;;; Generated autoloads from org-timer.el (autoload 'org-timer-start "org-timer" "\ @@ -1870,14 +1980,14 @@ Insert a description-type item with the current timer value. \(fn &optional ARG)" t nil) (autoload 'org-timer-set-timer "org-timer" "\ -Prompt for a duration and set a timer. +Prompt for a duration in minutes or hh:mm:ss and set a timer. -If `org-timer-default-timer' is not zero, suggest this value as +If `org-timer-default-timer' is not \"0\", suggest this value as the default duration for the timer. If a timer is already set, prompt the user if she wants to replace it. Called with a numeric prefix argument, use this numeric value as -the duration of the timer. +the duration of the timer in minutes. Called with a `C-u' prefix arguments, use `org-timer-default-timer' without prompting the user for a duration. @@ -1886,12 +1996,16 @@ With two `C-u' prefix arguments, use `org-timer-default-timer' without prompting the user for a duration and automatically replace any running timer. +By default, the timer duration will be set to the number of +minutes in the Effort property, if any. You can ignore this by +using three `C-u' prefix arguments. + \(fn &optional OPT)" t nil) ;;;*** ;;;### (autoloads (org-git-version org-release) "org-version" "org-version.el" -;;;;;; (21904 53461)) +;;;;;; (22209 26982)) ;;; Generated autoloads from org-version.el (autoload 'org-release "org-version" "\ @@ -1917,7 +2031,7 @@ The location of ODT styles.") ;;;;;; org-run-like-in-org-mode turn-on-orgstruct++ turn-on-orgstruct ;;;;;; orgstruct-mode org-global-cycle org-cycle org-mode org-clock-persistence-insinuate ;;;;;; turn-on-orgtbl org-version org-babel-load-file org-babel-do-load-languages) -;;;;;; "org" "org.el" (21903 33207)) +;;;;;; "org" "org.el" (22197 36410)) ;;; Generated autoloads from org.el (autoload 'org-babel-do-load-languages "org" "\ @@ -1935,10 +2049,11 @@ file to byte-code before it is loaded. \(fn FILE &optional COMPILE)" t nil) (autoload 'org-version "org" "\ -Show the org-mode version in the echo area. -With prefix argument HERE, insert it at point. -When FULL is non-nil, use a verbose version string. -When MESSAGE is non-nil, display a message with the version. +Show the org-mode version. +Interactively, or when MESSAGE is non-nil, show it in echo area. +With prefix argument, or when HERE is non-nil, insert it at point. +In non-interactive uses, a reduced version string is output unless +FULL is given. \(fn &optional HERE FULL MESSAGE)" t nil) @@ -1985,11 +2100,10 @@ in special contexts. 1. OVERVIEW: Show only top-level headlines. 2. CONTENTS: Show all headlines of all levels, but no body text. 3. SHOW ALL: Show everything. - When called with two `C-u C-u' prefixes, switch to the startup visibility, + With a double \\[universal-argument] prefix argument, switch to the startup visibility, determined by the variable `org-startup-folded', and by any VISIBILITY properties in the buffer. - When called with three `C-u C-u C-u' prefixed, show the entire buffer, - including any drawers. + With a triple \\[universal-argument] prefix argument, show the entire buffer, including any drawers. - When inside a table, re-align the table and move to the next field. @@ -2018,7 +2132,7 @@ in special contexts. - Special case: if point is at the beginning of the buffer and there is no headline in line 1, this function will act as if called with prefix arg - (C-u TAB, same as S-TAB) also when called without prefix arg. + (\\[universal-argument] TAB, same as S-TAB) also when called without prefix arg. But only if also the variable `org-cycle-global-at-bob' is t. \(fn &optional ARG)" t nil) @@ -2061,16 +2175,16 @@ call CMD. (autoload 'org-store-link "org" "\ \\Store an org-link to the current location. This link is added to `org-stored-links' and can later be inserted -into an org-buffer with \\[org-insert-link]. +into an Org buffer with \\[org-insert-link]. -For some link types, a prefix arg is interpreted. -For links to Usenet articles, arg negates `org-gnus-prefer-web-links'. -For file links, arg negates `org-context-in-file-links'. +For some link types, a prefix ARG is interpreted. +For links to Usenet articles, ARG negates `org-gnus-prefer-web-links'. +For file links, ARG negates `org-context-in-file-links'. -A double prefix arg force skipping storing functions that are not +A double prefix ARG force skipping storing functions that are not part of Org's core. -A triple prefix arg force storing a link for each line in the +A triple prefix ARG force storing a link for each line in the active region. \(fn ARG)" t nil) @@ -2138,7 +2252,7 @@ Call the customize function with org as argument. ;;;*** -;;;### (autoloads nil "ox" "ox.el" "a3f90141f011b5f549828135c723de85") +;;;### (autoloads nil "ox" "ox.el" "666ded911b08be6cee87ae459dc28b1c") ;;; Generated autoloads from ox.el (autoload 'org-export-as "ox" "\ @@ -2238,7 +2352,7 @@ use it to set a major mode there, e.g, (defun org-latex-export-as-latex (&optional async subtreep visible-only body-only ext-plist) (interactive) - (org-export-to-buffer 'latex \"*Org LATEX Export*\" + (org-export-to-buffer \\='latex \"*Org LATEX Export*\" async subtreep visible-only body-only ext-plist (lambda () (LaTeX-mode)))) This function returns BUFFER. @@ -2272,7 +2386,7 @@ to send the output file through additional processing, e.g, (&optional async subtreep visible-only body-only ext-plist) (interactive) (let ((outfile (org-export-output-file-name \".tex\" subtreep))) - (org-export-to-file 'latex outfile + (org-export-to-file \\='latex outfile async subtreep visible-only body-only ext-plist (lambda (file) (org-latex-compile file))) @@ -2308,7 +2422,7 @@ When ARG is \\[universal-argument] \\[universal-argument], display the asynchron ;;;### (autoloads (org-ascii-publish-to-utf8 org-ascii-publish-to-latin1 ;;;;;; org-ascii-publish-to-ascii org-ascii-export-to-ascii org-ascii-export-as-ascii) -;;;;;; "ox-ascii" "ox-ascii.el" "a37917c54242b5e574c47a7f18e9e125") +;;;;;; "ox-ascii" "ox-ascii.el" "8b996711b8e315a0dd406d54c0854eaa") ;;; Generated autoloads from ox-ascii.el (autoload 'org-ascii-export-as-ascii "ox-ascii" "\ @@ -2409,9 +2523,9 @@ Return output file name. ;;;*** ;;;### (autoloads (org-beamer-publish-to-pdf org-beamer-publish-to-latex -;;;;;; org-beamer-insert-options-template org-beamer-select-environment -;;;;;; org-beamer-export-to-pdf org-beamer-export-to-latex org-beamer-export-as-latex -;;;;;; org-beamer-mode) "ox-beamer" "ox-beamer.el" "bb0ba558b851a54fc6394a24106c4bb4") +;;;;;; org-beamer-select-environment org-beamer-export-to-pdf org-beamer-export-to-latex +;;;;;; org-beamer-export-as-latex org-beamer-mode) "ox-beamer" "ox-beamer.el" +;;;;;; "794938d6b0ee97f126e6c5d6330eeaff") ;;; Generated autoloads from ox-beamer.el (autoload 'org-beamer-mode "ox-beamer" "\ @@ -2522,11 +2636,6 @@ aid, but the tag does not have any semantic meaning. \(fn)" t nil) -(autoload 'org-beamer-insert-options-template "ox-beamer" "\ -Insert a settings template, to make sure users do this right. - -\(fn &optional KIND)" t nil) - (autoload 'org-beamer-publish-to-latex "ox-beamer" "\ Publish an Org file to a Beamer presentation (LaTeX). @@ -2553,7 +2662,7 @@ Return output file name. ;;;### (autoloads (org-html-publish-to-html org-html-export-to-html ;;;;;; org-html-convert-region-to-html org-html-export-as-html org-html-htmlize-generate-css) -;;;;;; "ox-html" "ox-html.el" "65604b7a2a80c70979b37eb44119d6f9") +;;;;;; "ox-html" "ox-html.el" "be510b0f85b906342b6f60ca8ba364a9") ;;; Generated autoloads from ox-html.el (put 'org-html-head-include-default-style 'safe-local-variable 'booleanp) @@ -2661,7 +2770,7 @@ Return output file name. ;;;### (autoloads (org-icalendar-combine-agenda-files org-icalendar-export-agenda-files ;;;;;; org-icalendar-export-to-ics) "ox-icalendar" "ox-icalendar.el" -;;;;;; "74a493ca40404cb8fd648526fd898b6f") +;;;;;; "0420c450f1da4a87e24a8afbc23f75f3") ;;; Generated autoloads from ox-icalendar.el (autoload 'org-icalendar-export-to-ics "ox-icalendar" "\ @@ -2713,7 +2822,7 @@ The file is stored under the name chosen in ;;;### (autoloads (org-latex-publish-to-pdf org-latex-publish-to-latex ;;;;;; org-latex-export-to-pdf org-latex-export-to-latex org-latex-convert-region-to-latex -;;;;;; org-latex-export-as-latex) "ox-latex" "ox-latex.el" "6277aa86c5275b5aae6c2c2d578a04fb") +;;;;;; org-latex-export-as-latex) "ox-latex" "ox-latex.el" "d27ca15eea14bcf3173e74f51b3d3e69") ;;; Generated autoloads from ox-latex.el (autoload 'org-latex-export-as-latex "ox-latex" "\ @@ -2838,8 +2947,9 @@ Return output file name. ;;;*** -;;;### (autoloads (org-md-export-to-markdown org-md-convert-region-to-md -;;;;;; org-md-export-as-markdown) "ox-md" "ox-md.el" "33f62cc6c4fd2d0ee63030f60bc3c5d3") +;;;### (autoloads (org-md-publish-to-md org-md-export-to-markdown +;;;;;; org-md-convert-region-to-md org-md-export-as-markdown) "ox-md" +;;;;;; "ox-md.el" "875c98308c9f63cd880c47ae90b2fb91") ;;; Generated autoloads from ox-md.el (autoload 'org-md-export-as-markdown "ox-md" "\ @@ -2898,10 +3008,21 @@ Return output file's name. \(fn &optional ASYNC SUBTREEP VISIBLE-ONLY)" t nil) +(autoload 'org-md-publish-to-md "ox-md" "\ +Publish an org file to Markdown. + +FILENAME is the filename of the Org file to be published. PLIST +is the property list for the given project. PUB-DIR is the +publishing directory. + +Return output file name. + +\(fn PLIST FILENAME PUB-DIR)" nil nil) + ;;;*** ;;;### (autoloads (org-odt-convert org-odt-export-to-odt org-odt-export-as-odf-and-open -;;;;;; org-odt-export-as-odf) "ox-odt" "ox-odt.el" "74b69feba31202aef277a075e012a392") +;;;;;; org-odt-export-as-odf) "ox-odt" "ox-odt.el" "e3a936f4f3bbe947f4d4b75ce359538f") ;;; Generated autoloads from ox-odt.el (put 'org-odt-preferred-output-format 'safe-local-variable 'stringp) @@ -2964,7 +3085,7 @@ using `org-open-file'. ;;;*** ;;;### (autoloads (org-org-publish-to-org org-org-export-to-org org-org-export-as-org) -;;;;;; "ox-org" "ox-org.el" "952b4282cdf7bddd86e2e7660934888f") +;;;;;; "ox-org" "ox-org.el" "8f2b09ccf51699abf1204d296e93a399") ;;; Generated autoloads from ox-org.el (autoload 'org-org-export-as-org "ox-org" "\ @@ -2986,6 +3107,9 @@ first. When optional argument VISIBLE-ONLY is non-nil, don't export contents of hidden elements. +When optional argument BODY-ONLY is non-nil, strip document +keywords from output. + EXT-PLIST, when provided, is a property list with external parameters overriding Org default settings, but still inferior to file-local settings. @@ -2994,7 +3118,7 @@ Export is done in a buffer named \"*Org ORG Export*\", which will be displayed when `org-export-show-temporary-export-buffer' is non-nil. -\(fn &optional ASYNC SUBTREEP VISIBLE-ONLY EXT-PLIST)" t nil) +\(fn &optional ASYNC SUBTREEP VISIBLE-ONLY BODY-ONLY EXT-PLIST)" t nil) (autoload 'org-org-export-to-org "ox-org" "\ Export current buffer to an org file. @@ -3015,13 +3139,16 @@ first. When optional argument VISIBLE-ONLY is non-nil, don't export contents of hidden elements. +When optional argument BODY-ONLY is non-nil, strip document +keywords from output. + EXT-PLIST, when provided, is a property list with external parameters overriding Org default settings, but still inferior to file-local settings. Return output file name. -\(fn &optional ASYNC SUBTREEP VISIBLE-ONLY EXT-PLIST)" t nil) +\(fn &optional ASYNC SUBTREEP VISIBLE-ONLY BODY-ONLY EXT-PLIST)" t nil) (autoload 'org-org-publish-to-org "ox-org" "\ Publish an org file to org. @@ -3038,7 +3165,7 @@ Return output file name. ;;;### (autoloads (org-publish-current-project org-publish-current-file ;;;;;; org-publish-all org-publish) "ox-publish" "ox-publish.el" -;;;;;; "20cfd65a07e6275687d28df1d264b407") +;;;;;; "a6e792ca3583d341a674e11cecfdd6e9") ;;; Generated autoloads from ox-publish.el (defalias 'org-publish-project 'org-publish) @@ -3082,7 +3209,7 @@ the project. ;;;*** ;;;### (autoloads (org-texinfo-convert-region-to-texinfo org-texinfo-publish-to-texinfo) -;;;;;; "ox-texinfo" "ox-texinfo.el" "ae3f8dd17715c8093138512ae3c347cc") +;;;;;; "ox-texinfo" "ox-texinfo.el" "78e9355de19d5650647109cc50825a58") ;;; Generated autoloads from ox-texinfo.el (autoload 'org-texinfo-publish-to-texinfo "ox-texinfo" "\ @@ -3108,7 +3235,7 @@ this command to convert it. ;;;### (autoloads (org-export-dispatch org-export-to-file org-export-to-buffer ;;;;;; org-export-insert-default-template org-export-replace-region-by -;;;;;; org-export-string-as org-export-as) "ox" "ox.el" "a3f90141f011b5f549828135c723de85") +;;;;;; org-export-string-as org-export-as) "ox" "ox.el" "666ded911b08be6cee87ae459dc28b1c") ;;; Generated autoloads from ox.el (autoload 'org-export-as "ox" "\ @@ -3208,7 +3335,7 @@ use it to set a major mode there, e.g, (defun org-latex-export-as-latex (&optional async subtreep visible-only body-only ext-plist) (interactive) - (org-export-to-buffer 'latex \"*Org LATEX Export*\" + (org-export-to-buffer \\='latex \"*Org LATEX Export*\" async subtreep visible-only body-only ext-plist (lambda () (LaTeX-mode)))) This function returns BUFFER. @@ -3240,7 +3367,7 @@ to send the output file through additional processing, e.g, (&optional async subtreep visible-only body-only ext-plist) (interactive) (let ((outfile (org-export-output-file-name \".tex\" subtreep))) - (org-export-to-file 'latex outfile + (org-export-to-file \\='latex outfile async subtreep visible-only body-only ext-plist (lambda (file) (org-latex-compile file))) diff --git a/elpa/org-20150629/org-macro.el b/elpa/org-20160215/org-macro.el similarity index 60% rename from elpa/org-20150629/org-macro.el rename to elpa/org-20160215/org-macro.el index 5b890346..fee33f61 100644 --- a/elpa/org-20150629/org-macro.el +++ b/elpa/org-20160215/org-macro.el @@ -1,6 +1,6 @@ ;;; org-macro.el --- Macro Replacement Code for Org Mode -;; Copyright (C) 2013-2014 Free Software Foundation, Inc. +;; Copyright (C) 2013-2016 Free Software Foundation, Inc. ;; Author: Nicolas Goaziou ;; Keywords: outlines, hypermedia, calendar, wp @@ -30,6 +30,10 @@ ;; `org-macro-initialize-templates', which recursively calls ;; `org-macro--collect-macros' in order to read setup files. +;; Argument in macros are separated with commas. Proper escaping rules +;; are implemented in `org-macro-escape-arguments' and arguments can +;; be extracted from a string with `org-macro-extract-arguments'. + ;; Along with macros defined through #+MACRO: keyword, default ;; templates include the following hard-coded macros: ;; {{{time(format-string)}}}, {{{property(node-property)}}}, @@ -40,14 +44,20 @@ ;;; Code: (require 'org-macs) +(require 'org-compat) -(declare-function org-element-at-point "org-element" (&optional keep-trail)) +(declare-function org-element-at-point "org-element" ()) (declare-function org-element-context "org-element" (&optional element)) +(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-remove-double-quotes "org" (s)) -(declare-function org-mode "org" ()) (declare-function org-file-contents "org" (file &optional noerror)) +(declare-function org-mode "org" ()) +(declare-function org-remove-double-quotes "org" (s)) (declare-function org-with-wide-buffer "org-macs" (&rest body)) ;;; Variables @@ -96,6 +106,8 @@ Return an alist containing all macro templates found." (org-remove-double-quotes val)))) (unless (member file files) (with-temp-buffer + (setq default-directory + (file-name-directory file)) (org-mode) (insert (org-file-contents file 'noerror)) (setq templates @@ -118,12 +130,22 @@ function installs the following ones: \"property\", (if old-template (setcdr old-template (cdr cell)) (push cell templates)))))) ;; Install hard-coded macros. - (mapc (lambda (cell) (funcall update-templates cell)) - (list (cons "property" "(eval (org-entry-get nil \"$1\" 'selective))") + (mapc update-templates + (list (cons "property" + "(eval (save-excursion + (let ((l \"$2\")) + (when (org-string-nw-p l) + (condition-case _ + (let ((org-link-search-must-match-exact-headline t)) + (org-link-search l nil t)) + (error + (error \"Macro property failed: cannot find location %s\" + l))))) + (org-entry-get nil \"$1\" 'selective)))") (cons "time" "(eval (format-time-string \"$1\"))"))) (let ((visited-file (buffer-file-name (buffer-base-buffer)))) (when (and visited-file (file-exists-p visited-file)) - (mapc (lambda (cell) (funcall update-templates cell)) + (mapc update-templates (list (cons "input-file" (file-name-nondirectory visited-file)) (cons "modification-time" (format "(eval (format-time-string \"$1\" '%s))" @@ -155,38 +177,107 @@ default value. Return nil if no template was found." ;; Return string. (format "%s" (or value "")))))) -(defun org-macro-replace-all (templates) +(defun org-macro-replace-all (templates &optional finalize keywords) "Replace all macros in current buffer by their expansion. + TEMPLATES is an alist of templates used for expansion. See -`org-macro-templates' for a buffer-local default value." - (save-excursion +`org-macro-templates' for a buffer-local default value. + +If optional arg FINALIZE is non-nil, raise an error if a macro is +found in the buffer with no definition in TEMPLATES. + +Optional argument KEYWORDS, when non-nil is a list of keywords, +as strings, where macro expansion is allowed." + (org-with-wide-buffer (goto-char (point-min)) - (let (record) + (let ((properties-regexp + (format "\\`EXPORT_%s\\+?\\'" (regexp-opt keywords))) + record) (while (re-search-forward "{{{[-A-Za-z0-9_]" nil t) - (let ((object (org-element-context))) - (when (eq (org-element-type object) 'macro) - (let* ((value (org-macro-expand object templates)) - (begin (org-element-property :begin object)) + (let* ((datum (save-match-data (org-element-context))) + (type (org-element-type datum)) + (macro + (cond + ((eq type 'macro) datum) + ;; In parsed keywords and associated node properties, + ;; force macro recognition. + ((or (and (eq type 'keyword) + (member (org-element-property :key datum) keywords)) + (and (eq type 'node-property) + (org-string-match-p + properties-regexp + (org-element-property :key datum)))) + (save-restriction + (narrow-to-region (match-beginning 0) (line-end-position)) + (org-element-map (org-element-parse-buffer) 'macro + #'identity nil t)))))) + (when macro + (let* ((value (org-macro-expand macro templates)) + (begin (org-element-property :begin macro)) (signature (list begin - object - (org-element-property :args object)))) + macro + (org-element-property :args macro)))) ;; Avoid circular dependencies by checking if the same ;; macro with the same arguments is expanded at the same ;; position twice. - (if (member signature record) - (error "Circular macro expansion: %s" - (org-element-property :key object)) - (when value - (push signature record) - (delete-region - begin - ;; Preserve white spaces after the macro. - (progn (goto-char (org-element-property :end object)) - (skip-chars-backward " \t") - (point))) - ;; Leave point before replacement in case of recursive - ;; expansions. - (save-excursion (insert value))))))))))) + (cond ((member signature record) + (error "Circular macro expansion: %s" + (org-element-property :key macro))) + (value + (push signature record) + (delete-region + begin + ;; Preserve white spaces after the macro. + (progn (goto-char (org-element-property :end macro)) + (skip-chars-backward " \t") + (point))) + ;; Leave point before replacement in case of + ;; recursive expansions. + (save-excursion (insert value))) + (finalize + (error "Undefined Org macro: %s; aborting" + (org-element-property :key macro))))))))))) + +(defun org-macro-escape-arguments (&rest args) + "Build macro's arguments string from ARGS. +ARGS are strings. Return value is a string with arguments +properly escaped and separated with commas. This is the opposite +of `org-macro-extract-arguments'." + (let ((s "")) + (dolist (arg (reverse args) (substring s 1)) + (setq s + (concat + "," + (replace-regexp-in-string + "\\(\\\\*\\)," + (lambda (m) + (concat (make-string (1+ (* 2 (length (match-string 1 m)))) ?\\) + ",")) + ;; If a non-terminal argument ends on backslashes, make + ;; sure to also escape them as they will be followed by + ;; a comma. + (concat arg (and (not (equal s "")) + (string-match "\\\\+\\'" arg) + (match-string 0 arg))) + nil t) + s))))) + +(defun org-macro-extract-arguments (s) + "Extract macro arguments from string S. +S is a string containing comma separated values properly escaped. +Return a list of arguments, as strings. This is the opposite of +`org-macro-escape-arguments'." + ;; Do not use `org-split-string' since empty strings are + ;; meaningful here. + (split-string + (replace-regexp-in-string + "\\(\\\\*\\)," + (lambda (str) + (let ((len (length (match-string 1 str)))) + (concat (make-string (/ len 2) ?\\) + (if (zerop (mod len 2)) "\000" ",")))) + s nil t) + "\000")) (provide 'org-macro) diff --git a/elpa/org-20150629/org-macs.el b/elpa/org-20160215/org-macs.el similarity index 95% rename from elpa/org-20150629/org-macs.el rename to elpa/org-20160215/org-macs.el index 905b0a61..631f83a7 100644 --- a/elpa/org-20150629/org-macs.el +++ b/elpa/org-20160215/org-macs.el @@ -1,6 +1,6 @@ ;;; org-macs.el --- Top-level definitions for Org-mode -;; Copyright (C) 2004-2014 Free Software Foundation, Inc. +;; Copyright (C) 2004-2016 Free Software Foundation, Inc. ;; Author: Carsten Dominik ;; Keywords: outlines, hypermedia, calendar, wp @@ -55,7 +55,7 @@ ,@body)) (defmacro org-called-interactively-p (&optional kind) - (declare (debug (&optional ("quote" symbolp)))) ;Why not just `t'? + (declare (debug (&optional ("quote" symbolp)))) ;Why not just t? (if (featurep 'xemacs) `(interactive-p) (if (or (> emacs-major-version 23) @@ -71,9 +71,10 @@ `(and (boundp (quote ,var)) ,var)) (defun org-string-nw-p (s) - "Is S a string with a non-white character?" + "Return S if S is a string containing a non-blank character. +Otherwise, return nil." (and (stringp s) - (org-string-match-p "\\S-" s) + (org-string-match-p "[^ \r\t\n]" s) s)) (defun org-not-nil (v) @@ -137,7 +138,7 @@ Otherwise return nil." ;; FIXME: Slated for removal. Current Org mode does not support Emacs < 22 (defmacro org-maybe-intangible (props) - "Add '(intangible t) to PROPS if Emacs version is earlier than Emacs 22. + "Add \\='(intangible t) to PROPS if Emacs version is earlier than Emacs 22. In Emacs 21, invisible text is not avoided by the command loop, so the intangible property is needed to make sure point skips this text. In Emacs 22, this is not necessary. The intangible text property has @@ -354,11 +355,16 @@ point nowhere." (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'" - (if (or (not (derived-mode-p 'org-mode)) (not (featurep 'org-inlinetask))) - org-outline-regexp - (let* ((limit-level (1- org-inlinetask-min-level)) - (nstars (if org-odd-levels-only (1- (* limit-level 2)) limit-level))) - (format "\\*\\{1,%d\\} " nstars)))) + (cond ((not (derived-mode-p 'org-mode)) + outline-regexp) + ((not (featurep 'org-inlinetask)) + org-outline-regexp) + (t + (let* ((limit-level (1- org-inlinetask-min-level)) + (nstars (if org-odd-levels-only + (1- (* limit-level 2)) + limit-level))) + (format "\\*\\{1,%d\\} " nstars))))) (defun org-format-seconds (string seconds) "Compatibility function replacing format-seconds." diff --git a/elpa/org-20150629/org-mhe.el b/elpa/org-20160215/org-mhe.el similarity index 99% rename from elpa/org-20150629/org-mhe.el rename to elpa/org-20160215/org-mhe.el index bdd6e150..e8abef9f 100644 --- a/elpa/org-20150629/org-mhe.el +++ b/elpa/org-20160215/org-mhe.el @@ -1,6 +1,6 @@ ;;; org-mhe.el --- Support for links to MH-E messages from within Org-mode -;; Copyright (C) 2004-2014 Free Software Foundation, Inc. +;; Copyright (C) 2004-2016 Free Software Foundation, Inc. ;; Author: Thomas Baumann ;; Keywords: outlines, hypermedia, calendar, wp diff --git a/elpa/org-20150629/org-mobile.el b/elpa/org-20160215/org-mobile.el similarity index 99% rename from elpa/org-20150629/org-mobile.el rename to elpa/org-20160215/org-mobile.el index 9c87791a..e6709e45 100644 --- a/elpa/org-20150629/org-mobile.el +++ b/elpa/org-20160215/org-mobile.el @@ -1,5 +1,5 @@ ;;; org-mobile.el --- Code for asymmetric sync with a mobile device -;; Copyright (C) 2009-2014 Free Software Foundation, Inc. +;; Copyright (C) 2009-2016 Free Software Foundation, Inc. ;; ;; Author: Carsten Dominik ;; Keywords: outlines, hypermedia, calendar, wp @@ -88,7 +88,7 @@ org-agenda-text-search-extra-files Encryption uses AES-256, with a password given in `org-mobile-encryption-password'. When nil, plain files are kept on the server. -Turning on encryption requires to set the same password in the MobileOrg +Turning on encryption requires setting the same password in the MobileOrg application. Before turning this on, check of MobileOrg does already support it - at the time of this writing it did not yet." :group 'org-mobile @@ -425,7 +425,7 @@ agenda view showing the flagged items." (def-tags (default-value 'org-tag-alist)) (target-file (expand-file-name org-mobile-index-file org-mobile-directory)) - file link-name todo-kwds done-kwds tags drawers entry kwds dwds twds) + file link-name todo-kwds done-kwds tags entry kwds dwds twds) (when (stringp (car def-todo)) (setq def-todo (list (cons 'sequence def-todo)))) (org-agenda-prepare-buffers (mapcar 'car files-alist)) @@ -433,21 +433,20 @@ agenda view showing the flagged items." (setq todo-kwds (org-delete-all done-kwds (org-uniquify org-todo-keywords-for-agenda))) - (setq drawers (org-uniquify org-drawers-for-agenda)) (setq tags (mapcar 'car (org-global-tags-completion-table (mapcar 'car files-alist)))) (with-temp-file (if org-mobile-use-encryption org-mobile-encryption-tempfile target-file) + (insert "#+READONLY\n") (while (setq entry (pop def-todo)) - (insert "#+READONLY\n") (setq kwds (mapcar (lambda (x) (if (string-match "(" x) (substring x 0 (match-beginning 0)) x)) (cdr entry))) (insert "#+TODO: " (mapconcat 'identity kwds " ") "\n") - (setq dwds (member "|" kwds) + (setq dwds (or (member "|" kwds) (last kwds)) twds (org-delete-all dwds kwds) todo-kwds (org-delete-all twds todo-kwds) done-kwds (org-delete-all dwds done-kwds))) @@ -469,7 +468,6 @@ agenda view showing the flagged items." (setq tags (sort tags (lambda (a b) (string< (downcase a) (downcase b))))) (setq tags (append def-tags tags nil)) (insert "#+TAGS: " (mapconcat 'identity tags " ") "\n") - (insert "#+DRAWERS: " (mapconcat 'identity drawers " ") "\n") (insert "#+ALLPRIORITIES: " org-mobile-allpriorities "\n") (when (file-exists-p (expand-file-name org-mobile-directory "agendas.org")) diff --git a/elpa/org-20150629/org-mouse.el b/elpa/org-20160215/org-mouse.el similarity index 98% rename from elpa/org-20150629/org-mouse.el rename to elpa/org-20160215/org-mouse.el index 74046c73..232a4beb 100644 --- a/elpa/org-20150629/org-mouse.el +++ b/elpa/org-20160215/org-mouse.el @@ -1,6 +1,6 @@ ;;; org-mouse.el --- Better mouse support for org-mode -;; Copyright (C) 2006-2014 Free Software Foundation, Inc. +;; Copyright (C) 2006-2016 Free Software Foundation, Inc. ;; Author: Piotr Zielinski ;; Maintainer: Carsten Dominik @@ -191,7 +191,7 @@ Changing this variable requires a restart of Emacs to get activated." (interactive) (end-of-line) (skip-chars-backward "\t ") - (when (org-looking-back ":[A-Za-z]+:") + (when (org-looking-back ":[A-Za-z]+:" (line-beginning-position)) (skip-chars-backward ":A-Za-z") (skip-chars-backward "\t "))) @@ -215,8 +215,7 @@ this function is called. Otherwise, the current major mode menu is used." (when (not (org-mouse-mark-active)) (goto-char (posn-point (event-start event))) (when (not (eolp)) (save-excursion (run-hooks 'post-command-hook))) - (let ((redisplay-dont-pause t)) - (sit-for 0))) + (sit-for 0)) (if (functionp org-mouse-context-menu-function) (funcall org-mouse-context-menu-function event) (if (fboundp 'mouse-menu-major-mode-map) @@ -378,7 +377,7 @@ nor a function, elements of KEYWORDS are used directly." (defvar org-mouse-priority-regexp "\\[#\\([A-Z]\\)\\]" "Regular expression matching the priority indicator. Differs from `org-priority-regexp' in that it doesn't contain the -leading '.*?'.") +leading `.*?'.") (defun org-mouse-get-priority (&optional default) "Return the priority of the current headline. @@ -498,7 +497,7 @@ SCHEDULED: or DEADLINE: or ANYTHINGLIKETHIS:" `("Main Menu" ["Show Overview" org-mouse-show-overview t] ["Show Headlines" org-mouse-show-headlines t] - ["Show All" show-all t] + ["Show All" outline-show-all t] ["Remove Highlights" org-remove-occur-highlights :visible org-occur-highlights] "--" @@ -539,7 +538,7 @@ SCHEDULED: or DEADLINE: or ANYTHINGLIKETHIS:" ((stringp (nth 2 entry)) (concat (org-mouse-agenda-type (nth 1 entry)) (nth 2 entry))) - (t "Agenda Command '%s'")) + (t "Agenda Command `%s'")) 30)))) "--" ["Delete Blank Lines" delete-blank-lines @@ -566,7 +565,7 @@ SCHEDULED: or DEADLINE: or ANYTHINGLIKETHIS:" (save-excursion (org-apply-on-list wrap-fun nil))))) (defun org-mouse-bolp () - "Return true if there only spaces, tabs, and '*' before point. + "Return true if there only spaces, tabs, and `*' before point. This means, between the beginning of line and the point." (save-excursion (skip-chars-backward " \t*") (bolp))) @@ -587,7 +586,7 @@ This means, between the beginning of line and the point." (:end ; insert text here (skip-chars-backward " \t") (kill-region (point) (point-at-eol)) - (unless (org-looking-back org-mouse-punctuation) + (unless (org-looking-back org-mouse-punctuation (line-beginning-position)) (insert (concat org-mouse-punctuation " "))))) (insert text) (beginning-of-line)) @@ -638,14 +637,15 @@ This means, between the beginning of line and the point." (progn (save-excursion (goto-char (region-beginning)) (insert "[[")) (save-excursion (goto-char (region-end)) (insert "]]")))] ["Insert Link Here" (org-mouse-yank-link ',event)])))) - ((save-excursion (beginning-of-line) (looking-at "#\\+STARTUP: \\(.*\\)")) + ((save-excursion (beginning-of-line) (looking-at "[ \t]*#\\+STARTUP: \\(.*\\)")) (popup-menu `(nil ,@(org-mouse-list-options-menu (mapcar 'car org-startup-options) 'org-mode-restart)))) ((or (eolp) (and (looking-at "\\( \\|\t\\)\\(+:[0-9a-zA-Z_:]+\\)?\\( \\|\t\\)+$") - (org-looking-back " \\|\t"))) + (org-looking-back " \\|\t" (- (point) 2) + (line-beginning-position)))) (org-mouse-popup-global-menu)) ((funcall get-context :checkbox) (popup-menu @@ -708,9 +708,9 @@ This means, between the beginning of line and the point." ((org-mouse-looking-at ":\\([A-Za-z0-9_]+\\):" "A-Za-z0-9_" -1) ;tags (popup-menu `(nil - [,(format "Display '%s'" (match-string 1)) + [,(format-message "Display `%s'" (match-string 1)) (org-tags-view nil ,(match-string 1))] - [,(format "Sparse Tree '%s'" (match-string 1)) + [,(format-message "Sparse Tree `%s'" (match-string 1)) (org-tags-sparse-tree nil ,(match-string 1))] "--" ,@(org-mouse-tag-menu)))) @@ -1008,7 +1008,7 @@ This means, between the beginning of line and the point." (let ((endmarker (with-current-buffer buffer (org-end-of-subtree nil t) (unless (eobp) (forward-char 1)) - (copy-marker (point))))) + (point-marker)))) (org-with-remote-undo buffer (with-current-buffer buffer (widen) @@ -1018,7 +1018,7 @@ This means, between the beginning of line and the point." (and (outline-next-heading) (org-flag-heading nil))) ; show the next heading (org-back-to-heading) - (setq marker (copy-marker (point))) + (setq marker (point-marker)) (goto-char (max (point-at-bol) (- (point-at-eol) anticol))) (funcall command) (message "_cmd: %S" org-mouse-cmd) diff --git a/elpa/org-20150629/org-pcomplete.el b/elpa/org-20160215/org-pcomplete.el similarity index 94% rename from elpa/org-20150629/org-pcomplete.el rename to elpa/org-20160215/org-pcomplete.el index 32dcaa68..e27492c7 100644 --- a/elpa/org-20150629/org-pcomplete.el +++ b/elpa/org-20160215/org-pcomplete.el @@ -1,6 +1,6 @@ ;;; org-pcomplete.el --- In-buffer completion code -;; Copyright (C) 2004-2014 Free Software Foundation, Inc. +;; Copyright (C) 2004-2016 Free Software Foundation, Inc. ;; ;; Author: Carsten Dominik ;; John Wiegley @@ -93,8 +93,10 @@ The return value is a string naming the thing at point." (skip-chars-backward "[ \t\n]") ;; org-drawer-regexp matches a whole line but while ;; looking-back, we just ignore trailing whitespaces - (or (org-looking-back (substring org-drawer-regexp 0 -1)) - (org-looking-back org-property-re)))) + (or (org-looking-back (substring org-drawer-regexp 0 -1) + (line-beginning-position)) + (org-looking-back org-property-re + (line-beginning-position))))) (cons "prop" nil)) ((and (equal (char-before beg1) ?:) (not (equal (char-after (point-at-bol)) ?*))) @@ -272,7 +274,7 @@ When completing for #+STARTUP, for example, this function returns ;; OPTION items from registered back-ends. (let (items) (dolist (backend (org-bound-and-true-p - org-export--registered-backends)) + org-export-registered-backends)) (dolist (option (org-export-backend-options backend)) (let ((item (nth 2 option))) (when item (push (concat item ":") items))))) @@ -363,25 +365,6 @@ This needs more work, to handle headings with lots of spaces in them." lst)) (substring pcomplete-stub 1))) -(defvar org-drawers) - -(defun pcomplete/org-mode/drawer () - "Complete a drawer name." - (let ((spc (save-excursion - (move-beginning-of-line 1) - (looking-at "^\\([ \t]*\\):") - (match-string 1))) - (cpllist (mapcar (lambda (x) (concat x ": ")) org-drawers))) - (pcomplete-here cpllist - (substring pcomplete-stub 1) - (unless (or (not (delq - nil - (mapcar (lambda(x) - (string-match (substring pcomplete-stub 1) x)) - cpllist))) - (looking-at "[ \t]*\n.*:END:")) - (save-excursion (insert "\n" spc ":END:")))))) - (defun pcomplete/org-mode/block-option/src () "Complete the arguments of a begin_src block. Complete a language in the first field, the header arguments and switches." diff --git a/elpa/org-20160215/org-pkg.el b/elpa/org-20160215/org-pkg.el new file mode 100644 index 00000000..cdf6c70a --- /dev/null +++ b/elpa/org-20160215/org-pkg.el @@ -0,0 +1,3 @@ +(define-package "org" + "20160215" "Outline-based notes management and organizer" ( )) +;; no-byte-compile: t diff --git a/elpa/org-20150629/org-plot.el b/elpa/org-20160215/org-plot.el similarity index 77% rename from elpa/org-20150629/org-plot.el rename to elpa/org-20160215/org-plot.el index faa34fc3..9dbf8825 100644 --- a/elpa/org-20150629/org-plot.el +++ b/elpa/org-20160215/org-plot.el @@ -1,6 +1,6 @@ ;;; org-plot.el --- Support for plotting from Org-mode -;; Copyright (C) 2008-2014 Free Software Foundation, Inc. +;; Copyright (C) 2008-2016 Free Software Foundation, Inc. ;; ;; Author: Eric Schulte ;; Keywords: tables, plotting @@ -94,7 +94,7 @@ Return value is the point at the beginning of the table." (goto-char (org-table-begin))) (defun org-plot/collect-options (&optional params) - "Collect options from an org-plot '#+Plot:' line. + "Collect options from an org-plot `#+Plot:' line. Accepts an optional property list PARAMS, to which the options will be added. Returns the resulting property list." (interactive) @@ -187,9 +187,7 @@ NUM-COLS controls the number of columns plotted in a 2-d plot. Optional argument PREFACE returns only option parameters in a manner suitable for prepending to a user-specified script." (let* ((type (plist-get params :plot-type)) - (with (if (equal type 'grid) - 'pm3d - (plist-get params :with))) + (with (if (eq type 'grid) 'pm3d (plist-get params :with))) (sets (plist-get params :set)) (lines (plist-get params :line)) (map (plist-get params :map)) @@ -209,63 +207,66 @@ manner suitable for prepending to a user-specified script." ('3d "splot") ('grid "splot"))) (script "reset") - ; ats = add-to-script - (ats (lambda (line) (setf script (format "%s\n%s" script line)))) + ;; ats = add-to-script + (ats (lambda (line) (setf script (concat script "\n" line)))) plot-lines) - (when file ;; output file + (when file ; output file (funcall ats (format "set term %s" (file-name-extension file))) (funcall ats (format "set output '%s'" file))) - (case type ;; type - ('2d ()) - ('3d (if map (funcall ats "set map"))) - ('grid (if map (funcall ats "set pm3d map") - (funcall ats "set pm3d")))) - (when title (funcall ats (format "set title '%s'" title))) ;; title - (when lines (mapc (lambda (el) (funcall ats el)) lines)) ;; line - (when sets ;; set - (mapc (lambda (el) (funcall ats (format "set %s" el))) sets)) - (when x-labels ;; x labels (xtics) + (case type ; type + (2d ()) + (3d (when map (funcall ats "set map"))) + (grid (if map (funcall ats "set pm3d map") (funcall ats "set pm3d")))) + (when title (funcall ats (format "set title '%s'" title))) ; title + (mapc ats lines) ; line + (dolist (el sets) (funcall ats (format "set %s" el))) ; set + ;; Unless specified otherwise, values are TAB separated. + (unless (org-string-match-p "^set datafile separator" script) + (funcall ats "set datafile separator \"\\t\"")) + (when x-labels ; x labels (xtics) (funcall ats (format "set xtics (%s)" (mapconcat (lambda (pair) (format "\"%s\" %d" (cdr pair) (car pair))) x-labels ", ")))) - (when y-labels ;; y labels (ytics) + (when y-labels ; y labels (ytics) (funcall ats (format "set ytics (%s)" (mapconcat (lambda (pair) (format "\"%s\" %d" (cdr pair) (car pair))) y-labels ", ")))) - (when time-ind ;; timestamp index + (when time-ind ; timestamp index (funcall ats "set xdata time") (funcall ats (concat "set timefmt \"" - (or timefmt ;; timefmt passed to gnuplot + (or timefmt ; timefmt passed to gnuplot "%Y-%m-%d-%H:%M:%S") "\""))) (unless preface - (case type ;; plot command - ('2d (dotimes (col num-cols) - (unless (and (equal type '2d) - (or (and ind (equal (+ 1 col) ind)) - (and deps (not (member (+ 1 col) deps))))) - (setf plot-lines - (cons - (format plot-str data-file - (or (and ind (> ind 0) - (not text-ind) - (format "%d:" ind)) "") - (+ 1 col) - (if text-ind (format ":xticlabel(%d)" ind) "") - with - (or (nth col col-labels) (format "%d" (+ 1 col)))) - plot-lines))))) - ('3d + (case type ; plot command + (2d (dotimes (col num-cols) + (unless (and (eq type '2d) + (or (and ind (equal (1+ col) ind)) + (and deps (not (member (1+ col) deps))))) + (setf plot-lines + (cons + (format plot-str data-file + (or (and ind (> ind 0) + (not text-ind) + (format "%d:" ind)) "") + (1+ col) + (if text-ind (format ":xticlabel(%d)" ind) "") + with + (or (nth col col-labels) (format "%d" (1+ col)))) + plot-lines))))) + (3d (setq plot-lines (list (format "'%s' matrix with %s title ''" data-file with)))) - ('grid + (grid (setq plot-lines (list (format "'%s' with %s title ''" data-file with))))) (funcall ats - (concat plot-cmd " " (mapconcat 'identity (reverse plot-lines) ",\\\n ")))) + (concat plot-cmd " " (mapconcat #'identity + (reverse plot-lines) + ",\\\n ")))) script)) ;;----------------------------------------------------------------------------- @@ -279,59 +280,58 @@ line directly before or after the table." (require 'gnuplot) (save-window-excursion (delete-other-windows) - (when (get-buffer "*gnuplot*") ;; reset *gnuplot* if it already running + (when (get-buffer "*gnuplot*") ; reset *gnuplot* if it already running (with-current-buffer "*gnuplot*" (goto-char (point-max)))) (org-plot/goto-nearest-table) - ;; set default options - (mapc - (lambda (pair) - (unless (plist-member params (car pair)) - (setf params (plist-put params (car pair) (cdr pair))))) - org-plot/gnuplot-default-options) + ;; Set default options. + (dolist (pair org-plot/gnuplot-default-options) + (unless (plist-member params (car pair)) + (setf params (plist-put params (car pair) (cdr pair))))) ;; collect table and table information (let* ((data-file (make-temp-file "org-plot")) (table (org-table-to-lisp)) (num-cols (length (if (eq (first table) 'hline) (second table) (first table))))) (run-with-idle-timer 0.1 nil #'delete-file data-file) - (while (equal 'hline (first table)) (setf table (cdr table))) - (when (equal (second table) 'hline) - (setf params (plist-put params :labels (first table))) ;; headers to labels - (setf table (delq 'hline (cdr table)))) ;; clean non-data from table - ;; collect options + (while (eq 'hline (car table)) (setf table (cdr table))) + (when (eq (cadr table) 'hline) + (setf params (plist-put params :labels (first table))) ; headers to labels + (setf table (delq 'hline (cdr table)))) ; clean non-data from table + ;; Collect options. (save-excursion (while (and (equal 0 (forward-line -1)) (looking-at "[[:space:]]*#\\+")) (setf params (org-plot/collect-options params)))) - ;; dump table to datafile (very different for grid) + ;; Dump table to datafile (very different for grid). (case (plist-get params :plot-type) - ('2d (org-plot/gnuplot-to-data table data-file params)) - ('3d (org-plot/gnuplot-to-data table data-file params)) - ('grid (let ((y-labels (org-plot/gnuplot-to-grid-data - table data-file params))) - (when y-labels (plist-put params :ylabels y-labels))))) - ;; check for timestamp ind column - (let ((ind (- (plist-get params :ind) 1))) - (when (and (>= ind 0) (equal '2d (plist-get params :plot-type))) + (2d (org-plot/gnuplot-to-data table data-file params)) + (3d (org-plot/gnuplot-to-data table data-file params)) + (grid (let ((y-labels (org-plot/gnuplot-to-grid-data + table data-file params))) + (when y-labels (plist-put params :ylabels y-labels))))) + ;; Check for timestamp ind column. + (let ((ind (1- (plist-get params :ind)))) + (when (and (>= ind 0) (eq '2d (plist-get params :plot-type))) (if (= (length (delq 0 (mapcar (lambda (el) - (if (string-match org-ts-regexp3 el) - 0 1)) - (mapcar (lambda (row) (nth ind row)) table)))) 0) + (if (string-match org-ts-regexp3 el) 0 1)) + (mapcar (lambda (row) (nth ind row)) table)))) + 0) (plist-put params :timeind t) - ;; check for text ind column + ;; Check for text ind column. (if (or (string= (plist-get params :with) "hist") (> (length (delq 0 (mapcar (lambda (el) (if (string-match org-table-number-regexp el) 0 1)) - (mapcar (lambda (row) (nth ind row)) table)))) 0)) + (mapcar (lambda (row) (nth ind row)) table)))) + 0)) (plist-put params :textind t))))) - ;; write script + ;; Write script. (with-temp-buffer - (if (plist-get params :script) ;; user script + (if (plist-get params :script) ; user script (progn (insert (org-plot/gnuplot-script data-file num-cols params t)) (insert "\n") @@ -339,12 +339,11 @@ line directly before or after the table." (goto-char (point-min)) (while (re-search-forward "$datafile" nil t) (replace-match data-file nil nil))) - (insert - (org-plot/gnuplot-script data-file num-cols params))) - ;; graph table + (insert (org-plot/gnuplot-script data-file num-cols params))) + ;; Graph table. (gnuplot-mode) (gnuplot-send-buffer-to-gnuplot)) - ;; cleanup + ;; Cleanup. (bury-buffer (get-buffer "*gnuplot*"))))) (provide 'org-plot) diff --git a/elpa/org-20150629/org-protocol.el b/elpa/org-20160215/org-protocol.el similarity index 96% rename from elpa/org-20150629/org-protocol.el rename to elpa/org-20160215/org-protocol.el index 0c6f2de3..2f2c54b6 100644 --- a/elpa/org-20150629/org-protocol.el +++ b/elpa/org-20160215/org-protocol.el @@ -1,6 +1,6 @@ ;;; org-protocol.el --- Intercept calls from emacsclient to trigger custom actions. ;; -;; Copyright (C) 2008-2014 Free Software Foundation, Inc. +;; Copyright (C) 2008-2016 Free Software Foundation, Inc. ;; ;; Authors: Bastien Guerry ;; Daniel M German @@ -197,7 +197,7 @@ Possible properties are: Example: (setq org-protocol-project-alist - '((\"http://orgmode.org/worg/\" + \\='((\"http://orgmode.org/worg/\" :online-suffix \".php\" :working-suffix \".org\" :base-url \"http://orgmode.org/worg/\" @@ -251,7 +251,7 @@ kill-client - If t, kill the client immediately, once the sub-protocol is Here is an example: (setq org-protocol-protocol-alist - '((\"my-protocol\" + \\='((\"my-protocol\" :protocol \"my-protocol\" :function my-protocol-handler-function) (\"your-protocol\" @@ -303,7 +303,7 @@ part." (defun org-protocol-flatten-greedy (param-list &optional strip-path replacement) "Greedy handlers might receive a list like this from emacsclient: - '((\"/dir/org-protocol:/greedy:/~/path1\" (23 . 12)) (\"/dir/param\") + ((\"/dir/org-protocol:/greedy:/~/path1\" (23 . 12)) (\"/dir/param\")) where \"/dir/\" is the absolute path to emacsclients working directory. This function transforms it into a flat list using `org-protocol-flatten' and transforms the elements of that list as follows: @@ -347,7 +347,7 @@ returned list." (defun org-protocol-flatten (l) "Greedy handlers might receive a list like this from emacsclient: - '( (\"/dir/org-protocol:/greedy:/~/path1\" (23 . 12)) (\"/dir/param\") + ((\"/dir/org-protocol:/greedy:/~/path1\" (23 . 12)) (\"/dir/param\")) where \"/dir/\" is the absolute path to emacsclients working directory. This function transforms it into a flat list." (if (null l) () @@ -365,9 +365,9 @@ link's URL to the `kill-ring'. The location for a browser's bookmark has to look like this: - javascript:location.href='org-protocol://store-link://'+ \\ + javascript:location.href=\\='org-protocol://store-link://\\='+ \\ encodeURIComponent(location.href) - encodeURIComponent(document.title)+'/'+ \\ + encodeURIComponent(document.title)+\\='/\\='+ \\ Don't use `escape()'! Use `encodeURIComponent()' instead. The title of the page could contain slashes and the location definitely will. @@ -394,18 +394,18 @@ The sub-protocol used to reach this function is set in `org-protocol-protocol-alist'. This function detects an URL, title and optional text, separated -by '/'. The location for a browser's bookmark looks like this: +by `/'. The location for a browser's bookmark looks like this: - javascript:location.href='org-protocol://capture://'+ \\ - encodeURIComponent(location.href)+'/' \\ - encodeURIComponent(document.title)+'/'+ \\ + javascript:location.href=\\='org-protocol://capture://\\='+ \\ + encodeURIComponent(location.href)+\\='/\\=' \\ + encodeURIComponent(document.title)+\\='/\\='+ \\ encodeURIComponent(window.getSelection()) By default, it uses the character `org-protocol-default-template-key', which should be associated with a template in `org-capture-templates'. But you may prepend the encoded URL with a character and a slash like so: - javascript:location.href='org-protocol://capture://b/'+ ... + javascript:location.href=\\='org-protocol://capture://b/\\='+ ... Now template ?b will be used." (if (and (boundp 'org-stored-links) @@ -455,7 +455,7 @@ in `org-protocol-project-alist'. The location for a browser's bookmark should look like this: - javascript:location.href='org-protocol://open-source://'+ \\ + javascript:location.href=\\='org-protocol://open-source://\\='+ \\ encodeURIComponent(location.href)" ;; As we enter this function for a match on our protocol, the return value ;; defaults to nil. @@ -561,7 +561,7 @@ as filename." (let ((fname (expand-file-name (car var)))) (setq fname (org-protocol-check-filename-for-protocol fname (member var flist) client)) - (if (eq fname t) ;; greedy? We need the `t' return value. + (if (eq fname t) ;; greedy? We need the t return value. (progn (ad-set-arg 0 nil) (throw 'greedy t)) diff --git a/elpa/org-20150629/org-rmail.el b/elpa/org-20160215/org-rmail.el similarity index 96% rename from elpa/org-20150629/org-rmail.el rename to elpa/org-20160215/org-rmail.el index 6859b659..d737aff4 100644 --- a/elpa/org-20150629/org-rmail.el +++ b/elpa/org-20160215/org-rmail.el @@ -1,6 +1,6 @@ ;;; org-rmail.el --- Support for links to Rmail messages from within Org-mode -;; Copyright (C) 2004-2014 Free Software Foundation, Inc. +;; Copyright (C) 2004-2016 Free Software Foundation, Inc. ;; Author: Carsten Dominik ;; Keywords: outlines, hypermedia, calendar, wp @@ -36,9 +36,11 @@ (declare-function rmail-show-message "rmail" (&optional n no-summary)) (declare-function rmail-what-message "rmail" (&optional pos)) (declare-function rmail-toggle-header "rmail" (&optional arg)) +(declare-function rmail "rmail" (&optional file-name-arg)) (declare-function rmail-widen "rmail" ()) (defvar rmail-current-message) ; From rmail.el (defvar rmail-header-style) ; From rmail.el +(defvar rmail-file-name) ; From rmail.el ;; Install the link type (org-add-link-type "rmail" 'org-rmail-open) diff --git a/elpa/org-20160215/org-src.el b/elpa/org-20160215/org-src.el new file mode 100644 index 00000000..b7bbf31f --- /dev/null +++ b/elpa/org-20160215/org-src.el @@ -0,0 +1,979 @@ +;;; org-src.el --- Source code examples in Org +;; +;; Copyright (C) 2004-2016 Free Software Foundation, Inc. +;; +;; Author: Carsten Dominik +;; Bastien Guerry +;; Dan Davison +;; Keywords: outlines, hypermedia, calendar, wp +;; Homepage: http://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 . +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: + +;; This file contains the code dealing with source code examples in Org-mode. + +;;; Code: + +(require 'org-macs) +(require 'org-compat) +(require 'ob-keys) +(require 'ob-comint) +(eval-when-compile (require 'cl)) + +(declare-function org-base-buffer "org" (buffer)) +(declare-function org-do-remove-indentation "org" (&optional n)) +(declare-function org-element-at-point "org-element" ()) +(declare-function org-element-context "org-element" (&optional element)) +(declare-function org-element-lineage "org-element" + (blob &optional types with-self)) +(declare-function org-element-property "org-element" (property element)) +(declare-function org-element-type "org-element" (element)) +(declare-function org-footnote-goto-definition "org-footnote" + (label &optional location)) +(declare-function org-get-indentation "org" (&optional line)) +(declare-function org-pop-to-buffer-same-window "org-compat" + (&optional buffer-or-name norecord label)) +(declare-function org-some "org" (pred seq)) +(declare-function org-switch-to-buffer-other-window "org" (&rest args)) +(declare-function org-trim "org" (s)) + +(defvar org-element-all-elements) +(defvar org-inhibit-startup) + +(defcustom org-edit-src-turn-on-auto-save nil + "Non-nil means turn `auto-save-mode' on when editing a source block. +This will save the content of the source code editing buffer into +a newly created file, not the base buffer for this source block. + +If you want to regularly save the base buffer instead of the source +code editing buffer, see `org-edit-src-auto-save-idle-delay' instead." + :group 'org-edit-structure + :version "24.4" + :package-version '(Org . "8.0") + :type 'boolean) + +(defcustom org-edit-src-auto-save-idle-delay 0 + "Delay before saving a source code buffer back into its base buffer. +When a positive integer N, save after N seconds of idle time. +When 0 (the default), don't auto-save. + +If you want to save the source code buffer itself, don't use this. +Check `org-edit-src-turn-on-auto-save' instead." + :group 'org-edit-structure + :version "24.4" + :package-version '(Org . "8.0") + :type 'integer) + +(defcustom org-coderef-label-format "(ref:%s)" + "The default coderef format. +This format string will be used to search for coderef labels in literal +examples (EXAMPLE and SRC blocks). The format can be overwritten in +an individual literal example with the -l option, like + +#+BEGIN_SRC pascal +n -r -l \"((%s))\" +... +#+END_SRC + +If you want to use this for HTML export, make sure that the format does +not introduce special font-locking, and avoid the HTML special +characters `<', `>', and `&'. The reason for this restriction is that +the labels are searched for only after htmlize has done its job." + :group 'org-edit-structure ; FIXME this is not in the right group + :type 'string) + +(defcustom org-edit-fixed-width-region-mode 'artist-mode + "The mode that should be used to edit fixed-width regions. +These are the regions where each line starts with a colon." + :group 'org-edit-structure + :type '(choice + (const artist-mode) + (const picture-mode) + (const fundamental-mode) + (function :tag "Other (specify)"))) + +(defcustom org-src-preserve-indentation nil + "If non-nil preserve leading whitespace characters on export. +If non-nil leading whitespace characters in source code blocks +are preserved on export, and when switching between the org +buffer and the language mode edit buffer. + +When this variable is nil, after editing with \\[org-edit-src-code], +the minimum (across-lines) number of leading whitespace characters +are removed from all lines, and the code block is uniformly indented +according to the value of `org-edit-src-content-indentation'." + :group 'org-edit-structure + :type 'boolean) + +(defcustom org-edit-src-content-indentation 2 + "Indentation for the content of a source code block. +This should be the number of spaces added to the indentation of the #+begin +line in order to compute the indentation of the block content after +editing it with \\[org-edit-src-code]. Has no effect if +`org-src-preserve-indentation' is non-nil." + :group 'org-edit-structure + :type 'integer) + +(defcustom org-edit-src-persistent-message t + "Non-nil means show persistent exit help message while editing src examples. +The message is shown in the header-line, which will be created in the +first line of the window showing the editing buffer." + :group 'org-edit-structure + :type 'boolean) + +(defcustom org-src-ask-before-returning-to-edit-buffer t + "Non-nil means ask before switching to an existing edit buffer. +If nil, when `org-edit-src-code' is used on a block that already +has an active edit buffer, it will switch to that edit buffer +immediately; otherwise it will ask whether you want to return to +the existing edit buffer." + :group 'org-edit-structure + :version "24.4" + :package-version '(Org . "8.0") + :type 'boolean) + +(defcustom org-src-window-setup 'reorganize-frame + "How the source code edit buffer should be displayed. +Possible values for this option are: + +current-window Show edit buffer in 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, + return to one window. +other-frame Use `switch-to-buffer-other-frame' to display edit buffer. + Also, when exiting the edit buffer, kill that frame." + :group 'org-edit-structure + :type '(choice + (const current-window) + (const other-frame) + (const other-window) + (const reorganize-frame))) + +(defvar org-src-mode-hook nil + "Hook run after Org switched a source code snippet to its Emacs mode. +\\ +This hook will run: +- when editing a source code snippet with \\[org-edit-special] +- when formatting a source code snippet for export with htmlize. + +You may want to use this hook for example to turn off `outline-minor-mode' +or similar things which you want to have when editing a source code file, +but which mess up the display of a snippet in Org exported files.") + +(defcustom org-src-lang-modes + '(("ocaml" . tuareg) ("elisp" . emacs-lisp) ("ditaa" . artist) + ("asymptote" . asy) ("dot" . fundamental) ("sqlite" . sql) + ("calc" . fundamental) ("C" . c) ("cpp" . c++) ("C++" . c++) + ("screen" . shell-script) ("shell" . sh) ("bash" . sh)) + "Alist mapping languages to their major mode. +The key is the language name, the value is the string that should +be inserted as the name of the major mode. For many languages this is +simple, but for language where this is not the case, this variable +provides a way to simplify things on the user side. +For example, there is no ocaml-mode in Emacs, but the mode to use is +`tuareg-mode'." + :group 'org-edit-structure + :type '(repeat + (cons + (string "Language name") + (symbol "Major mode")))) + +(defcustom org-src-tab-acts-natively nil + "If non-nil, the effect of TAB in a code block is as if it were +issued in the language major mode buffer." + :type 'boolean + :version "24.1" + :group 'org-babel) + + + +;;; Internal functions and variables + +(defvar org-src--allow-write-back t) +(defvar org-src--auto-save-timer nil) +(defvar org-src--babel-info nil) +(defvar org-src--beg-marker nil) +(defvar org-src--block-indentation nil) +(defvar org-src--end-marker nil) +(defvar org-src--from-org-mode nil) +(defvar org-src--overlay nil) +(defvar org-src--preserve-indentation nil) +(defvar org-src--remote nil) +(defvar org-src--saved-temp-window-config nil) + +(defun org-src--construct-edit-buffer-name (org-buffer-name lang) + "Construct the buffer name for a source editing buffer." + (concat "*Org Src " org-buffer-name "[ " lang " ]*")) + +(defun org-src--edit-buffer (beg end) + "Return buffer editing area between BEG and END. +Return nil if there is no such buffer." + (catch 'exit + (dolist (b (buffer-list)) + (with-current-buffer b + (and (org-src-edit-buffer-p) + (= beg org-src--beg-marker) + (eq (marker-buffer beg) (marker-buffer org-src--beg-marker)) + (= end org-src--end-marker) + (eq (marker-buffer end) (marker-buffer org-src--end-marker)) + (throw 'exit b)))))) + +(defun org-src--source-buffer () + "Return source buffer edited by current buffer." + (unless (org-src-edit-buffer-p) (error "Not in a source buffer")) + (or (marker-buffer org-src--beg-marker) + (error "No source buffer available for current editing session"))) + +(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 +a cons cell (LINE . COLUMN) or symbol `end'. See also +`org-src--goto-coordinates'." + (if (>= pos end) 'end + (org-with-wide-buffer + (goto-char (max beg pos)) + (cons (count-lines beg (line-beginning-position)) + ;; Column is relative to the end of line to avoid problems of + ;; comma escaping or colons appended in front of the line. + (- (current-column) + (progn (end-of-line) (current-column))))))) + +(defun org-src--goto-coordinates (coord beg end) + "Move to coordinates COORD relatively to BEG and END. +COORD are coordinates, as returned by `org-src--coordinates', +which see. BEG and END are buffer positions." + (goto-char + (if (eq coord 'end) (max (1- end) beg) + ;; If BEG happens to be located outside of the narrowed part of + ;; the buffer, widen it first. + (org-with-wide-buffer + (goto-char beg) + (forward-line (car coord)) + (end-of-line) + (org-move-to-column (max (+ (current-column) (cdr coord)) 0)) + (point))))) + +(defun org-src--contents-area (datum) + "Return contents boundaries of DATUM. +DATUM is an element or object. Return a list (BEG END CONTENTS) +where BEG and END are buffer positions and CONTENTS is a string." + (let ((type (org-element-type datum))) + (org-with-wide-buffer + (cond + ((eq type 'footnote-definition) + (let* ((beg (progn + (goto-char (org-element-property :post-affiliated datum)) + (search-forward "]"))) + (end (or (org-element-property :contents-end datum) beg))) + (list beg end (buffer-substring-no-properties beg end)))) + ((org-element-property :contents-begin datum) + (let ((beg (org-element-property :contents-begin datum)) + (end (org-element-property :contents-end datum))) + (list beg end (buffer-substring-no-properties beg end)))) + ((memq type '(example-block export-block src-block)) + (list (progn (goto-char (org-element-property :post-affiliated datum)) + (line-beginning-position 2)) + (progn (goto-char (org-element-property :end datum)) + (skip-chars-backward " \r\t\n") + (line-beginning-position 1)) + (org-element-property :value datum))) + ((memq type '(fixed-width table)) + (let ((beg (org-element-property :post-affiliated datum)) + (end (progn (goto-char (org-element-property :end datum)) + (skip-chars-backward " \r\t\n") + (line-beginning-position 2)))) + (list beg + end + (if (eq type 'fixed-width) (org-element-property :value datum) + (buffer-substring-no-properties beg end))))) + (t (error "Unsupported element or object: %s" type)))))) + +(defun org-src--make-source-overlay (beg end edit-buffer) + "Create overlay between BEG and END positions and return it. +EDIT-BUFFER is the buffer currently editing area between BEG and +END." + (let ((overlay (make-overlay beg end))) + (overlay-put overlay 'face 'secondary-selection) + (overlay-put overlay 'edit-buffer edit-buffer) + (overlay-put overlay 'help-echo + "Click with mouse-1 to switch to buffer editing this segment") + (overlay-put overlay 'face 'secondary-selection) + (overlay-put overlay 'keymap + (let ((map (make-sparse-keymap))) + (define-key map [mouse-1] 'org-edit-src-continue) + map)) + (let ((read-only + (list + (lambda (&rest _) + (user-error + "Cannot modify an area being edited in a dedicated buffer"))))) + (overlay-put overlay 'modification-hooks read-only) + (overlay-put overlay 'insert-in-front-hooks read-only) + (overlay-put overlay 'insert-behind-hooks read-only)) + overlay)) + +(defun org-src--remove-overlay () + "Remove overlay from current source buffer." + (when (overlayp org-src--overlay) (delete-overlay org-src--overlay))) + +(defun org-src--on-datum-p (datum) + "Non-nil when point is on DATUM. +DATUM is an element or an object. Consider blank lines or white +spaces after it as being outside." + (and (>= (point) (org-element-property :begin datum)) + (<= (point) + (org-with-wide-buffer + (goto-char (org-element-property :end datum)) + (skip-chars-backward " \r\t\n") + (if (memq (org-element-type datum) org-element-all-elements) + (line-end-position) + (point)))))) + +(defun org-src--contents-for-write-back () + "Return buffer contents in a format appropriate for write back. +Assume point is in the corresponding edit buffer." + (let ((indentation (or org-src--block-indentation 0)) + (preserve-indentation org-src--preserve-indentation) + (contents (org-with-wide-buffer (buffer-string))) + (write-back org-src--allow-write-back)) + (with-temp-buffer + (insert (org-no-properties contents)) + (goto-char (point-min)) + (when (functionp write-back) (funcall write-back)) + (unless (or preserve-indentation (= indentation 0)) + (let ((ind (make-string indentation ?\s))) + (goto-char (point-min)) + (while (not (eobp)) + (when (org-looking-at-p "[ \t]*\\S-") (insert ind)) + (forward-line)))) + (buffer-string)))) + +(defun org-src--edit-element + (datum name &optional major write-back contents remote) + "Edit DATUM contents in a dedicated buffer NAME. + +MAJOR is the major mode used in the edit buffer. A nil value is +equivalent to `fundamental-mode'. + +When WRITE-BACK is non-nil, assume contents will replace original +region. Moreover, if it is a function, apply it in the edit +buffer, from point min, before returning the contents. + +When CONTENTS is non-nil, display them in the edit buffer. +Otherwise, show DATUM contents as specified by +`org-src--contents-area'. + +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)) + (old-edit-buffer (org-src--edit-buffer beg end)) + (contents (or contents (nth 2 area)))) + (if (and old-edit-buffer + (or (not org-src-ask-before-returning-to-edit-buffer) + (y-or-n-p "Return to existing edit buffer ([n] will revert changes)? "))) + ;; Move to existing buffer. + (org-src-switch-to-buffer old-edit-buffer 'return) + ;; Discard old edit buffer. + (when old-edit-buffer + (with-current-buffer old-edit-buffer (org-src--remove-overlay)) + (kill-buffer old-edit-buffer)) + (let* ((org-mode-p (derived-mode-p 'org-mode)) + (type (org-element-type datum)) + (ind (org-with-wide-buffer + (goto-char (org-element-property :begin datum)) + (org-get-indentation))) + (preserve-ind + (and (memq type '(example-block src-block)) + (or (org-element-property :preserve-indent datum) + org-src-preserve-indentation))) + ;; Store relative positions of mark (if any) and point + ;; within the edited area. + (point-coordinates (and (not remote) + (org-src--coordinates (point) beg end))) + (mark-coordinates (and (not remote) + (org-region-active-p) + (let ((m (mark))) + (and (>= m beg) (>= end m) + (org-src--coordinates m beg end))))) + ;; Generate a new edit buffer. + (buffer (generate-new-buffer name)) + ;; Add an overlay on top of source. + (overlay (org-src--make-source-overlay beg end buffer))) + ;; Switch to edit buffer. + (org-src-switch-to-buffer buffer 'edit) + ;; Insert contents. + (insert contents) + (remove-text-properties (point-min) (point-max) + '(display nil invisible nil intangible nil)) + (unless preserve-ind (org-do-remove-indentation)) + (set-buffer-modified-p nil) + (setq buffer-file-name nil) + ;; Start major mode. + (if (not major) (fundamental-mode) + (let ((org-inhibit-startup t)) + (condition-case e (funcall major) + (error (message "Language mode `%s' fails with: %S" + major (nth 1 e)))))) + ;; Transmit buffer-local variables for exit function. It must + ;; be done after initializing major mode, as this operation + ;; may reset them otherwise. + (org-set-local 'org-src--from-org-mode org-mode-p) + (org-set-local 'org-src--beg-marker beg) + (org-set-local 'org-src--end-marker end) + (org-set-local 'org-src--remote remote) + (org-set-local 'org-src--block-indentation ind) + (org-set-local 'org-src--preserve-indentation preserve-ind) + (org-set-local 'org-src--overlay overlay) + (org-set-local 'org-src--allow-write-back write-back) + ;; Start minor mode. + (org-src-mode) + ;; Move mark and point in edit buffer to the corresponding + ;; location. + (if remote + (progn + ;; Put point at first non read-only character after + ;; leading blank. + (goto-char + (or (text-property-any (point-min) (point-max) 'read-only nil) + (point-max))) + (skip-chars-forward " \r\t\n")) + ;; Set mark and point. + (when mark-coordinates + (org-src--goto-coordinates mark-coordinates (point-min) (point-max)) + (push-mark (point) 'no-message t) + (setq deactivate-mark nil)) + (org-src--goto-coordinates + point-coordinates (point-min) (point-max))))))) + + + +;;; Fontification of source blocks + +(defun org-src-font-lock-fontify-block (lang start end) + "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))) + (when (fboundp lang-mode) + (let ((string (buffer-substring-no-properties start end)) + (modified (buffer-modified-p)) + (org-buffer (current-buffer)) pos next) + (remove-text-properties start end '(face nil)) + (with-current-buffer + (get-buffer-create + (concat " org-src-fontification:" (symbol-name lang-mode))) + (delete-region (point-min) (point-max)) + (insert string " ") ;; so there's a final property change + (unless (eq major-mode lang-mode) (funcall lang-mode)) + (org-font-lock-ensure) + (setq pos (point-min)) + (while (setq next (next-single-property-change pos 'face)) + (put-text-property + (+ start (1- pos)) (1- (+ start next)) 'face + (get-text-property pos 'face) org-buffer) + (setq pos next))) + (add-text-properties + start end + '(font-lock-fontified t fontified t font-lock-multiline t)) + (set-buffer-modified-p modified))))) + + + +;;; Escape contents + +(defun org-escape-code-in-region (beg end) + "Escape lines between BEG and END. +Escaping happens when a line starts with \"*\", \"#+\", \",*\" or +\",#+\" by appending a comma to it." + (interactive "r") + (save-excursion + (goto-char end) + (while (re-search-backward "^[ \t]*,?\\(\\*\\|#\\+\\)" beg t) + (save-excursion (replace-match ",\\1" nil nil nil 1))))) + +(defun org-escape-code-in-string (s) + "Escape lines in string S. +Escaping happens when a line starts with \"*\", \"#+\", \",*\" or +\",#+\" by appending a comma to it." + (replace-regexp-in-string "^[ \t]*,?\\(\\*\\|#\\+\\)" ",\\1" s nil nil 1)) + +(defun org-unescape-code-in-region (beg end) + "Un-escape lines between BEG and END. +Un-escaping happens by removing the first comma on lines starting +with \",*\", \",#+\", \",,*\" and \",,#+\"." + (interactive "r") + (save-excursion + (goto-char end) + (while (re-search-backward "^[ \t]*,?\\(,\\)\\(?:\\*\\|#\\+\\)" beg t) + (save-excursion (replace-match "" nil nil nil 1))))) + +(defun org-unescape-code-in-string (s) + "Un-escape lines in string S. +Un-escaping happens by removing the first comma on lines starting +with \",*\", \",#+\", \",,*\" and \",,#+\"." + (replace-regexp-in-string + "^[ \t]*,?\\(,\\)\\(?:\\*\\|#\\+\\)" "" s nil nil 1)) + + + +;;; Org src minor mode + +(defvar org-src-mode-map + (let ((map (make-sparse-keymap))) + (define-key map "\C-c'" 'org-edit-src-exit) + (define-key map "\C-c\C-k" 'org-edit-src-abort) + (define-key map "\C-x\C-s" 'org-edit-src-save) + map)) + +(define-minor-mode org-src-mode + "Minor mode for language major mode buffers generated by Org. +\\ +This minor mode is turned on in two situations: + - when editing a source code snippet with \\[org-edit-special] + - when formatting a source code snippet for export with htmlize. + +\\{org-src-mode-map} + +See also `org-src-mode-hook'." + nil " OrgSrc" nil + (when org-edit-src-persistent-message + (org-set-local + 'header-line-format + (substitute-command-keys + (if org-src--allow-write-back + "Edit, then exit with \\[org-edit-src-exit] or abort with \ +\\[org-edit-src-abort]" + "Exit with \\[org-edit-src-exit] or abort with \ +\\[org-edit-src-abort]")))) + ;; Possibly activate various auto-save features (for the edit buffer + ;; or the source buffer). + (when org-edit-src-turn-on-auto-save + (setq buffer-auto-save-file-name + (concat (make-temp-name "org-src-") + (format-time-string "-%Y-%d-%m") + ".txt"))) + (unless (or org-src--auto-save-timer (zerop org-edit-src-auto-save-idle-delay)) + (setq org-src--auto-save-timer + (run-with-idle-timer + org-edit-src-auto-save-idle-delay t + (lambda () + (save-excursion + (let (edit-flag) + (dolist (b (buffer-list)) + (with-current-buffer b + (when (org-src-edit-buffer-p) + (unless edit-flag (setq edit-flag t)) + (when (buffer-modified-p) (org-edit-src-save))))) + (unless edit-flag + (cancel-timer org-src--auto-save-timer) + (setq org-src--auto-save-timer nil))))))))) + +(defun org-src-mode-configure-edit-buffer () + (when (org-bound-and-true-p org-src--from-org-mode) + (org-add-hook 'kill-buffer-hook #'org-src--remove-overlay nil 'local) + (if (org-bound-and-true-p org-src--allow-write-back) + (progn + (setq buffer-offer-save t) + (setq buffer-file-name + (concat (buffer-file-name (marker-buffer org-src--beg-marker)) + "[" (buffer-name) "]")) + (if (featurep 'xemacs) + (progn + (make-variable-buffer-local 'write-contents-hooks) ; needed only for 21.4 + (setq write-contents-hooks '(org-edit-src-save))) + (setq write-contents-functions '(org-edit-src-save)))) + (setq buffer-read-only t)))) + +(org-add-hook 'org-src-mode-hook #'org-src-mode-configure-edit-buffer) + + + +;;; Babel related functions + +(defun org-src-associate-babel-session (info) + "Associate edit buffer with comint session." + (interactive) + (let ((session (cdr (assoc :session (nth 2 info))))) + (and session (not (string= session "none")) + (org-babel-comint-buffer-livep session) + (let ((f (intern (format "org-babel-%s-associate-session" + (nth 0 info))))) + (and (fboundp f) (funcall f session)))))) + +(defun org-src-babel-configure-edit-buffer () + (when org-src--babel-info + (org-src-associate-babel-session org-src--babel-info))) + +(org-add-hook 'org-src-mode-hook #'org-src-babel-configure-edit-buffer) + +(defmacro org-src-do-at-code-block (&rest body) + "Execute a command from an edit buffer in the Org mode buffer." + `(let ((beg-marker org-src--beg-marker)) + (when beg-marker + (with-current-buffer (marker-buffer beg-marker) + (goto-char beg-marker) + ,@body)))) +(def-edebug-spec org-src-do-at-code-block (body)) + +(defun org-src-do-key-sequence-at-code-block (&optional key) + "Execute key sequence at code block in the source Org buffer. +The command bound to KEY in the Org-babel key map is executed +remotely with point temporarily at the start of the code block in +the Org buffer. + +This command is not bound to a key by default, to avoid conflicts +with language major mode bindings. To bind it to C-c @ in all +language major modes, you could use + + (add-hook \\='org-src-mode-hook + (lambda () (define-key org-src-mode-map \"\\C-c@\" + \\='org-src-do-key-sequence-at-code-block))) + +In that case, for example, C-c @ t issued in code edit buffers +would tangle the current Org code block, C-c @ e would execute +the block and C-c @ h would display the other available +Org-babel commands." + (interactive "kOrg-babel key: ") + (if (equal key (kbd "C-g")) (keyboard-quit) + (org-edit-src-save) + (org-src-do-at-code-block + (call-interactively (lookup-key org-babel-map key))))) + + + +;;; Public functions + +(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." + (let ((buffer (org-base-buffer (or buffer (current-buffer))))) + (and (buffer-live-p buffer) + (local-variable-p 'org-src--beg-marker buffer) + (local-variable-p 'org-src--end-marker buffer)))) + +(defun org-src-switch-to-buffer (buffer context) + (case org-src-window-setup + (current-window (org-pop-to-buffer-same-window buffer)) + (other-window + (switch-to-buffer-other-window buffer)) + (other-frame + (case context + (exit + (let ((frame (selected-frame))) + (switch-to-buffer-other-frame buffer) + (delete-frame frame))) + (save + (kill-buffer (current-buffer)) + (org-pop-to-buffer-same-window buffer)) + (t (switch-to-buffer-other-frame buffer)))) + (reorganize-frame + (when (eq context 'edit) (delete-other-windows)) + (org-switch-to-buffer-other-window buffer) + (when (eq context 'exit) (delete-other-windows))) + (switch-invisibly (set-buffer buffer)) + (t + (message "Invalid value %s for `org-src-window-setup'" + org-src-window-setup) + (org-pop-to-buffer-same-window buffer)))) + +(defun org-edit-footnote-reference () + "Edit definition of footnote reference at point." + (interactive) + (let* ((context (org-element-context)) + (label (org-element-property :label context))) + (unless (and (eq (org-element-type context) 'footnote-reference) + (org-src--on-datum-p context)) + (user-error "Not on a footnote reference")) + (unless label (user-error "Cannot edit remotely anonymous footnotes")) + (let* ((definition (org-with-wide-buffer + (org-footnote-goto-definition label) + (backward-char) + (org-element-context))) + (inline (eq (org-element-type definition) 'footnote-reference)) + (contents + (let ((c (org-with-wide-buffer + (org-trim (buffer-substring-no-properties + (org-element-property :begin definition) + (org-element-property :end definition)))))) + (add-text-properties + 0 + (progn (string-match (if inline "\\`\\[fn:.*?:" "\\`.*?\\]") c) + (match-end 0)) + '(read-only "Cannot edit footnote label" front-sticky t + rear-nonsticky t) + c) + (when inline + (let ((l (length c))) + (add-text-properties + (1- l) l + '(read-only "Cannot edit past footnote reference" + front-sticky nil rear-nonsticky nil) + c))) + c))) + (org-src--edit-element + definition + (format "*Edit footnote [%s]*" label) + #'org-mode + `(lambda () + (if ,(not inline) (delete-region (point) (search-forward "]")) + (delete-region (point) (search-forward ":" nil t 2)) + (delete-region (1- (point-max)) (point-max)) + (when (re-search-forward "\n[ \t]*\n" nil t) + (user-error "Inline definitions cannot contain blank lines")) + ;; If footnote reference belongs to a table, make sure to + ;; remove any newline characters in order to preserve + ;; table's structure. + (when ,(org-element-lineage definition '(table-cell)) + (while (search-forward "\n" nil t) (delete-char -1))))) + (concat contents + (and (not (org-element-property :contents-begin definition)) + " ")) + 'remote)) + ;; Report success. + t)) + +(defun org-edit-table.el () + "Edit \"table.el\" table at point. + +A new buffer is created and the table is copied into it. Then +the table is recognized with `table-recognize'. When done +editing, exit with \\[org-edit-src-exit]. The edited text will +then replace the area in the Org mode buffer. + +Throw an error when not at such a table." + (interactive) + (let ((element (org-element-at-point))) + (unless (and (eq (org-element-type element) 'table) + (eq (org-element-property :type element) 'table.el) + (org-src--on-datum-p element)) + (user-error "Not in a table.el table")) + (org-src--edit-element + element + (org-src--construct-edit-buffer-name (buffer-name) "Table") + #'text-mode t) + (when (org-bound-and-true-p flyspell-mode) (flyspell-mode -1)) + (table-recognize) + t)) + +(defun org-edit-export-block () + "Edit export block at point. + +A new buffer is created and the block is copied into it, and the +buffer is switched into an appropriate major mode. See also +`org-src-lang-modes'. When done, exit with +\\[org-edit-src-exit]. The edited text will then replace the +area in the Org mode buffer. + +Throw an error when not at an export block." + (interactive) + (let ((element (org-element-at-point))) + (unless (and (eq (org-element-type element) 'export-block) + (org-src--on-datum-p element)) + (user-error "Not in an export block")) + (let* ((type (downcase (org-element-property :type element))) + (mode (org-src--get-lang-mode type))) + (unless (functionp mode) (error "No such language mode: %s" mode)) + (org-src--edit-element + element + (org-src--construct-edit-buffer-name (buffer-name) type) + mode + (lambda () (org-escape-code-in-region (point-min) (point-max))))) + t)) + +(defun org-edit-src-code (&optional code edit-buffer-name) + "Edit the source or example block at point. +\\ +The code is copied to a separate buffer and the appropriate mode +is turned on. When done, exit with \\[org-edit-src-exit]. This \ +will remove the +original code in the Org buffer, and replace it with the edited +version. See `org-src-window-setup' to configure the display of +windows containing the Org buffer and the code buffer. + +When optional argument CODE is a string, edit it in a dedicated +buffer instead. + +When optional argument EDIT-BUFFER-NAME is non-nil, use it as the +name of the sub-editing buffer." + (interactive) + (let* ((element (org-element-at-point)) + (type (org-element-type element))) + (unless (and (memq type '(example-block src-block)) + (org-src--on-datum-p element)) + (user-error "Not in a source or example block")) + (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))) + (babel-info (and (eq type 'src-block) + (org-babel-get-src-block-info 'light))) + deactivate-mark) + (when (and (eq type 'src-block) (not (functionp lang-f))) + (error "No such language mode: %s" lang-f)) + (org-src--edit-element + element + (or edit-buffer-name + (org-src--construct-edit-buffer-name (buffer-name) lang)) + lang-f + (and (null code) + `(lambda () + (unless ,(or org-src-preserve-indentation + (org-element-property :preserve-indent element)) + (untabify (point-min) (point-max)) + (when (> org-edit-src-content-indentation 0) + (let ((ind (make-string org-edit-src-content-indentation + ?\s))) + (while (not (eobp)) + (unless (looking-at "[ \t]*$") (insert ind)) + (forward-line))))) + (org-escape-code-in-region (point-min) (point-max)))) + (and code (org-unescape-code-in-string code))) + ;; Finalize buffer. + (org-set-local 'org-coderef-label-format + (or (org-element-property :label-fmt element) + org-coderef-label-format)) + (when (eq type 'src-block) + (org-set-local 'org-src--babel-info babel-info) + (let ((edit-prep-func (intern (concat "org-babel-edit-prep:" lang)))) + (when (fboundp edit-prep-func) + (funcall edit-prep-func babel-info)))) + t))) + +(defun org-edit-fixed-width-region () + "Edit the fixed-width ASCII drawing at point. + +This must be a region where each line starts with a colon +followed by a space or a newline character. + +A new buffer is created and the fixed-width region is copied into +it, and the buffer is switched into the major mode defined in +`org-edit-fixed-width-region-mode', which see. When done, exit +with \\[org-edit-src-exit]. The edited text will then replace +the area in the Org mode buffer." + (interactive) + (let ((element (org-element-at-point))) + (unless (and (eq (org-element-type element) 'fixed-width) + (org-src--on-datum-p element)) + (user-error "Not in a fixed-width area")) + (org-src--edit-element + element + (org-src--construct-edit-buffer-name (buffer-name) "Fixed Width") + org-edit-fixed-width-region-mode + (lambda () (while (not (eobp)) (insert ": ") (forward-line)))) + ;; Return success. + t)) + +(defun org-edit-src-abort () + "Abort editing of the src code and return to the Org buffer." + (interactive) + (let (org-src--allow-write-back) (org-edit-src-exit))) + +(defun org-edit-src-continue (e) + "Unconditionally return to buffer editing area under point. +Throw an error if there is no such buffer." + (interactive "e") + (mouse-set-point e) + (let ((buf (get-char-property (point) 'edit-buffer))) + (if buf (org-src-switch-to-buffer buf 'continue) + (user-error "No sub-editing buffer for area at point")))) + +(defun org-edit-src-save () + "Save parent buffer with current state source-code buffer." + (interactive) + (unless (org-src-edit-buffer-p) (user-error "Not in a sub-editing buffer")) + (set-buffer-modified-p nil) + (let ((edited-code (org-src--contents-for-write-back)) + (beg org-src--beg-marker) + (end org-src--end-marker) + (overlay org-src--overlay)) + (with-current-buffer (org-src--source-buffer) + (undo-boundary) + (goto-char beg) + ;; Temporarily disable read-only features of OVERLAY in order to + ;; insert new contents. + (delete-overlay overlay) + (delete-region beg end) + (let ((expecting-bol (bolp))) + (insert edited-code) + (when (and expecting-bol (not (bolp))) (insert "\n"))) + (save-buffer) + (move-overlay overlay beg (point))))) + +(defun org-edit-src-exit () + "Kill current sub-editing buffer and return to source buffer." + (interactive) + (unless (org-src-edit-buffer-p) (error "Not in a sub-editing buffer")) + (let* ((beg org-src--beg-marker) + (end org-src--end-marker) + (write-back org-src--allow-write-back) + (remote org-src--remote) + (coordinates (and (not remote) + (org-src--coordinates (point) 1 (point-max)))) + (code (and write-back (org-src--contents-for-write-back)))) + (set-buffer-modified-p nil) + ;; Switch to source buffer. Kill sub-editing buffer. + (let ((edit-buffer (current-buffer))) + (org-src-switch-to-buffer (marker-buffer beg) 'exit) + (kill-buffer edit-buffer)) + ;; Insert modified code. Ensure it ends with a newline character. + (org-with-wide-buffer + (when (and write-back (not (equal (buffer-substring beg end) code))) + (undo-boundary) + (goto-char beg) + (delete-region beg end) + (let ((expecting-bol (bolp))) + (insert code) + (when (and expecting-bol (not (bolp))) (insert "\n"))))) + ;; If we are to return to source buffer, put point at an + ;; appropriate location. In particular, if block is hidden, move + ;; to the beginning of the block opening line. + (unless remote + (goto-char beg) + (cond + ;; Block is hidden; move at start of block. + ((org-some (lambda (o) (eq (overlay-get o 'invisible) 'org-hide-block)) + (overlays-at (point))) + (beginning-of-line 0)) + (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)))) + + +(provide 'org-src) + +;;; org-src.el ends here diff --git a/elpa/org-20150629/org-table.el b/elpa/org-20160215/org-table.el similarity index 58% rename from elpa/org-20150629/org-table.el rename to elpa/org-20160215/org-table.el index 30a66c9c..e43f0f84 100644 --- a/elpa/org-20150629/org-table.el +++ b/elpa/org-20160215/org-table.el @@ -1,6 +1,6 @@ -;;; org-table.el --- The table editor for Org-mode +;;; org-table.el --- The table editor for Org mode -;; Copyright (C) 2004-2014 Free Software Foundation, Inc. +;; Copyright (C) 2004-2016 Free Software Foundation, Inc. ;; Author: Carsten Dominik ;; Keywords: outlines, hypermedia, calendar, wp @@ -24,10 +24,10 @@ ;; ;;; Commentary: -;; This file contains the table editor and spreadsheet for Org-mode. +;; This file contains the table editor and spreadsheet for Org mode. ;; Watch out: Here we are talking about two different kind of tables. -;; Most of the code is for the tables created with the Org-mode table editor. +;; Most of the code is for the tables created with the Org mode table editor. ;; Sometimes, we talk about tables created and edited with the table.el ;; Emacs package. We call the former org-type tables, and the latter ;; table.el-type tables. @@ -38,9 +38,30 @@ (require 'cl)) (require 'org) -(declare-function org-export-string-as "ox" - (string backend &optional body-only ext-plist)) -(declare-function aa2u "ext:ascii-art-to-unicode" ()) +(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-property "org-element" (property element)) +(declare-function org-element-type "org-element" (element)) + +(declare-function org-export-create-backend "org-export" (&rest rest)) +(declare-function org-export-data-with-backend "org-export" (arg1 arg2 arg3)) +(declare-function org-export-first-sibling-p "org-export" (arg1 arg2)) +(declare-function org-export-get-backend "org-export" (arg1)) +(declare-function org-export-get-environment "org-export" (&optional arg1 arg2 arg3)) +(declare-function org-export-table-has-special-column-p "org-export" (arg1)) +(declare-function org-export-table-row-is-special-p "org-export" (arg1 arg2)) + +(declare-function calc-eval "calc" (str &optional separator &rest args)) + (defvar orgtbl-mode) ; defined below (defvar orgtbl-mode-menu) ; defined when orgtbl mode get initialized (defvar constants-unit-system) @@ -52,7 +73,7 @@ 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-TBLFM-begin-regexp "|\n[ \t]*#\\+TBLFM: ") +(defvar org-table-TBLFM-begin-regexp "^[ \t]*|.*\n[ \t]*#\\+TBLFM: ") (defcustom orgtbl-optimized (eq org-enable-table-editor 'optimized) "Non-nil means use the optimized table editor version for `orgtbl-mode'. @@ -238,7 +259,12 @@ t accept as input and present for editing" (defcustom org-table-copy-increment t "Non-nil means increment when copying current field with \\[org-table-copy-down]." :group 'org-table-calculation - :type 'boolean) + :version "25.1" + :package-version '(Org . "8.3") + :type '(choice + (const :tag "Use the difference between the current and the above fields" t) + (integer :tag "Use a number" 1) + (const :tag "Don't increment the value when copying a field" nil))) (defcustom org-calc-default-modes '(calc-internal-prec 12 @@ -258,9 +284,9 @@ relies on the variables to be present in the list." (defcustom org-table-duration-custom-format 'hours "Format for the output of calc computations like $1+$2;t. -The default value is 'hours, and will output the results as a -number of hours. Other allowed values are 'seconds, 'minutes and -'days, and the output will be a fraction of seconds, minutes or +The default value is `hours', and will output the results as a +number of hours. Other allowed values are `seconds', `minutes' and +`days', and the output will be a fraction of seconds, minutes or days." :group 'org-table-calculation :version "24.1" @@ -303,7 +329,7 @@ The car of each element is a name of a constant, without the `$' before it. The cdr is the value as a string. For example, if you'd like to use the speed of light in a formula, you would configure - (setq org-table-formula-constants '((\"c\" . \"299792458.\"))) + (setq org-table-formula-constants \\='((\"c\" . \"299792458.\"))) and then use it in an equation like `$1*$c'. @@ -317,15 +343,12 @@ Constants can also be defined on a per-file basis using a line like (defcustom org-table-allow-automatic-line-recalculation t "Non-nil means lines marked with |#| or |*| will be recomputed automatically. -Automatically means when TAB or RET or C-c C-c are pressed in the line." +\\\ +Automatically means when TAB or RET or \\[org-ctrl-c-ctrl-c] \ +are pressed in the line." :group 'org-table-calculation :type 'boolean) -(defcustom org-table-error-on-row-ref-crossing-hline t - "OBSOLETE VARIABLE, please see `org-table-relative-ref-may-cross-hline'." - :group 'org-table - :type 'boolean) - (defcustom org-table-relative-ref-may-cross-hline t "Non-nil means relative formula references may cross hlines. Here are the allowed values: @@ -345,6 +368,18 @@ portability of tables." (const :tag "Stick to hline" nil) (const :tag "Error on attempt to cross" error))) +(defcustom org-table-formula-create-columns nil + "Non-nil means that evaluation of a field formula can add new +columns if an out-of-bounds field is being set." + :group 'org-table-calculation + :version "25.1" + :package-version '(Org . "8.3") + :type '(choice + (const :tag "Setting an out-of-bounds field generates an error (default)" nil) + (const :tag "Setting an out-of-bounds field silently adds columns as needed" t) + (const :tag "Setting an out-of-bounds field adds columns as needed, but issues a warning message" warn) + (const :tag "When setting an out-of-bounds field, the user is prompted" prompt))) + (defgroup org-table-import-export nil "Options concerning table import and export in Org-mode." :tag "Org Table Import Export" @@ -359,38 +394,73 @@ available parameters." :group 'org-table-import-export :type 'string) +(defcustom org-table-convert-region-max-lines 999 + "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." + :group 'org-table-import-export + :type 'integer + :version "25.1" + :package-version '(Org . "8.3")) + (defconst org-table-auto-recalculate-regexp "^[ \t]*| *# *\\(|\\|$\\)" - "Detects a table line marked for automatic recalculation.") + "Regexp matching a line marked for automatic recalculation.") + (defconst org-table-recalculate-regexp "^[ \t]*| *[#*] *\\(|\\|$\\)" - "Detects a table line marked for automatic recalculation.") + "Regexp matching a line marked for recalculation.") + (defconst org-table-calculate-mark-regexp "^[ \t]*| *[!$^_#*] *\\(|\\|$\\)" - "Detects a table line marked for automatic recalculation.") + "Regexp matching a line marked for calculation.") + (defconst org-table-border-regexp "^[ \t]*[^| \t]" - "Searching from within a table (any type) this finds the first line outside the table.") + "Regexp matching any line outside an Org table.") + (defvar org-table-last-highlighted-reference nil) + (defvar org-table-formula-history nil) (defvar org-table-column-names nil - "Alist with column names, derived from the `!' line.") + "Alist with column names, derived from the `!' line. +This variable is initialized with `org-table-analyze'.") + (defvar org-table-column-name-regexp nil - "Regular expression matching the current column names.") + "Regular expression matching the current column names. +This variable is initialized with `org-table-analyze'.") + (defvar org-table-local-parameters nil - "Alist with parameter names, derived from the `$' line.") + "Alist with parameter names, derived from the `$' line. +This variable is initialized with `org-table-analyze'.") + (defvar org-table-named-field-locations nil - "Alist with locations of named fields.") + "Alist with locations of named fields. +Associations follow the pattern (NAME LINE COLUMN) where + NAME is the name of the field as a string, + LINE is the number of lines from the beginning of the table, + COLUMN is the column of the field, as an integer. +This variable is initialized with `org-table-analyze'.") (defvar org-table-current-line-types nil - "Table row types, non-nil only for the duration of a command.") -(defvar org-table-current-begin-line nil - "Table begin line, non-nil only for the duration of a command.") + "Table row types in current table. +This variable is initialized with `org-table-analyze'.") + (defvar org-table-current-begin-pos nil - "Table begin position, non-nil only for the duration of a command.") + "Current table begin position, as a marker. +This variable is initialized with `org-table-analyze'.") + (defvar org-table-current-ncol nil - "Number of columns in table, non-nil only for the duration of a command.") + "Number of columns in current table. +This variable is initialized with `org-table-analyze'.") + (defvar org-table-dlines nil - "Vector of data line line numbers in the current table.") + "Vector of data line line numbers in the current table. +Line numbers are counted from the beginning of the table. This +variable is initialized with `org-table-analyze'.") + (defvar org-table-hlines nil - "Vector of hline line numbers in the current table.") + "Vector of hline line numbers in the current table. +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]+\\)?\\)?" @@ -404,75 +474,23 @@ available parameters." "\\(" "@?[-0-9I$&]+" "\\|" "[a-zA-Z]\\{1,2\\}\\([0-9]+\\|&\\)" "\\|" "\\$[a-zA-Z0-9]+" "\\)") "Match a range for reference display.") -(defun org-table-colgroup-line-p (line) - "Is this a table line colgroup information?" - (save-match-data - (and (string-match "[<>]\\|&[lg]t;" line) - (string-match "\\`[ \t]*|[ \t]*/[ \t]*\\(|[ \t<>0-9|lgt&;]+\\)\\'" - line) - (not (delq - nil - (mapcar - (lambda (s) - (not (member s '("" "<" ">" "<>" "<" ">" "<>")))) - (org-split-string (match-string 1 line) "[ \t]*|[ \t]*"))))))) - -(defun org-table-cookie-line-p (line) - "Is this a table line with only alignment/width cookies?" - (save-match-data - (and (string-match "[<>]\\|&[lg]t;" line) - (or (string-match - "\\`[ \t]*|[ \t]*/[ \t]*\\(|[ \t<>0-9|lrcgt&;]+\\)\\'" line) - (string-match "\\(\\`[ \t<>lrc0-9|gt&;]+\\'\\)" line)) - (not (delq nil (mapcar - (lambda (s) - (not (or (equal s "") - (string-match - "\\`<\\([lrc]?[0-9]+\\|[lrc]\\)>\\'" s) - (string-match - "\\`<\\([lrc]?[0-9]+\\|[lrc]\\)>\\'" - s)))) - (org-split-string (match-string 1 line) - "[ \t]*|[ \t]*"))))))) - -(defvar org-table-clean-did-remove-column nil) ; dynamically scoped -(defun org-table-clean-before-export (lines &optional maybe-quoted) - "Check if the table has a marking column. -If yes remove the column and the special lines." - (let ((special (if maybe-quoted - "^[ \t]*| *\\\\?[\#!$*_^/ ] *|" - "^[ \t]*| *[\#!$*_^/ ] *|")) - (ignore (if maybe-quoted - "^[ \t]*| *\\\\?[!$_^/] *|" - "^[ \t]*| *[!$_^/] *|"))) - (setq org-table-clean-did-remove-column - (not (memq nil - (mapcar - (lambda (line) - (or (string-match org-table-hline-regexp line) - (string-match special line))) - lines)))) - (delq nil - (mapcar - (lambda (line) - (cond - ((or (org-table-colgroup-line-p line) ;; colgroup info - (org-table-cookie-line-p line) ;; formatting cookies - (and org-table-clean-did-remove-column - (string-match ignore line))) ;; non-exportable data - nil) - ((and org-table-clean-did-remove-column - (or (string-match "^\\([ \t]*\\)|-+\\+" line) - (string-match "^\\([ \t]*\\)|[^|]*|" line))) - ;; remove the first column - (replace-match "\\1|" t nil line)) - (t line))) - lines)))) - (defconst org-table-translate-regexp (concat "\\(" "@[-0-9I$]+" "\\|" "[a-zA-Z]\\{1,2\\}\\([0-9]+\\|&\\)" "\\)") "Match a reference that needs translation, for reference display.") +(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))))) + ;;;###autoload (defun org-table-create-with-table.el () "Use the table.el package to insert a new table. @@ -545,9 +563,11 @@ slightly, to make sure a beginning of line in the first line is included. SEPARATOR specifies the field separator in the lines. It can have the following values: -'(4) Use the comma as a field separator -'(16) Use a TAB as field separator +(4) Use the comma as a field separator +(16) Use a TAB as field separator +(64) Prompt for a regular expression as field separator integer When a number, use that many spaces as field separator +regexp When a regular expression, use it to match the separator nil When nil, the command tries to be smart and figure out the separator in the following way: - when each line contains a TAB, assume TAB-separated material @@ -557,45 +577,52 @@ nil When nil, the command tries to be smart and figure out the (let* ((beg (min beg0 end0)) (end (max beg0 end0)) re) - (goto-char beg) - (beginning-of-line 1) - (setq beg (point-marker)) - (goto-char end) - (if (bolp) (backward-char 1) (end-of-line 1)) - (setq end (point-marker)) - ;; Get the right field separator - (unless separator + (if (> (count-lines beg end) org-table-convert-region-max-lines) + (user-error "Region is longer than `org-table-convert-region-max-lines' (%s) lines; not converting" + org-table-convert-region-max-lines) + (if (equal separator '(64)) + (setq separator (read-regexp "Regexp for field separator"))) + (goto-char beg) + (beginning-of-line 1) + (setq beg (point-marker)) + (goto-char end) + (if (bolp) (backward-char 1) (end-of-line 1)) + (setq end (point-marker)) + ;; Get the right field separator + (unless separator + (goto-char beg) + (setq separator + (cond + ((not (re-search-forward "^[^\n\t]+$" end t)) '(16)) + ((not (re-search-forward "^[^\n,]+$" end t)) '(4)) + (t 1)))) (goto-char beg) - (setq separator + (if (equal separator '(4)) + (while (< (point) end) + ;; parse the csv stuff (cond - ((not (re-search-forward "^[^\n\t]+$" end t)) '(16)) - ((not (re-search-forward "^[^\n,]+$" end t)) '(4)) - (t 1)))) - (goto-char beg) - (if (equal separator '(4)) - (while (< (point) end) - ;; parse the csv stuff - (cond - ((looking-at "^") (insert "| ")) - ((looking-at "[ \t]*$") (replace-match " |") (beginning-of-line 2)) - ((looking-at "[ \t]*\"\\([^\"\n]*\\)\"") - (replace-match "\\1") - (if (looking-at "\"") (insert "\""))) - ((looking-at "[^,\n]+") (goto-char (match-end 0))) - ((looking-at "[ \t]*,") (replace-match " | ")) - (t (beginning-of-line 2)))) - (setq re (cond - ((equal separator '(4)) "^\\|\"?[ \t]*,[ \t]*\"?") - ((equal separator '(16)) "^\\|\t") - ((integerp separator) - (if (< separator 1) - (user-error "Number of spaces in separator must be >= 1") - (format "^ *\\| *\t *\\| \\{%d,\\}" separator))) - (t (error "This should not happen")))) - (while (re-search-forward re end t) - (replace-match "| " t t))) - (goto-char beg) - (org-table-align))) + ((looking-at "^") (insert "| ")) + ((looking-at "[ \t]*$") (replace-match " |") (beginning-of-line 2)) + ((looking-at "[ \t]*\"\\([^\"\n]*\\)\"") + (replace-match "\\1") + (if (looking-at "\"") (insert "\""))) + ((looking-at "[^,\n]+") (goto-char (match-end 0))) + ((looking-at "[ \t]*,") (replace-match " | ")) + (t (beginning-of-line 2)))) + (setq re (cond + ((equal separator '(4)) "^\\|\"?[ \t]*,[ \t]*\"?") + ((equal separator '(16)) "^\\|\t") + ((integerp separator) + (if (< separator 1) + (user-error "Number of spaces in separator must be >= 1") + (format "^ *\\| *\t *\\| \\{%d,\\}" separator))) + ((stringp separator) + (format "^ *\\|%s" separator)) + (t (error "This should not happen")))) + (while (re-search-forward re end t) + (replace-match "| " t t))) + (goto-char beg) + (org-table-align)))) ;;;###autoload (defun org-table-import (file arg) @@ -611,8 +638,6 @@ are found, lines will be split on whitespace into fields." (org-table-convert-region beg (+ (point) (- (point-max) pm)) arg))) -(defvar org-table-last-alignment) -(defvar org-table-last-column-widths) ;;;###autoload (defun org-table-export (&optional file format) "Export table to a file, with configurable format. @@ -630,77 +655,61 @@ extension of the given file name, and finally on the variable `org-table-export-default-format'." (interactive) (unless (org-at-table-p) (user-error "No table at point")) - (org-table-align) ;; make sure we have everything we need - (let* ((beg (org-table-begin)) - (end (org-table-end)) - (txt (buffer-substring-no-properties beg end)) - (file (or file (org-entry-get beg "TABLE_EXPORT_FILE" t))) - (formats '("orgtbl-to-tsv" "orgtbl-to-csv" - "orgtbl-to-latex" "orgtbl-to-html" - "orgtbl-to-generic" "orgtbl-to-texinfo" - "orgtbl-to-orgtbl")) - (format (or format - (org-entry-get beg "TABLE_EXPORT_FORMAT" t))) - buf deffmt-readable fileext) + (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"))) - (if (file-directory-p file) - (user-error "This is a directory path, not a file")) - (if (and (buffer-file-name) - (equal (file-truename file) - (file-truename (buffer-file-name)))) - (user-error "Please specify a file name that is different from current")) - (setq fileext (concat (file-name-extension file) "$")) - (unless format - (setq deffmt-readable - (or (car (delq nil (mapcar (lambda(f) (if (string-match fileext f) f)) formats))) - org-table-export-default-format)) - (while (string-match "\t" deffmt-readable) - (setq deffmt-readable (replace-match "\\t" t t deffmt-readable))) - (while (string-match "\n" deffmt-readable) - (setq deffmt-readable (replace-match "\\n" t t deffmt-readable))) - (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 (if (match-end 2) - (read (concat "(" (match-string 2 format) ")")))) - (skip (plist-get params :skip)) - (skipcols (plist-get params :skipcols)) - (lines (nthcdr (or skip 0) (org-split-string txt "[ \t]*\n[ \t]*"))) - (lines (org-table-clean-before-export lines)) - (i0 (if org-table-clean-did-remove-column 2 1)) - (table (mapcar - (lambda (x) - (if (string-match org-table-hline-regexp x) - 'hline - (org-remove-by-index - (org-split-string (org-trim x) "\\s-*|\\s-*") - skipcols i0))) - lines)) - (fun (if (= i0 2) 'cdr 'identity)) - (org-table-last-alignment - (org-remove-by-index (funcall fun org-table-last-alignment) - skipcols i0)) - (org-table-last-column-widths - (org-remove-by-index (funcall fun org-table-last-column-widths) - skipcols i0))) - - (unless (fboundp transform) - (user-error "No such transformation function %s" transform)) - (setq txt (funcall transform table params)) - - (with-current-buffer (find-file-noselect file) - (setq buf (current-buffer)) - (erase-buffer) - (fundamental-mode) - (insert txt "\n") - (save-buffer)) - (kill-buffer buf) - (message "Export done.")) - (user-error "TABLE_EXPORT_FORMAT invalid")))) + (when (file-directory-p file) + (user-error "This is a directory path, not a file")) + (when (and (buffer-file-name (buffer-base-buffer)) + (org-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 (org-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. @@ -731,216 +740,199 @@ When nil, simply write \"#ERROR\" in corrupted fields.") (defun org-table-align () "Align the table at point by aligning all vertical bars." (interactive) - (let* ( - ;; Limits of table - (beg (org-table-begin)) - (end (org-table-end)) - ;; Current cursor position - (linepos (org-current-line)) - (colpos (org-table-current-column)) - (winstart (window-start)) - (winstartline (org-current-line (min winstart (1- (point-max))))) - lines (new "") lengths l typenums ty fields maxfields i - column - (indent "") cnt frac - rfmt hfmt - (spaces '(1 . 1)) - (sp1 (car spaces)) - (sp2 (cdr spaces)) - (rfmt1 (concat - (make-string sp2 ?\ ) "%%%s%ds" (make-string sp1 ?\ ) "|")) - (hfmt1 (concat - (make-string sp2 ?-) "%s" (make-string sp1 ?-) "+")) - emptystrings links dates emph raise narrow - falign falign1 fmax f1 len c e space) - (untabify beg end) - (remove-text-properties beg end '(org-cwidth t org-dwidth t display t)) - ;; Check if we have links or dates - (goto-char beg) - (setq links (re-search-forward org-bracket-link-regexp end t)) - (goto-char beg) - (setq emph (and org-hide-emphasis-markers - (re-search-forward org-emph-re end t))) - (goto-char beg) - (setq raise (and org-use-sub-superscripts - (re-search-forward org-match-substring-regexp end t))) - (goto-char beg) - (setq dates (and org-display-custom-times - (re-search-forward org-ts-regexp-both end t))) - ;; Make sure the link properties are right - (when links (goto-char beg) (while (org-activate-bracket-links end))) - ;; Make sure the date properties are right - (when dates (goto-char beg) (while (org-activate-dates end))) - (when emph (goto-char beg) (while (org-do-emphasis-faces end))) - (when raise (goto-char beg) (while (org-raise-scripts end))) - - ;; Check if we are narrowing any columns - (goto-char beg) - (setq narrow (and org-table-do-narrow - org-format-transports-properties-p - (re-search-forward "<[lrc]?[0-9]+>" end t))) - (goto-char beg) - (setq falign (re-search-forward "<[lrc][0-9]*>" end t)) - (goto-char beg) - ;; Get the rows - (setq lines (org-split-string - (buffer-substring beg end) "\n")) - ;; Store the indentation of the first line - (if (string-match "^ *" (car lines)) - (setq indent (make-string (- (match-end 0) (match-beginning 0)) ?\ ))) - ;; Mark the hlines by setting the corresponding element to nil - ;; At the same time, we remove trailing space. - (setq lines (mapcar (lambda (l) - (if (string-match "^ *|-" l) - nil - (if (string-match "[ \t]+$" l) - (substring l 0 (match-beginning 0)) - l))) - lines)) - ;; Get the data fields by splitting the lines. - (setq fields (mapcar - (lambda (l) - (org-split-string l " *| *")) - (delq nil (copy-sequence lines)))) - ;; How many fields in the longest line? - (condition-case nil - (setq maxfields (apply 'max (mapcar 'length fields))) - (error - (kill-region beg end) - (org-table-create org-table-default-size) - (user-error "Empty table - created default table"))) - ;; A list of empty strings to fill any short rows on output - (setq emptystrings (make-list maxfields "")) - ;; Check for special formatting. - (setq i -1) - (while (< (setq i (1+ i)) maxfields) ;; Loop over all columns - (setq column (mapcar (lambda (x) (or (nth i x) "")) fields)) - ;; Check if there is an explicit width specified - (setq fmax nil) - (when (or narrow falign) - (setq c column fmax nil falign1 nil) - (while c - (setq e (pop c)) - (when (and (stringp e) (string-match "^<\\([lrc]\\)?\\([0-9]+\\)?>$" e)) - (if (match-end 1) (setq falign1 (match-string 1 e))) - (if (and org-table-do-narrow (match-end 2)) - (setq fmax (string-to-number (match-string 2 e)) c nil)))) - ;; Find fields that are wider than fmax, and shorten them - (when fmax - (loop for xx in column do - (when (and (stringp xx) - (> (org-string-width xx) fmax)) - (org-add-props xx nil - 'help-echo - (concat "Clipped table field, use C-c ` to edit. Full value is:\n" (org-no-properties (copy-sequence xx)))) - (setq f1 (min fmax (or (string-match org-bracket-link-regexp xx) fmax))) - (unless (> f1 1) - (user-error "Cannot narrow field starting with wide link \"%s\"" - (match-string 0 xx))) - (add-text-properties f1 (length xx) (list 'org-cwidth t) xx) - (add-text-properties (- f1 2) f1 - (list 'display org-narrow-column-arrow) - xx))))) - ;; Get the maximum width for each column - (push (apply 'max (or fmax 1) 1 (mapcar 'org-string-width column)) - lengths) - ;; Get the fraction of numbers, to decide about alignment of the column - (if falign1 - (push (equal (downcase falign1) "r") typenums) - (setq cnt 0 frac 0.0) - (loop for x in column do - (if (equal x "") - nil - (setq frac ( / (+ (* frac cnt) - (if (string-match org-table-number-regexp x) 1 0)) - (setq cnt (1+ cnt)))))) - (push (>= frac org-table-number-fraction) typenums))) - (setq lengths (nreverse lengths) typenums (nreverse typenums)) - - ;; Store the alignment of this table, for later editing of single fields - (setq org-table-last-alignment typenums - org-table-last-column-widths lengths) - - ;; With invisible characters, `format' does not get the field width right - ;; So we need to make these fields wide by hand. - (when (or links emph raise) - (loop for i from 0 upto (1- maxfields) do - (setq len (nth i lengths)) - (loop for j from 0 upto (1- (length fields)) do - (setq c (nthcdr i (car (nthcdr j fields)))) - (if (and (stringp (car c)) - (or (text-property-any 0 (length (car c)) - 'invisible 'org-link (car c)) - (text-property-any 0 (length (car c)) - 'org-dwidth t (car c))) - (< (org-string-width (car c)) len)) - (progn - (setq space (make-string (- len (org-string-width (car c))) ?\ )) - (setcar c (if (nth i typenums) - (concat space (car c)) - (concat (car c) space)))))))) - - ;; Compute the formats needed for output of the table - (setq rfmt (concat indent "|") hfmt (concat indent "|")) - (while (setq l (pop lengths)) - (setq ty (if (pop typenums) "" "-")) ; number types flushright - (setq rfmt (concat rfmt (format rfmt1 ty l)) - hfmt (concat hfmt (format hfmt1 (make-string l ?-))))) - (setq rfmt (concat rfmt "\n") - hfmt (concat (substring hfmt 0 -1) "|\n")) - - (setq new (mapconcat - (lambda (l) - (if l (apply 'format rfmt - (append (pop fields) emptystrings)) - hfmt)) - lines "")) - (move-marker org-table-aligned-begin-marker (point)) - (insert new) - ;; Replace the old one - (delete-region (point) end) - (move-marker end nil) - (move-marker org-table-aligned-end-marker (point)) - (when (and orgtbl-mode (not (derived-mode-p 'org-mode))) - (goto-char org-table-aligned-begin-marker) - (while (org-hide-wide-columns org-table-aligned-end-marker))) - ;; Try to move to the old location - (org-goto-line winstartline) - (setq winstart (point-at-bol)) - (org-goto-line linepos) - (when (eq (window-buffer (selected-window)) (current-buffer)) - (set-window-start (selected-window) winstart 'noforce)) - (org-table-goto-column colpos) - (and org-table-overlay-coordinates (org-table-overlay-coordinates)) - (setq org-table-may-need-update nil) - )) + (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. + (font-lock-fontify-region beg end) + (move-marker org-table-aligned-begin-marker beg) + (move-marker org-table-aligned-end-marker end) + (goto-char beg) + (let* ((indent (progn (looking-at "[ \t]*") (match-string 0))) + ;; Table's rows. Separators are replaced by nil. Trailing + ;; spaces are also removed. + (lines (mapcar (lambda (l) + (and (not (org-string-match-p "\\`[ \t]*|-" l)) + (let ((l (org-trim l))) + (remove-text-properties + 0 (length l) '(display t org-cwidth t) l) + l))) + (org-split-string (buffer-substring beg end) "\n"))) + ;; Get the data fields by splitting the lines. + (fields (mapcar (lambda (l) (org-split-string l " *| *")) + (remq nil lines))) + ;; Compute number of fields in the longest line. If the + ;; table contains no field, create a default table. + (maxfields (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"))) + ;; A list of empty strings to fill any short rows on output. + (emptycells (make-list maxfields "")) + lengths typenums) + ;; Check for special formatting. + (dotimes (i maxfields) + (let ((column (mapcar (lambda (x) (or (nth i x) "")) fields)) + fmax falign) + ;; Look for an explicit width or alignment. + (when (save-excursion + (or (re-search-forward "| *<[lrc][0-9]*> *\\(|\\|$\\)" end t) + (and org-table-do-narrow + (re-search-forward + "| *<[lrc]?[0-9]+> *\\(|\\|$\\)" end t)))) + (catch :exit + (dolist (cell column) + (when (string-match "\\`<\\([lrc]\\)?\\([0-9]+\\)?>\\'" cell) + (when (match-end 1) (setq falign (match-string 1 cell))) + (when (and org-table-do-narrow (match-end 2)) + (setq fmax (string-to-number (match-string 2 cell)))) + (when (or falign fmax) (throw :exit nil))))) + ;; Find fields that are wider than FMAX, and shorten them. + (when fmax + (dolist (x column) + (when (> (org-string-width x) fmax) + (org-add-props x nil + 'help-echo + (concat + (substitute-command-keys + "Clipped table field, use \\[org-table-edit-field] to \ +edit. Full value is:\n") + (substring-no-properties x))) + (let ((l (length x)) + (f1 (min fmax + (or (string-match org-bracket-link-regexp x) + fmax))) + (f2 1)) + (unless (> f1 1) + (user-error + "Cannot narrow field starting with wide link \"%s\"" + (match-string 0 x))) + (if (= (org-string-width x) l) (setq f2 f1) + (setq f2 1) + (while (< (org-string-width (substring x 0 f2)) f1) + (incf f2))) + (add-text-properties f2 l (list 'org-cwidth t) x) + (add-text-properties + (if (>= (string-width (substring x (1- f2) f2)) 2) (1- f2) + (- f2 2)) + f2 + (list 'display org-narrow-column-arrow) + x)))))) + ;; Get the maximum width for each column + (push (apply #'max (or fmax 1) 1 (mapcar #'org-string-width column)) + lengths) + ;; Get the fraction of numbers among non-empty cells to + ;; decide about alignment of the column. + (if falign (push (equal (downcase falign) "r") typenums) + (let ((cnt 0) + (frac 0.0)) + (dolist (x column) + (unless (equal x "") + (setq frac + (/ (+ (* frac cnt) + (if (org-string-match-p org-table-number-regexp x) + 1 + 0)) + (incf cnt))))) + (push (>= frac org-table-number-fraction) typenums))))) + (setq lengths (nreverse lengths)) + (setq typenums (nreverse typenums)) + ;; Store alignment of this table, for later editing of single + ;; fields. + (setq org-table-last-alignment typenums) + (setq org-table-last-column-widths lengths) + ;; With invisible characters, `format' does not get the field + ;; width right So we need to make these fields wide by hand. + ;; Invisible characters may be introduced by fontified links, + ;; emphasis, macros or sub/superscripts. + (when (or (text-property-any beg end 'invisible 'org-link) + (text-property-any beg end 'invisible t)) + (dotimes (i maxfields) + (let ((len (nth i lengths))) + (dotimes (j (length fields)) + (let* ((c (nthcdr i (nth j fields))) + (cell (car c))) + (when (and + (stringp cell) + (let ((l (length cell))) + (or (text-property-any 0 l 'invisible 'org-link cell) + (text-property-any beg end 'invisible t))) + (< (org-string-width cell) len)) + (let ((s (make-string (- len (org-string-width cell)) ?\s))) + (setcar c (if (nth i typenums) (concat s cell) + (concat cell s)))))))))) + + ;; Compute the formats needed for output of the table. + (let ((hfmt (concat indent "|")) + (rfmt (concat indent "|")) + (rfmt1 " %%%s%ds |") + (hfmt1 "-%s-+")) + (dolist (l lengths (setq hfmt (concat (substring hfmt 0 -1) "|"))) + (let ((ty (if (pop typenums) "" "-"))) ; Flush numbers right. + (setq rfmt (concat rfmt (format rfmt1 ty l))) + (setq hfmt (concat hfmt (format hfmt1 (make-string l ?-)))))) + ;; Replace modified lines only. Check not only contents, but + ;; also columns' width. + (dolist (l lines) + (let ((line + (if l (apply #'format rfmt (append (pop fields) emptycells)) + hfmt)) + (previous (buffer-substring (point) (line-end-position)))) + (if (and (equal previous line) + (let ((a 0) + (b 0)) + (while (and (progn + (setq a (next-single-property-change + a 'org-cwidth previous)) + (setq b (next-single-property-change + b 'org-cwidth line))) + (eq a b))) + (eq a b))) + (forward-line) + (insert line "\n") + (delete-region (point) (line-beginning-position 2)))))) + (when (and orgtbl-mode (not (derived-mode-p 'org-mode))) + (goto-char org-table-aligned-begin-marker) + (while (org-hide-wide-columns org-table-aligned-end-marker))) + (set-marker end nil) + (when org-table-overlay-coordinates (org-table-overlay-coordinates)) + (setq org-table-may-need-update nil))))) ;;;###autoload (defun org-table-begin (&optional table-type) "Find the beginning of the table and return its position. -With argument TABLE-TYPE, go to the beginning of a table.el-type table." - (save-excursion - (if (not (re-search-backward - (if table-type org-table-any-border-regexp - org-table-border-regexp) - nil t)) - (progn (goto-char (point-min)) (point)) - (goto-char (match-beginning 0)) - (beginning-of-line 2) - (point)))) +With a non-nil optional argument TABLE-TYPE, return the beginning +of a table.el-type table. This function assumes point is on +a table." + (cond (table-type + (org-element-property :post-affiliated (org-element-at-point))) + ((save-excursion + (and (re-search-backward org-table-border-regexp nil t) + (line-beginning-position 2)))) + (t (point-min)))) ;;;###autoload (defun org-table-end (&optional table-type) "Find the end of the table and return its position. -With argument TABLE-TYPE, go to the end of a table.el-type table." +With a non-nil optional argument TABLE-TYPE, return the end of +a table.el-type table. This function assumes point is on +a table." (save-excursion - (if (not (re-search-forward - (if table-type org-table-any-border-regexp - org-table-border-regexp) - nil t)) - (goto-char (point-max)) - (goto-char (match-beginning 0))) - (point-marker))) + (cond (table-type + (goto-char (org-element-property :end (org-element-at-point))) + (skip-chars-backward " \t\n") + (line-beginning-position 2)) + ((re-search-forward org-table-border-regexp nil t) + (match-beginning 0)) + ;; When the line right after the table is the last line in + ;; the buffer with trailing spaces but no final newline + ;; character, be sure to catch the correct ending at its + ;; beginning. In any other case, ending is expected to be + ;; at point max. + (t (goto-char (point-max)) + (skip-chars-backward " \t") + (if (bolp) (point) (line-end-position)))))) ;;;###autoload (defun org-table-justify-field-maybe (&optional new) @@ -967,13 +959,16 @@ Optional argument NEW may specify text to replace the current field content." (progn (setq s (match-string 1) o (match-string 0) - l (max 1 (- (match-end 0) (match-beginning 0) 3)) + l (max 1 + (- (org-string-width + (buffer-substring-no-properties + (match-end 0) (match-beginning 0))) 3)) e (not (= (match-beginning 2) (match-end 2)))) (setq f (format (if num " %%%ds %s" " %%-%ds %s") l (if e "|" (setq org-table-may-need-update t) "")) n (format f s)) (if new - (if (<= (length new) l) ;; FIXME: length -> str-width? + (if (<= (org-string-width new) l) (setq n (format f new)) (setq n (concat new "|") org-table-may-need-update t))) (if (equal (string-to-char n) ?-) (setq n (concat " " n))) @@ -1036,9 +1031,10 @@ Before doing so, re-align the table if necessary." (goto-char (match-end 0)))) (defun org-table-beginning-of-field (&optional n) - "Move to the end of the current table field. -If already at or after the end, move to the end of the next table field. -With numeric argument N, move N-1 fields forward first." + "Move to the beginning of the current table field. +If already at or before the beginning, move to the beginning of the +previous field. +With numeric argument N, move N-1 fields backward first." (interactive "p") (let ((pos (point))) (while (> n 1) @@ -1051,10 +1047,9 @@ With numeric argument N, move N-1 fields forward first." (if (>= (point) pos) (org-table-beginning-of-field 2)))) (defun org-table-end-of-field (&optional n) - "Move to the beginning of the current table field. -If already at or before the beginning, move to the beginning of the -previous field. -With numeric argument N, move N-1 fields backward first." + "Move to the end of the current table field. +If already at or after the end, move to the end of the next table field. +With numeric argument N, move N-1 fields forward first." (interactive "p") (let ((pos (point))) (while (> n 1) @@ -1093,30 +1088,36 @@ Before doing so, re-align the table if necessary." ;;;###autoload (defun org-table-copy-down (n) - "Copy a field down in the current column. -If the field at the cursor is empty, copy into it 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. + "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. In the case of a timestamp, increment by one day." +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 txt-up inc) (org-table-check-inside-data-field) - (if non-empty - (progn - (setq txt (org-trim field)) - (org-table-next-row) - (org-table-blank-field)) + (if (not non-empty) (save-excursion (setq txt (catch 'exit @@ -1127,35 +1128,60 @@ copying. In the case of a timestamp, increment by one day." (if (and (looking-at "|[ \t]*\\([^| \t][^|]*?\\)[ \t]*|") (<= (setq n (1- n)) 0)) - (throw 'exit (match-string 1)))))))) - (if txt - (progn - (if (and org-table-copy-increment - (not (equal orig-n 0)) - (string-match "^[0-9]+$" txt) - (< (string-to-number txt) 100000000)) - (setq txt (format "%d" (+ (string-to-number txt) 1)))) - (insert txt) - (org-move-to-column col) - (if (and org-table-copy-increment (org-at-timestamp-p t)) - (org-timestamp-up-day) - (org-table-maybe-recalculate-line)) - (org-table-align) - (org-move-to-column col)) - (user-error "No non-empty field found")))) + (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 + (setq txt (org-trim field)) + (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 "^[-+^/*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 t)) + (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) "Is point inside a table data field? I.e. not on a hline or before the first or after the last column? This actually throws an error, so it aborts the current command." - (if (or (not (org-at-table-p)) - (= (org-table-current-column) 0) - (org-at-table-hline-p) - (looking-at "[ \t]*$")) - (if noerror - nil - (user-error "Not in table data field")) - t)) + (cond ((and (org-at-table-p) + (not (save-excursion (skip-chars-backward " \t") (bolp))) + (not (org-at-table-hline-p)) + (not (looking-at "[ \t]*$")))) + (noerror nil) + (t (user-error "Not in table data field")))) (defvar org-table-clip nil "Clipboard for table regions.") @@ -1166,7 +1192,7 @@ If LINE is larger than the number of data lines in the table, the function returns nil. However, if COLUMN is too large, we will simply return an empty string. If LINE is nil, use the current line. -If column is nil, use the current column." +If COLUMN is nil, use the current column." (setq column (or column (org-table-current-column))) (save-excursion (and (or (not line) (org-table-goto-line line)) @@ -1242,31 +1268,32 @@ is always the old value." "Show info about the current field, and highlight any reference at point." (interactive "P") (unless (org-at-table-p) (user-error "Not at a table")) - (org-table-get-specials) + (org-table-analyze) (save-excursion (let* ((pos (point)) (col (org-table-current-column)) (cname (car (rassoc (int-to-string col) org-table-column-names))) - (name (car (rassoc (list (org-current-line) col) + (name (car (rassoc (list (count-lines org-table-current-begin-pos + (line-beginning-position)) + col) org-table-named-field-locations))) (eql (org-table-expand-lhs-ranges (mapcar (lambda (e) - (cons (org-table-formula-handle-first/last-rc - (car e)) (cdr e))) + (cons (org-table-formula-handle-first/last-rc (car e)) + (cdr e))) (org-table-get-stored-formulas)))) (dline (org-table-current-dline)) (ref (format "@%d$%d" dline col)) (ref1 (org-table-convert-refs-to-an ref)) + ;; Prioritize field formulas over column formulas. (fequation (or (assoc name eql) (assoc ref eql))) - (cequation (assoc (int-to-string col) eql)) + (cequation (assoc (format "$%d" col) eql)) (eqn (or fequation cequation))) - (if (and eqn (get-text-property 0 :orig-eqn (car eqn))) - (setq eqn (get-text-property 0 :orig-eqn (car eqn)))) + (let ((p (and eqn (get-text-property 0 :orig-eqn (car eqn))))) + (when p (setq eqn p))) (goto-char pos) - (condition-case nil - (org-table-show-reference 'local) - (error nil)) + (ignore-errors (org-table-show-reference 'local)) (message "line @%d, col $%s%s, ref @%d$%d or %s%s%s" dline col (if cname (concat " or $" cname) "") @@ -1284,15 +1311,14 @@ is always the old value." (defun org-table-current-column () "Find out which column we are in." (interactive) - (if (org-called-interactively-p 'any) (org-table-check-inside-data-field)) + (when (org-called-interactively-p 'any) (org-table-check-inside-data-field)) (save-excursion - (let ((cnt 0) (pos (point))) - (beginning-of-line 1) - (while (search-forward "|" pos t) - (setq cnt (1+ cnt))) + (let ((column 0) (pos (point))) + (beginning-of-line) + (while (search-forward "|" pos t) (incf column)) (when (org-called-interactively-p 'interactive) - (message "In table column %d" cnt)) - cnt))) + (message "In table column %d" column)) + column))) ;;;###autoload (defun org-table-current-dline () @@ -1302,14 +1328,15 @@ Only data lines count for this." (when (org-called-interactively-p 'any) (org-table-check-inside-data-field)) (save-excursion - (let ((cnt 0) (pos (point))) + (let ((c 0) + (pos (point))) (goto-char (org-table-begin)) (while (<= (point) pos) - (if (looking-at org-table-dataline-regexp) (setq cnt (1+ cnt))) - (beginning-of-line 2)) + (when (looking-at org-table-dataline-regexp) (incf c)) + (forward-line)) (when (org-called-interactively-p 'any) - (message "This is table line %d" cnt)) - cnt))) + (message "This is table line %d" c)) + c))) ;;;###autoload (defun org-table-goto-column (n &optional on-delim force) @@ -1338,25 +1365,19 @@ However, when FORCE is non-nil, create new columns if necessary." (defun org-table-insert-column () "Insert a new column into the table." (interactive) - (if (not (org-at-table-p)) - (user-error "Not at a table")) + (unless (org-at-table-p) (user-error "Not at a table")) (org-table-find-dataline) (let* ((col (max 1 (org-table-current-column))) (beg (org-table-begin)) - (end (org-table-end)) - ;; Current cursor position - (linepos (org-current-line)) - (colpos col)) - (goto-char beg) - (while (< (point) end) - (if (org-at-table-hline-p) - nil - (org-table-goto-column col t) - (insert "| ")) - (beginning-of-line 2)) - (move-marker end nil) - (org-goto-line linepos) - (org-table-goto-column colpos) + (end (copy-marker (org-table-end)))) + (org-table-save-field + (goto-char beg) + (while (< (point) end) + (unless (org-at-table-hline-p) + (org-table-goto-column col t) + (insert "| ")) + (forward-line))) + (set-marker end nil) (org-table-align) (when (or (not org-table-fix-formulas-confirm) (funcall org-table-fix-formulas-confirm "Fix formulas? ")) @@ -1384,58 +1405,55 @@ However, when FORCE is non-nil, create new columns if necessary." (defun org-table-line-to-dline (line &optional above) "Turn a buffer line number into a data line number. + If there is no data line in this line, return nil. -If there is no matching dline (most likely te reference was a hline), the -first dline below it is used. When ABOVE is non-nil, the one above is used." - (catch 'exit - (let ((ll (length org-table-dlines)) - i) - (if above - (progn - (setq i (1- ll)) - (while (> i 0) - (if (<= (aref org-table-dlines i) line) - (throw 'exit i)) - (setq i (1- i)))) - (setq i 1) - (while (< i ll) - (if (>= (aref org-table-dlines i) line) - (throw 'exit i)) - (setq i (1+ i))))) - nil)) + +If there is no matching dline (most likely the reference was +a hline), the first dline below it is used. When ABOVE is +non-nil, the one above is used." + (let ((min 1) + (max (1- (length org-table-dlines)))) + (cond ((or (> (aref org-table-dlines min) line) + (< (aref org-table-dlines max) line)) + nil) + ((= (aref org-table-dlines max) line) max) + (t (catch 'exit + (while (> (- max min) 1) + (let* ((mean (/ (+ max min) 2)) + (v (aref org-table-dlines mean))) + (cond ((= v line) (throw 'exit mean)) + ((> v line) (setq max mean)) + (t (setq min mean))))) + (if above min max)))))) ;;;###autoload (defun org-table-delete-column () "Delete a column from the table." (interactive) - (if (not (org-at-table-p)) - (user-error "Not at a table")) + (unless (org-at-table-p) (user-error "Not at a table")) (org-table-find-dataline) (org-table-check-inside-data-field) - (let* ((col (org-table-current-column)) - (beg (org-table-begin)) - (end (org-table-end)) - ;; Current cursor position - (linepos (org-current-line)) - (colpos col)) - (goto-char beg) - (while (< (point) end) - (if (org-at-table-hline-p) - nil - (org-table-goto-column col t) - (and (looking-at "|[^|\n]+|") - (replace-match "|"))) - (beginning-of-line 2)) - (move-marker end nil) - (org-goto-line linepos) - (org-table-goto-column colpos) + (let ((col (org-table-current-column)) + (beg (org-table-begin)) + (end (copy-marker (org-table-end)))) + (org-table-save-field + (goto-char beg) + (while (< (point) end) + (if (org-at-table-hline-p) + nil + (org-table-goto-column col t) + (and (looking-at "|[^|\n]+|") + (replace-match "|"))) + (forward-line))) + (set-marker end nil) + (org-table-goto-column (max 1 (1- col))) (org-table-align) (when (or (not org-table-fix-formulas-confirm) (funcall org-table-fix-formulas-confirm "Fix formulas? ")) - (org-table-fix-formulas "$" (list (cons (number-to-string col) "INVALID")) - col -1 col) - (org-table-fix-formulas "$LR" (list (cons (number-to-string col) "INVALID")) - col -1 col)))) + (org-table-fix-formulas + "$" (list (cons (number-to-string col) "INVALID")) col -1 col) + (org-table-fix-formulas + "$LR" (list (cons (number-to-string col) "INVALID")) col -1 col)))) ;;;###autoload (defun org-table-move-column-right () @@ -1452,31 +1470,27 @@ first dline below it is used. When ABOVE is non-nil, the one above is used." (defun org-table-move-column (&optional left) "Move the current column to the right. With arg LEFT, move to the left." (interactive "P") - (if (not (org-at-table-p)) - (user-error "Not at a table")) + (unless (org-at-table-p) (user-error "Not at a table")) (org-table-find-dataline) (org-table-check-inside-data-field) (let* ((col (org-table-current-column)) (col1 (if left (1- col) col)) + (colpos (if left (1- col) (1+ col))) (beg (org-table-begin)) - (end (org-table-end)) - ;; Current cursor position - (linepos (org-current-line)) - (colpos (if left (1- col) (1+ col)))) - (if (and left (= col 1)) - (user-error "Cannot move column further left")) - (if (and (not left) (looking-at "[^|\n]*|[^|\n]*$")) - (user-error "Cannot move column further right")) - (goto-char beg) - (while (< (point) end) - (if (org-at-table-hline-p) - nil - (org-table-goto-column col1 t) - (and (looking-at "|\\([^|\n]+\\)|\\([^|\n]+\\)|") - (replace-match "|\\2|\\1|"))) - (beginning-of-line 2)) - (move-marker end nil) - (org-goto-line linepos) + (end (copy-marker (org-table-end)))) + (when (and left (= col 1)) + (user-error "Cannot move column further left")) + (when (and (not left) (looking-at "[^|\n]*|[^|\n]*$")) + (user-error "Cannot move column further right")) + (org-table-save-field + (goto-char beg) + (while (< (point) end) + (unless (org-at-table-hline-p) + (org-table-goto-column col1 t) + (when (looking-at "|\\([^|\n]+\\)|\\([^|\n]+\\)|") + (replace-match "|\\2|\\1|"))) + (forward-line))) + (set-marker end nil) (org-table-goto-column colpos) (org-table-align) (when (or (not org-table-fix-formulas-confirm) @@ -1623,7 +1637,7 @@ In particular, this does handle wide and invisible characters." dline -1 dline)))) ;;;###autoload -(defun org-table-sort-lines (with-case &optional sorting-type) +(defun org-table-sort-lines (with-case &optional sorting-type getkey-func compare-func) "Sort table lines according to the column at point. The position of point indicates the column to be used for @@ -1636,76 +1650,107 @@ 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). Sorting in reverse order is also possible. +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 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) where the capital letter indicate that sorting -should be done in reverse order." +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 either +a string or a number that should serve as the sorting key for that +row. It will then use COMPARE-FUNC to compare entries. If GETKEY-FUNC +is specified interactively, the comparison will be either a string or +numeric compare based on the type of the first key in the table." (interactive "P") - (let* ((thisline (org-current-line)) - (thiscol (org-table-current-column)) - (otc org-table-overlay-coordinates) - beg end bcol ecol tend tbeg column lns pos) - (when (equal thiscol 0) - (if (org-called-interactively-p 'any) - (setq thiscol - (string-to-number - (read-string "Use column N for sorting: "))) - (setq thiscol 1)) - (org-table-goto-column thiscol)) - (org-table-check-inside-data-field) - (if (org-region-active-p) - (progn - (setq beg (region-beginning) end (region-end)) - (goto-char beg) - (setq column (org-table-current-column) - beg (point-at-bol)) - (goto-char end) - (setq end (point-at-bol 2))) - (setq column (org-table-current-column) - pos (point) - tbeg (org-table-begin) - tend (org-table-end)) - (if (re-search-backward org-table-hline-regexp tbeg t) - (setq beg (point-at-bol 2)) - (goto-char tbeg) - (setq beg (point-at-bol 1))) - (goto-char pos) - (if (re-search-forward org-table-hline-regexp tend t) - (setq end (point-at-bol 1)) - (goto-char tend) - (setq end (point-at-bol)))) - (setq beg (move-marker (make-marker) beg) - end (move-marker (make-marker) end)) - (untabify beg end) - (goto-char beg) - (org-table-goto-column column) - (skip-chars-backward "^|") - (setq bcol (current-column)) - (org-table-goto-column (1+ column)) - (skip-chars-backward "^|") - (setq ecol (1- (current-column))) - (org-table-goto-column column) - (setq lns (mapcar (lambda(x) (cons - (org-sort-remove-invisible - (nth (1- column) - (org-split-string x "[ \t]*|[ \t]*"))) - x)) - (org-split-string (buffer-substring beg end) "\n"))) - (setq lns (org-do-sort lns "Table" with-case sorting-type)) - (when org-table-overlay-coordinates - (org-table-toggle-coordinate-overlays)) - (delete-region beg end) - (move-marker beg nil) - (move-marker end nil) - (insert (mapconcat 'cdr lns "\n") "\n") - (org-goto-line thisline) - (org-table-goto-column thiscol) - (when otc (org-table-toggle-coordinate-overlays)) - (message "%d lines sorted, based on column %d" (length lns) column))) + (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) + ((org-called-interactively-p 'any) + (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: ")))) + (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)))) + (let ((start (org-table-begin)) + (end (org-table-end))) + (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* ((sort-fold-case (not with-case)) + (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. + (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) + (org-float-time + (org-time-string-to-time (match-string 0 f)))) + ((string-match "[0-9]\\{1,2\\}:[0-9]\\{2\\}" f) + (org-hh:mm-string-to-minutes f)) + (t 0)))) + ((?f ?F) + (or getkey-func + (and (org-called-interactively-p 'any) + (intern + (completing-read "Sort using function: " + obarray #'fboundp t))) + (error "Missing key extractor to sort rows"))) + (t (user-error "Invalid sorting type `%c'" sorting-type)))) + (predicate + (case sorting-type + ((?n ?N ?t ?T) #'<) + ((?a ?A) #'string<) + ((?f ?F) compare-func)))) + (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) + ;; Move back to initial field. + (forward-line (car coordinates)) + (move-to-column (cdr coordinates)))))) ;;;###autoload (defun org-table-cut-region (beg end) @@ -1725,34 +1770,31 @@ with `org-table-paste-rectangle'." (if (org-region-active-p) (region-beginning) (point)) (if (org-region-active-p) (region-end) (point)) current-prefix-arg)) - (let* (l01 c01 l02 c02 l1 c1 l2 c2 ic1 ic2 - region cols - (rpl (if cut " " nil))) - (goto-char beg) - (org-table-check-inside-data-field) - (setq l01 (org-current-line) - c01 (org-table-current-column)) - (goto-char end) + (goto-char (min beg end)) + (org-table-check-inside-data-field) + (let ((beg (line-beginning-position)) + (c01 (org-table-current-column)) + region) + (goto-char (max beg end)) (org-table-check-inside-data-field) - (setq l02 (org-current-line) - c02 (org-table-current-column)) - (setq l1 (min l01 l02) l2 (max l01 l02) - c1 (min c01 c02) c2 (max c01 c02)) - (catch 'exit - (while t - (catch 'nextline - (if (> l1 l2) (throw 'exit t)) - (org-goto-line l1) - (if (org-at-table-hline-p) (throw 'nextline (setq l1 (1+ l1)))) - (setq cols nil ic1 c1 ic2 c2) - (while (< ic1 (1+ ic2)) - (push (org-table-get-field ic1 rpl) cols) - (setq ic1 (1+ ic1))) - (push (nreverse cols) region) - (setq l1 (1+ l1))))) - (setq org-table-clip (nreverse region)) - (if cut (org-table-align)) - org-table-clip)) + (let* ((end (copy-marker (line-end-position))) + (c02 (org-table-current-column)) + (column-start (min c01 c02)) + (column-end (max c01 c02)) + (column-number (1+ (- column-end column-start))) + (rpl (and cut " "))) + (goto-char beg) + (while (< (point) end) + (unless (org-at-table-hline-p) + ;; Collect every cell between COLUMN-START and COLUMN-END. + (let (cols) + (dotimes (c column-number) + (push (org-table-get-field (+ c column-start) rpl) cols)) + (push (nreverse cols) region))) + (forward-line)) + (set-marker end nil)) + (when cut (org-table-align)) + (setq org-table-clip (nreverse region)))) ;;;###autoload (defun org-table-paste-rectangle () @@ -1762,27 +1804,25 @@ will be overwritten. If the rectangle does not fit into the present table, the table is enlarged as needed. The process ignores horizontal separator lines." (interactive) - (unless (and org-table-clip (listp org-table-clip)) + (unless (consp org-table-clip) (user-error "First cut/copy a region to paste!")) (org-table-check-inside-data-field) - (let* ((clip org-table-clip) - (line (org-current-line)) - (col (org-table-current-column)) + (let* ((column (org-table-current-column)) (org-enable-table-editor t) - (org-table-automatic-realign nil) - c cols field) - (while (setq cols (pop clip)) - (while (org-at-table-hline-p) (beginning-of-line 2)) - (if (not (org-at-table-p)) - (progn (end-of-line 0) (org-table-next-field))) - (setq c col) - (while (setq field (pop cols)) - (org-table-goto-column c nil 'force) - (org-table-get-field nil field) - (setq c (1+ c))) - (beginning-of-line 2)) - (org-goto-line line) - (org-table-goto-column col) + (org-table-automatic-realign nil)) + (org-table-save-field + (dolist (row org-table-clip) + (while (org-at-table-hline-p) (forward-line)) + ;; If we left the table, create a new row. + (when (and (bolp) (not (looking-at "[ \t]*|"))) + (end-of-line 0) + (org-table-next-field)) + (let ((c column)) + (dolist (field row) + (org-table-goto-column c nil 'force) + (org-table-get-field nil field) + (incf c))) + (forward-line))) (org-table-align))) ;;;###autoload @@ -1799,8 +1839,8 @@ blindly applies a recipe that works for simple tables." (require 'table) (if (org-at-table.el-p) ;; convert to Org-mode table - (let ((beg (move-marker (make-marker) (org-table-begin t))) - (end (move-marker (make-marker) (org-table-end t)))) + (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) @@ -1808,8 +1848,8 @@ blindly applies a recipe that works for simple tables." (goto-char beg)) (if (org-at-table-p) ;; convert to table.el table - (let ((beg (move-marker (make-marker) (org-table-begin))) - (end (move-marker (make-marker) (org-table-end)))) + (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) @@ -1832,7 +1872,7 @@ blindly applies a recipe that works for simple tables." (goto-char beg))))) (defun org-table-transpose-table-at-point () - "Transpose orgmode table at point and eliminate hlines. + "Transpose Org table at point and eliminate hlines. So a table like | 1 | 2 | 4 | 5 | @@ -1847,9 +1887,11 @@ will be transposed as | 4 | c | g | | 5 | d | h | -Note that horizontal lines disappeared." +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 (p) (let ((tp table)) (mapcar @@ -1859,10 +1901,17 @@ Note that horizontal lines disappeared." (setq tp (cdr tp)))) table))) (car table)))) - (delete-region (org-table-begin) (org-table-end)) - (insert (mapconcat (lambda(x) (concat "| " (mapconcat 'identity x " | " ) " |\n" )) - contents "")) - (org-table-align))) + (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) @@ -1873,7 +1922,8 @@ 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]' +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 @@ -1890,48 +1940,43 @@ 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* ((beg (region-beginning)) - (cline (save-excursion (goto-char beg) (org-current-line))) - (ccol (save-excursion (goto-char beg) (org-table-current-column))) - nlines) + ;; There is a region: fill as a paragraph. + (let ((start (region-beginning))) (org-table-cut-region (region-beginning) (region-end)) - (if (> (length (car org-table-clip)) 1) - (user-error "Region must be limited to single column")) - (setq nlines (if arg - (if (< arg 1) - (+ (length org-table-clip) arg) - arg) - (length org-table-clip))) - (setq org-table-clip - (mapcar 'list (org-wrap (mapconcat 'car org-table-clip " ") - nil nlines))) - (org-goto-line cline) - (org-table-goto-column ccol) + (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 + ;; 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|")) - (if arg - ;; combine with field above - (let ((s (org-table-blank-field)) - (col (org-table-current-column))) - (beginning-of-line 0) - (while (org-at-table-hline-p) (beginning-of-line 0)) - (org-table-goto-column col) - (skip-chars-forward "^|") - (skip-chars-backward " ") - (insert " " (org-trim s)) - (org-table-align)) - ;; split field - (if (looking-at "\\([^|]+\\)+|") - (let ((s (match-string 1))) - (replace-match " |") - (goto-char (match-beginning 0)) - (org-table-next-row) - (insert (org-trim s) " ") - (org-table-align)) - (org-table-next-row))))) + (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))))) (defvar org-field-marker nil) @@ -2120,42 +2165,51 @@ If NLAST is a number, only the NLAST fields will actually be summed." (defun org-table-current-field-formula (&optional key noerror) "Return the formula active for the current field. -Assumes that specials are in place. -If KEY is given, return the key to this formula. -Otherwise return the formula preceded with \"=\" or \":=\"." - (let* ((name (car (rassoc (list (org-current-line) - (org-table-current-column)) - org-table-named-field-locations))) - (col (org-table-current-column)) - (scol (int-to-string col)) - (ref (format "@%d$%d" (org-table-current-dline) col)) - (stored-list (org-table-get-stored-formulas noerror)) - (ass (or (assoc name stored-list) - (assoc ref stored-list) - (assoc scol stored-list)))) - (if key - (car ass) - (if ass (concat (if (string-match "^[0-9]+$" (car ass)) "=" ":=") - (cdr ass)))))) + +Assumes that table is already analyzed. If KEY is given, return +the key to this formula. Otherwise return the formula preceded +with \"=\" or \":=\"." + (let* ((line (count-lines org-table-current-begin-pos + (line-beginning-position))) + (row (org-table-line-to-dline line))) + (cond + (row + (let* ((col (org-table-current-column)) + (name (car (rassoc (list line col) + org-table-named-field-locations))) + (scol (format "$%d" col)) + (ref (format "@%d$%d" (org-table-current-dline) col)) + (stored-list (org-table-get-stored-formulas noerror)) + (ass (or (assoc name stored-list) + (assoc ref stored-list) + (assoc scol stored-list)))) + (cond (key (car ass)) + (ass (concat (if (string-match "^[0-9]+$" (car ass)) "=" ":=") + (cdr ass)))))) + (noerror nil) + (t (error "No formula active for the current field"))))) (defun org-table-get-formula (&optional equation named) "Read a formula from the minibuffer, offer stored formula as default. When NAMED is non-nil, look for a named equation." (let* ((stored-list (org-table-get-stored-formulas)) - (name (car (rassoc (list (org-current-line) + (name (car (rassoc (list (count-lines org-table-current-begin-pos + (line-beginning-position)) (org-table-current-column)) org-table-named-field-locations))) - (ref (format "@%d$%d" (org-table-current-dline) + (ref (format "@%d$%d" + (org-table-current-dline) (org-table-current-column))) (refass (assoc ref stored-list)) (nameass (assoc name stored-list)) - (scol (if named - (if (and name (not (string-match "^LR[0-9]+$" name))) - name - ref) - (int-to-string (org-table-current-column)))) - (dummy (and (or nameass refass) (not named) - (not (y-or-n-p "Replace existing field formula with column formula? " )) + (scol (cond + ((not named) (format "$%d" (org-table-current-column))) + ((and name (not (string-match "\\`LR[0-9]+\\'" name))) name) + (t ref))) + (dummy (and (or nameass refass) + (not named) + (not (y-or-n-p "Replace existing field formula with \ +column formula? " )) (message "Formula not replaced"))) (name (or name ref)) (org-table-may-need-update nil) @@ -2168,9 +2222,8 @@ When NAMED is non-nil, look for a named equation." (t (org-table-formula-from-user (read-string (org-table-formula-to-user - (format "%s formula %s%s=" + (format "%s formula %s=" (if named "Field" "Column") - (if (member (string-to-char scol) '(?$ ?@)) "" "$") scol)) (if stored (org-table-formula-to-user stored) "") 'org-table-formula-history @@ -2194,25 +2247,27 @@ When NAMED is non-nil, look for a named equation." (org-table-store-formulas stored-list)) eq)) -(defun org-table-store-formulas (alist) - "Store the list of formulas below the current table." - (setq alist (sort alist 'org-table-formula-less-p)) - (let ((case-fold-search t)) - (save-excursion - (goto-char (org-table-end)) - (if (looking-at "\\([ \t]*\n\\)*[ \t]*\\(#\\+tblfm:\\)\\(.*\n?\\)") +(defun org-table-store-formulas (alist &optional location) + "Store the list of formulas below the current table. +If optional argument LOCATION is a buffer position, insert it at +LOCATION instead." + (save-excursion + (if location + (progn (goto-char location) (beginning-of-line)) + (goto-char (org-table-end))) + (let ((case-fold-search t)) + (if (looking-at "\\([ \t]*\n\\)*[ \t]*\\(#\\+TBLFM:\\)\\(.*\n?\\)") (progn - ;; don't overwrite TBLFM, we might use text properties to store stuff + ;; Don't overwrite TBLFM, we might use text properties to + ;; store stuff. (goto-char (match-beginning 3)) (delete-region (match-beginning 3) (match-end 0))) (org-indent-line) (insert (or (match-string 2) "#+TBLFM:"))) (insert " " - (mapconcat (lambda (x) - (concat - (if (equal (string-to-char (car x)) ?@) "" "$") - (car x) "=" (cdr x))) - alist "::") + (mapconcat (lambda (x) (concat (car x) "=" (cdr x))) + (sort alist #'org-table-formula-less-p) + "::") "\n")))) (defsubst org-table-formula-make-cmp-string (a) @@ -2241,33 +2296,47 @@ When NAMED is non-nil, look for a named equation." (and as bs (string< as bs)))) ;;;###autoload -(defun org-table-get-stored-formulas (&optional noerror) - "Return an alist with the stored formulas directly after current table." - (interactive) ;; FIXME interactive? - (let ((case-fold-search t) scol eq eq-alist strings string seen) - (save-excursion - (goto-char (org-table-end)) - (when (looking-at "\\([ \t]*\n\\)*[ \t]*#\\+tblfm: *\\(.*\\)") - (setq strings (org-split-string (org-match-string-no-properties 2) - " *:: *")) - (while (setq string (pop strings)) - (when (string-match "\\`\\(@[-+I<>0-9.$@]+\\|@?[0-9]+\\|\\$\\([a-zA-Z0-9]+\\|[<>]+\\)\\) *= *\\(.*[^ \t]\\)" string) - (setq scol (if (match-end 2) - (match-string 2 string) - (match-string 1 string)) - scol (if (member (string-to-char scol) '(?< ?>)) - (concat "$" scol) scol) - eq (match-string 3 string) - eq-alist (cons (cons scol eq) eq-alist)) - (if (member scol seen) - (if noerror - (progn - (message "Double definition `$%s=' in TBLFM line, please fix by hand" scol) - (ding) - (sit-for 2)) - (user-error "Double definition `$%s=' in TBLFM line, please fix by hand" scol)) - (push scol seen)))))) - (nreverse eq-alist))) +(defun org-table-get-stored-formulas (&optional noerror location) + "Return an alist with the stored formulas directly after current table. +By default, only return active formulas, i.e., formulas located +on the first line after the table. However, if optional argument +LOCATION is a buffer position, consider the formulas there." + (save-excursion + (if location + (progn (goto-char location) (beginning-of-line)) + (goto-char (org-table-end))) + (let ((case-fold-search t)) + (when (looking-at "\\([ \t]*\n\\)*[ \t]*#\\+TBLFM: *\\(.*\\)") + (let ((strings (org-split-string (org-match-string-no-properties 2) + " *:: *")) + eq-alist seen) + (dolist (string strings (nreverse eq-alist)) + (when (string-match "\\`\\(@[-+I<>0-9.$@]+\\|\\$\\([_a-zA-Z0-9]+\\|\ +[<>]+\\)\\) *= *\\(.*[^ \t]\\)" + string) + (let ((lhs + (let ((m (match-string 1 string))) + (cond + ((not (match-end 2)) m) + ;; Is it a column reference? + ((org-string-match-p "\\`$\\([0-9]+\\|[<>]+\\)\\'" m) m) + ;; Since named columns are not possible in + ;; LHS, assume this is a named field. + (t (match-string 2 string))))) + (rhs (match-string 3 string))) + (push (cons lhs rhs) eq-alist) + (cond + ((not (member lhs seen)) (push lhs seen)) + (noerror + (message + "Double definition `%s=' in TBLFM line, please fix by hand" + lhs) + (ding) + (sit-for 2)) + (t + (user-error + "Double definition `%s=' in TBLFM line, please fix by hand" + lhs))))))))))) (defun org-table-fix-formulas (key replace &optional limit delta remove) "Modify the equations after the table structure has been edited. @@ -2305,83 +2374,6 @@ For all numbers larger than LIMIT, shift them by DELTA." (message msg)))))) (forward-line)))) -(defun org-table-get-specials () - "Get the column names and local parameters for this table." - (save-excursion - (let ((beg (org-table-begin)) (end (org-table-end)) - names name fields fields1 field cnt - c v l line col types dlines hlines last-dline) - (setq org-table-column-names nil - org-table-local-parameters nil - org-table-named-field-locations nil - org-table-current-begin-line nil - org-table-current-begin-pos nil - org-table-current-line-types nil - org-table-current-ncol 0) - (goto-char beg) - (when (re-search-forward "^[ \t]*| *! *\\(|.*\\)" end t) - (setq names (org-split-string (match-string 1) " *| *") - cnt 1) - (while (setq name (pop names)) - (setq cnt (1+ cnt)) - (if (string-match "^[a-zA-Z][_a-zA-Z0-9]*$" name) - (push (cons name (int-to-string cnt)) org-table-column-names)))) - (setq org-table-column-names (nreverse org-table-column-names)) - (setq org-table-column-name-regexp - (concat "\\$\\(" (mapconcat 'car org-table-column-names "\\|") "\\)\\>")) - (goto-char beg) - (while (re-search-forward "^[ \t]*| *\\$ *\\(|.*\\)" end t) - (setq fields (org-split-string (match-string 1) " *| *")) - (while (setq field (pop fields)) - (if (string-match "^\\([a-zA-Z][_a-zA-Z0-9]*\\|%\\) *= *\\(.*\\)" field) - (push (cons (match-string 1 field) (match-string 2 field)) - org-table-local-parameters)))) - (goto-char beg) - (while (re-search-forward "^[ \t]*| *\\([_^]\\) *\\(|.*\\)" end t) - (setq c (match-string 1) - fields (org-split-string (match-string 2) " *| *")) - (save-excursion - (beginning-of-line (if (equal c "_") 2 0)) - (setq line (org-current-line) col 1) - (and (looking-at "^[ \t]*|[^|]*\\(|.*\\)") - (setq fields1 (org-split-string (match-string 1) " *| *")))) - (while (and fields1 (setq field (pop fields))) - (setq v (pop fields1) col (1+ 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)))) - ;; Analyse the line types - (goto-char beg) - (setq org-table-current-begin-line (org-current-line) - org-table-current-begin-pos (point) - l org-table-current-begin-line) - (while (looking-at "[ \t]*|\\(-\\)?") - (push (if (match-end 1) 'hline 'dline) types) - (if (match-end 1) (push l hlines) (push l dlines)) - (beginning-of-line 2) - (setq l (1+ l))) - (push 'hline types) ;; add an imaginary extra hline to the end - (setq org-table-current-line-types (apply 'vector (nreverse types)) - last-dline (car dlines) - org-table-dlines (apply 'vector (cons nil (nreverse dlines))) - org-table-hlines (apply 'vector (cons nil (nreverse hlines)))) - (org-goto-line last-dline) - (let* ((l last-dline) - (fields (org-split-string - (buffer-substring (point-at-bol) (point-at-eol)) - "[ \t]*|[ \t]*")) - (nfields (length fields)) - al al2) - (setq org-table-current-ncol nfields) - (loop for i from 1 to nfields do - (push (list (format "LR%d" i) l i) al) - (push (cons (format "LR%d" i) (nth (1- 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)))))) - ;;;###autoload (defun org-table-maybe-eval-formula () "Check if the current field starts with \"=\" or \":=\". @@ -2424,56 +2416,199 @@ After each change, a message will be displayed indicating the meaning of the new mark." (interactive) (unless (org-at-table-p) (user-error "Not at a table")) - (let* ((marks (append (mapcar 'car org-recalc-marks) '(" "))) - (beg (org-table-begin)) - (end (org-table-end)) - (l (org-current-line)) - (l1 (if (org-region-active-p) (org-current-line (region-beginning)))) - (l2 (if (org-region-active-p) (org-current-line (region-end)))) - (have-col - (save-excursion - (goto-char beg) - (not (re-search-forward "^[ \t]*|[^-|][^|]*[^#!$*_^| \t][^|]*|" end t)))) + (let* ((region (org-region-active-p)) + (l1 (and region + (save-excursion (goto-char (region-beginning)) + (copy-marker (line-beginning-position))))) + (l2 (and region + (save-excursion (goto-char (region-end)) + (copy-marker (line-beginning-position))))) + (l (copy-marker (line-beginning-position))) (col (org-table-current-column)) - (forcenew (car (assoc newchar org-recalc-marks))) - epos new) - (when l1 - (message "Change region to what mark? Type # * ! $ or SPC: ") - (setq newchar (char-to-string (read-char-exclusive)) - forcenew (car (assoc newchar org-recalc-marks)))) - (if (and newchar (not forcenew)) - (user-error "Invalid NEWCHAR `%s' in `org-table-rotate-recalc-marks'" - newchar)) - (if l1 (org-goto-line l1)) + (newchar (if region + (char-to-string + (read-char-exclusive + "Change region to what mark? Type # * ! $ or SPC: ")) + newchar)) + (no-special-column + (save-excursion + (goto-char (org-table-begin)) + (re-search-forward + "^[ \t]*|[^-|][^|]*[^#!$*_^| \t][^|]*|" (org-table-end) t)))) + (when (and newchar (not (assoc newchar org-recalc-marks))) + (user-error "Invalid character `%s' in `org-table-rotate-recalc-marks'" + newchar)) + (when l1 (goto-char l1)) (save-excursion - (beginning-of-line 1) + (beginning-of-line) (unless (looking-at org-table-dataline-regexp) (user-error "Not at a table data line"))) - (unless have-col + (when no-special-column (org-table-goto-column 1) - (org-table-insert-column) - (org-table-goto-column (1+ col))) - (setq epos (point-at-eol)) + (org-table-insert-column)) + (let ((previous-line-end (line-end-position)) + (newchar + (save-excursion + (beginning-of-line) + (cond ((not (looking-at "^[ \t]*| *\\([#!$*^_ ]\\) *|")) "#") + (newchar) + (t (cadr (member (match-string 1) + (append (mapcar #'car org-recalc-marks) + '(" "))))))))) + ;; Rotate mark in first row. + (org-table-get-field 1 (format " %s " newchar)) + ;; Rotate marks in additional rows if a region is active. + (when region + (save-excursion + (forward-line) + (while (<= (point) l2) + (when (looking-at org-table-dataline-regexp) + (org-table-get-field 1 (format " %s " newchar))) + (forward-line)))) + ;; Only align if rotation actually changed lines' length. + (when (/= previous-line-end (line-end-position)) (org-table-align))) + (goto-char l) + (org-table-goto-column (if no-special-column (1+ col) col)) + (when l1 (set-marker l1 nil)) + (when l2 (set-marker l2 nil)) + (set-marker l nil) + (when (org-called-interactively-p 'interactive) + (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 - (beginning-of-line 1) - (org-table-get-field - 1 (if (looking-at "^[ \t]*| *\\([#!$*^_ ]\\) *|") - (concat " " - (setq new (or forcenew - (cadr (member (match-string 1) marks)))) - " ") - " # "))) - (if (and l1 l2) - (progn - (org-goto-line l1) - (while (progn (beginning-of-line 2) (not (= (org-current-line) l2))) - (and (looking-at org-table-dataline-regexp) - (org-table-get-field 1 (concat " " new " ")))) - (org-goto-line l1))) - (if (not (= epos (point-at-eol))) (org-table-align)) - (org-goto-line l) - (and (org-called-interactively-p 'interactive) - (message "%s" (cdr (assoc new org-recalc-marks)))))) + (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) " *| *")) + (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 (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))) + (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) + (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 () @@ -2481,7 +2616,7 @@ of the new mark." (interactive) (and org-table-allow-automatic-line-recalculation (not (and (memq last-command org-recalc-commands) - (equal org-last-recalc-line (org-current-line)))) + (eq org-last-recalc-line (line-beginning-position)))) (save-excursion (beginning-of-line 1) (looking-at org-table-auto-recalculate-regexp)) (org-table-recalculate) t)) @@ -2540,10 +2675,9 @@ it is already stored, or because it is a modified equation that should not overwrite the stored one." (interactive "P") (org-table-check-inside-data-field) - (or suppress-analysis (org-table-get-specials)) + (or suppress-analysis (org-table-analyze)) (if (equal arg '(16)) (let ((eq (org-table-current-field-formula))) - (or eq (user-error "No equation active for current field")) (org-table-get-field nil eq) (org-table-align) (setq org-table-may-need-update t)) @@ -2557,7 +2691,7 @@ not overwrite the stored one." (org-table-get-formula equation (equal arg '(4))))) (n0 (org-table-current-column)) (org-tbl-calc-modes (copy-sequence org-calc-default-modes)) - (numbers nil) ; was a variable, now fixed default + (numbers nil) ; was a variable, now fixed default (keep-empty nil) n form form0 formrpl formrg bw fmt x ev orig c lispp literal duration duration-output-format) @@ -2608,7 +2742,9 @@ not overwrite the stored one." (setq orig (or (get-text-property 1 :orig-formula formula) "?")) (while (> ndown 0) (setq fields (org-split-string - (buffer-substring-no-properties (point-at-bol) (point-at-eol)) + (org-trim + (buffer-substring-no-properties + (line-beginning-position) (line-end-position))) " *| *")) ;; replace fields with duration values if relevant (if duration @@ -2641,9 +2777,10 @@ not overwrite the stored one." t t form))) ;; Check for old vertical references - (setq form (org-table-rewrite-old-row-references form)) + (org-table--error-on-old-row-references form) ;; Insert remote references - (while (string-match "\\ (length (match-string 0 form)) 1)) - (setq formrg (save-match-data - (org-table-get-range (match-string 0 form) nil n0))) + (setq formrg + (save-match-data + (org-table-get-range + (match-string 0 form) org-table-current-begin-pos n0))) (setq formrpl (save-match-data (org-table-make-reference @@ -2676,15 +2815,19 @@ not overwrite the stored one." (string-match (regexp-quote form) formrpl))) (setq form (replace-match formrpl t t form)) (user-error "Spreadsheet error: invalid reference \"%s\"" form))) - ;; Insert simple ranges - (while (string-match "\\$\\([0-9]+\\)\\.\\.\\$\\([0-9]+\\)" form) + ;; Insert simple ranges, i.e. included in the current row. + (while (string-match + "\\$\\(\\([-+]\\)?[0-9]+\\)\\.\\.\\$\\(\\([-+]\\)?[0-9]+\\)" + form) (setq form (replace-match (save-match-data (org-table-make-reference - (org-sublist - fields (string-to-number (match-string 1 form)) - (string-to-number (match-string 2 form))) + (org-sublist fields + (+ (if (match-end 2) n0 0) + (string-to-number (match-string 1 form))) + (+ (if (match-end 4) n0 0) + (string-to-number (match-string 3 form)))) keep-empty numbers lispp)) t t form))) (setq form0 form) @@ -2692,14 +2835,16 @@ not overwrite the stored one." (while (string-match "\\$\\(\\([-+]\\)?[0-9]+\\)" form) (setq n (+ (string-to-number (match-string 1 form)) (if (match-end 2) n0 0)) - x (nth (1- (if (= n 0) n0 (max n 1))) fields)) - (unless x (user-error "Invalid field specifier \"%s\"" - (match-string 0 form))) - (setq form (replace-match - (save-match-data - (org-table-make-reference - x keep-empty numbers lispp)) - t t form))) + x (nth (1- (if (= n 0) n0 (max n 1))) fields) + formrpl (save-match-data + (org-table-make-reference + x keep-empty numbers lispp))) + (when (or (not x) + (save-match-data + (string-match (regexp-quote formula) formrpl))) + (user-error "Invalid field specifier \"%s\"" + (match-string 0 form))) + (setq form (replace-match formrpl t t form))) (if lispp (setq ev (condition-case nil @@ -2742,7 +2887,7 @@ Orig: %s $xyz-> %s @r$c-> %s $1-> %s\n" orig formula form0 form)) - (if (listp ev) + (if (consp ev) (princ (format " %s^\nError: %s" (make-string (car ev) ?\-) (nth 1 ev))) (princ (format "Result: %s\nFormat: %s\nFinal: %s" @@ -2757,7 +2902,7 @@ $1-> %s\n" orig formula form0 form)) (user-error "Abort")) (delete-window bw) (message ""))) - (if (listp ev) (setq fmt nil ev "#ERROR")) + (when (consp ev) (setq fmt nil ev "#ERROR")) (org-table-justify-field-maybe (format org-table-formula-field-format (if fmt (format fmt (string-to-number ev)) ev))) @@ -2776,146 +2921,152 @@ $1-> %s\n" orig formula form0 form)) (defun org-table-get-range (desc &optional tbeg col highlight corners-only) "Get a calc vector from a column, according to descriptor DESC. + Optional arguments TBEG and COL can give the beginning of the table and the current column, to avoid unnecessary parsing. HIGHLIGHT means just highlight the range. When CORNERS-ONLY is set, only return the corners of the range as -a list (line1 column1 line2 column2) where line1 and line2 are line numbers -in the buffer and column1 and column2 are table column numbers." - (if (not (equal (string-to-char desc) ?@)) - (setq desc (concat "@" desc))) - (save-excursion - (or tbeg (setq tbeg (org-table-begin))) - (or col (setq col (org-table-current-column))) - (let ((thisline (org-current-line)) - beg end c1 c2 r1 r2 rangep tmp) - (unless (string-match org-table-range-regexp desc) - (user-error "Invalid table range specifier `%s'" desc)) - (setq rangep (match-end 3) - r1 (and (match-end 1) (match-string 1 desc)) - r2 (and (match-end 4) (match-string 4 desc)) - c1 (and (match-end 2) (substring (match-string 2 desc) 1)) - c2 (and (match-end 5) (substring (match-string 5 desc) 1))) - - (and c1 (setq c1 (+ (string-to-number c1) - (if (memq (string-to-char c1) '(?- ?+)) col 0)))) - (and c2 (setq c2 (+ (string-to-number c2) - (if (memq (string-to-char c2) '(?- ?+)) col 0)))) - (if (equal r1 "") (setq r1 nil)) - (if (equal r2 "") (setq r2 nil)) - (if r1 (setq r1 (org-table-get-descriptor-line r1))) - (if r2 (setq r2 (org-table-get-descriptor-line r2))) - ; (setq r2 (or r2 r1) c2 (or c2 c1)) - (if (not r1) (setq r1 thisline)) - (if (not r2) (setq r2 thisline)) - (if (or (not c1) (= 0 c1)) (setq c1 col)) - (if (or (not c2) (= 0 c2)) (setq c2 col)) - (if (and (not corners-only) - (or (not rangep) (and (= r1 r2) (= c1 c2)))) - ;; just one field - (progn - (org-goto-line r1) - (while (not (looking-at org-table-dataline-regexp)) - (beginning-of-line 2)) - (prog1 (org-trim (org-table-get-field c1)) - (if highlight (org-table-highlight-rectangle (point) (point))))) - ;; A range, return a vector - ;; First sort the numbers to get a regular rectangle - (if (< r2 r1) (setq tmp r1 r1 r2 r2 tmp)) - (if (< c2 c1) (setq tmp c1 c1 c2 c2 tmp)) - (if corners-only - ;; Only return the corners of the range - (list r1 c1 r2 c2) - ;; Copy the range values into a list - (org-goto-line r1) - (while (not (looking-at org-table-dataline-regexp)) - (beginning-of-line 2)) - (org-table-goto-column c1) - (setq beg (point)) - (org-goto-line r2) - (while (not (looking-at org-table-dataline-regexp)) - (beginning-of-line 0)) - (org-table-goto-column c2) - (setq end (point)) - (if highlight - (org-table-highlight-rectangle - beg (progn (skip-chars-forward "^|\n") (point)))) - ;; return string representation of calc vector - (mapcar 'org-trim - (apply 'append (org-table-copy-region beg end)))))))) - -(defun org-table-get-descriptor-line (desc &optional cline bline table) - "Analyze descriptor DESC and retrieve the corresponding line number. -The cursor is currently in line CLINE, the table begins in line BLINE, -and TABLE is a vector with line types." - (if (string-match "^[0-9]+$" desc) +a list (line1 column1 line2 column2) where line1 and line2 are +line numbers relative to beginning of table, or TBEG, and column1 +and column2 are table column numbers." + (let* ((desc (if (org-string-match-p "\\`\\$[0-9]+\\.\\.\\$[0-9]+\\'" desc) + (replace-regexp-in-string "\\$" "@0$" desc) + desc)) + (col (or col (org-table-current-column))) + (tbeg (or tbeg (org-table-begin))) + (thisline (count-lines tbeg (line-beginning-position)))) + (unless (string-match org-table-range-regexp desc) + (user-error "Invalid table range specifier `%s'" desc)) + (let ((rangep (match-end 3)) + (r1 (let ((r (and (match-end 1) (match-string 1 desc)))) + (or (save-match-data + (and (org-string-nw-p r) + (org-table--descriptor-line r thisline))) + thisline))) + (r2 (let ((r (and (match-end 4) (match-string 4 desc)))) + (or (save-match-data + (and (org-string-nw-p r) + (org-table--descriptor-line r thisline))) + thisline))) + (c1 (let ((c (and (match-end 2) (substring (match-string 2 desc) 1)))) + (if (or (not c) (= (string-to-number c) 0)) col + (+ (string-to-number c) + (if (memq (string-to-char c) '(?- ?+)) col 0))))) + (c2 (let ((c (and (match-end 5) (substring (match-string 5 desc) 1)))) + (if (or (not c) (= (string-to-number c) 0)) col + (+ (string-to-number c) + (if (memq (string-to-char c) '(?- ?+)) col 0)))))) + (save-excursion + (if (and (not corners-only) + (or (not rangep) (and (= r1 r2) (= c1 c2)))) + ;; Just one field. + (progn + (forward-line (- r1 thisline)) + (while (not (looking-at org-table-dataline-regexp)) + (forward-line)) + (prog1 (org-trim (org-table-get-field c1)) + (when highlight (org-table-highlight-rectangle)))) + ;; A range, return a vector. First sort the numbers to get + ;; a regular rectangle. + (let ((first-row (min r1 r2)) + (last-row (max r1 r2)) + (first-column (min c1 c2)) + (last-column (max c1 c2))) + (if corners-only (list first-row first-column last-row last-column) + ;; Copy the range values into a list. + (forward-line (- first-row thisline)) + (while (not (looking-at org-table-dataline-regexp)) + (forward-line) + (incf first-row)) + (org-table-goto-column first-column) + (let ((beg (point))) + (forward-line (- last-row first-row)) + (while (not (looking-at org-table-dataline-regexp)) + (forward-line -1)) + (org-table-goto-column last-column) + (let ((end (point))) + (when highlight + (org-table-highlight-rectangle + beg (progn (skip-chars-forward "^|\n") (point)))) + ;; Return string representation of calc vector. + (mapcar #'org-trim + (apply #'append + (org-table-copy-region beg end)))))))))))) + +(defun org-table--descriptor-line (desc cline) + "Return relative line number corresponding to descriptor DESC. +The cursor is currently in relative line number CLINE." + (if (string-match "\\`[0-9]+\\'" desc) (aref org-table-dlines (string-to-number desc)) - (setq cline (or cline (org-current-line)) - bline (or bline org-table-current-begin-line) - table (or table org-table-current-line-types)) - (if (or - (not (string-match "^\\(\\([-+]\\)?\\(I+\\)\\)?\\(\\([-+]\\)?\\([0-9]+\\)\\)?" desc)) - ;; 1 2 3 4 5 6 - (and (not (match-end 3)) (not (match-end 6))) - (and (match-end 3) (match-end 6) (not (match-end 5)))) - (user-error "Invalid row descriptor `%s'" desc)) - (let* ((hdir (and (match-end 2) (match-string 2 desc))) - (hn (if (match-end 3) (- (match-end 3) (match-beginning 3)) nil)) - (odir (and (match-end 5) (match-string 5 desc))) - (on (if (match-end 6) (string-to-number (match-string 6 desc)))) - (i (- cline bline)) + (when (or (not (string-match + "^\\(\\([-+]\\)?\\(I+\\)\\)?\\(\\([-+]\\)?\\([0-9]+\\)\\)?" + ;; 1 2 3 4 5 6 + desc)) + (and (not (match-end 3)) (not (match-end 6))) + (and (match-end 3) (match-end 6) (not (match-end 5)))) + (user-error "Invalid row descriptor `%s'" desc)) + (let* ((hn (and (match-end 3) (- (match-end 3) (match-beginning 3)))) + (hdir (match-string 2 desc)) + (odir (match-string 5 desc)) + (on (and (match-end 6) (string-to-number (match-string 6 desc)))) (rel (and (match-end 6) (or (and (match-end 1) (not (match-end 3))) (match-end 5))))) - (if (and hn (not hdir)) - (progn - (setq i 0 hdir "+") - (if (eq (aref table 0) 'hline) (setq hn (1- hn))))) - (if (and (not hn) on (not odir)) - (user-error "Should never happen");;(aref org-table-dlines on) - (if (and hn (> hn 0)) - (setq i (org-table-find-row-type table i 'hline (equal hdir "-") - nil hn cline desc))) - (if on - (setq i (org-table-find-row-type table i 'dline (equal odir "-") - rel on cline desc))) - (+ bline i))))) - -(defun org-table-find-row-type (table i type backwards relative n cline desc) - "FIXME: Needs more documentation." - (let ((l (length table))) - (while (> n 0) - (while (and (setq i (+ i (if backwards -1 1))) - (>= i 0) (< i l) - (not (eq (aref table i) type)) - (if (and relative (eq (aref table i) 'hline)) - (cond - ((eq org-table-relative-ref-may-cross-hline t) t) - ((eq org-table-relative-ref-may-cross-hline 'error) - (user-error "Row descriptor %s used in line %d crosses hline" desc cline)) - (t (setq i (- i (if backwards -1 1)) - n 1) - nil)) - t))) - (setq n (1- n))) - (if (or (< i 0) (>= i l)) - (user-error "Row descriptor %s used in line %d leads outside table" - desc cline) - i))) - -(defun org-table-rewrite-old-row-references (s) - (if (string-match "&[-+0-9I]" s) - (user-error "Formula contains old &row reference, please rewrite using @-syntax") - s)) + (when (and hn (not hdir)) + (setq cline 0) + (setq hdir "+") + (when (eq (aref org-table-current-line-types 0) 'hline) (decf hn))) + (when (and (not hn) on (not odir)) (user-error "Should never happen")) + (when hn + (setq cline + (org-table--row-type 'hline hn cline (equal hdir "-") nil desc))) + (when on + (setq cline + (org-table--row-type 'dline on cline (equal odir "-") rel desc))) + cline))) + +(defun org-table--row-type (type n i backwards relative desc) + "Return relative line of Nth row with type TYPE. +Search starts from relative line I. When BACKWARDS in non-nil, +look before I. When RELATIVE is non-nil, the reference is +relative. DESC is the original descriptor that started the +search, as a string." + (let ((l (length org-table-current-line-types))) + (catch :exit + (dotimes (_ n) + (while (and (incf i (if backwards -1 1)) + (>= i 0) + (< i l) + (not (eq (aref org-table-current-line-types i) type)) + ;; We are going to cross a hline. Check if this is + ;; an authorized move. + (cond + ((not relative)) + ((not (eq (aref org-table-current-line-types i) 'hline))) + ((eq org-table-relative-ref-may-cross-hline t)) + ((eq org-table-relative-ref-may-cross-hline 'error) + (user-error "Row descriptor %s crosses hline" desc)) + (t (decf i (if backwards -1 1)) ; Step back. + (throw :exit nil))))))) + (cond ((or (< i 0) (>= i l)) + (user-error "Row descriptor %s leads outside table" desc)) + ;; The last hline doesn't exist. Instead, point to last row + ;; in table. + ((= i (1- l)) (1- i)) + (t i)))) + +(defun org-table--error-on-old-row-references (s) + (when (string-match "&[-+0-9I]" s) + (user-error "Formula contains old &row reference, please rewrite using @-syntax"))) (defun org-table-make-reference (elements keep-empty numbers lispp) "Convert list ELEMENTS to something appropriate to insert into formula. KEEP-EMPTY indicated to keep empty fields, default is to skip them. NUMBERS indicates that everything should be converted to numbers. LISPP non-nil means to return something appropriate for a Lisp -list, 'literal is for the format specifier L." +list, `literal' is for the format specifier L." ;; Calc nan (not a number) is used for the conversion of the empty ;; field to a reference for several reasons: (i) It is accepted in a ;; Calc formula (e. g. "" or "()" would result in a Calc error). @@ -2961,23 +3112,16 @@ list, 'literal is for the format specifier L." elements ",") "]")))) -;;;###autoload -(defun org-table-set-constants () - "Set `org-table-formula-constants-local' in the current buffer." - (let (cst consts const-str) - (save-excursion - (goto-char (point-min)) - (while (re-search-forward "^[ \t]*#\\+CONSTANTS: \\(.*\\)" nil t) - (setq const-str (substring-no-properties (match-string 1))) - (setq consts (append consts (org-split-string const-str "[ \t]+"))) - (when consts - (let (e) - (while (setq e (pop consts)) - (when (string-match "^\\([a-zA-Z0][_a-zA-Z0-9]*\\)=\\(.*\\)" e) - (if (assoc-string (match-string 1 e) cst) - (setq cst (delete (assoc-string (match-string 1 e) cst) cst))) - (push (cons (match-string 1 e) (match-string 2 e)) cst))) - (setq org-table-formula-constants-local cst))))))) +(defun org-table-message-once-per-second (t1 &rest args) + "If there has been more than one second since T1, display message. +ARGS are passed as arguments to the `message' function. Returns +current time if a message is printed, otherwise returns T1. If +T1 is nil, always messages." + (let ((curtime (current-time))) + (if (or (not t1) (< 0 (nth 1 (time-subtract curtime t1)))) + (progn (apply 'message args) + curtime) + t1))) ;;;###autoload (defun org-table-recalculate (&optional all noalign) @@ -2990,133 +3134,160 @@ If NOALIGN is not nil, do not re-align the table after the computations are done. This is typically used internally to save time, if it is known that the table will be realigned a little later anyway." (interactive "P") - (or (memq this-command org-recalc-commands) - (setq org-recalc-commands (cons this-command org-recalc-commands))) + (unless (memq this-command org-recalc-commands) + (push this-command org-recalc-commands)) (unless (org-at-table-p) (user-error "Not at a table")) (if (or (eq all 'iterate) (equal all '(16))) (org-table-iterate) - (org-table-get-specials) + (org-table-analyze) (let* ((eqlist (sort (org-table-get-stored-formulas) (lambda (a b) (string< (car a) (car b))))) - (eqlist1 (copy-sequence eqlist)) (inhibit-redisplay (not debug-on-error)) (line-re org-table-dataline-regexp) - (thisline (org-current-line)) - (thiscol (org-table-current-column)) - seen-fields lhs1 - beg end entry eqlnum eqlname eqlname1 eql (cnt 0) eq a name name1) - ;; Insert constants in all formulas - (setq eqlist - (mapcar (lambda (x) - (when (string-match "\\`$[<>]" (car x)) - (setq lhs1 (car x)) - (setq x (cons (substring - (org-table-formula-handle-first/last-rc - (car x)) 1) - (cdr x))) - (if (assoc (car x) eqlist1) - (user-error "\"%s=\" formula tries to overwrite existing formula for column %s" - lhs1 (car x)))) - (cons - (org-table-formula-handle-first/last-rc (car x)) - (org-table-formula-substitute-names - (org-table-formula-handle-first/last-rc (cdr x))))) - eqlist)) - ;; Split the equation list - (while (setq eq (pop eqlist)) - (if (<= (string-to-char (car eq)) ?9) - (push eq eqlnum) - (push eq eqlname))) - (setq eqlnum (nreverse eqlnum) eqlname (nreverse eqlname)) - ;; Expand ranges in lhs of formulas - (setq eqlname (org-table-expand-lhs-ranges eqlname)) - - ;; Get the correct line range to process - (if all - (progn - (setq end (move-marker (make-marker) (1+ (org-table-end)))) - (goto-char (setq beg (org-table-begin))) - (if (re-search-forward org-table-calculate-mark-regexp end t) - ;; This is a table with marked lines, compute selected lines - (setq line-re org-table-recalculate-regexp) - ;; Move forward to the first non-header line - (if (and (re-search-forward org-table-dataline-regexp end t) - (re-search-forward org-table-hline-regexp end t) - (re-search-forward org-table-dataline-regexp end t)) - (setq beg (match-beginning 0)) - nil))) ;; just leave beg where it is - (setq beg (point-at-bol) - end (move-marker (make-marker) (1+ (point-at-eol))))) - (goto-char beg) - (and all (message "Re-applying formulas to full table...")) - - ;; First find the named fields, and mark them untouchable. - ;; Also check if several field/range formulas try to set the same field. - (remove-text-properties beg end '(org-untouchable t)) - (while (setq eq (pop eqlname)) - (setq name (car eq) - a (assoc name org-table-named-field-locations)) - (setq name1 name) - (if a (setq name1 (format "@%d$%d" (org-table-line-to-dline (nth 1 a)) - (nth 2 a)))) - (when (member name1 seen-fields) - (user-error "Several field/range formulas try to set %s" name1)) - (push name1 seen-fields) - - (and (not a) - (string-match "@\\([0-9]+\\)\\$\\([0-9]+\\)" name) - (setq a (list name - (condition-case nil - (aref org-table-dlines - (string-to-number (match-string 1 name))) - (error (user-error "Invalid row number in %s" - name))) - (string-to-number (match-string 2 name))))) - (when (and a (or all (equal (nth 1 a) thisline))) - (message "Re-applying formula to field: %s" name) - (org-goto-line (nth 1 a)) - (org-table-goto-column (nth 2 a)) - (push (append a (list (cdr eq))) eqlname1) - (org-table-put-field-property :org-untouchable t))) - (setq eqlname1 (nreverse eqlname1)) - - ;; Now evaluate the column formulas, but skip fields covered by - ;; field formulas - (goto-char beg) - (while (re-search-forward line-re end t) - (unless (string-match "^ *[_^!$/] *$" (org-table-get-field 1)) - ;; Unprotected line, recalculate - (and all (message "Re-applying formulas to full table...(line %d)" - (setq cnt (1+ cnt)))) - (setq org-last-recalc-line (org-current-line)) - (setq eql eqlnum) - (while (setq entry (pop eql)) - (org-goto-line org-last-recalc-line) - (org-table-goto-column (string-to-number (car entry)) nil 'force) - (unless (get-text-property (point) :org-untouchable) - (org-table-eval-formula nil (cdr entry) - 'noalign 'nocst 'nostore 'noanalysis))))) - - ;; Now evaluate the field formulas - (while (setq eq (pop eqlname1)) - (message "Re-applying formula to field: %s" (car eq)) - (org-goto-line (nth 1 eq)) - (org-table-goto-column (nth 2 eq)) - (org-table-eval-formula nil (nth 3 eq) 'noalign 'nocst - 'nostore 'noanalysis)) - - (org-goto-line thisline) - (org-table-goto-column thiscol) - (remove-text-properties (point-min) (point-max) '(org-untouchable t)) - (or noalign (and org-table-may-need-update (org-table-align)) - (and all (message "Re-applying formulas to %d lines...done" cnt))) - - ;; back to initial position - (message "Re-applying formulas...done") - (org-goto-line thisline) - (org-table-goto-column thiscol) - (or noalign (and org-table-may-need-update (org-table-align)) - (and all (message "Re-applying formulas...done")))))) + (log-first-time (current-time)) + (log-last-time log-first-time) + (cnt 0) + beg end eqlcol eqlfield) + ;; Insert constants in all formulas. + (when eqlist + (org-table-save-field + ;; Expand equations, then split the equation list between + ;; column formulas and field formulas. + (dolist (eq eqlist) + (let* ((rhs (org-table-formula-substitute-names + (org-table-formula-handle-first/last-rc (cdr eq)))) + (old-lhs (car eq)) + (lhs + (org-table-formula-handle-first/last-rc + (cond + ((string-match "\\`@-?I+" old-lhs) + (user-error "Can't assign to hline relative reference")) + ((string-match "\\`$[<>]" old-lhs) + (let ((new (org-table-formula-handle-first/last-rc + old-lhs))) + (when (assoc new eqlist) + (user-error "\"%s=\" formula tries to overwrite \ +existing formula for column %s" + old-lhs + new)) + new)) + (t old-lhs))))) + (if (org-string-match-p "\\`\\$[0-9]+\\'" lhs) + (push (cons lhs rhs) eqlcol) + (push (cons lhs rhs) eqlfield)))) + (setq eqlcol (nreverse eqlcol)) + ;; Expand ranges in lhs of formulas + (setq eqlfield (org-table-expand-lhs-ranges (nreverse eqlfield))) + ;; Get the correct line range to process. + (if all + (progn + (setq end (copy-marker (org-table-end))) + (goto-char (setq beg org-table-current-begin-pos)) + (cond + ((re-search-forward org-table-calculate-mark-regexp end t) + ;; This is a table with marked lines, compute selected + ;; lines. + (setq line-re org-table-recalculate-regexp)) + ;; Move forward to the first non-header line. + ((and (re-search-forward org-table-dataline-regexp end t) + (re-search-forward org-table-hline-regexp end t) + (re-search-forward org-table-dataline-regexp end t)) + (setq beg (match-beginning 0))) + ;; Just leave BEG where it is. + (t (setq beg (line-beginning-position))))) + (setq beg (line-beginning-position) + end (copy-marker (line-beginning-position 2)))) + (goto-char beg) + ;; Mark named fields untouchable. Also check if several + ;; field/range formulas try to set the same field. + (remove-text-properties beg end '(org-untouchable t)) + (let ((current-line (count-lines org-table-current-begin-pos + (line-beginning-position))) + seen-fields) + (dolist (eq eqlfield) + (let* ((name (car eq)) + (location (assoc name org-table-named-field-locations)) + (eq-line (or (nth 1 location) + (and (string-match "\\`@\\([0-9]+\\)" name) + (aref org-table-dlines + (string-to-number + (match-string 1 name)))))) + (reference + (if location + ;; Turn field coordinates associated to NAME + ;; into an absolute reference. + (format "@%d$%d" + (org-table-line-to-dline eq-line) + (nth 2 location)) + name))) + (when (member reference seen-fields) + (user-error "Several field/range formulas try to set %s" + reference)) + (push reference seen-fields) + (when (or all (eq eq-line current-line)) + (org-table-goto-field name) + (org-table-put-field-property :org-untouchable t))))) + ;; Evaluate the column formulas, but skip fields covered by + ;; field formulas. + (goto-char beg) + (while (re-search-forward line-re end t) + (unless (string-match "\\` *[_^!$/] *\\'" (org-table-get-field 1)) + ;; Unprotected line, recalculate. + (incf cnt) + (when all + (setq log-last-time + (org-table-message-once-per-second + log-last-time + "Re-applying formulas to full table...(line %d)" cnt))) + (if (markerp org-last-recalc-line) + (move-marker org-last-recalc-line (line-beginning-position)) + (setq org-last-recalc-line + (copy-marker (line-beginning-position)))) + (dolist (entry eqlcol) + (goto-char org-last-recalc-line) + (org-table-goto-column + (string-to-number (substring (car entry) 1)) nil 'force) + (unless (get-text-property (point) :org-untouchable) + (org-table-eval-formula + nil (cdr entry) 'noalign 'nocst 'nostore 'noanalysis))))) + ;; Evaluate the field formulas. + (dolist (eq eqlfield) + (let ((reference (car eq)) + (formula (cdr eq))) + (setq log-last-time + (org-table-message-once-per-second + (and all log-last-time) + "Re-applying formula to field: %s" (car eq))) + (org-table-goto-field + reference + ;; Possibly create a new column, as long as + ;; `org-table-formula-create-columns' allows it. + (let ((column-count (progn (end-of-line) + (1- (org-table-current-column))))) + `(lambda (column) + (when (> column 1000) + (user-error "Formula column target too large")) + (and (> column ,column-count) + (or (eq org-table-formula-create-columns t) + (and (eq org-table-formula-create-columns 'warn) + (progn + (org-display-warning + "Out-of-bounds formula added columns") + t)) + (and (eq org-table-formula-create-columns 'prompt) + (yes-or-no-p + "Out-of-bounds formula. Add columns? "))))))) + (org-table-eval-formula nil formula t t t t)))) + ;; Clean up markers and internal text property. + (remove-text-properties (point-min) (point-max) '(org-untouchable t)) + (set-marker end nil) + (unless noalign + (when org-table-may-need-update (org-table-align)) + (when all + (org-table-message-once-per-second + log-first-time "Re-applying formulas to %d lines... done" cnt))) + (org-table-message-once-per-second + (and all log-first-time) "Re-applying formulas... done"))))) ;;;###autoload (defun org-table-iterate (&optional arg) @@ -3177,66 +3348,71 @@ with the prefix ARG." (interactive "P") (unless (org-at-TBLFM-p) (user-error "Not at a #+TBLFM line")) (let ((formula (buffer-substring - (point-at-bol) - (point-at-eol))) - s e) + (line-beginning-position) + (line-end-position)))) (save-excursion ;; Insert a temporary formula at right after the table (goto-char (org-table-TBLFM-begin)) - (setq s (set-marker (make-marker) (point))) - (insert (concat formula "\n")) - (setq e (set-marker (make-marker) (point))) - ;; Recalculate the table - (beginning-of-line 0) ; move to the inserted line - (skip-chars-backward " \r\n\t") - (if (org-at-table-p) + (let ((s (point-marker))) + (insert formula "\n") + (let ((e (point-marker))) + ;; Recalculate the table. + (beginning-of-line 0) ; move to the inserted line + (skip-chars-backward " \r\n\t") (unwind-protect - (org-call-with-arg 'org-table-recalculate (or arg t)) - ;; delete the formula inserted temporarily - (delete-region s e)))))) + (org-call-with-arg #'org-table-recalculate (or arg t)) + ;; Delete the formula inserted temporarily. + (delete-region s e) + (set-marker s nil) + (set-marker e nil))))))) (defun org-table-TBLFM-begin () "Find the beginning of the TBLFM lines and return its position. Return nil when the beginning of TBLFM line was not found." (save-excursion (when (progn (forward-line 1) - (re-search-backward - org-table-TBLFM-begin-regexp - nil t)) - (point-at-bol 2)))) + (re-search-backward org-table-TBLFM-begin-regexp nil t)) + (line-beginning-position 2)))) (defun org-table-expand-lhs-ranges (equations) "Expand list of formulas. -If some of the RHS in the formulas are ranges or a row reference, expand -them to individual field equations for each field." - (let (e res lhs rhs range r1 r2 c1 c2) - (while (setq e (pop equations)) - (setq lhs (car e) rhs (cdr e)) - (cond - ((string-match "^@-?[-+0-9]+\\$-?[0-9]+$" lhs) - ;; This just refers to one fixed field - (push e res)) - ((string-match "^[a-zA-Z][_a-zA-Z0-9]*$" lhs) - ;; This just refers to one fixed named field - (push e res)) - ((string-match "^@[0-9]+$" lhs) - (loop for ic from 1 to org-table-current-ncol do - (push (cons (format "%s$%d" lhs ic) rhs) res) - (put-text-property 0 (length (caar res)) - :orig-eqn e (caar res)))) - (t - (setq range (org-table-get-range lhs org-table-current-begin-pos - 1 nil 'corners)) - (setq r1 (nth 0 range) c1 (nth 1 range) - r2 (nth 2 range) c2 (nth 3 range)) - (setq r1 (org-table-line-to-dline r1)) - (setq r2 (org-table-line-to-dline r2 'above)) - (loop for ir from r1 to r2 do - (loop for ic from c1 to c2 do - (push (cons (format "@%d$%d" ir ic) rhs) res) - (put-text-property 0 (length (caar res)) - :orig-eqn e (caar res))))))) - (nreverse res))) +If some of the RHS in the formulas are ranges or a row reference, +expand them to individual field equations for each field. This +function assumes the table is already analyzed (i.e., using +`org-table-analyze')." + (let (res) + (dolist (e equations (nreverse res)) + (let ((lhs (car e)) + (rhs (cdr e))) + (cond + ((org-string-match-p "\\`@-?[-+0-9]+\\$-?[0-9]+\\'" lhs) + ;; This just refers to one fixed field. + (push e res)) + ((org-string-match-p "\\`[a-zA-Z][_a-zA-Z0-9]*\\'" lhs) + ;; This just refers to one fixed named field. + (push e res)) + ((org-string-match-p "\\`\\$[0-9]+\\'" lhs) + ;; Column formulas are treated specially and are not + ;; expanded. + (push e res)) + ((string-match "\\`@[0-9]+\\'" lhs) + (dotimes (ic org-table-current-ncol) + (push (cons (propertize (format "%s$%d" lhs (1+ ic)) :orig-eqn e) + rhs) + res))) + (t + (let* ((range (org-table-get-range + lhs org-table-current-begin-pos 1 nil 'corners)) + (r1 (org-table-line-to-dline (nth 0 range))) + (c1 (nth 1 range)) + (r2 (org-table-line-to-dline (nth 2 range) 'above)) + (c2 (nth 3 range))) + (loop for ir from r1 to r2 do + (loop for ic from c1 to c2 do + (push + (cons (propertize (format "@%d$%d" ir ic) :orig-eqn e) + rhs) + res)))))))))) (defun org-table-formula-handle-first/last-rc (s) "Replace @<, @>, $<, $> with first/last row/column of the table. @@ -3248,7 +3424,7 @@ formulas that use a range of rows or columns, it may often be better to anchor the formula with \"I\" row markers, or to offset from the borders of the table using the @< @> $< $> makers." (let (n nmax len char (start 0)) - (while (string-match "\\([@$]\\)\\(<+\\|>+\\)\\|\\(remote([^\)]+)\\)" + (while (string-match "\\([@$]\\)\\(<+\\|>+\\)\\|\\(remote([^)]+)\\)" s start) (if (match-end 3) (setq start (match-end 3)) @@ -3269,25 +3445,33 @@ borders of the table using the @< @> $< $> makers." (defun org-table-formula-substitute-names (f) "Replace $const with values in string F." - (let ((start 0) a (f1 f) (pp (/= (string-to-char f) ?'))) - ;; First, check for column names - (while (setq start (string-match org-table-column-name-regexp f start)) - (setq start (1+ start)) - (setq a (assoc (match-string 1 f) org-table-column-names)) - (setq f (replace-match (concat "$" (cdr a)) t t f))) - ;; Parameters and constants - (setq start 0) - (while (setq start (string-match "\\$\\([a-zA-Z][_a-zA-Z0-9]*\\)\\|\\(\\]" (car entry)) 'column) - ((equal (string-to-char (car entry)) ?@) 'field) - ((string-match "^[0-9]" (car entry)) 'column) - (t 'named))) - (when (setq title (assq type titles)) - (or (bobp) (insert "\n")) - (insert (org-add-props (cdr title) nil 'face font-lock-comment-face)) - (setq titles (remove title titles))) - (if (equal key (car entry)) (setq startline (org-current-line))) - (setq s (concat (if (member (string-to-char (car entry)) '(?@ ?$)) "" "$") - (car entry) " = " (cdr entry) "\n")) - (remove-text-properties 0 (length s) '(face nil) s) - (insert s)) - (if (eq org-table-use-standard-references t) + (let ((at-tblfm (org-at-TBLFM-p))) + (unless (or at-tblfm (org-at-table-p)) + (user-error "Not at a table")) + (save-excursion + ;; Move point within the table before analyzing it. + (when at-tblfm (re-search-backward "^[ \t]*|")) + (org-table-analyze)) + (let ((key (org-table-current-field-formula 'key 'noerror)) + (eql (sort (org-table-get-stored-formulas t (and at-tblfm (point))) + #'org-table-formula-less-p)) + (pos (point-marker)) + (source (copy-marker (line-beginning-position))) + (startline 1) + (wc (current-window-configuration)) + (sel-win (selected-window)) + (titles '((column . "# Column Formulas\n") + (field . "# Field and Range Formulas\n") + (named . "# Named Field Formulas\n")))) + (org-switch-to-buffer-other-window "*Edit Formulas*") + (erase-buffer) + ;; Keep global-font-lock-mode from turning on font-lock-mode + (let ((font-lock-global-modes '(not fundamental-mode))) + (fundamental-mode)) + (org-set-local 'font-lock-global-modes (list 'not major-mode)) + (org-set-local 'org-pos pos) + (org-set-local 'org-table--fedit-source source) + (org-set-local 'org-window-configuration wc) + (org-set-local 'org-selected-window sel-win) + (use-local-map org-table-fedit-map) + (org-add-hook 'post-command-hook #'org-table-fedit-post-command t t) + (easy-menu-add org-table-fedit-menu) + (setq startline (org-current-line)) + (dolist (entry eql) + (let* ((type (cond + ((string-match "\\`$\\([0-9]+\\|[<>]+\\)\\'" (car entry)) + 'column) + ((equal (string-to-char (car entry)) ?@) 'field) + (t 'named))) + (title (assq type titles))) + (when title + (unless (bobp) (insert "\n")) + (insert + (org-add-props (cdr title) nil 'face font-lock-comment-face)) + (setq titles (remove title titles))) + (when (equal key (car entry)) (setq startline (org-current-line))) + (let ((s (concat + (if (memq (string-to-char (car entry)) '(?@ ?$)) "" "$") + (car entry) " = " (cdr entry) "\n"))) + (remove-text-properties 0 (length s) '(face nil) s) + (insert s)))) + (when (eq org-table-use-standard-references t) (org-table-fedit-toggle-ref-type)) - (org-goto-line startline) - (message "Edit formulas, finish with `C-c C-c' or `C-c ' '. See menu for more commands."))) + (org-goto-line startline) + (message + (substitute-command-keys "\\\ +Edit formulas, finish with `\\[org-ctrl-c-ctrl-c]' or `\\[org-edit-special]'. \ +See menu for more commands."))))) (defun org-table-fedit-post-command () (when (not (memq this-command '(lisp-complete-symbol))) (let ((win (selected-window))) (save-excursion - (condition-case nil - (org-table-show-reference) - (error nil)) + (ignore-errors (org-table-show-reference)) (select-window win))))) (defun org-table-formula-to-user (s) @@ -3542,13 +3736,14 @@ minutes or seconds." (defun org-table-fedit-convert-buffer (function) "Convert all references in this buffer, using FUNCTION." - (let ((line (org-current-line))) + (let ((origin (copy-marker (line-beginning-position)))) (goto-char (point-min)) (while (not (eobp)) - (insert (funcall function (buffer-substring (point) (point-at-eol)))) - (delete-region (point) (point-at-eol)) - (or (eobp) (forward-char 1))) - (org-goto-line line))) + (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." @@ -3579,16 +3774,16 @@ minutes or seconds." (defun org-table-fedit-shift-reference (dir) (cond - ((org-at-regexp-p "\\(\\<[a-zA-Z]\\)&") + ((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-at-regexp-p "\\(\\<[a-zA-Z]\\{1,2\\}\\)\\([0-9]+\\)") + ((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-at-regexp-p + ((org-in-regexp "\\(@\\|\\.\\.\\)\\([-+]?\\(I+\\>\\|[0-9]+\\)\\)\\(\\$\\([-+]?[0-9]+\\)\\)?") ;; An internal reference (if (memq dir '(up down)) @@ -3649,32 +3844,31 @@ a translation reference." With prefix ARG, apply the new formulas to the table." (interactive "P") (org-table-remove-rectangle-highlight) - (if org-table-use-standard-references - (progn - (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) eql var form) + (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) - (setq var (if (match-end 2) (match-string 2) (match-string 1)) - form (match-string 3)) - (setq form (org-trim form)) - (when (not (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))) - (setq org-pos nil) + (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 pos) - (unless (org-at-table-p) - (user-error "Lost table position - cannot install formulas")) + (goto-char source) (org-table-store-formulas eql) - (move-marker pos nil) + (set-marker pos nil) + (set-marker source nil) (kill-buffer "*Edit Formulas*") (if arg (org-table-recalculate 'all) @@ -3733,9 +3927,11 @@ With prefix ARG, apply the new formulas to the table." (defvar org-show-positions nil) (defun org-table-show-reference (&optional local) - "Show the location/value of the $ expression at point." + "Show the location/value of the $ expression at point. +When LOCAL is non-nil, show references for the table at point." (interactive) (org-table-remove-rectangle-highlight) + (when local (org-table-analyze)) (catch 'exit (let ((pos (if local (point) org-pos)) (face2 'highlight) @@ -3743,23 +3939,22 @@ With prefix ARG, apply the new formulas to the table." (win (selected-window)) (org-show-positions nil) var name e what match dest) - (if local (org-table-get-specials)) (setq what (cond - ((org-at-regexp-p "^@[0-9]+[ \t=]") + ((org-in-regexp "^@[0-9]+[ \t=]") (setq match (concat (substring (match-string 0) 0 -1) "$1.." (substring (match-string 0) 0 -1) "$100")) 'range) - ((or (org-at-regexp-p org-table-range-regexp2) - (org-at-regexp-p org-table-translate-regexp) - (org-at-regexp-p org-table-range-regexp)) + ((or (org-in-regexp org-table-range-regexp2) + (org-in-regexp org-table-translate-regexp) + (org-in-regexp org-table-range-regexp)) (setq match (save-match-data (org-table-convert-refs-to-rc (match-string 0)))) 'range) - ((org-at-regexp-p "\\$[a-zA-Z][a-zA-Z0-9]*") 'name) - ((org-at-regexp-p "\\$[0-9]+") 'column) + ((org-in-regexp "\\$[a-zA-Z][a-zA-Z0-9]*") 'name) + ((org-in-regexp "\\$[0-9]+") 'column) ((not local) nil) (t (user-error "No reference at point"))) match (and what (or match (match-string 0)))) @@ -3767,17 +3962,18 @@ With prefix ARG, apply the new formulas to the table." (org-table-add-rectangle-overlay (match-beginning 0) (match-end 0) 'secondary-selection)) (org-add-hook 'before-change-functions - 'org-table-remove-rectangle-highlight) - (if (eq what 'name) (setq var (substring match 1))) + #'org-table-remove-rectangle-highlight) + (when (eq what 'name) (setq var (substring match 1))) (when (eq what 'range) - (or (equal (string-to-char match) ?@) (setq match (concat "@" match))) + (unless (eq (string-to-char match) ?@) (setq match (concat "@" match))) (setq match (org-table-formula-substitute-names match))) (unless local (save-excursion - (end-of-line 1) + (end-of-line) (re-search-backward "^\\S-" nil t) - (beginning-of-line 1) - (when (looking-at "\\(\\$[0-9a-zA-Z]+\\|@[0-9]+\\$[0-9]+\\|[a-zA-Z]+\\([0-9]+\\|&\\)\\) *=") + (beginning-of-line) + (when (looking-at "\\(\\$[0-9a-zA-Z]+\\|@[0-9]+\\$[0-9]+\\|[a-zA-Z]+\ +\\([0-9]+\\|&\\)\\) *=") (setq dest (save-match-data (org-table-convert-refs-to-rc (match-string 1)))) @@ -3790,60 +3986,52 @@ With prefix ARG, apply the new formulas to the table." (marker-buffer pos))))) (goto-char pos) (org-table-force-dataline) - (when dest - (setq name (substring dest 1)) - (cond - ((string-match "^\\$[a-zA-Z][a-zA-Z0-9]*" dest) - (setq e (assoc name org-table-named-field-locations)) - (org-goto-line (nth 1 e)) - (org-table-goto-column (nth 2 e))) - ((string-match "^@\\([0-9]+\\)\\$\\([0-9]+\\)" dest) - (let ((l (string-to-number (match-string 1 dest))) - (c (string-to-number (match-string 2 dest)))) - (org-goto-line (aref org-table-dlines l)) - (org-table-goto-column c))) - (t (org-table-goto-column (string-to-number name)))) - (move-marker pos (point)) - (org-table-highlight-rectangle nil nil face2)) - (cond - ((equal dest match)) - ((not match)) - ((eq what 'range) - (condition-case nil - (save-excursion - (org-table-get-range match nil nil 'highlight)) - (error nil))) - ((setq e (assoc var org-table-named-field-locations)) - (org-goto-line (nth 1 e)) - (org-table-goto-column (nth 2 e)) - (org-table-highlight-rectangle (point) (point)) - (message "Named field, column %d of line %d" (nth 2 e) (nth 1 e))) - ((setq e (assoc var org-table-column-names)) - (org-table-goto-column (string-to-number (cdr e))) - (org-table-highlight-rectangle (point) (point)) - (goto-char (org-table-begin)) - (if (re-search-forward (concat "^[ \t]*| *! *.*?| *\\(" var "\\) *|") - (org-table-end) t) - (progn - (goto-char (match-beginning 1)) - (org-table-highlight-rectangle) - (message "Named column (column %s)" (cdr e))) - (user-error "Column name not found"))) - ((eq what 'column) - ;; column number - (org-table-goto-column (string-to-number (substring match 1))) - (org-table-highlight-rectangle (point) (point)) - (message "Column %s" (substring match 1))) - ((setq e (assoc var org-table-local-parameters)) - (goto-char (org-table-begin)) - (if (re-search-forward (concat "^[ \t]*| *\\$ *.*?| *\\(" var "=\\)") nil t) - (progn - (goto-char (match-beginning 1)) - (org-table-highlight-rectangle) - (message "Local parameter.")) - (user-error "Parameter not found"))) - (t + (let ((table-start + (if local org-table-current-begin-pos (org-table-begin)))) + (when dest + (setq name (substring dest 1)) + (cond + ((org-string-match-p "\\`\\$[a-zA-Z][a-zA-Z0-9]*" dest) + (org-table-goto-field dest)) + ((org-string-match-p "\\`@\\([1-9][0-9]*\\)\\$\\([1-9][0-9]*\\)\\'" + dest) + (org-table-goto-field dest)) + (t (org-table-goto-column (string-to-number name)))) + (move-marker pos (point)) + (org-table-highlight-rectangle nil nil face2)) (cond + ((equal dest match)) + ((not match)) + ((eq what 'range) + (ignore-errors (org-table-get-range match table-start nil 'highlight))) + ((setq e (assoc var org-table-named-field-locations)) + (org-table-goto-field var) + (org-table-highlight-rectangle) + (message "Named field, column %d of line %d" (nth 2 e) (nth 1 e))) + ((setq e (assoc var org-table-column-names)) + (org-table-goto-column (string-to-number (cdr e))) + (org-table-highlight-rectangle) + (goto-char table-start) + (if (re-search-forward (concat "^[ \t]*| *! *.*?| *\\(" var "\\) *|") + (org-table-end) t) + (progn + (goto-char (match-beginning 1)) + (org-table-highlight-rectangle) + (message "Named column (column %s)" (cdr e))) + (user-error "Column name not found"))) + ((eq what 'column) + ;; Column number. + (org-table-goto-column (string-to-number (substring match 1))) + (org-table-highlight-rectangle) + (message "Column %s" (substring match 1))) + ((setq e (assoc var org-table-local-parameters)) + (goto-char table-start) + (if (re-search-forward (concat "^[ \t]*| *\\$ *.*?| *\\(" var "=\\)") nil t) + (progn + (goto-char (match-beginning 1)) + (org-table-highlight-rectangle) + (message "Local parameter.")) + (user-error "Parameter not found"))) ((not var) (user-error "No reference at point")) ((setq e (assoc var org-table-formula-constants-local)) (message "Local Constant: $%s=%s in #+CONSTANTS line." @@ -3854,19 +4042,19 @@ With prefix ARG, apply the new formulas to the table." ((setq e (and (fboundp 'constants-get) (constants-get var))) (message "Constant: $%s=%s, from `constants.el'%s." var e (format " (%s units)" constants-unit-system))) - (t (user-error "Undefined name $%s" var))))) - (goto-char pos) - (when (and org-show-positions - (not (memq this-command '(org-table-fedit-scroll - org-table-fedit-scroll-down)))) - (push pos org-show-positions) - (push org-table-current-begin-pos org-show-positions) - (let ((min (apply 'min org-show-positions)) - (max (apply 'max org-show-positions))) - (set-window-start (selected-window) min) - (goto-char max) - (or (pos-visible-in-window-p max) - (set-window-start (selected-window) max)))) + (t (user-error "Undefined name $%s" var))) + (goto-char pos) + (when (and org-show-positions + (not (memq this-command '(org-table-fedit-scroll + org-table-fedit-scroll-down)))) + (push pos org-show-positions) + (push table-start org-show-positions) + (let ((min (apply 'min org-show-positions)) + (max (apply 'max org-show-positions))) + (set-window-start (selected-window) min) + (goto-char max) + (or (pos-visible-in-window-p max) + (set-window-start (selected-window) max))))) (select-window win)))) (defun org-table-force-dataline () @@ -3926,32 +4114,39 @@ Use COMMAND to do the motion, repeat if necessary to end up in a data line." (push ov org-table-rectangle-overlays))) (defun org-table-highlight-rectangle (&optional beg end face) - "Highlight rectangular region in a table." - (setq beg (or beg (point)) end (or end (point))) - (let ((b (min beg end)) - (e (max beg end)) - l1 c1 l2 c2 tmp) - (and (boundp 'org-show-positions) - (setq org-show-positions (cons b (cons e org-show-positions)))) - (goto-char (min beg end)) - (setq l1 (org-current-line) - c1 (org-table-current-column)) - (goto-char (max beg end)) - (setq l2 (org-current-line) - c2 (org-table-current-column)) - (if (> c1 c2) (setq tmp c1 c1 c2 c2 tmp)) - (org-goto-line l1) - (beginning-of-line 1) - (loop for line from l1 to l2 do - (when (looking-at org-table-dataline-regexp) - (org-table-goto-column c1) - (skip-chars-backward "^|\n") (setq beg (point)) - (org-table-goto-column c2) - (skip-chars-forward "^|\n") (setq end (point)) - (org-table-add-rectangle-overlay beg end face)) - (beginning-of-line 2)) - (goto-char b)) - (add-hook 'before-change-functions 'org-table-remove-rectangle-highlight)) + "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." @@ -4290,7 +4485,10 @@ to execute outside of tables." 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) @@ -4316,7 +4514,6 @@ With prefix arg, also recompute table." (when (orgtbl-send-table 'maybe) (run-hooks 'orgtbl-after-send-table-hook))) ((eq action 'recalc) - (org-table-set-constants) (save-excursion (beginning-of-line 1) (skip-chars-backward " \r\n\t") @@ -4398,6 +4595,7 @@ overwritten, and the table is not marked as requiring realignment." (setq org-self-insert-command-undo-counter (1+ org-self-insert-command-undo-counter)))))))) +;;;###autoload (defvar orgtbl-exp-regexp "^\\([-+]?[0-9][0-9.]*\\)[eE]\\([-+]?[0-9]+\\)$" "Regular expression matching exponentials as produced by calc.") @@ -4425,15 +4623,12 @@ a radio table." (unless (re-search-forward (concat "BEGIN +RECEIVE +ORGTBL +" name "\\([ \t]\\|$\\)") nil t) (user-error "Don't know where to insert translated table")) - (goto-char (match-beginning 0)) - (beginning-of-line 2) - (save-excursion - (let ((beg (point))) - (unless (re-search-forward - (concat "END +RECEIVE +ORGTBL +" name) nil t) - (user-error "Cannot find end of insertion region")) - (beginning-of-line 1) - (delete-region beg (point)))) + (let ((beg (line-beginning-position 2))) + (unless (re-search-forward + (concat "END +RECEIVE +ORGTBL +" name) nil t) + (user-error "Cannot find end of insertion region")) + (beginning-of-line) + (delete-region beg (point))) (insert txt "\n"))) ;;;###autoload @@ -4442,76 +4637,43 @@ a radio table." The structure will be a list. Each item is either the symbol `hline' for a horizontal separator line, or a list of field values as strings. The table is taken from the parameter TXT, or from the buffer at point." - (unless txt - (unless (org-at-table-p) - (user-error "No table at point"))) - (let* ((txt (or txt - (buffer-substring-no-properties (org-table-begin) - (org-table-end)))) - (lines (org-split-string txt "[ \t]*\n[ \t]*"))) - - (mapcar - (lambda (x) - (if (string-match org-table-hline-regexp x) - 'hline - (org-split-string (org-trim x) "\\s-*|\\s-*"))) - lines))) + (unless (or txt (org-at-table-p)) (user-error "No table at point")) + (let ((txt (or txt + (buffer-substring-no-properties (org-table-begin) + (org-table-end))))) + (mapcar (lambda (x) + (if (string-match org-table-hline-regexp x) 'hline + (org-split-string (org-trim x) "\\s-*|\\s-*"))) + (org-split-string txt "[ \t]*\n[ \t]*")))) (defun orgtbl-send-table (&optional maybe) - "Send a transformed version of this table to the receiver position. -With argument MAYBE, fail quietly if no transformation is defined for -this table." + "Send a transformed version of table at point to the receiver position. +With argument MAYBE, fail quietly if no transformation is defined +for this table." (interactive) (catch 'exit (unless (org-at-table-p) (user-error "Not at a table")) ;; when non-interactive, we assume align has just happened. (when (org-called-interactively-p 'any) (org-table-align)) (let ((dests (orgtbl-gather-send-defs)) - (txt (buffer-substring-no-properties (org-table-begin) - (org-table-end))) + (table (org-table-to-lisp + (buffer-substring-no-properties (org-table-begin) + (org-table-end)))) (ntbl 0)) - (unless dests (if maybe (throw 'exit nil) - (user-error "Don't know how to transform this table"))) + (unless dests + (if maybe (throw 'exit nil) + (user-error "Don't know how to transform this table"))) (dolist (dest dests) - (let* ((name (plist-get dest :name)) - (transform (plist-get dest :transform)) - (params (plist-get dest :params)) - (skip (plist-get params :skip)) - (skipcols (plist-get params :skipcols)) - (no-escape (plist-get params :no-escape)) - beg - (lines (org-table-clean-before-export - (nthcdr (or skip 0) - (org-split-string txt "[ \t]*\n[ \t]*")))) - (i0 (if org-table-clean-did-remove-column 2 1)) - (lines (if no-escape lines - (mapcar (lambda(l) (replace-regexp-in-string - "\\([&%#_^]\\)" "\\\\\\1{}" l)) lines))) - (table (mapcar - (lambda (x) - (if (string-match org-table-hline-regexp x) - 'hline - (org-remove-by-index - (org-split-string (org-trim x) "\\s-*|\\s-*") - skipcols i0))) - lines)) - (fun (if (= i0 2) 'cdr 'identity)) - (org-table-last-alignment - (org-remove-by-index (funcall fun org-table-last-alignment) - skipcols i0)) - (org-table-last-column-widths - (org-remove-by-index (funcall fun org-table-last-column-widths) - skipcols i0)) - (txt (if (fboundp transform) - (funcall transform table params) - (user-error "No such transformation function %s" transform)))) - (orgtbl-send-replace-tbl name txt)) - (setq ntbl (1+ ntbl))) + (let ((name (plist-get dest :name)) + (transform (plist-get dest :transform)) + (params (plist-get dest :params))) + (unless (fboundp transform) + (user-error "No such transformation function %s" transform)) + (orgtbl-send-replace-tbl name (funcall transform table params))) + (incf ntbl)) (message "Table converted and installed at %d receiver location%s" ntbl (if (> ntbl 1) "s" "")) - (if (> ntbl 0) - ntbl - nil)))) + (and (> ntbl 0) ntbl)))) (defun org-remove-by-index (list indices &optional i0) "Remove the elements in LIST with indices in INDICES. @@ -4561,356 +4723,501 @@ First element has index 0, or I0 if given." (insert txt) (goto-char pos))) -;; Dynamically bound input and output for table formatting. -(defvar *orgtbl-table* nil - "Carries the current table through formatting routines.") -(defvar *orgtbl-rtn* nil - "Formatting routines push the output lines here.") -;; Formatting parameters for the current table section. -(defvar *orgtbl-hline* nil "Text used for horizontal lines.") -(defvar *orgtbl-sep* nil "Text used as a column separator.") -(defvar *orgtbl-default-fmt* nil "Default format for each entry.") -(defvar *orgtbl-fmt* nil "Format for each entry.") -(defvar *orgtbl-efmt* nil "Format for numbers.") -(defvar *orgtbl-lfmt* nil "Format for an entire line, overrides fmt.") -(defvar *orgtbl-llfmt* nil "Specializes lfmt for the last row.") -(defvar *orgtbl-lstart* nil "Text starting a row.") -(defvar *orgtbl-llstart* nil "Specializes lstart for the last row.") -(defvar *orgtbl-lend* nil "Text ending a row.") -(defvar *orgtbl-llend* nil "Specializes lend for the last row.") - -(defsubst orgtbl-get-fmt (fmt i) - "Retrieve the format from FMT corresponding to the Ith column." - (if (and (not (functionp fmt)) (consp fmt)) - (plist-get fmt i) - fmt)) - -(defsubst orgtbl-apply-fmt (fmt &rest args) - "Apply format FMT to arguments ARGS. -When FMT is nil, return the first argument from ARGS." - (cond ((functionp fmt) (apply fmt args)) - (fmt (apply 'format fmt args)) - (args (car args)) - (t args))) - -(defsubst orgtbl-eval-str (str) - "If STR is a function, evaluate it with no arguments." - (if (functionp str) - (funcall str) - str)) - -(defun orgtbl-format-line (line) - "Format LINE as a table row." - (if (eq line 'hline) (if *orgtbl-hline* (push *orgtbl-hline* *orgtbl-rtn*)) - (let* ((i 0) - (line - (mapcar - (lambda (f) - (setq i (1+ i)) - (let* ((efmt (orgtbl-get-fmt *orgtbl-efmt* i)) - (f (if (and efmt (string-match orgtbl-exp-regexp f)) - (orgtbl-apply-fmt efmt (match-string 1 f) - (match-string 2 f)) - f))) - (orgtbl-apply-fmt (or (orgtbl-get-fmt *orgtbl-fmt* i) - *orgtbl-default-fmt*) - f))) - line))) - (push (if *orgtbl-lfmt* - (apply #'orgtbl-apply-fmt *orgtbl-lfmt* line) - (concat (orgtbl-eval-str *orgtbl-lstart*) - (mapconcat 'identity line *orgtbl-sep*) - (orgtbl-eval-str *orgtbl-lend*))) - *orgtbl-rtn*)))) - -(defun orgtbl-format-section (section-stopper) - "Format lines until the first occurrence of SECTION-STOPPER." - (let (prevline) - (progn - (while (not (eq (car *orgtbl-table*) section-stopper)) - (if prevline (orgtbl-format-line prevline)) - (setq prevline (pop *orgtbl-table*))) - (if prevline (let ((*orgtbl-lstart* *orgtbl-llstart*) - (*orgtbl-lend* *orgtbl-llend*) - (*orgtbl-lfmt* *orgtbl-llfmt*)) - (orgtbl-format-line prevline)))))) - ;;;###autoload -(defun orgtbl-to-generic (table params &optional backend) +(defun orgtbl-to-generic (table params) "Convert the orgtbl-mode TABLE to some other format. + This generic routine can be used for many standard cases. -TABLE is a list, each entry either the symbol `hline' for a horizontal -separator line, or a list of fields for that line. -PARAMS is a property list of parameters that can influence the conversion. -A third optional argument BACKEND can be used to convert the content of -the cells using a specific export back-end. -For the generic converter, some parameters are obligatory: you need to -specify either :lfmt, or all of (:lstart :lend :sep). +TABLE is a list, each entry either the symbol `hline' for +a horizontal separator line, or a list of fields for that +line. PARAMS is a property list of parameters that can +influence the conversion. Valid parameters are: -:splice When set to t, return only table body lines, don't wrap - them into :tstart and :tend. Default is nil. When :splice - is non-nil, this also means that the exporter should not look - for and interpret header and footer sections. +:backend, :raw + + Export back-end used as a basis to transcode elements of the + table, when no specific parameter applies to it. It is also + used to translate cells contents. You can prevent this by + setting :raw property to a non-nil value. + +:splice + + When non-nil, only convert rows, not the table itself. This is + equivalent to setting to the empty string both :tstart + and :tend, which see. + +:skip -:hline String to be inserted on horizontal separation lines. - May be nil to ignore hlines. + When set to an integer N, skip the first N lines of the table. + Horizontal separation lines do count for this parameter! -:sep Separator between two fields -:remove-nil-lines Do not include lines that evaluate to nil. +:skipcols + + List of columns that should be skipped. If the table has + a column with calculation marks, that column is automatically + discarded beforehand. + +:hline + + String to be inserted on horizontal separation lines. May be + nil to ignore these lines altogether. + +:sep + + Separator between two fields, as a string. Each in the following group may be either a string or a function of no arguments returning a string: -:tstart String to start the table. Ignored when :splice is t. -:tend String to end the table. Ignored when :splice is t. -:lstart String to start a new table line. -:llstart String to start the last table line, defaults to :lstart. -:lend String to end a table line -:llend String to end the last table line, defaults to :lend. - -Each in the following group may be a string, a function of one -argument (the field or line) returning a string, or a plist -mapping columns to either of the above: - -:lfmt Format for entire line, with enough %s to capture all fields. - If this is present, :lstart, :lend, and :sep are ignored. -:llfmt Format for the entire last line, defaults to :lfmt. -:fmt A format to be used to wrap the field, should contain - %s for the original field value. For example, to wrap - everything in dollars, you could use :fmt \"$%s$\". - This may also be a property list with column numbers and - formats. For example :fmt (2 \"$%s$\" 4 \"%s%%\") -:hlstart :hllstart :hlend :hllend :hlsep :hlfmt :hllfmt :hfmt - Same as above, specific for the header lines in the table. - All lines before the first hline are treated as header. - If any of these is not present, the data line value is used. +:tstart, :tend + + Strings to start and end the table. Ignored when :splice is t. + +:lstart, :lend + + Strings to start and end a new table line. + +:llstart, :llend + + Strings to start and end the last table line. Default, + respectively, to :lstart and :lend. + +Each in the following group may be a string or a function of one +argument (either the cells in the current row, as a list of +strings, or the current cell) returning a string: + +:lfmt + + Format string for an entire row, with enough %s to capture all + fields. When non-nil, :lstart, :lend, and :sep are ignored. + +:llfmt + + Format for the entire last line, defaults to :lfmt. + +:fmt + + A format to be used to wrap the field, should contain %s for + the original field value. For example, to wrap everything in + dollars, you could use :fmt \"$%s$\". This may also be + a property list with column numbers and format strings, or + functions, e.g., + + \(:fmt (2 \"$%s$\" 4 (lambda (c) (format \"$%s$\" c)))) + +:hlstart :hllstart :hlend :hllend :hsep :hlfmt :hllfmt :hfmt + + Same as above, specific for the header lines in the table. + All lines before the first hline are treated as header. If + any of these is not present, the data line value is used. This may be either a string or a function of two arguments: -:efmt Use this format to print numbers with exponentials. - The format 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. :fmt will still be applied after :efmt. - -In addition to this, the parameters :skip and :skipcols are always handled -directly by `orgtbl-send-table'. See manual." - (let* ((splicep (plist-get params :splice)) - (hline (plist-get params :hline)) - (skipheadrule (plist-get params :skipheadrule)) - (remove-nil-linesp (plist-get params :remove-nil-lines)) - (remove-newlines (plist-get params :remove-newlines)) - (*orgtbl-hline* hline) - (*orgtbl-table* table) - (*orgtbl-sep* (plist-get params :sep)) - (*orgtbl-efmt* (plist-get params :efmt)) - (*orgtbl-lstart* (plist-get params :lstart)) - (*orgtbl-llstart* (or (plist-get params :llstart) *orgtbl-lstart*)) - (*orgtbl-lend* (plist-get params :lend)) - (*orgtbl-llend* (or (plist-get params :llend) *orgtbl-lend*)) - (*orgtbl-lfmt* (plist-get params :lfmt)) - (*orgtbl-llfmt* (or (plist-get params :llfmt) *orgtbl-lfmt*)) - (*orgtbl-fmt* (plist-get params :fmt)) - *orgtbl-rtn*) - ;; Convert cells content to backend BACKEND - (when backend - (setq *orgtbl-table* - (mapcar - (lambda(r) - (if (listp r) - (mapcar - (lambda (c) - (org-trim (org-export-string-as c backend t '(:with-tables t)))) - r) - r)) - *orgtbl-table*))) - ;; Put header - (unless splicep - (when (plist-member params :tstart) - (let ((tstart (orgtbl-eval-str (plist-get params :tstart)))) - (if tstart (push tstart *orgtbl-rtn*))))) - ;; If we have a heading, format it and handle the trailing hline. - (if (and (not splicep) - (or (consp (car *orgtbl-table*)) - (consp (nth 1 *orgtbl-table*))) - (memq 'hline (cdr *orgtbl-table*))) - (progn - (when (eq 'hline (car *orgtbl-table*)) - ;; There is a hline before the first data line - (and hline (push hline *orgtbl-rtn*)) - (pop *orgtbl-table*)) - (let* ((*orgtbl-lstart* (or (plist-get params :hlstart) - *orgtbl-lstart*)) - (*orgtbl-llstart* (or (plist-get params :hllstart) - *orgtbl-llstart*)) - (*orgtbl-lend* (or (plist-get params :hlend) *orgtbl-lend*)) - (*orgtbl-llend* (or (plist-get params :hllend) - (plist-get params :hlend) *orgtbl-llend*)) - (*orgtbl-lfmt* (or (plist-get params :hlfmt) *orgtbl-lfmt*)) - (*orgtbl-llfmt* (or (plist-get params :hllfmt) - (plist-get params :hlfmt) *orgtbl-llfmt*)) - (*orgtbl-sep* (or (plist-get params :hlsep) *orgtbl-sep*)) - (*orgtbl-fmt* (or (plist-get params :hfmt) *orgtbl-fmt*))) - (orgtbl-format-section 'hline)) - (if (and hline (not skipheadrule)) (push hline *orgtbl-rtn*)) - (pop *orgtbl-table*))) - ;; Now format the main section. - (orgtbl-format-section nil) - (unless splicep - (when (plist-member params :tend) - (let ((tend (orgtbl-eval-str (plist-get params :tend)))) - (if tend (push tend *orgtbl-rtn*))))) - (mapconcat (if remove-newlines - (lambda (tend) - (replace-regexp-in-string "[\n\r\t\f]" "\\\\n" tend)) - 'identity) - (nreverse (if remove-nil-linesp - (remq nil *orgtbl-rtn*) - *orgtbl-rtn*)) "\n"))) +:efmt + + Use this format to print numbers with exponential. The format + 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 format strings or functions. + :fmt will still be applied after :efmt." + ;; Make sure `org-export-create-backend' is available. + (require 'ox) + (let* ((backend (plist-get params :backend)) + (custom-backend + ;; Build a custom back-end according to PARAMS. Before + ;; defining a translator, check if there is anything to do. + ;; When there isn't, let BACKEND handle the element. + (org-export-create-backend + :parent (or backend 'org) + :transcoders + `((table . ,(org-table--to-generic-table params)) + (table-row . ,(org-table--to-generic-row params)) + (table-cell . ,(org-table--to-generic-cell params)) + ;; Macros are not going to be expanded. However, no + ;; regular back-end has a transcoder for them. We + ;; provide one so they are not ignored, but displayed + ;; as-is instead. + (macro . (lambda (m c i) (org-element-macro-interpreter m nil)))))) + data info) + ;; Store TABLE as Org syntax in DATA. Tolerate non-string cells. + ;; Initialize communication channel in INFO. + (with-temp-buffer + (let ((org-inhibit-startup t)) (org-mode)) + (let ((standard-output (current-buffer))) + (dolist (e table) + (cond ((eq e 'hline) (princ "|--\n")) + ((consp e) + (princ "| ") (dolist (c e) (princ c) (princ " |")) + (princ "\n"))))) + (setq data + (org-element-map (org-element-parse-buffer) 'table + #'identity nil t)) + (setq info (org-export-get-environment backend nil params))) + (when (and backend (symbolp backend) (not (org-export-get-backend backend))) + (user-error "Unknown :backend value")) + (when (or (not backend) (plist-get info :raw)) (require 'ox-org)) + ;; Handle :skip parameter. + (let ((skip (plist-get info :skip))) + (when skip + (unless (wholenump skip) (user-error "Wrong :skip value")) + (let ((n 0)) + (org-element-map data 'table-row + (lambda (row) + (if (>= n skip) t + (org-element-extract-element row) + (incf n) + nil)) + nil t)))) + ;; Handle :skipcols parameter. + (let ((skipcols (plist-get info :skipcols))) + (when skipcols + (unless (consp skipcols) (user-error "Wrong :skipcols value")) + (org-element-map data 'table + (lambda (table) + (let ((specialp (org-export-table-has-special-column-p table))) + (dolist (row (org-element-contents table)) + (when (eq (org-element-property :type row) 'standard) + (let ((c 1)) + (dolist (cell (nthcdr (if specialp 1 0) + (org-element-contents row))) + (when (memq c skipcols) + (org-element-extract-element cell)) + (incf c)))))))))) + ;; Since we are going to export using a low-level mechanism, + ;; ignore special column and special rows manually. + (let ((special? (org-export-table-has-special-column-p data)) + ignore) + (org-element-map data (if special? '(table-cell table-row) 'table-row) + (lambda (datum) + (when (if (eq (org-element-type datum) 'table-row) + (org-export-table-row-is-special-p datum nil) + (org-export-first-sibling-p datum nil)) + (push datum ignore)))) + (setq info (plist-put info :ignore-list ignore))) + ;; We use a low-level mechanism to export DATA so as to skip all + ;; usual pre-processing and post-processing, i.e., hooks, filters, + ;; Babel code evaluation, include keywords and macro expansion, + ;; and filters. + (let ((output (org-export-data-with-backend data custom-backend info))) + ;; Remove final newline. + (if (org-string-nw-p output) (substring-no-properties output 0 -1) "")))) + +(defun org-table--generic-apply (value name &optional with-cons &rest args) + (cond ((null value) nil) + ((functionp value) `(funcall ',value ,@args)) + ((stringp value) + (cond ((consp (car args)) `(apply #'format ,value ,@args)) + (args `(format ,value ,@args)) + (t value))) + ((and with-cons (consp value)) + `(let ((val (cadr (memq column ',value)))) + (cond ((null val) contents) + ((stringp val) (format val ,@args)) + ((functionp val) (funcall val ,@args)) + (t (user-error "Wrong %s value" ,name))))) + (t (user-error "Wrong %s value" name)))) + +(defun org-table--to-generic-table (params) + "Return custom table transcoder according to PARAMS. +PARAMS is a plist. See `orgtbl-to-generic' for more +information." + (let ((backend (plist-get params :backend)) + (splice (plist-get params :splice)) + (tstart (plist-get params :tstart)) + (tend (plist-get params :tend))) + `(lambda (table contents info) + (concat + ,(and tstart (not splice) + `(concat ,(org-table--generic-apply tstart ":tstart") "\n")) + ,(if (or (not backend) tstart tend splice) 'contents + `(org-export-with-backend ',backend table contents info)) + ,(org-table--generic-apply (and (not splice) tend) ":tend"))))) + +(defun org-table--to-generic-row (params) + "Return custom table row transcoder according to PARAMS. +PARAMS is a plist. See `orgtbl-to-generic' for more +information." + (let* ((backend (plist-get params :backend)) + (lstart (plist-get params :lstart)) + (llstart (plist-get params :llstart)) + (hlstart (plist-get params :hlstart)) + (hllstart (plist-get params :hllstart)) + (lend (plist-get params :lend)) + (llend (plist-get params :llend)) + (hlend (plist-get params :hlend)) + (hllend (plist-get params :hllend)) + (lfmt (plist-get params :lfmt)) + (llfmt (plist-get params :llfmt)) + (hlfmt (plist-get params :hlfmt)) + (hllfmt (plist-get params :hllfmt))) + `(lambda (row contents info) + (if (eq (org-element-property :type row) 'rule) + ,(cond + ((plist-member params :hline) + (org-table--generic-apply (plist-get params :hline) ":hline")) + (backend `(org-export-with-backend ',backend row nil info))) + (let ((headerp (org-export-table-row-in-header-p row info)) + (lastp (not (org-export-get-next-element row info))) + (last-header-p (org-export-table-row-ends-header-p row info))) + (when contents + ;; Check if we can apply `:lfmt', `:llfmt', `:hlfmt', or + ;; `:hllfmt' to CONTENTS. Otherwise, fallback on + ;; `:lstart', `:lend' and their relatives. + ,(let ((cells + '(org-element-map row 'table-cell + (lambda (cell) + ;; Export all cells, without separators. + ;; + ;; Use `org-export-data-with-backend' + ;; instead of `org-export-data' to eschew + ;; cached values, which + ;; ignore :orgtbl-ignore-sep parameter. + (org-export-data-with-backend + cell + (plist-get info :back-end) + (org-combine-plists info '(:orgtbl-ignore-sep t)))) + info))) + `(cond + ,(and hllfmt + `(last-header-p ,(org-table--generic-apply + hllfmt ":hllfmt" nil cells))) + ,(and hlfmt + `(headerp ,(org-table--generic-apply + hlfmt ":hlfmt" nil cells))) + ,(and llfmt + `(lastp ,(org-table--generic-apply + llfmt ":llfmt" nil cells))) + (t + ,(if lfmt (org-table--generic-apply lfmt ":lfmt" nil cells) + `(concat + (cond + ,(and + (or hllstart hllend) + `(last-header-p + (concat + ,(org-table--generic-apply hllstart ":hllstart") + contents + ,(org-table--generic-apply hllend ":hllend")))) + ,(and + (or hlstart hlend) + `(headerp + (concat + ,(org-table--generic-apply hlstart ":hlstart") + contents + ,(org-table--generic-apply hlend ":hlend")))) + ,(and + (or llstart llend) + `(lastp + (concat + ,(org-table--generic-apply llstart ":llstart") + contents + ,(org-table--generic-apply llend ":llend")))) + (t + ,(cond + ((or lstart lend) + `(concat + ,(org-table--generic-apply lstart ":lstart") + contents + ,(org-table--generic-apply lend ":lend"))) + (backend + `(org-export-with-backend + ',backend row contents info)) + (t 'contents))))))))))))))) + +(defun org-table--to-generic-cell (params) + "Return custom table cell transcoder according to PARAMS. +PARAMS is a plist. See `orgtbl-to-generic' for more +information." + (let* ((backend (plist-get params :backend)) + (efmt (plist-get params :efmt)) + (fmt (plist-get params :fmt)) + (hfmt (plist-get params :hfmt)) + (sep (plist-get params :sep)) + (hsep (plist-get params :hsep))) + `(lambda (cell contents info) + (let ((headerp (org-export-table-row-in-header-p + (org-export-get-parent-element cell) info)) + (column (1+ (cdr (org-export-table-cell-address cell info))))) + ;; Make sure that contents are exported as Org data when :raw + ;; parameter is non-nil. + ,(when (and backend (plist-get params :raw)) + `(setq contents + ;; Since we don't know what are the pseudo object + ;; types defined in backend, we cannot pass them to + ;; `org-element-interpret-data'. As a consequence, + ;; they will be treated as pseudo elements, and + ;; will have newlines appended instead of spaces. + ;; Therefore, we must make sure :post-blank value + ;; is really turned into spaces. + (replace-regexp-in-string + "\n" " " + (org-trim + (org-element-interpret-data + (org-element-contents cell)))))) + (when contents + ;; Check if we can apply `:efmt' on CONTENTS. + ,(when efmt + `(when (string-match orgtbl-exp-regexp contents) + (let ((mantissa (match-string 1 contents)) + (exponent (match-string 2 contents))) + (setq contents ,(org-table--generic-apply + efmt ":efmt" t 'mantissa 'exponent))))) + ;; Check if we can apply FMT (or HFMT) on CONTENTS. + (cond + ,(and hfmt `(headerp (setq contents ,(org-table--generic-apply + hfmt ":hfmt" t 'contents)))) + ,(and fmt `(t (setq contents ,(org-table--generic-apply + fmt ":fmt" t 'contents)))))) + ;; If a separator is provided, use it instead of BACKEND's. + ;; Separators are ignored when LFMT (or equivalent) is + ;; provided. + ,(cond + ((or hsep sep) + `(if (or ,(and (not sep) '(not headerp)) + (plist-get info :orgtbl-ignore-sep) + (not (org-export-get-next-element cell info))) + ,(if (not backend) 'contents + `(org-export-with-backend ',backend cell contents info)) + (concat contents + ,(if (and sep hsep) `(if headerp ,hsep ,sep) + (or hsep sep))))) + (backend `(org-export-with-backend ',backend cell contents info)) + (t 'contents)))))) ;;;###autoload (defun orgtbl-to-tsv (table params) "Convert the orgtbl-mode table to TAB separated material." (orgtbl-to-generic table (org-combine-plists '(:sep "\t") params))) + ;;;###autoload (defun orgtbl-to-csv (table params) "Convert the orgtbl-mode table to CSV material. This does take care of the proper quoting of fields with comma or quotes." - (orgtbl-to-generic table (org-combine-plists - '(:sep "," :fmt org-quote-csv-field) - params))) + (orgtbl-to-generic table + (org-combine-plists '(:sep "," :fmt org-quote-csv-field) + params))) ;;;###autoload (defun orgtbl-to-latex (table params) "Convert the orgtbl-mode TABLE to LaTeX. -TABLE is a list, each entry either the symbol `hline' for a horizontal -separator line, or a list of fields for that line. -PARAMS is a property list of parameters that can influence the conversion. -Supports all parameters from `orgtbl-to-generic'. Most important for -LaTeX are: - -:splice When set to t, return only table body lines, don't wrap - them into a tabular environment. Default is nil. - -:fmt A format to be used to wrap the field, should contain %s for the - original field value. For example, to wrap everything in dollars, - use :fmt \"$%s$\". This may also be a property list with column - numbers and formats. For example :fmt (2 \"$%s$\" 4 \"%s%%\") - The format may also be a function that formats its one argument. - -:efmt Format for transforming numbers with exponentials. The format - should have %s twice for inserting mantissa and exponent, for - example \"%s\\\\times10^{%s}\". LaTeX default is \"%s\\\\,(%s)\". - This may also be a property list with column numbers and formats. - The format may also be a function that formats its two arguments. - -:llend If you find too much space below the last line of a table, - pass a value of \"\" for :llend to suppress the final \\\\. - -The general parameters :skip and :skipcols have already been applied when -this function is called." - (let* ((alignment (mapconcat (lambda (x) (if x "r" "l")) - org-table-last-alignment "")) - (params2 - (list - :tstart (concat "\\begin{tabular}{" alignment "}") - :tend "\\end{tabular}" - :lstart "" :lend " \\\\" :sep " & " - :efmt "%s\\,(%s)" :hline "\\hline"))) - (require 'ox-latex) - (orgtbl-to-generic table (org-combine-plists params2 params) 'latex))) + +TABLE is a list, each entry either the symbol `hline' for +a horizontal separator line, or a list of fields for that line. +PARAMS is a property list of parameters that can influence the +conversion. All parameters from `orgtbl-to-generic' are +supported. It is also possible to use the following ones: + +:booktabs + + When non-nil, use formal \"booktabs\" style. + +:environment + + Specify environment to use, as a string. If you use + \"longtable\", you may also want to specify :language property, + as a string, to get proper continuation strings." + (require 'ox-latex) + (orgtbl-to-generic + table + (org-combine-plists + ;; Provide sane default values. + (list :backend 'latex + :latex-default-table-mode 'table + :latex-tables-centered nil + :latex-tables-booktabs (plist-get params :booktabs) + :latex-table-scientific-notation nil + :latex-default-table-environment + (or (plist-get params :environment) "tabular")) + params))) ;;;###autoload (defun orgtbl-to-html (table params) "Convert the orgtbl-mode TABLE to HTML. -TABLE is a list, each entry either the symbol `hline' for a horizontal -separator line, or a list of fields for that line. -PARAMS is a property list of parameters that can influence the conversion. -Currently this function recognizes the following parameters: -:splice When set to t, return only table body lines, don't wrap - them into a
environment. Default is nil. +TABLE is a list, each entry either the symbol `hline' for +a horizontal separator line, or a list of fields for that line. +PARAMS is a property list of parameters that can influence the +conversion. All parameters from `orgtbl-to-generic' are +supported. It is also possible to use the following one: -The general parameters :skip and :skipcols have already been applied when -this function is called. The function does *not* use `orgtbl-to-generic', -so you cannot specify parameters for it." +:attributes + + Attributes and values, as a plist, which will be used in +
tag." (require 'ox-html) - (let ((output (org-export-string-as - (orgtbl-to-orgtbl table nil) 'html t '(:with-tables t)))) - (if (not (plist-get params :splice)) output - (org-trim - (replace-regexp-in-string - "\\`
\n" "" - (replace-regexp-in-string "
\n*\\'" "" output)))))) + (orgtbl-to-generic + table + (org-combine-plists + ;; Provide sane default values. + (list :backend 'html + :html-table-data-tags '("" . "") + :html-table-use-header-tags-for-first-column nil + :html-table-align-individual-fields t + :html-table-row-tags '("" . "") + :html-table-attributes + (if (plist-member params :attributes) + (plist-get params :attributes) + '(:border "2" :cellspacing "0" :cellpadding "6" :rules "groups" + :frame "hsides"))) + params))) ;;;###autoload (defun orgtbl-to-texinfo (table params) - "Convert the orgtbl-mode TABLE to TeXInfo. -TABLE is a list, each entry either the symbol `hline' for a horizontal -separator line, or a list of fields for that line. -PARAMS is a property list of parameters that can influence the conversion. -Supports all parameters from `orgtbl-to-generic'. Most important for -TeXInfo are: - -:splice nil/t When set to t, return only table body lines, don't wrap - them into a multitable environment. Default is nil. - -:fmt fmt A format to be used to wrap the field, should contain - %s for the original field value. For example, to wrap - everything in @kbd{}, you could use :fmt \"@kbd{%s}\". - This may also be a property list with column numbers and - formats. For example :fmt (2 \"@kbd{%s}\" 4 \"@code{%s}\"). - Each format also may be a function that formats its one - argument. - -:cf \"f1 f2..\" The column fractions for the table. By default these - are computed automatically from the width of the columns - under org-mode. - -The general parameters :skip and :skipcols have already been applied when -this function is called." - (let* ((total (float (apply '+ org-table-last-column-widths))) - (colfrac (or (plist-get params :cf) - (mapconcat - (lambda (x) (format "%.3f" (/ (float x) total))) - org-table-last-column-widths " "))) - (params2 - (list - :tstart (concat "@multitable @columnfractions " colfrac) - :tend "@end multitable" - :lstart "@item " :lend "" :sep " @tab " - :hlstart "@headitem "))) - (require 'ox-texinfo) - (orgtbl-to-generic table (org-combine-plists params2 params) 'texinfo))) + "Convert the orgtbl-mode TABLE to Texinfo. + +TABLE is a list, each entry either the symbol `hline' for +a horizontal separator line, or a list of fields for that line. +PARAMS is a property list of parameters that can influence the +conversion. All parameters from `orgtbl-to-generic' are +supported. It is also possible to use the following one: + +:columns + + Column widths, as a string. When providing column fractions, + \"@columnfractions\" command can be omitted." + (require 'ox-texinfo) + (let ((output + (orgtbl-to-generic + table + (org-combine-plists + (list :backend 'texinfo + :texinfo-tables-verbatim nil + :texinfo-table-scientific-notation nil) + params))) + (columns (let ((w (plist-get params :columns))) + (cond ((not w) nil) + ((org-string-match-p "{\\|@columnfractions " w) w) + (t (concat "@columnfractions " w)))))) + (if (not columns) output + (replace-regexp-in-string + "@multitable \\(.*\\)" columns output t nil 1)))) ;;;###autoload (defun orgtbl-to-orgtbl (table params) "Convert the orgtbl-mode TABLE into another orgtbl-mode table. + +TABLE is a list, each entry either the symbol `hline' for +a horizontal separator line, or a list of fields for that line. +PARAMS is a property list of parameters that can influence the +conversion. All parameters from `orgtbl-to-generic' are +supported. + Useful when slicing one table into many. The :hline, :sep, -:lstart, and :lend provide orgtbl framing. The default nil :tstart -and :tend suppress strings without splicing; they can be set to -provide ORGTBL directives for the generated table." - (let* ((params2 - (list - :remove-newlines t - :tstart nil :tend nil - :hline "|---" - :sep " | " - :lstart "| " - :lend " |")) - (params (org-combine-plists params2 params))) - (with-temp-buffer - (insert (orgtbl-to-generic table params)) - (goto-char (point-min)) - (while (re-search-forward org-table-hline-regexp nil t) - (org-table-align)) - (buffer-substring 1 (buffer-size))))) +:lstart, and :lend provide orgtbl framing. :tstart and :tend can +be set to provide ORGTBL directives for the generated table." + (require 'ox-org) + (orgtbl-to-generic table (org-combine-plists params (list :backend 'org)))) (defun orgtbl-to-table.el (table params) - "Convert the orgtbl-mode TABLE into a table.el table." + "Convert the orgtbl-mode TABLE into a table.el table. +TABLE is a list, each entry either the symbol `hline' for +a horizontal separator line, or a list of fields for that line. +PARAMS is a property list of parameters that can influence the +conversion. All parameters from `orgtbl-to-generic' are +supported." (with-temp-buffer (insert (orgtbl-to-orgtbl table params)) (org-table-align) @@ -4920,19 +5227,134 @@ provide ORGTBL directives for the generated table." (defun orgtbl-to-unicode (table params) "Convert the orgtbl-mode TABLE into a table with unicode characters. -You need the ascii-art-to-unicode.el package for this. You can download -it here: http://gnuvola.org/software/j/aa2u/ascii-art-to-unicode.el." - (with-temp-buffer - (insert (orgtbl-to-table.el table params)) - (goto-char (point-min)) - (if (or (featurep 'ascii-art-to-unicode) - (require 'ascii-art-to-unicode nil t)) - (aa2u) - (unless (delq nil (mapcar (lambda (l) (string-match "aa2u" (car l))) org-stored-links)) - (push '("http://gnuvola.org/software/j/aa2u/ascii-art-to-unicode.el" - "Link to ascii-art-to-unicode.el") org-stored-links)) - (user-error "Please download ascii-art-to-unicode.el (use C-c C-l to insert the link to it)")) - (buffer-string))) + +TABLE is a list, each entry either the symbol `hline' for +a horizontal separator line, or a list of fields for that line. +PARAMS is a property list of parameters that can influence the +conversion. All parameters from `orgtbl-to-generic' are +supported. It is also possible to use the following ones: + +:ascii-art + + When non-nil, use \"ascii-art-to-unicode\" package to translate + the table. You can download it here: + http://gnuvola.org/software/j/aa2u/ascii-art-to-unicode.el. + +:narrow + + When non-nil, narrow columns width than provided width cookie, + using \"=>\" as an ellipsis, just like in an Org mode buffer." + (require 'ox-ascii) + (orgtbl-to-generic + table + (org-combine-plists + (list :backend 'ascii + :ascii-charset 'utf-8 + :ascii-table-widen-columns (not (plist-get params :narrow)) + :ascii-table-use-ascii-art (plist-get params :ascii-art)) + params))) + +;; Put the cursor in a column containing numerical values +;; of an Org-Mode table, +;; type C-c " a +;; A new column is added with a bar plot. +;; When the table is refreshed (C-u C-c *), +;; the plot is updated to reflect the new values. + +(defun orgtbl-ascii-draw (value min max &optional width characters) + "Draw an ascii bar in a table. +VALUE is a the value to plot, the width of the bar to draw. A +value equal to MIN will be displayed as empty (zero width bar). +A value equal to MAX will draw a bar filling all the WIDTH. +WIDTH is the expected width in characters of the column. +CHARACTERS is a string that will compose the bar, with shades of +grey from pure white to pure black. It defaults to a 10 +characters string of regular ascii characters." + (let* ((characters (or characters " .:;c!lhVHW")) + (width (or width 12)) + (value (if (numberp value) value (string-to-number value))) + (value (* (/ (- (+ value 0.0) min) (- max min)) width))) + (cond + ((< value 0) "too small") + ((> value width) "too large") + (t + (let ((len (1- (length characters)))) + (concat + (make-string (floor value) (elt characters len)) + (string (elt characters + (floor (* (- value (floor value)) len)))))))))) + +;;;###autoload +(defun orgtbl-ascii-plot (&optional ask) + "Draw an ascii bar plot in a column. +With cursor in a column containing numerical values, this +function will draw a plot in a new column. +ASK, if given, is a numeric prefix to override the default 12 +characters width of the plot. ASK may also be the +\\[universal-argument] prefix, which will prompt for the width." + (interactive "P") + (let ((col (org-table-current-column)) + (min 1e999) ; 1e999 will be converted to infinity + (max -1e999) ; which is the desired result + (table (org-table-to-lisp)) + (length + (cond ((consp ask) + (read-number "Length of column " 12)) + ((numberp ask) ask) + (t 12)))) + ;; Skip any hline a the top of table. + (while (eq (car table) 'hline) (setq table (cdr table))) + ;; Skip table header if any. + (dolist (x (or (cdr (memq 'hline table)) table)) + (when (consp x) + (setq x (nth (1- col) x)) + (when (string-match + "^[-+]?\\([0-9]*[.]\\)?[0-9]*\\([eE][+-]?[0-9]+\\)?$" + x) + (setq x (string-to-number x)) + (when (> min x) (setq min x)) + (when (< max x) (setq max x))))) + (org-table-insert-column) + (org-table-move-column-right) + (org-table-store-formulas + (cons + (cons + (concat "$" (number-to-string (1+ col))) + (format "'(%s $%s %s %s %s)" + "orgtbl-ascii-draw" col min max length)) + (org-table-get-stored-formulas))) + (org-table-recalculate t))) + +;; Example of extension: unicode characters +;; Here are two examples of different styles. + +;; Unicode block characters are used to give a smooth effect. +;; See http://en.wikipedia.org/wiki/Block_Elements +;; Use one of those drawing functions +;; - orgtbl-ascii-draw (the default ascii) +;; - orgtbl-uc-draw-grid (unicode with a grid effect) +;; - orgtbl-uc-draw-cont (smooth unicode) + +;; This is best viewed with the "DejaVu Sans Mono" font +;; (use M-x set-default-font). + +(defun orgtbl-uc-draw-grid (value min max &optional width) + "Draw a bar in a table using block unicode characters. +It is a variant of orgtbl-ascii-draw with Unicode block +characters, for a smooth display. Bars appear as grids (to the +extent the font allows)." + ;; http://en.wikipedia.org/wiki/Block_Elements + ;; best viewed with the "DejaVu Sans Mono" font. + (orgtbl-ascii-draw value min max width + " \u258F\u258E\u258D\u258C\u258B\u258A\u2589")) + +(defun orgtbl-uc-draw-cont (value min max &optional width) + "Draw a bar in a table using block unicode characters. +It is a variant of orgtbl-ascii-draw with Unicode block +characters, for a smooth display. Bars are solid (to the extent +the font allows)." + (orgtbl-ascii-draw value min max width + " \u258F\u258E\u258D\u258C\u258B\u258A\u2589\u2588")) (defun org-table-get-remote-range (name-or-id form) "Get a field value or a list of values in a range from table at ID. @@ -4949,52 +5371,69 @@ The return value is either a single string for a single field, or a list of the fields in the rectangle." (save-match-data (let ((case-fold-search t) (id-loc nil) - ;; Protect a bunch of variables from being overwritten - ;; by the context of the remote table + ;; Protect a bunch of variables from being overwritten by + ;; the context of the remote table. org-table-column-names org-table-column-name-regexp org-table-local-parameters org-table-named-field-locations - org-table-current-line-types org-table-current-begin-line + org-table-current-line-types org-table-current-begin-pos org-table-dlines org-table-current-ncol org-table-hlines org-table-last-alignment org-table-last-column-widths org-table-last-alignment - org-table-last-column-widths tbeg + org-table-last-column-widths buffer loc) (setq form (org-table-convert-refs-to-rc form)) - (save-excursion - (save-restriction - (widen) - (save-excursion - (goto-char (point-min)) - (if (re-search-forward - (concat "^[ \t]*#\\+\\(tbl\\)?name:[ \t]*" - (regexp-quote name-or-id) "[ \t]*$") - nil t) - (setq buffer (current-buffer) loc (match-beginning 0)) - (setq id-loc (org-id-find name-or-id 'marker)) - (unless (and id-loc (markerp id-loc)) - (user-error "Can't find remote table \"%s\"" name-or-id)) - (setq buffer (marker-buffer id-loc) - loc (marker-position id-loc)) - (move-marker id-loc nil))) - (with-current-buffer buffer - (save-excursion - (save-restriction - (widen) - (goto-char loc) - (forward-char 1) - (unless (and (re-search-forward "^\\(\\*+ \\)\\|[ \t]*|" nil t) - (not (match-beginning 1))) - (user-error "Cannot find a table at NAME or ID %s" name-or-id)) - (setq tbeg (point-at-bol)) - (org-table-get-specials) - (setq form (org-table-formula-substitute-names - (org-table-formula-handle-first/last-rc form))) - (if (and (string-match org-table-range-regexp form) - (> (length (match-string 0 form)) 1)) - (save-match-data - (org-table-get-range (match-string 0 form) tbeg 1)) - form))))))))) + (org-with-wide-buffer + (goto-char (point-min)) + (if (re-search-forward + (concat "^[ \t]*#\\+\\(tbl\\)?name:[ \t]*" + (regexp-quote name-or-id) "[ \t]*$") + nil t) + (setq buffer (current-buffer) loc (match-beginning 0)) + (setq id-loc (org-id-find name-or-id 'marker)) + (unless (and id-loc (markerp id-loc)) + (user-error "Can't find remote table \"%s\"" name-or-id)) + (setq buffer (marker-buffer id-loc) + loc (marker-position id-loc)) + (move-marker id-loc nil)) + (with-current-buffer buffer + (org-with-wide-buffer + (goto-char loc) + (forward-char 1) + (unless (and (re-search-forward "^\\(\\*+ \\)\\|^[ \t]*|" nil t) + (not (match-beginning 1))) + (user-error "Cannot find a table at NAME or ID %s" name-or-id)) + (org-table-analyze) + (setq form (org-table-formula-substitute-names + (org-table-formula-handle-first/last-rc form))) + (if (and (string-match org-table-range-regexp form) + (> (length (match-string 0 form)) 1)) + (org-table-get-range + (match-string 0 form) org-table-current-begin-pos 1) + form))))))) + +(defun org-table-remote-reference-indirection (form) + "Return formula with table remote references substituted by indirection. +For example \"remote($1, @>$2)\" => \"remote(year_2013, @>$1)\". +This indirection works only with the format @ROW$COLUMN. The +format \"B3\" is not supported because it can not be +distinguished from a plain table name or ID." + (let ((regexp + ;; Same as in `org-table-eval-formula'. + (concat "\\ ;; Keywords: outlines, hypermedia, calendar, wp @@ -24,13 +24,20 @@ ;; ;;; Commentary: -;; This file contains the relative timer code for Org-mode +;; This file implements two types of timers for Org buffers: +;; +;; - A relative timer that counts up (from 0 or a specified offset) +;; - A countdown timer that counts down from a specified time +;; +;; The relative and countdown timers differ in their entry points. +;; Use `org-timer' or `org-timer-start' to start the relative timer, +;; and `org-timer-set-timer' to start the countdown timer. ;;; Code: (require 'org) +(require 'org-clock) -(declare-function org-notify "org-clock" (notification &optional play-sound)) (declare-function org-agenda-error "org-agenda" ()) (defvar org-timer-start-time nil @@ -39,22 +46,32 @@ (defvar org-timer-pause-time nil "Time when the timer was paused.") +(defvar org-timer-countdown-timer nil + "Current countdown timer. +This is a timer object if there is an active countdown timer, +`paused' if there is a paused countdown timer, and nil +otherwise.") + +(defvar org-timer-countdown-timer-title nil + "Title for notification displayed when a countdown finishes.") + (defconst org-timer-re "\\([-+]?[0-9]+\\):\\([0-9]\\{2\\}\\):\\([0-9]\\{2\\}\\)" "Regular expression used to match timer stamps.") (defcustom org-timer-format "%s " "The format to insert the time of the timer. This format must contain one instance of \"%s\" which will be replaced by -the value of the relative timer." +the value of the timer." :group 'org-time :type 'string) -(defcustom org-timer-default-timer 0 - "The default timer when a timer is set. +(defcustom org-timer-default-timer "0" + "The default timer when a timer is set, in minutes or hh:mm:ss format. When 0, the user is prompted for a value." :group 'org-time - :version "24.1" - :type 'number) + :version "25.1" + :package-version '(Org . "8.3") + :type 'string) (defcustom org-timer-display 'mode-line "When a timer is running, org-mode can display it in the mode @@ -76,13 +93,13 @@ nil current timer is not displayed" "Hook run after relative timer is started.") (defvar org-timer-stop-hook nil - "Hook run before relative timer is stopped.") + "Hook run before relative or countdown timer is stopped.") (defvar org-timer-pause-hook nil - "Hook run before relative timer is paused.") + "Hook run before relative or countdown timer is paused.") (defvar org-timer-continue-hook nil - "Hook run after relative timer is continued.") + "Hook run after relative or countdown timer is continued.") (defvar org-timer-set-hook nil "Hook run after countdown timer is set.") @@ -90,9 +107,6 @@ nil current timer is not displayed" (defvar org-timer-done-hook nil "Hook run after countdown timer reaches zero.") -(defvar org-timer-cancel-hook nil - "Hook run before countdown timer is canceled.") - ;;;###autoload (defun org-timer-start (&optional offset) "Set the starting time for the relative timer to now. @@ -105,8 +119,12 @@ region will be shifted by a specific amount. You will be prompted for the amount, with the default to make the first timer string in the region 0:00:00." (interactive "P") - (if (equal offset '(16)) - (call-interactively 'org-timer-change-times-in-region) + (cond + ((equal offset '(16)) + (call-interactively 'org-timer-change-times-in-region)) + (org-timer-countdown-timer + (user-error "Countdown timer is running. Cancel first")) + (t (let (delta def s) (if (not offset) (setq org-timer-start-time (current-time)) @@ -123,47 +141,65 @@ the region 0:00:00." (setq delta (org-timer-hms-to-secs (org-timer-fix-incomplete s))))) (setq org-timer-start-time (seconds-to-time - (- (org-float-time) delta)))) + ;; Pass `current-time' result to `org-float-time' + ;; (instead of calling without arguments) so that only + ;; `current-time' has to be overriden in tests. + (- (org-float-time (current-time)) delta)))) + (setq org-timer-pause-time nil) (org-timer-set-mode-line 'on) (message "Timer start time set to %s, current value is %s" (format-time-string "%T" org-timer-start-time) (org-timer-secs-to-hms (or delta 0))) - (run-hooks 'org-timer-start-hook)))) + (run-hooks 'org-timer-start-hook))))) (defun org-timer-pause-or-continue (&optional stop) - "Pause or continue the relative timer. + "Pause or continue the relative or countdown timer. With prefix arg STOP, stop it entirely." (interactive "P") (cond (stop (org-timer-stop)) ((not org-timer-start-time) (error "No timer is running")) (org-timer-pause-time - ;; timer is paused, continue - (setq org-timer-start-time - (seconds-to-time - (- - (org-float-time) - (- (org-float-time org-timer-pause-time) - (org-float-time org-timer-start-time)))) - org-timer-pause-time nil) - (org-timer-set-mode-line 'on) - (run-hooks 'org-timer-continue-hook) - (message "Timer continues at %s" (org-timer-value-string))) + (let ((start-secs (org-float-time org-timer-start-time)) + (pause-secs (org-float-time org-timer-pause-time))) + (if org-timer-countdown-timer + (let ((new-secs (- start-secs pause-secs))) + (setq org-timer-countdown-timer + (org-timer--run-countdown-timer + new-secs org-timer-countdown-timer-title)) + (setq org-timer-start-time + (time-add (current-time) (seconds-to-time new-secs)))) + (setq org-timer-start-time + ;; Pass `current-time' result to `org-float-time' + ;; (instead of calling without arguments) so that only + ;; `current-time' has to be overriden in tests. + (seconds-to-time (- (org-float-time (current-time)) + (- pause-secs start-secs))))) + (setq org-timer-pause-time nil) + (org-timer-set-mode-line 'on) + (run-hooks 'org-timer-continue-hook) + (message "Timer continues at %s" (org-timer-value-string)))) (t ;; pause timer + (when org-timer-countdown-timer + (cancel-timer org-timer-countdown-timer) + (setq org-timer-countdown-timer 'paused)) (run-hooks 'org-timer-pause-hook) (setq org-timer-pause-time (current-time)) - (org-timer-set-mode-line 'pause) + (org-timer-set-mode-line 'paused) (message "Timer paused at %s" (org-timer-value-string))))) -(defvar org-timer-current-timer nil) (defun org-timer-stop () - "Stop the relative timer." + "Stop the relative or countdown timer." (interactive) + (unless org-timer-start-time + (user-error "No timer running")) + (when (timerp org-timer-countdown-timer) + (cancel-timer org-timer-countdown-timer)) (run-hooks 'org-timer-stop-hook) (setq org-timer-start-time nil org-timer-pause-time nil - org-timer-current-timer nil) + org-timer-countdown-timer nil) (org-timer-set-mode-line 'off) (message "Timer stopped")) @@ -179,11 +215,13 @@ that was not started at the correct moment. If NO-INSERT-P is non-nil, return the string instead of inserting it in the buffer." (interactive "P") - (when (or (equal restart '(4)) (not org-timer-start-time)) - (org-timer-start)) - (if no-insert-p - (org-timer-value-string) - (insert (org-timer-value-string)))) + (if (equal restart '(16)) + (org-timer-start restart) + (when (or (equal restart '(4)) (not org-timer-start-time)) + (org-timer-start)) + (if no-insert-p + (org-timer-value-string) + (insert (org-timer-value-string))))) (defun org-timer-value-string () "Set the timer string." @@ -191,11 +229,13 @@ it in the buffer." (org-timer-secs-to-hms (abs (floor (org-timer-seconds)))))) -(defvar org-timer-timer-is-countdown nil) (defun org-timer-seconds () - (if org-timer-timer-is-countdown + ;; Pass `current-time' result to `org-float-time' (instead of + ;; calling without arguments) so that only `current-time' has to be + ;; overriden in tests. + (if org-timer-countdown-timer (- (org-float-time org-timer-start-time) - (org-float-time (current-time))) + (org-float-time (or org-timer-pause-time (current-time)))) (- (org-float-time (or org-timer-pause-time (current-time))) (org-float-time org-timer-start-time)))) @@ -290,8 +330,8 @@ If the integer is negative, the string will start with \"-\"." (defvar org-timer-mode-line-string nil) (defun org-timer-set-mode-line (value) - "Set the mode-line display of the relative timer. -VALUE can be `on', `off', or `pause'." + "Set the mode-line display for relative or countdown timer. +VALUE can be `on', `off', or `paused'." (when (or (eq org-timer-display 'mode-line) (eq org-timer-display 'both)) (or global-mode-string (setq global-mode-string '(""))) @@ -317,7 +357,7 @@ VALUE can be `on', `off', or `pause'." (setq frame-title-format (delq 'org-timer-mode-line-string frame-title-format))) (force-mode-line-update)) - ((equal value 'pause) + ((equal value 'paused) (when org-timer-mode-line-timer (cancel-timer org-timer-mode-line-timer) (setq org-timer-mode-line-timer nil))) @@ -349,102 +389,114 @@ VALUE can be `on', `off', or `pause'." (concat " <" (substring (org-timer-value-string) 0 -1) ">")) (force-mode-line-update))) -(defun org-timer-cancel-timer () - "Cancel the current timer." - (interactive) - (when (eval org-timer-current-timer) - (run-hooks 'org-timer-cancel-hook) - (cancel-timer org-timer-current-timer) - (setq org-timer-current-timer nil) - (setq org-timer-timer-is-countdown nil) - (org-timer-set-mode-line 'off)) - (message "Last timer canceled")) - (defun org-timer-show-remaining-time () "Display the remaining time before the timer ends." (interactive) (require 'time) - (if (not org-timer-current-timer) + (if (not org-timer-countdown-timer) (message "No timer set") (let* ((rtime (decode-time - (time-subtract (timer--time org-timer-current-timer) + (time-subtract (timer--time org-timer-countdown-timer) (current-time)))) (rsecs (nth 0 rtime)) (rmins (nth 1 rtime))) (message "%d minute(s) %d seconds left before next time out" rmins rsecs)))) -(defvar org-clock-sound) - ;;;###autoload (defun org-timer-set-timer (&optional opt) - "Prompt for a duration and set a timer. + "Prompt for a duration in minutes or hh:mm:ss and set a timer. -If `org-timer-default-timer' is not zero, suggest this value as +If `org-timer-default-timer' is not \"0\", suggest this value as the default duration for the timer. If a timer is already set, prompt the user if she wants to replace it. Called with a numeric prefix argument, use this numeric value as -the duration of the timer. +the duration of the timer in minutes. Called with a `C-u' prefix arguments, use `org-timer-default-timer' without prompting the user for a duration. With two `C-u' prefix arguments, use `org-timer-default-timer' without prompting the user for a duration and automatically -replace any running timer." +replace any running timer. + +By default, the timer duration will be set to the number of +minutes in the Effort property, if any. You can ignore this by +using three `C-u' prefix arguments." (interactive "P") - (let ((minutes (or (and (numberp opt) (number-to-string opt)) - (and (listp opt) (not (null opt)) - (number-to-string org-timer-default-timer)) - (read-from-minibuffer - "How many minutes left? " - (if (not (eq org-timer-default-timer 0)) - (number-to-string org-timer-default-timer)))))) + (when (and org-timer-start-time + (not org-timer-countdown-timer)) + (user-error "Relative timer is running. Stop first")) + (let* ((default-timer + ;; `org-timer-default-timer' used to be a number, don't choke: + (if (numberp org-timer-default-timer) + (number-to-string org-timer-default-timer) + org-timer-default-timer)) + (effort-minutes (ignore-errors (org-get-at-eol 'effort-minutes 1))) + (minutes (or (and (not (equal opt '(64))) + effort-minutes + (number-to-string effort-minutes)) + (and (numberp opt) (number-to-string opt)) + (and (consp opt) default-timer) + (and (stringp opt) opt) + (read-from-minibuffer + "How much time left? (minutes or h:mm:ss) " + (and (not (string-equal default-timer "0")) default-timer))))) + (when (string-match "\\`[0-9]+\\'" minutes) + (setq minutes (concat minutes ":00"))) (if (not (string-match "[0-9]+" minutes)) (org-timer-show-remaining-time) - (let* ((mins (string-to-number (match-string 0 minutes))) - (secs (* mins 60)) - (hl (cond - ((string-match "Org Agenda" (buffer-name)) - (let* ((marker (or (get-text-property (point) 'org-marker) - (org-agenda-error))) - (hdmarker (or (get-text-property (point) 'org-hd-marker) - marker)) - (pos (marker-position marker))) - (with-current-buffer (marker-buffer marker) - (widen) - (goto-char pos) - (org-show-entry) - (or (ignore-errors (org-get-heading)) - (concat "File:" (file-name-nondirectory (buffer-file-name))))))) - ((derived-mode-p 'org-mode) - (or (ignore-errors (org-get-heading)) - (concat "File:" (file-name-nondirectory (buffer-file-name))))) - (t (error "Not in an Org buffer")))) - timer-set) - (if (or (and org-timer-current-timer - (or (equal opt '(16)) - (y-or-n-p "Replace current timer? "))) - (not org-timer-current-timer)) - (progn - (require 'org-clock) - (when org-timer-current-timer - (cancel-timer org-timer-current-timer)) - (setq org-timer-current-timer - (run-with-timer - secs nil `(lambda () - (setq org-timer-current-timer nil) - (org-notify ,(format "%s: time out" hl) ,org-clock-sound) - (setq org-timer-timer-is-countdown nil) - (org-timer-set-mode-line 'off) - (run-hooks 'org-timer-done-hook)))) - (run-hooks 'org-timer-set-hook) - (setq org-timer-timer-is-countdown t - org-timer-start-time - (time-add (current-time) (seconds-to-time (* mins 60)))) - (org-timer-set-mode-line 'on)) - (message "No timer set")))))) + (let ((secs (org-timer-hms-to-secs (org-timer-fix-incomplete minutes))) + (hl (org-timer--get-timer-title))) + (if (and org-timer-countdown-timer + (not (or (equal opt '(16)) + (y-or-n-p "Replace current timer? ")))) + (message "No timer set") + (when (timerp org-timer-countdown-timer) + (cancel-timer org-timer-countdown-timer)) + (setq org-timer-countdown-timer-title + (org-timer--get-timer-title)) + (setq org-timer-countdown-timer + (org-timer--run-countdown-timer + secs org-timer-countdown-timer-title)) + (run-hooks 'org-timer-set-hook) + (setq org-timer-start-time + (time-add (current-time) (seconds-to-time secs))) + (setq org-timer-pause-time nil) + (org-timer-set-mode-line 'on)))))) + +(defun org-timer--run-countdown-timer (secs title) + "Start countdown timer that will last SECS. +TITLE will be appended to the notification message displayed when +time is up." + (let ((msg (format "%s: time out" title))) + (run-with-timer + secs nil `(lambda () + (setq org-timer-countdown-timer nil + org-timer-start-time nil) + (org-notify ,msg ,org-clock-sound) + (org-timer-set-mode-line 'off) + (run-hooks 'org-timer-done-hook))))) + +(defun org-timer--get-timer-title () + "Construct timer title from heading or file name of Org buffer." + (cond + ((derived-mode-p 'org-agenda-mode) + (let* ((marker (or (get-text-property (point) 'org-marker) + (org-agenda-error))) + (hdmarker (or (get-text-property (point) 'org-hd-marker) + marker))) + (with-current-buffer (marker-buffer marker) + (org-with-wide-buffer + (goto-char hdmarker) + (org-show-entry) + (or (ignore-errors (org-get-heading)) + (buffer-name (buffer-base-buffer))))))) + ((derived-mode-p 'org-mode) + (or (ignore-errors (org-get-heading)) + (buffer-name (buffer-base-buffer)))) + (t (error "Not in an Org buffer")))) (provide 'org-timer) diff --git a/elpa/org-20150629/org-version.el b/elpa/org-20160215/org-version.el similarity index 87% rename from elpa/org-20150629/org-version.el rename to elpa/org-20160215/org-version.el index 6d389371..d2462952 100644 --- a/elpa/org-20150629/org-version.el +++ b/elpa/org-20160215/org-version.el @@ -5,13 +5,13 @@ (defun org-release () "The release version of org-mode. Inserted by installing org-mode or when a release is made." - (let ((org-release "8.2.10")) + (let ((org-release "8.3.3")) org-release)) ;;;###autoload (defun org-git-version () "The Git version of org-mode. Inserted by installing org-mode or when a release is made." - (let ((org-git-version "8.2.10-41-g42228a-elpa")) + (let ((org-git-version "8.3.3-55-g9f737b-elpa")) org-git-version)) ;;;###autoload (defvar org-odt-data-dir "/usr/share/emacs/etc/org" diff --git a/elpa/org-20150629/org-w3m.el b/elpa/org-20160215/org-w3m.el similarity index 99% rename from elpa/org-20150629/org-w3m.el rename to elpa/org-20160215/org-w3m.el index c8ddc82d..894dbef9 100644 --- a/elpa/org-20150629/org-w3m.el +++ b/elpa/org-20160215/org-w3m.el @@ -1,6 +1,6 @@ ;;; org-w3m.el --- Support from copy and paste from w3m to Org-mode -;; Copyright (C) 2008-2014 Free Software Foundation, Inc. +;; Copyright (C) 2008-2016 Free Software Foundation, Inc. ;; Author: Andy Stewart ;; Keywords: outlines, hypermedia, calendar, wp diff --git a/elpa/org-20150629/org.el b/elpa/org-20160215/org.el similarity index 78% rename from elpa/org-20150629/org.el rename to elpa/org-20160215/org.el index 4636830d..690d923c 100644 --- a/elpa/org-20150629/org.el +++ b/elpa/org-20160215/org.el @@ -1,7 +1,7 @@ ;;; org.el --- Outline-based notes management and organizer ;; Carstens outline-mode for keeping track of everything. -;; Copyright (C) 2004-2014 Free Software Foundation, Inc. +;; Copyright (C) 2004-2016 Free Software Foundation, Inc. ;; ;; Author: Carsten Dominik ;; Maintainer: Carsten Dominik @@ -77,7 +77,16 @@ (require 'find-func) (require 'format-spec) -(load "org-loaddefs.el" t t t) +(or (equal this-command 'eval-buffer) + (condition-case nil + (load (concat (file-name-directory load-file-name) + "org-loaddefs.el") + nil t t t) + (error + (message "WARNING: No org-loaddefs.el file could be found from where org.el is loaded.") + (sit-for 3) + (message "You need to run \"make\" or \"make autoloads\" from Org lisp directory") + (sit-for 3)))) (require 'org-macs) (require 'org-compat) @@ -111,63 +120,77 @@ Stars are put in group 1 and the trimmed body in group 2.") (unless (boundp 'diary-fancy-buffer) (org-defvaralias 'diary-fancy-buffer 'fancy-diary-buffer)) +(declare-function cdlatex-environment "ext:cdlatex" (environment item)) (declare-function org-add-archive-files "org-archive" (files)) - -(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-pop-to-buffer-same-window "org-compat" (&optional buffer-or-name norecord label)) +(declare-function org-agenda-entry-get-agenda-timestamp "org-agenda" (pom)) +(declare-function org-agenda-list "org-agenda" (&optional arg start-day span)) +(declare-function org-agenda-redo "org-agenda" (&optional all)) +(declare-function org-babel-do-in-edit-buffer "ob-core" (&rest body)) +(declare-function org-babel-tangle-file "ob-tangle" (file &optional target-file lang)) +(declare-function org-beamer-mode "ox-beamer" ()) (declare-function org-clock-get-last-clock-out-time "org-clock" ()) -(declare-function org-clock-timestamps-up "org-clock" (&optional n)) -(declare-function org-clock-timestamps-down "org-clock" (&optional n)) +(declare-function org-clock-out "org-clock" (&optional switch-to-state fail-quietly at-time)) (declare-function org-clock-remove-overlays "org-clock" (&optional beg end noremove)) +(declare-function org-clock-sum "org-clock" (&optional tstart tend headline-filter propname)) (declare-function org-clock-sum-current-item "org-clock" (&optional tstart)) +(declare-function org-clock-timestamps-down "org-clock" (&optional n)) +(declare-function org-clock-timestamps-up "org-clock" (&optional n)) (declare-function org-clock-update-time-maybe "org-clock" ()) (declare-function org-clocktable-shift "org-clock" (dir n)) - -(declare-function orgtbl-mode "org-table" (&optional arg)) -(declare-function org-clock-out "org-clock" (&optional switch-to-state fail-quietly at-time)) -(declare-function org-beamer-mode "ox-beamer" ()) -(declare-function org-table-edit-field "org-table" (arg)) -(declare-function org-table-justify-field-maybe "org-table" (&optional new)) -(declare-function org-table-set-constants "org-table" ()) -(declare-function org-table-calc-current-TBLFM "org-table" (&optional arg)) -(declare-function org-id-get-create "org-id" (&optional force)) +(declare-function org-element-at-point "org-element" ()) +(declare-function org-element-cache-refresh "org-element" (pos)) +(declare-function org-element-cache-reset "org-element" (&optional all)) +(declare-function org-element-contents "org-element" (element)) +(declare-function org-element-context "org-element" (&optional element)) +(declare-function org-element-copy "org-element" (datum)) +(declare-function org-element-interpret-data "org-element" (data &optional parent)) +(declare-function org-element-lineage "org-element" (blob &optional types with-self)) +(declare-function org-element-nested-p "org-element" (elem-a elem-b)) +(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-put-property "org-element" (element property value)) +(declare-function org-element-swap-A-B "org-element" (elem-a elem-b)) +(declare-function org-element-type "org-element" (element)) +(declare-function org-element-update-syntax "org-element" ()) (declare-function org-id-find-id-file "org-id" (id)) -(declare-function org-tags-view "org-agenda" (&optional todo-only match)) -(declare-function org-agenda-list "org-agenda" (&optional arg start-day span)) -(declare-function org-agenda-redo "org-agenda" (&optional all)) +(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-plot/gnuplot "org-plot" (&optional params)) +(declare-function org-pop-to-buffer-same-window "org-compat" (&optional buffer-or-name norecord label)) (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-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-insert-row "org-table" (&optional arg)) -(declare-function org-table-paste-rectangle "org-table" ()) +(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-wrap-region "org-table" (arg)) +(declare-function org-tags-view "org-agenda" (&optional todo-only match)) +(declare-function orgtbl-ascii-plot "org-table" (&optional ask)) +(declare-function orgtbl-mode "org-table" (&optional arg)) -(declare-function org-element--parse-objects "org-element" - (beg end acc restriction)) -(declare-function org-element-at-point "org-element" (&optional keep-trail)) -(declare-function org-element-contents "org-element" (element)) -(declare-function org-element-context "org-element" (&optional element)) -(declare-function org-element-interpret-data "org-element" - (data &optional parent)) -(declare-function org-element-map "org-element" - (data types fun &optional info first-match no-recursion)) -(declare-function org-element-nested-p "org-element" (elem-a elem-b)) -(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-put-property "org-element" - (element property value)) -(declare-function org-element-swap-A-B "org-element" (elem-a elem-b)) -(declare-function org-element--parse-objects "org-element" - (beg end acc restriction)) -(declare-function org-element-parse-buffer "org-element" - (&optional granularity visible-only)) -(declare-function org-element-restriction "org-element" (element)) -(declare-function org-element-type "org-element" (element)) +(defsubst org-uniquify (list) + "Non-destructively remove duplicate elements from LIST." + (let ((res (copy-sequence list))) (delete-dups res))) + +(defsubst org-get-at-bol (property) + "Get text property PROPERTY at the beginning of line." + (get-text-property (point-at-bol) property)) + +(defsubst org-trim (s) + "Remove whitespace at the beginning and the end of string S." + (replace-regexp-in-string + "\\`[ \t\n\r]+" "" + (replace-regexp-in-string "[ \t\n\r]+\\'" "" s))) ;; load languages based on value of `org-babel-load-languages' (defvar org-babel-load-languages) @@ -197,7 +220,6 @@ 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." (interactive "fFile to load: \nP") - (require 'ob-core) (let* ((age (lambda (file) (float-time (time-subtract (current-time) @@ -208,8 +230,10 @@ file to byte-code before it is loaded." ;; tangle if the org-mode 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 (org-babel-tangle-file file exported-file "emacs-lisp")))) + (car (last (org-babel-tangle-file file exported-file "emacs-lisp"))))) (message "%s %s" (if compile (progn (byte-compile-file exported-file 'load) @@ -244,10 +268,12 @@ requirements) is loaded." (const :tag "Ditaa" ditaa) (const :tag "Dot" dot) (const :tag "Emacs Lisp" emacs-lisp) + (const :tag "Forth" forth) (const :tag "Fortran" fortran) (const :tag "Gnuplot" gnuplot) (const :tag "Haskell" haskell) (const :tag "IO" io) + (const :tag "J" J) (const :tag "Java" java) (const :tag "Javascript" js) (const :tag "LaTeX" latex) @@ -270,10 +296,11 @@ requirements) is loaded." (const :tag "Scala" scala) (const :tag "Scheme" scheme) (const :tag "Screen" screen) - (const :tag "Shell Script" sh) + (const :tag "Shell Script" shell) (const :tag "Shen" shen) (const :tag "Sql" sql) - (const :tag "Sqlite" sqlite)) + (const :tag "Sqlite" sqlite) + (const :tag "ebnf2ps" ebnf2ps)) :value-type (boolean :tag "Activate" :value t))) ;;;; Customization variables @@ -291,11 +318,12 @@ identifier." ;;;###autoload (defun org-version (&optional here full message) - "Show the org-mode version in the echo area. -With prefix argument HERE, insert it at point. -When FULL is non-nil, use a verbose version string. -When MESSAGE is non-nil, display a message with the version." - (interactive "P") + "Show the org-mode version. +Interactively, or when MESSAGE is non-nil, show it in echo area. +With prefix argument, or when HERE is non-nil, insert it at point. +In non-interactive uses, a reduced version string is output unless +FULL is given." + (interactive (list current-prefix-arg t (not current-prefix-arg))) (let* ((org-dir (ignore-errors (org-find-library-dir "org"))) (save-load-suffixes (when (boundp 'load-suffixes) load-suffixes)) (load-suffixes (list ".el")) @@ -315,17 +343,287 @@ When MESSAGE is non-nil, display a message with the version." (concat "mixed installation! " org-install-dir " and " org-dir)) "org-loaddefs.el can not be found!"))) (version1 (if full version org-version))) - (if (org-called-interactively-p 'interactive) - (if here - (insert version) - (message version)) - (if message (message version1)) - version1))) + (when here (insert version1)) + (when message (message "%s" version1)) + version1)) (defconst org-version (org-version)) -;;; Compatibility constants + +;;; Syntax Constants + +;;;; Block + +(defconst org-block-regexp + "^[ \t]*#\\+begin_?\\([^ \n]+\\)\\(\\([^\n]+\\)\\)?\n\\([^\000]+?\\)#\\+end_?\\1[ \t]*$" + "Regular expression for hiding blocks.") + +(defconst org-dblock-start-re + "^[ \t]*#\\+\\(?:BEGIN\\|begin\\):[ \t]+\\(\\S-+\\)\\([ \t]+\\(.*\\)\\)?" + "Matches the start line of a dynamic block, with parameters.") + +(defconst org-dblock-end-re "^[ \t]*#\\+\\(?:END\\|end\\)\\([: \t\r\n]\\|$\\)" + "Matches the end of a dynamic block.") + +;;;; Clock and Planning + +(defconst org-clock-string "CLOCK:" + "String used as prefix for timestamps clocking work hours on an item.") + +(defvar org-closed-string "CLOSED:" + "String used as the prefix for timestamps logging closing a TODO entry.") + +(defvar org-deadline-string "DEADLINE:" + "String to mark deadline entries. +A deadline is this string, followed by a time stamp. Should be a word, +terminated by a colon. You can insert a schedule keyword and +a timestamp with \\[org-deadline].") + +(defvar org-scheduled-string "SCHEDULED:" + "String to mark scheduled TODO entries. +A schedule is this string, followed by a time stamp. Should be a word, +terminated by a colon. You can insert a schedule keyword and +a timestamp with \\[org-schedule].") + +(defconst org-ds-keyword-length + (+ 2 + (apply #'max + (mapcar #'length + (list org-deadline-string org-scheduled-string + org-clock-string org-closed-string)))) + "Maximum length of the DEADLINE and SCHEDULED keywords.") + +(defconst org-planning-line-re + (concat "^[ \t]*" + (regexp-opt + (list org-closed-string org-deadline-string org-scheduled-string) + t)) + "Matches a line with planning info. +Matched keyword is in group 1.") + +(defconst org-clock-line-re + (concat "^[ \t]*" org-clock-string) + "Matches a line with clock info.") + +(defconst org-deadline-regexp (concat "\\<" org-deadline-string) + "Matches the DEADLINE keyword.") + +(defconst org-deadline-time-regexp + (concat "\\<" org-deadline-string " *<\\([^>]+\\)>") + "Matches the DEADLINE keyword together with a time stamp.") + +(defconst org-deadline-time-hour-regexp + (concat "\\<" org-deadline-string + " *<\\([^>]+[0-9]\\{1,2\\}:[0-9]\\{2\\}[0-9-+:hdwmy \t.]*\\)>") + "Matches the DEADLINE keyword together with a time-and-hour stamp.") + +(defconst org-deadline-line-regexp + (concat "\\<\\(" org-deadline-string "\\).*") + "Matches the DEADLINE keyword and the rest of the line.") + +(defconst org-scheduled-regexp (concat "\\<" org-scheduled-string) + "Matches the SCHEDULED keyword.") + +(defconst org-scheduled-time-regexp + (concat "\\<" org-scheduled-string " *<\\([^>]+\\)>") + "Matches the SCHEDULED keyword together with a time stamp.") + +(defconst org-scheduled-time-hour-regexp + (concat "\\<" org-scheduled-string + " *<\\([^>]+[0-9]\\{1,2\\}:[0-9]\\{2\\}[0-9-+:hdwmy \t.]*\\)>") + "Matches the SCHEDULED keyword together with a time-and-hour stamp.") + +(defconst org-closed-time-regexp + (concat "\\<" org-closed-string " *\\[\\([^]]+\\)\\]") + "Matches the CLOSED keyword together with a time stamp.") + +(defconst org-keyword-time-regexp + (concat "\\<" + (regexp-opt + (list org-scheduled-string org-deadline-string org-closed-string + org-clock-string) + t) + " *[[<]\\([^]>]+\\)[]>]") + "Matches any of the 4 keywords, together with the time stamp.") + +(defconst org-keyword-time-not-clock-regexp + (concat + "\\<" + (regexp-opt + (list org-scheduled-string org-deadline-string org-closed-string) t) + " *[[<]\\([^]>]+\\)[]>]") + "Matches any of the 3 keywords, together with the time stamp.") + +(defconst org-maybe-keyword-time-regexp + (concat "\\(\\<" + (regexp-opt + (list org-scheduled-string org-deadline-string org-closed-string + org-clock-string) + t) + "\\)?" + " *\\([[<][0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\} ?[^]\r\n>]*?[]>]" + "\\|" + "<%%([^\r\n>]*>\\)") + "Matches a timestamp, possibly preceded by a keyword.") + +(defconst org-all-time-keywords + (mapcar (lambda (w) (substring w 0 -1)) + (list org-scheduled-string org-deadline-string + org-clock-string org-closed-string)) + "List of time keywords.") + +;;;; Drawer + +(defconst org-drawer-regexp "^[ \t]*:\\(\\(?:\\w\\|[-_]\\)+\\):[ \t]*$" + "Matches first or last line of a hidden block. +Group 1 contains drawer's name or \"END\".") + +(defconst org-property-start-re "^[ \t]*:PROPERTIES:[ \t]*$" + "Regular expression matching the first line of a property drawer.") + +(defconst org-property-end-re "^[ \t]*:END:[ \t]*$" + "Regular expression matching the last line of a property drawer.") + +(defconst org-clock-drawer-start-re "^[ \t]*:CLOCK:[ \t]*$" + "Regular expression matching the first line of a clock drawer.") + +(defconst org-clock-drawer-end-re "^[ \t]*:END:[ \t]*$" + "Regular expression matching the last line of a clock drawer.") + +(defconst org-property-drawer-re + (concat "^[ \t]*:PROPERTIES:[ \t]*\n" + "\\(?:[ \t]*:\\S-+:\\(?: .*\\)?[ \t]*\n\\)*?" + "[ \t]*:END:[ \t]*$") + "Matches an entire property drawer.") + +(defconst org-clock-drawer-re + (concat "\\(" org-clock-drawer-start-re "\\)[^\000]*?\\(" + org-clock-drawer-end-re "\\)\n?") + "Matches an entire clock drawer.") + +;;;; Headline + +(defconst org-heading-keyword-regexp-format + "^\\(\\*+\\)\\(?: +%s\\)\\(?: +\\(.*?\\)\\)?[ \t]*$" + "Printf format for a regexp matching a headline with some keyword. +This regexp will match the headline of any node which has the +exact keyword that is put into the format. The keyword isn't in +any group by default, but the stars and the body are.") + +(defconst org-heading-keyword-maybe-regexp-format + "^\\(\\*+\\)\\(?: +%s\\)?\\(?: +\\(.*?\\)\\)?[ \t]*$" + "Printf format for a regexp matching a headline, possibly with some keyword. +This regexp can match any headline with the specified keyword, or +without a keyword. The keyword isn't in any group by default, +but the stars and the body are.") + +(defconst org-archive-tag "ARCHIVE" + "The tag that marks a subtree as archived. +An archived subtree does not open during visibility cycling, and does +not contribute to the agenda listings.") + +(defconst org-comment-string "COMMENT" + "Entries starting with this keyword will never be exported. +An entry can be toggled between COMMENT and normal with +\\[org-toggle-comment].") + + +;;;; LaTeX Environments and Fragments + +(defconst org-latex-regexps + '(("begin" "^[ \t]*\\(\\\\begin{\\([a-zA-Z0-9\\*]+\\)[^\000]+?\\\\end{\\2}\\)" 1 t) + ;; ("$" "\\([ (]\\|^\\)\\(\\(\\([$]\\)\\([^ \r\n,.$].*?\\(\n.*?\\)\\{0,5\\}[^ \r\n,.$]\\)\\4\\)\\)\\([ .,?;:'\")]\\|$\\)" 2 nil) + ;; \000 in the following regex is needed for org-inside-LaTeX-fragment-p + ("$1" "\\([^$]\\|^\\)\\(\\$[^ \r\n,;.$]\\$\\)\\(\\s.\\|\\s-\\|\\s(\\|\\s)\\|\\s\"\\|\000\\|$\\)" 2 nil) + ("$" "\\([^$]\\|^\\)\\(\\(\\$\\([^ \r\n,;.$][^$\n\r]*?\\(\n[^$\n\r]*?\\)\\{0,2\\}[^ \r\n,.$]\\)\\$\\)\\)\\(\\s.\\|\\s-\\|\\s(\\|\\s)\\|\\s\"\\|\000\\|$\\)" 2 nil) + ("\\(" "\\\\([^\000]*?\\\\)" 0 nil) + ("\\[" "\\\\\\[[^\000]*?\\\\\\]" 0 nil) + ("$$" "\\$\\$[^\000]*?\\$\\$" 0 nil)) + "Regular expressions for matching embedded LaTeX.") + +;;;; Node Property + +(defconst org-effort-property "Effort" + "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>]*?\\)>" + "Regular expression for fast time stamp matching.") + +(defconst org-ts-regexp-inactive + "\\[\\([0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\} ?[^\r\n>]*?\\)\\]" + "Regular expression for fast inactive time stamp matching.") + +(defconst org-ts-regexp-both "[[<]\\([0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\} ?[^]\r\n>]*?\\)[]>]" + "Regular expression for fast time stamp matching.") + +(defconst org-ts-regexp0 + "\\(\\([0-9]\\{4\\}\\)-\\([0-9]\\{2\\}\\)-\\([0-9]\\{2\\}\\)\\( +[^]+0-9>\r\n -]+\\)?\\( +\\([0-9]\\{1,2\\}\\):\\([0-9]\\{2\\}\\)\\)?\\)" + "Regular expression matching time strings for analysis. +This one does not require the space after the date, so it can be used +on a string that terminates immediately after the date.") + +(defconst org-ts-regexp1 "\\(\\([0-9]\\{4\\}\\)-\\([0-9]\\{2\\}\\)-\\([0-9]\\{2\\}\\) *\\([^]+0-9>\r\n -]*\\)\\( \\([0-9]\\{1,2\\}\\):\\([0-9]\\{2\\}\\)\\)?\\)" + "Regular expression matching time strings for analysis.") + +(defconst org-ts-regexp2 (concat "<" org-ts-regexp1 "[^>\n]\\{0,16\\}>") + "Regular expression matching time stamps, with groups.") + +(defconst org-ts-regexp3 (concat "[[<]" org-ts-regexp1 "[^]>\n]\\{0,16\\}[]>]") + "Regular expression matching time stamps (also [..]), with groups.") + +(defconst org-tr-regexp (concat org-ts-regexp "--?-?" org-ts-regexp) + "Regular expression matching a time stamp range.") + +(defconst org-tr-regexp-both + (concat org-ts-regexp-both "--?-?" org-ts-regexp-both) + "Regular expression matching a time stamp range.") + +(defconst org-tsr-regexp (concat org-ts-regexp "\\(--?-?" + org-ts-regexp "\\)?") + "Regular expression matching a time stamp or time stamp range.") + +(defconst org-tsr-regexp-both + (concat org-ts-regexp-both "\\(--?-?" + org-ts-regexp-both "\\)?") + "Regular expression matching a time stamp or time stamp range. +The time stamps may be either active or inactive.") + +(defconst org-repeat-re + "<[0-9]\\{4\\}-[0-9][0-9]-[0-9][0-9] [^>\n]*?\\([.+]?\\+[0-9]+[hdwmy]\\(/[0-9]+[hdwmy]\\)?\\)" + "Regular expression for specifying repeated events. +After a match, group 1 contains the repeat expression.") + +(defconst org-time-stamp-formats '("<%Y-%m-%d %a>" . "<%Y-%m-%d %a %H:%M>") + "Formats for `format-time-string' which are used for time stamps.") + ;;; The custom variables (defgroup org nil @@ -367,7 +665,8 @@ When MESSAGE is non-nil, display a message with the version." "Set VAR to VALUE and call `org-load-modules-maybe' with the force flag." (set var value) (when (featurep 'org) - (org-load-modules-maybe 'force))) + (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) "Modules that should always be loaded together with org.el. @@ -381,7 +680,7 @@ core modules, nor modules from the CONTRIB directory). Just add symbols to the end of the list. If the package is called org-xyz.el, then you need to add the symbol `xyz', and the package must have a call to: - \(provide 'org-xyz) + (provide \\='org-xyz) For export specific modules, see also `org-export-backends'." :group 'org @@ -419,12 +718,12 @@ For export specific modules, see also `org-export-backends'." (const :tag "C eshell Support for links to working directories in eshell" org-eshell) (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 eww: Store link to url of eww" org-eww) (const :tag "C expiry: Expiry mechanism for Org-mode entries" org-expiry) (const :tag "C favtable: Lookup table of favorite references and links" org-favtable) (const :tag "C git-link: Provide org links to specific file version" org-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 jira: Add a jira:ticket protocol to Org-mode" org-jira) (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) @@ -446,7 +745,7 @@ For export specific modules, see also `org-export-backends'." (const :tag "C wl: Links to Wanderlust folders/messages" org-wl) (repeat :tag "External packages" :inline t (symbol :tag "Package")))) -(defvar org-export--registered-backends) ; From ox.el. +(defvar org-export-registered-backends) ; From ox.el. (declare-function org-export-derived-backend-p "ox" (backend &rest backends)) (declare-function org-export-backend-name "ox" (backend)) (defcustom org-export-backends '(ascii html icalendar latex) @@ -465,26 +764,26 @@ need to make a change while Emacs is running, use the customize interface or run the following code, where VAL stands for the new value of the variable, after updating it: - \(progn - \(setq org-export--registered-backends - \(org-remove-if-not - \(lambda (backend) - \(let ((name (org-export-backend-name backend))) - \(or (memq name val) - \(catch 'parentp - \(dolist (b val) - \(and (org-export-derived-backend-p b name) - \(throw 'parentp t))))))) - org-export--registered-backends)) - \(let ((new-list (mapcar 'org-export-backend-name - org-export--registered-backends))) - \(dolist (backend val) - \(cond - \((not (load (format \"ox-%s\" backend) t t)) - \(message \"Problems while trying to load export back-end `%s'\" + (progn + (setq org-export-registered-backends + (org-remove-if-not + (lambda (backend) + (let ((name (org-export-backend-name backend))) + (or (memq name val) + (catch \\='parentp + (dolist (b val) + (and (org-export-derived-backend-p b name) + (throw \\='parentp t))))))) + org-export-registered-backends)) + (let ((new-list (mapcar #\\='org-export-backend-name + org-export-registered-backends))) + (dolist (backend val) + (cond + ((not (load (format \"ox-%s\" backend) t t)) + (message \"Problems while trying to load export back-end \\=`%s\\='\" backend)) - \((not (memq backend new-list)) (push backend new-list)))) - \(set-default 'org-export-backends new-list))) + ((not (memq backend new-list)) (push backend new-list)))) + (set-default \\='org-export-backends new-list))) Adding a back-end to this list will also pull the back-end it depends on, if any." @@ -498,7 +797,7 @@ depends on, if any." ;; Any back-end not required anymore (not present in VAL and not ;; a parent of any back-end in the new value) is removed from the ;; list of registered back-ends. - (setq org-export--registered-backends + (setq org-export-registered-backends (org-remove-if-not (lambda (backend) (let ((name (org-export-backend-name backend))) @@ -507,11 +806,11 @@ depends on, if any." (dolist (b val) (and (org-export-derived-backend-p b name) (throw 'parentp t))))))) - org-export--registered-backends)) + org-export-registered-backends)) ;; Now build NEW-LIST of both new back-ends and required ;; parents. - (let ((new-list (mapcar 'org-export-backend-name - org-export--registered-backends))) + (let ((new-list (mapcar #'org-export-backend-name + org-export-registered-backends))) (dolist (backend val) (cond ((not (load (format "ox-%s" backend) t t)) @@ -550,6 +849,7 @@ depends on, if any." (defcustom org-support-shift-select nil "Non-nil means make shift-cursor commands select text when possible. +\\\ In Emacs 23, when `shift-select-mode' is on, shifted cursor keys start selecting a region, or enlarge regions started in this way. @@ -576,10 +876,13 @@ if the cursor is exactly on the bullet. If you set this variable to the symbol `always', then the keys will not be special in headlines, property lines, and item lines, to make shift selection work there as well. If this is what you -want, you can use the following alternative commands: `C-c C-t' -and `C-c ,' to change TODO state and priority, `C-u C-u C-c C-t' -can be used to switch TODO sets, `C-c -' to cycle item bullet -types, and properties can be edited by hand or in column view. +want, you can use the following alternative commands: +`\\[org-todo]' and `\\[org-priority]' \ +to change TODO state and priority, +`\\[universal-argument] \\[universal-argument] \\[org-todo]' \ +can be used to switch TODO sets, +`\\[org-ctrl-c-minus]' to cycle item bullet types, +and properties can be edited by hand or in column view. However, when the cursor is on a timestamp, shift-cursor commands will still edit the time stamp - this is just too good to give up. @@ -595,7 +898,7 @@ XEmacs user should have this variable set to nil, because (defcustom org-loop-over-headlines-in-active-region nil "Shall some commands act upon headlines in the active region? -When set to `t', some commands will be performed in all headlines +When set to t, some commands will be performed in all headlines within the active region. When set to `start-level', some commands will be performed in all @@ -827,7 +1130,7 @@ When nil, just use the standard three dots. When a string, use that string instead. When a face, use the standard 3 dots, but with the specified face. The change affects only Org-mode (which will then use its own display table). -Changing this requires executing `M-x org-mode RET' in a buffer to become +Changing this requires executing \\[org-mode] in a buffer to become effective." :group 'org-startup :type '(choice (const :tag "Default" nil) @@ -842,34 +1145,6 @@ effective." :tag "Org Keywords" :group 'org) -(defcustom org-deadline-string "DEADLINE:" - "String to mark deadline entries. -A deadline is this string, followed by a time stamp. Should be a word, -terminated by a colon. You can insert a schedule keyword and -a timestamp with \\[org-deadline]. -Changes become only effective after restarting Emacs." - :group 'org-keywords - :type 'string) - -(defcustom org-scheduled-string "SCHEDULED:" - "String to mark scheduled TODO entries. -A schedule is this string, followed by a time stamp. Should be a word, -terminated by a colon. You can insert a schedule keyword and -a timestamp with \\[org-schedule]. -Changes become only effective after restarting Emacs." - :group 'org-keywords - :type 'string) - -(defcustom org-closed-string "CLOSED:" - "String used as the prefix for timestamps logging closing a TODO entry." - :group 'org-keywords - :type 'string) - -(defcustom org-clock-string "CLOCK:" - "String used as prefix for timestamps clocking work hours on an item." - :group 'org-keywords - :type 'string) - (defcustom org-closed-keep-when-no-todo nil "Remove CLOSED: time-stamp when switching back to a non-todo state?" :group 'org-todo @@ -878,35 +1153,6 @@ Changes become only effective after restarting Emacs." :package-version '(Org . "8.0") :type 'boolean) -(defconst org-planning-or-clock-line-re (concat "^[ \t]*\\(" - org-scheduled-string "\\|" - org-deadline-string "\\|" - org-closed-string "\\|" - org-clock-string "\\)") - "Matches a line with planning or clock info.") - -(defcustom org-comment-string "COMMENT" - "Entries starting with this keyword will never be exported. -An entry can be toggled between COMMENT and normal with -\\[org-toggle-comment]. -Changes become only effective after restarting Emacs." - :group 'org-keywords - :type 'string) - -(defcustom org-quote-string "QUOTE" - "Entries starting with this keyword will be exported in fixed-width font. -Quoting applies only to the text in the entry following the headline, and does -not extend beyond the next headline, even if that is lower level. -An entry can be toggled between QUOTE and normal with -\\[org-toggle-fixed-width-section]." - :group 'org-keywords - :type 'string) - -(defconst org-repeat-re - "<[0-9]\\{4\\}-[0-9][0-9]-[0-9][0-9] [^>\n]*?\\([.+]?\\+[0-9]+[hdwmy]\\(/[0-9]+[hdwmy]\\)?\\)" - "Regular expression for specifying repeated events. -After a match, group 1 contains the repeat expression.") - (defgroup org-structure nil "Options concerning the general structure of Org-mode files." :tag "Org Structure" @@ -917,87 +1163,80 @@ After a match, group 1 contains the repeat expression.") :tag "Org Reveal Location" :group 'org-structure) -(defconst org-context-choice - '(choice - (const :tag "Always" t) - (const :tag "Never" nil) - (repeat :greedy t :tag "Individual contexts" - (cons - (choice :tag "Context" - (const agenda) - (const org-goto) - (const occur-tree) - (const tags-tree) - (const link-search) - (const mark-goto) - (const bookmark-jump) - (const isearch) - (const default)) - (boolean)))) - "Contexts for the reveal options.") - -(defcustom org-show-hierarchy-above '((default . t)) - "Non-nil means show full hierarchy when revealing a location. -Org-mode often shows locations in an org-mode file which might have -been invisible before. When this is set, the hierarchy of headings -above the exposed location is shown. -Turning this off for example for sparse trees makes them very compact. -Instead of t, this can also be an alist specifying this option for different -contexts. Valid contexts are +(defcustom org-show-context-detail '((isearch . lineage) + (bookmark-jump . lineage) + (default . ancestors)) + "Alist between context and visibility span when revealing a location. + +\\Some actions may move point into invisible +locations. As a consequence, Org always expose a neighborhood +around point. How much is shown depends on the initial action, +or context. Valid contexts are + agenda when exposing an entry from the agenda - org-goto when using the command `org-goto' on key C-c C-j - occur-tree when using the command `org-occur' on key C-c / + org-goto when using the command `org-goto' (\\[org-goto]) + occur-tree when using the command `org-occur' (\\[org-sparse-tree] /) tags-tree when constructing a sparse tree based on tags matches link-search when exposing search matches associated with a link mark-goto when exposing the jump goal of a mark bookmark-jump when exposing a bookmark location isearch when exiting from an incremental search - default default for all contexts not set explicitly" - :group 'org-reveal-location - :type org-context-choice) - -(defcustom org-show-following-heading '((default . nil)) - "Non-nil means show following heading when revealing a location. -Org-mode often shows locations in an org-mode file which might have -been invisible before. When this is set, the heading following the -match is shown. -Turning this off for example for sparse trees makes them very compact, -but makes it harder to edit the location of the match. In such a case, -use the command \\[org-reveal] to show more context. -Instead of t, this can also be an alist specifying this option for different -contexts. See `org-show-hierarchy-above' for valid contexts." - :group 'org-reveal-location - :type org-context-choice) - -(defcustom org-show-siblings '((default . nil) (isearch t) (bookmark-jump t)) - "Non-nil means show all sibling heading when revealing a location. -Org-mode often shows locations in an org-mode file which might have -been invisible before. When this is set, the sibling of the current entry -heading are all made visible. If `org-show-hierarchy-above' is t, -the same happens on each level of the hierarchy above the current entry. - -By default this is on for the isearch context, off for all other contexts. -Turning this off for example for sparse trees makes them very compact, -but makes it harder to edit the location of the match. In such a case, -use the command \\[org-reveal] to show more context. -Instead of t, this can also be an alist specifying this option for different -contexts. See `org-show-hierarchy-above' for valid contexts." - :group 'org-reveal-location - :type org-context-choice - :version "24.4" - :package-version '(Org . "8.0")) + default default for all contexts not set explicitly + +Allowed visibility spans are + + minimal show current headline; if point is not on headline, + also show entry + + local show current headline, entry and next headline + + ancestors show current headline and its direct ancestors; if + point is not on headline, also show entry + + lineage show current headline, its direct ancestors and all + their children; if point is not on headline, also show + entry and first child -(defcustom org-show-entry-below '((default . nil)) - "Non-nil means show the entry below a headline when revealing a location. -Org-mode often shows locations in an org-mode file which might have -been invisible before. When this is set, the text below the headline that is -exposed is also shown. + tree show current headline, its direct ancestors and all + their children; if point is not on headline, also show + entry and all children -By default this is off for all contexts. -Instead of t, this can also be an alist specifying this option for different -contexts. See `org-show-hierarchy-above' for valid contexts." + canonical show current headline, its direct ancestors along with + their entries and children; if point is not located on + the headline, also show current entry and all children + +As special cases, a nil or t value means show all contexts in +`minimal' or `canonical' view, respectively. + +Some views can make displayed information very compact, but also +make it harder to edit the location of the match. In such +a case, use the command `org-reveal' (\\[org-reveal]) to show +more context." :group 'org-reveal-location - :type org-context-choice) + :version "25.1" + :package-version '(Org . "8.3") + :type '(choice + (const :tag "Canonical" t) + (const :tag "Minimal" nil) + (repeat :greedy t :tag "Individual contexts" + (cons + (choice :tag "Context" + (const agenda) + (const org-goto) + (const occur-tree) + (const tags-tree) + (const link-search) + (const mark-goto) + (const bookmark-jump) + (const isearch) + (const default)) + (choice :tag "Detail level" + (const minimal) + (const local) + (const ancestors) + (const lineage) + (const tree) + (const canonical)))))) (defcustom org-indirect-buffer-display 'other-window "How should indirect tree buffers be displayed? @@ -1021,7 +1260,13 @@ new-frame Make a new frame each time. Note that in this case (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." +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) @@ -1051,10 +1296,10 @@ commands in the Help buffer using the `?' speed command." (sexp)))))) (defcustom org-bookmark-names-plist - '(:last-capture "org-capture-last-stored" - :last-refile "org-refile-last-stored" - :last-capture-marker "org-capture-last-stored-marker") - "Names for bookmarks automatically set by some Org commands. + '(:last-capture "org-capture-last-stored" + :last-refile "org-refile-last-stored" + :last-capture-marker "org-capture-last-stored-marker") + "Names for bookmarks automatically set by some Org commands. This can provide strings as names for a number of bookmarks Org sets automatically. The following keys are currently implemented: :last-capture @@ -1062,8 +1307,8 @@ automatically. The following keys are currently implemented: :last-refile When a key does not show up in the property list, the corresponding bookmark is not set." - :group 'org-structure - :type 'plist) + :group 'org-structure + :type 'plist) (defgroup org-cycle nil "Options concerning visibility cycling in Org-mode." @@ -1090,23 +1335,6 @@ than its value." (const :tag "No limit" nil) (integer :tag "Maximum level"))) -(defcustom org-drawers '("PROPERTIES" "CLOCK" "LOGBOOK" "RESULTS") - "Names of drawers. Drawers are not opened by cycling on the headline above. -Drawers only open with a TAB on the drawer line itself. A drawer looks like -this: - :DRAWERNAME: - ..... - :END: -The drawer \"PROPERTIES\" is special for capturing properties through -the property API. - -Drawers can be defined on the per-file basis with a line like: - -#+DRAWERS: HIDDEN STATE PROPERTIES" - :group 'org-structure - :group 'org-cycle - :type '(repeat (string :tag "Drawer Name"))) - (defcustom org-hide-block-startup nil "Non-nil means entering Org-mode will fold all blocks. This can also be set in on a per-file basis with @@ -1189,7 +1417,6 @@ the values `folded', `children', or `subtree'." (defcustom org-cycle-hook '(org-cycle-hide-archived-subtrees org-cycle-hide-drawers - org-cycle-hide-inline-tasks org-cycle-show-empty-lines org-optimize-window-after-visibility-change) "Hook that is run after `org-cycle' has changed the buffer visibility. @@ -1199,7 +1426,9 @@ argument is a symbol. After a global state change, it can have the values `overview', `contents', or `all'. After a local state change, it can have the values `folded', `children', or `subtree'." :group 'org-cycle - :type 'hook) + :type 'hook + :version "25.1" + :package-version '(Org . "8.3")) (defgroup org-edit-structure nil "Options concerning structure editing in Org-mode." @@ -1226,23 +1455,25 @@ lines to the buffer: "Non-nil means adapt indentation to outline node level. When this variable is set, Org assumes that you write outlines by -indenting text in each node to align with the headline (after the stars). -The following issues are influenced by this variable: +indenting text in each node to align with the headline (after the +stars). The following issues are influenced by this variable: -- When this is set and the *entire* text in an entry is indented, the - indentation is increased by one space in a demotion command, and - decreased by one in a promotion command. If any line in the entry - body starts with text at column 0, indentation is not changed at all. +- The indentation is increased by one space in a demotion + command, and decreased by one in a promotion command. However, + in the latter case, if shifting some line in the entry body + would alter document structure (e.g., insert a new headline), + indentation is not changed at all. -- Property drawers and planning information is inserted indented when - this variable is set. When nil, they will not be indented. +- Property drawers and planning information is inserted indented + when this variable is set. When nil, they will not be indented. -- TAB indents a line relative to context. The lines below a headline - will be indented when this variable is set. +- TAB indents a line relative to current level. The lines below + a headline will be indented when this variable is set. -Note that this is all about true indentation, by adding and removing -space characters. See also `org-indent.el' which does level-dependent -indentation in a virtual way, i.e. at display time in Emacs." +Note that this is all about true indentation, by adding and +removing space characters. See also `org-indent.el' which does +level-dependent indentation in a virtual way, i.e. at display +time in Emacs." :group 'org-edit-structure :type 'boolean) @@ -1419,8 +1650,7 @@ the list structure." (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. -See also the QUOTE keyword." +When nil, such lines will be treated like ordinary lines." :group 'org-edit-structure :type 'boolean) @@ -1451,10 +1681,12 @@ changed by an edit command." (defcustom org-remove-highlights-with-change t "Non-nil means any change to the buffer will remove temporary highlights. +\\\ Such highlights are created by `org-occur' and `org-clock-display'. -When nil, `C-c C-c needs to be used to get rid of the highlights. -The highlights created by `org-preview-latex-fragment' always need -`C-c C-c' to be removed." +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." :group 'org-sparse-trees :group 'org-time :type 'boolean) @@ -1548,8 +1780,8 @@ links in Org-mode buffers can have an optional tag after a double colon, e.g. [[linkkey:tag][description]] -The 'linkkey' must be a word word, starting with a letter, followed -by letters, numbers, '-' or '_'. +The `linkkey' must be a word 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 @@ -1575,7 +1807,7 @@ See the manual for examples." "Non-nil means Org will display descriptive links. E.g. [[http://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 +description. When set to nil, Org will display the full links literally. You can interactively set the value of this variable by calling @@ -1600,11 +1832,18 @@ adaptive Use relative path for files in the current directory and sub- (const noabbrev) (const adaptive))) -(defcustom org-activate-links '(bracket angle plain radio tag date footnote) - "Types of links that should be activated in Org-mode files. -This is a list of symbols, each leading to the activation of a certain link -type. In principle, it does not hurt to turn on most link types - there may -be a small gain when turning off unused link types. The types are: +(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-mode files. + +This is a list of symbols, each one of them leading to the +highlighting of a certain link type. + +You can still open links that are not highlighted. + +In principle, it does not hurt to turn on highlighting for all +link types. There may be a small gain when turning off unused +link types. The types are: bracket The recommended [[link][description]] or [[link]] links with hiding. angle Links in angular brackets that may contain whitespace like @@ -1615,8 +1854,10 @@ tag Tag settings in a headline (link to tag search). date Time stamps (link to calendar). footnote Footnote labels. -Changing this variable requires a restart of Emacs to become effective." +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) (const :tag "Angular bracket links" angle) @@ -1857,19 +2098,6 @@ window on that directory." :group 'org-link-follow :type 'boolean) -(defcustom org-link-mailto-program '(browse-url "mailto:%a?subject=%s") - "Function and arguments to call for following mailto links. -This is a list with the first element being a Lisp function, and the -remaining elements being arguments to the function. In string arguments, -%a will be replaced by the address, and %s will be replaced by the subject -if one was given like in ." - :group 'org-link-follow - :type '(choice - (const :tag "browse-url" (browse-url-mail "mailto:%a?subject=%s")) - (const :tag "compose-mail" (compose-mail "%a" "%s")) - (const :tag "message-mail" (message-mail "%a" "%s")) - (cons :tag "other" (function) (repeat :tag "argument" sexp)))) - (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 @@ -1888,7 +2116,7 @@ single keystroke rather than having to type \"yes\"." (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)))) + (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." @@ -1914,7 +2142,7 @@ single keystroke rather than having to type \"yes\"." (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)))) + (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." @@ -1982,7 +2210,7 @@ file identifier are filename matches the regexp. If you want to use groups here, use shy groups. - Example: (\"\\.x?html\\'\" . \"firefox %s\") + Example: (\"\\.x?html\\\\='\" . \"firefox %s\") (\"\\(?:xhtml\\|html\\)\" . \"firefox %s\") to open *.html and *.xhtml with firefox. @@ -1998,7 +2226,7 @@ file identifier are In a custom lisp form, you can access the group matches with (match-string n link). - Example: (\"\\.pdf::\\(\\d+\\)\\'\" . \"evince -p %1 %s\") + Example: (\"\\.pdf::\\(\\d+\\)\\\\='\" . \"evince -p %1 %s\") to open [[file:document.pdf::5]] with evince at page 5. `directory' Matches a directory @@ -2065,17 +2293,17 @@ For more examples, see the system specific constants :group 'org) (defcustom org-directory "~/org" - "Directory with org files. + "Directory with Org files. This is just a default location to look for Org files. There is no need -at all to put your files into this directory. It is only used in the +at all to put your files into this directory. It is used in the following situations: 1. When a capture template specifies a target file that is not an absolute path. The path will then be interpreted relative to `org-directory' -2. When a capture note is filed away in an interactive way (when exiting the - note buffer with `C-1 C-c C-c'. The user is prompted for an org file, - with `org-directory' as the default path." +2. When the value of variable `org-agenda-files' is a single file, any + relative paths in this file will be taken as relative to + `org-directory'." :group 'org-refile :group 'org-capture :type 'directory) @@ -2086,9 +2314,7 @@ Used as a fall back file for org-capture.el, for templates that do not specify a target file." :group 'org-refile :group 'org-capture - :type '(choice - (const :tag "Default from remember-data-file" nil) - file)) + :type 'file) (defcustom org-goto-interface 'outline "The default interface to be used for `org-goto'. @@ -2215,12 +2441,15 @@ of the subtree." (defcustom org-refile-use-cache nil "Non-nil means cache refile targets to speed up the process. +\\\ The cache for a particular file will be updated automatically when the buffer has been killed, or when any of the marker used for flagging refile targets no longer points at a live buffer. If you have added new entries to a buffer that might themselves be targets, -you need to clear the cache manually by pressing `C-0 C-c C-w' or, if you -find that easier, `C-u C-u C-u C-c C-w'." +you need to clear the cache manually by pressing `C-0 \\[org-refile]' or, +if you find that easier, \ +`\\[universal-argument] \\[universal-argument] \\[universal-argument] \ +\\[org-refile]'." :group 'org-refile :version "24.1" :type 'boolean) @@ -2245,7 +2474,7 @@ When `full-file-path', include the full file path." "Non-nil means complete the outline path in hierarchical steps. When Org-mode uses the refile interface to select an outline path \(see variable `org-refile-use-outline-path'), the completion of -the path can be done is a single go, or if can be done in steps down +the path can be done in a single go, or it can be done in steps down the headline hierarchy. Going in steps is probably the best if you do not use a special completion package like `ido' or `icicles'. However, when using these packages, going in one step can be very @@ -2254,7 +2483,7 @@ fast, while still showing the whole path to the entry." :type 'boolean) (defcustom org-refile-allow-creating-parent-nodes nil - "Non-nil means allow to create new nodes as refile targets. + "Non-nil means allow the creation of new nodes as refile targets. New nodes are then created by adding \"/new node name\" to the completion of an existing node. When the value of this variable is `confirm', new node creation must be confirmed by the user (recommended). @@ -2353,9 +2582,9 @@ taken from the (otherwise obsolete) variable `org-todo-interpretation'." (lambda (widget) (widget-put widget :args (mapcar - #'(lambda (x) - (widget-convert - (cons 'const x))) + (lambda (x) + (widget-convert + (cons 'const x))) org-todo-interpretation-widgets)) widget)) (repeat @@ -2366,7 +2595,6 @@ taken from the (otherwise obsolete) variable `org-todo-interpretation'." (make-variable-buffer-local 'org-todo-keywords-1) (defvar org-todo-keywords-for-agenda nil) (defvar org-done-keywords-for-agenda nil) -(defvar org-drawers-for-agenda nil) (defvar org-todo-keyword-alist-for-agenda nil) (defvar org-tag-alist-for-agenda nil "Alist of all tags from all agenda files.") @@ -2404,7 +2632,8 @@ more information." (const type))) (defcustom org-use-fast-todo-selection t - "Non-nil means use the fast todo selection scheme with C-c C-t. + "\\\ +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. @@ -2412,8 +2641,9 @@ selection scheme. When nil, fast selection is never used. When the symbol `prefix', it will be used when `org-todo' is called -with a prefix argument, i.e. `C-u C-c C-t' in an Org-mode buffer, and -`C-u t' in an agenda buffer. +with a prefix argument, i.e. `\\[universal-argument] \\[org-todo]' \ +in an Org-mode buffer, and +`\\[universal-argument] t' in an agenda buffer. When t, fast selection is used by default. In this case, the prefix argument forces cycling instead. @@ -2433,6 +2663,9 @@ ALL-HEADLINES means update todo statistics by including headlines with no TODO keyword as well, counting them as not done. A list of TODO keywords means the same, but skip keywords that are not in this list. +When set to a list of two lists, the first list contains keywords +to consider as TODO keywords, the second list contains keywords +to consider as DONE keywords. When this is set, todo statistics is updated in the parent of the current entry each time a todo state is changed." @@ -2442,6 +2675,9 @@ current entry each time a todo state is changed." (const :tag "Yes, including all entries" all-headlines) (repeat :tag "Yes, for TODOs in this list" (string :tag "TODO keyword")) + (list :tag "Yes, for TODOs and DONEs in these lists" + (repeat (string :tag "TODO keyword")) + (repeat (string :tag "DONE keyword"))) (other :tag "No TODO statistics" nil))) (defcustom org-hierarchical-todo-statistics t @@ -2487,7 +2723,7 @@ TODO state changes ------------------ :type todo-state-change :from previous state (keyword as a string), or nil, or a symbol - 'todo' or 'done', to indicate the general type of state. + `todo' or `done', to indicate the general type of state. :to new state, like in :from") (defcustom org-enforce-todo-dependencies nil @@ -2664,20 +2900,23 @@ When nil, only the date will be recorded." (refile . "Refiled on %t") (clock-out . "")) "Headings for notes added to entries. -The value is an alist, with the car being a symbol indicating the note -context, and the cdr is the heading to be used. The heading may also be the -empty string. -%t in the heading will be replaced by a time stamp. -%T will be an active time stamp instead the default inactive one -%d will be replaced by a short-format time stamp. -%D will be replaced by an active short-format time stamp. -%s will be replaced by the new TODO state, in double quotes. -%S will be replaced by the old TODO state, in double quotes. -%u will be replaced by the user name. -%U will be replaced by the full user name. - -In fact, it is not a good idea to change the `state' entry, because -agenda log mode depends on the format of these entries." + +The value is an alist, with the car being a symbol indicating the +note context, and the cdr is the heading to be used. The heading +may also be the empty string. The following placeholders can be +used: + + %t a time stamp. + %T an active time stamp instead the default inactive one + %d a short-format time stamp. + %D an active short-format time stamp. + %s the new TODO state or time stamp (inactive), in double quotes. + %S the old TODO state or time stamp (inactive), in double quotes. + %u the user name. + %U full user name. + +In fact, it is not a good idea to change the `state' entry, +because Agenda Log mode depends on the format of these entries." :group 'org-todo :group 'org-progress :type '(list :greedy t @@ -2716,7 +2955,10 @@ If this variable is set, `org-log-state-notes-insert-after-drawers' will be ignored. You can set the property LOG_INTO_DRAWER to overrule this setting for -a subtree." +a subtree. + +Do not check directly this variable in a Lisp program. Call +function `org-log-into-drawer' instead." :group 'org-todo :group 'org-progress :type '(choice @@ -2727,15 +2969,17 @@ a subtree." (org-defvaralias 'org-log-state-notes-into-drawer 'org-log-into-drawer) (defun org-log-into-drawer () - "Return the value of `org-log-into-drawer', but let properties overrule. -If the current entry has or inherits a LOG_INTO_DRAWER property, it will be -used instead of the default value." + "Name of the log drawer, as a string, or nil. +This is the value of `org-log-into-drawer'. However, if the +current entry has or inherits a LOG_INTO_DRAWER property, it will +be used instead of the default value." (let ((p (org-entry-get nil "LOG_INTO_DRAWER" 'inherit t))) - (cond - ((not p) org-log-into-drawer) - ((equal p "nil") nil) - ((equal p "t") "LOGBOOK") - (t p)))) + (cond ((equal p "nil") nil) + ((equal p "t") "LOGBOOK") + ((stringp p) p) + (p "LOGBOOK") + ((stringp org-log-into-drawer) org-log-into-drawer) + (org-log-into-drawer "LOGBOOK")))) (defcustom org-log-state-notes-insert-after-drawers nil "Non-nil means insert state change notes after any drawers in entry. @@ -2858,25 +3102,14 @@ as an argument and return the numeric priority." (const nil) (function))) -(defgroup org-time nil - "Options concerning time stamps and deadlines in Org-mode." - :tag "Org Time" - :group 'org) - -(defcustom org-insert-labeled-timestamps-at-point nil - "Non-nil means SCHEDULED and DEADLINE timestamps are inserted at point. -When nil, these labeled time stamps are forces into the second line of an -entry, just after the headline. When scheduling from the global TODO list, -the time stamp will always be forced into the second line." - :group 'org-time - :type 'boolean) - -(defconst org-time-stamp-formats '("<%Y-%m-%d %a>" . "<%Y-%m-%d %a %H:%M>") - "Formats for `format-time-string' which are used for time stamps. -It is not recommended to change this constant.") +(defgroup org-time nil + "Options concerning time stamps and deadlines in Org-mode." + :tag "Org Time" + :group 'org) (defcustom org-time-stamp-rounding-minutes '(0 5) "Number of minutes to round time stamps to. +\\\ These are two values, the first applies when first creating a time stamp. The second applies when changing it with the commands `S-up' and `S-down'. When changing the time stamp, this means that it will change in steps @@ -2886,14 +3119,15 @@ When a setting is 0 or 1, insert the time unmodified. Useful rounding numbers should be factors of 60, so for example 5, 10, 15. When this is larger than 1, you can still force an exact time stamp by using -a double prefix argument to a time stamp command like `C-c .' or `C-c !', +a double prefix argument to a time stamp command like \ +`\\[org-time-stamp]' or `\\[org-time-stamp-inactive], and by using a prefix arg to `S-up/down' to specify the exact number of minutes to shift." :group 'org-time - :get #'(lambda (var) ; Make sure both elements are there - (if (integerp (default-value var)) - (list (default-value var) 5) - (default-value var))) + :get (lambda (var) ; Make sure both elements are there + (if (integerp (default-value var)) + (list (default-value var) 5) + (default-value var))) :type '(list (integer :tag "when inserting times") (integer :tag "when modifying times"))) @@ -2957,7 +3191,7 @@ its value is 0. For example, - \(:days \"%dd\" :hours \"%d\" :require-hours t :minutes \":%02d\" + (:days \"%dd\" :hours \"%d\" :require-hours t :minutes \":%02d\" :require-minutes t) means durations longer than a day will be expressed in days, @@ -2967,7 +3201,7 @@ hour). The value - \(:days \"%dd\" :minutes \"%dm\") + (:days \"%dd\" :minutes \"%dm\") means durations longer than a day will be expressed in days and minutes, and durations less than a day will be expressed entirely @@ -3049,9 +3283,9 @@ is used." :group 'org-time :type '(choice (string :tag "Format string") (set (group :inline t (const :tag "Years" :years) - (string :tag "Format string")) + (string :tag "Format string")) (group :inline t (const :tag "Months" :months) - (string :tag "Format string")) + (string :tag "Format string")) (group :inline t (const :tag "Weeks" :weeks) (string :tag "Format string")) (group :inline t (const :tag "Days" :days) @@ -3257,11 +3491,17 @@ See the manual for details." (list :tag "Start radio group" (const :startgroup) (option (string :tag "Group description"))) + (list :tag "Start tag group, non distinct" + (const :startgrouptag) + (option (string :tag "Group description"))) (list :tag "Group tags delimiter" (const :grouptags)) (list :tag "End radio group" (const :endgroup) (option (string :tag "Group description"))) + (list :tag "End tag group, non distinct" + (const :endgrouptag) + (option (string :tag "Group description"))) (const :tag "New line" (:newline))))) (defcustom org-tag-persistent-alist nil @@ -3291,10 +3531,10 @@ Instead of customizing this variable directly, you might want to set it locally for capture buffers, because there no list of tags in that file can be created dynamically (there are none). - (add-hook 'org-capture-mode-hook + (add-hook \\='org-capture-mode-hook (lambda () (set (make-local-variable - 'org-complete-tags-always-offer-all-agenda-tags) + \\='org-complete-tags-always-offer-all-agenda-tags) t)))" :group 'org-tags :version "24.1" @@ -3542,13 +3782,6 @@ or nil if the normal value should be used." :group 'org-properties :type '(choice (const nil) (function))) -(defcustom org-effort-property "Effort" - "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." - :group 'org-properties - :group 'org-progress - :type '(string :tag "Property")) - (defconst org-global-properties-fixed '(("VISIBILITY_ALL" . "folded children content all") ("CLOCK_MODELINE_TOTAL_ALL" . "current today repeat all auto")) @@ -3603,7 +3836,7 @@ or contain a special line If the file does not specify a category, then file's base name is used instead.") (make-variable-buffer-local 'org-category) -(put 'org-category 'safe-local-variable #'(lambda (x) (or (symbolp x) (stringp x)))) +(put 'org-category 'safe-local-variable (lambda (x) (or (symbolp x) (stringp x)))) (defcustom org-agenda-files nil "The files to be used for agenda display. @@ -3634,7 +3867,8 @@ regular expression will be included." (defcustom org-agenda-text-search-extra-files nil "List of extra files to be searched by text search commands. These files will be searched in addition to the agenda files by the -commands `org-search-view' (`C-c a s') and `org-occur-in-agenda-files'. +commands `org-search-view' (`\\[org-agenda] s') \ +and `org-occur-in-agenda-files'. Note that these files will only be searched for text search commands, not for the other agenda views like todo lists, tag searches or the weekly agenda. This variable is intended to list notes and possibly archive files @@ -3752,12 +3986,17 @@ Replace format-specifiers in the command as noted below and use `shell-command' to convert LaTeX to MathML. %j: Executable file in fully expanded form as specified by `org-latex-to-mathml-jar-file'. -%I: Input LaTeX file in fully expanded form -%o: Output MathML file +%I: Input LaTeX file in fully expanded form. +%i: The latex fragment to be converted. +%o: Output MathML file. + This command is used by `org-create-math-formula'. -When using MathToWeb as the converter, set this to -\"java -jar %j -unicode -force -df %o %I\"." +When using MathToWeb as the converter, set this option to +\"java -jar %j -unicode -force -df %o %I\". + +When using LaTeXML set this option to +\"latexmlmath \"%i\" --presentationmathml=%o\"." :group 'org-latex :version "24.1" :type '(choice @@ -3848,18 +4087,16 @@ header, or they will be appended." ("T1" "fontenc" t) ("" "fixltx2e" nil) ("" "graphicx" t) + ("" "grffile" t) ("" "longtable" nil) - ("" "float" nil) ("" "wrapfig" nil) ("" "rotating" nil) ("normalem" "ulem" t) ("" "amsmath" t) ("" "textcomp" t) - ("" "marvosym" t) - ("" "wasysym" t) ("" "amssymb" t) - ("" "hyperref" nil) - "\\tolerance=1000") + ("" "capt-of" nil) + ("" "hyperref" nil)) "Alist of default packages to be inserted in the header. Change this only if one of the packages here causes an @@ -3871,14 +4108,16 @@ Org mode to function properly: - inputenc, fontenc: for basic font and character selection - fixltx2e: Important patches of LaTeX itself - graphicx: for including images +- grffile: allow periods and spaces in graphics file names - longtable: For multipage tables -- float, wrapfig: for figure placement +- wrapfig: for figure placement - rotating: for sideways figures and tables - ulem: for underline and strike-through - amsmath: for subscript and superscript and math environments -- textcomp, marvosymb, wasysym, amssymb: for various symbols used +- textcomp, amssymb: for various symbols used for interpreting the entities in `org-entities'. You can skip some of these packages if you don't use any of their symbols. +- capt-of: for captions outside of floats - hyperref: for cross references Therefore you should not modify this variable unless you know @@ -3887,9 +4126,9 @@ you might be loading some other package that conflicts with one of the default packages. Each element is either a cell or a string. -A cell is of the format: +A cell is of the format - \( \"options\" \"package\" SNIPPET-FLAG). + (\"options\" \"package\" SNIPPET-FLAG) If SNIPPET-FLAG is non-nil, the package also needs to be included when compiling LaTeX snippets into images for inclusion into @@ -3900,7 +4139,8 @@ A string will be inserted as-is in the header of the document." :group 'org-export-latex :set 'org-set-packages-alist :get 'org-get-packages-alist - :version "24.1" + :version "25.1" + :package-version '(Org . "8.3") :type '(repeat (choice (list :tag "options/package pair" @@ -3917,7 +4157,7 @@ Each element is either a cell or a string. A cell is of the format: - \(\"options\" \"package\" SNIPPET-FLAG) + (\"options\" \"package\" SNIPPET-FLAG) SNIPPET-FLAG, when non-nil, indicates that this package is also needed when turning LaTeX snippets into images for inclusion into @@ -3974,7 +4214,7 @@ lines to the buffer: (defcustom org-hidden-keywords nil "List of symbols corresponding to keywords to be hidden the org buffer. -For example, a value '(title) for this list will make the document's title +For example, a value \\='(title) for this list will make the document's title appear in the buffer without the initial #+TITLE: keyword." :group 'org-appearance :version "24.1" @@ -4035,6 +4275,11 @@ following symbols: :group 'org-appearance :type 'boolean) +(defcustom org-hide-macro-markers nil + "Non-nil mean font-lock should hide the brackets marking macro calls." + :group 'org-appearance + :type 'boolean) + (defcustom org-pretty-entities nil "Non-nil means show entities as UTF8 characters. When nil, the \\name form remains in the buffer." @@ -4121,7 +4366,7 @@ After a match, the match groups contain these elements: ;; set this option proved cumbersome. See this message/thread: ;; http://article.gmane.org/gmane.emacs.orgmode/68681 (defvar org-emphasis-regexp-components - '(" \t('\"{" "- \t.,:!?;'\")}\\" " \t\r\n,\"'" "." 1) + '(" \t('\"{" "- \t.,:!?;'\")}\\[" " \t\r\n,\"'" "." 1) "Components used to build the regular expression for emphasis. This is a list with five entries. Terminology: In an emphasis string like \" *strong word* \", we call the initial space PREMATCH, the final @@ -4255,30 +4500,7 @@ Normal means, no org-mode-specific context." (defvar texmathp-why) (declare-function speedbar-line-directory "speedbar" (&optional depth)) (declare-function table--at-cell-p "table" (position &optional object at-column)) - -(defvar org-latex-regexps) - -;;; Autoload and prepare some org modules - -;; Some table stuff that needs to be defined here, because it is used -;; by the functions setting up org-mode or checking for table context. - -(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.") +(declare-function calc-eval "calc" (str &optional separator &rest args)) ;;;###autoload (defun turn-on-orgtbl () @@ -4287,56 +4509,52 @@ This works for both table types.") (orgtbl-mode 1)) (defun org-at-table-p (&optional table-type) - "Return t if the cursor is inside an org-type table. -If TABLE-TYPE is non-nil, also check for table.el-type tables." - (if org-enable-table-editor - (save-excursion - (beginning-of-line 1) - (looking-at (if table-type org-table-any-line-regexp - org-table-line-regexp))) - nil)) + "Non-nil if the cursor is inside an Org table. +If TABLE-TYPE is non-nil, also check for table.el-type tables. +If `org-enable-table-editor' is nil, return nil unconditionally." + (and + org-enable-table-editor + (save-excursion + (beginning-of-line) + (org-looking-at-p (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-element-property :type e) 'org))))))) (defsubst org-table-p () (org-at-table-p)) (defun org-at-table.el-p () - "Return t if and only if we are at a table.el table." - (and (org-at-table-p 'any) - (save-excursion - (goto-char (org-table-begin 'any)) - (looking-at org-table1-hline-regexp)))) + "Non-nil when point is at a table.el table." + (and (save-excursion (beginning-of-line) (looking-at "[ \t]*[|+]")) + (let ((element (org-element-at-point))) + (and (eq (org-element-type element) 'table) + (eq (org-element-property :type element) 'table.el))))) (defun org-table-recognize-table.el () "If there is a table.el table nearby, recognize it and move into it." - (if org-table-tab-recognizes-table.el - (if (org-at-table.el-p) - (progn - (beginning-of-line 1) - (if (looking-at org-table-dataline-regexp) - nil - (if (looking-at org-table1-hline-regexp) - (progn - (beginning-of-line 2) - (if (looking-at org-table-any-border-regexp) - (beginning-of-line -1))))) - (if (re-search-forward "|" (org-table-end t) t) - (progn - (require 'table) - (if (table--at-cell-p (point)) - t - (message "recognizing table.el table...") - (table-recognize-table) - (message "recognizing table.el table...done"))) - (error "This should not happen")) - t) - nil) - nil)) + (when (and org-table-tab-recognizes-table.el (org-at-table.el-p)) + (beginning-of-line) + (unless (or (looking-at org-table-dataline-regexp) + (not (looking-at org-table1-hline-regexp))) + (forward-line) + (when (looking-at org-table-any-border-regexp) + (forward-line -2))) + (if (re-search-forward "|" (org-table-end t) t) + (progn + (require 'table) + (if (table--at-cell-p (point)) t + (message "recognizing table.el table...") + (table-recognize-table) + (message "recognizing table.el table...done"))) + (error "This should not happen")))) (defun org-at-table-hline-p () - "Return t if the cursor is inside a hline in a table." - (if org-enable-table-editor - (save-excursion - (beginning-of-line 1) - (looking-at org-table-hline-regexp)) - nil)) + "Non-nil when point is inside a hline in a table. +Assume point is already in a table. If `org-enable-table-editor' +is nil, return nil unconditionally." + (and org-enable-table-editor + (save-excursion + (beginning-of-line) + (looking-at org-table-hline-regexp)))) (defun org-table-map-tables (function &optional quietly) "Apply FUNCTION to the start of all tables in the buffer." @@ -4346,7 +4564,8 @@ If TABLE-TYPE is non-nil, also check for table.el-type tables." (goto-char (point-min)) (while (re-search-forward org-table-any-line-regexp nil t) (unless quietly - (message "Mapping tables: %d%%" (/ (* 100.0 (point)) (buffer-size)))) + (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 @@ -4363,12 +4582,12 @@ If TABLE-TYPE is non-nil, also check for table.el-type tables." (&optional also-non-dangling-p prompt last-valid)) (defun org-at-TBLFM-p (&optional pos) - "Return t when point (or POS) is in #+TBLFM line." + "Non-nil when point (or POS) is in #+TBLFM line." (save-excursion - (let ((pos pos))) (goto-char (or pos (point))) - (beginning-of-line 1) - (looking-at org-TBLFM-regexp))) + (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) @@ -4468,16 +4687,6 @@ the hierarchy, it will be used." :group 'org-archive :type 'string) -(defcustom org-archive-tag "ARCHIVE" - "The tag that marks a subtree as archived. -An archived subtree does not open during visibility cycling, and does -not contribute to the agenda listings. -After changing this, font-lock must be restarted in the relevant buffers to -get the proper fontification." - :group 'org-archive - :group 'org-keywords - :type 'string) - (defcustom org-agenda-skip-archived-trees t "Non-nil means the agenda will skip any items located in archived trees. An archived tree is a tree marked with the tag ARCHIVE. The use of this @@ -4510,24 +4719,25 @@ collapsed state." :group 'org-sparse-trees :type 'boolean) -(defcustom org-sparse-tree-default-date-type 'scheduled-or-deadline +(defcustom org-sparse-tree-default-date-type nil "The default date type when building a sparse tree. When this is nil, a date is a scheduled or a deadline timestamp. Otherwise, these types are allowed: all: all timestamps active: only active timestamps (<...>) - inactive: only inactive timestamps (<...) + inactive: only inactive timestamps ([...]) scheduled: only scheduled timestamps deadline: only deadline timestamps" - :type '(choice (const :tag "Scheduled or deadline" scheduled-or-deadline) + :type '(choice (const :tag "Scheduled or deadline" nil) (const :tag "All timestamps" all) (const :tag "Only active timestamps" active) (const :tag "Only inactive timestamps" inactive) (const :tag "Only scheduled timestamps" scheduled) (const :tag "Only deadline timestamps" deadline) (const :tag "Only closed timestamps" closed)) - :version "24.3" + :version "25.1" + :package-version '(Org . "8.3") :group 'org-sparse-trees) (defun org-cycle-hide-archived-subtrees (state) @@ -4553,13 +4763,16 @@ Otherwise, these types are allowed: (defun org-hide-archived-subtrees (beg end) "Re-hide all archived subtrees after a visibility state change." - (save-excursion - (let* ((re (concat ":" org-archive-tag ":"))) - (goto-char beg) - (while (re-search-forward re end t) - (when (org-at-heading-p) - (org-flag-subtree t) - (org-end-of-subtree t)))))) + (org-with-wide-buffer + (let ((case-fold-search nil) + (re (concat org-outline-regexp-bol ".*:" org-archive-tag ":"))) + (goto-char beg) + ;; Include headline point is currently on. + (beginning-of-line) + (while (and (< (point) end) (re-search-forward re end t)) + (when (member org-archive-tag (org-get-tags)) + (org-flag-subtree t) + (org-end-of-subtree t)))))) (declare-function outline-end-of-heading "outline" ()) (declare-function outline-flag-region "outline" (from to flag)) @@ -4588,9 +4801,6 @@ Otherwise, these types are allowed: ;;; Variables for pre-computed regular expressions, all buffer local -(defvar org-drawer-regexp "^[ \t]*:PROPERTIES:[ \t]*$" - "Matches first line of a hidden block.") -(make-variable-buffer-local 'org-drawer-regexp) (defvar org-todo-regexp nil "Matches any of the TODO state keywords.") (make-variable-buffer-local 'org-todo-regexp) @@ -4599,7 +4809,7 @@ Otherwise, these types are allowed: (make-variable-buffer-local 'org-not-done-regexp) (defvar org-not-done-heading-regexp nil "Matches a TODO headline that is not done.") -(make-variable-buffer-local 'org-not-done-regexp) +(make-variable-buffer-local 'org-not-done-heading-regexp) (defvar org-todo-line-regexp nil "Matches a headline and puts TODO state into group 2 if present.") (make-variable-buffer-local 'org-todo-line-regexp) @@ -4621,46 +4831,6 @@ TODO state, priority and tags.") "Matches a headline and puts TODO state into group 2 if present. Also put tags into group 4 if tags are present.") (make-variable-buffer-local 'org-todo-line-tags-regexp) -(defvar org-ds-keyword-length 12 - "Maximum length of the DEADLINE and SCHEDULED keywords.") -(make-variable-buffer-local 'org-ds-keyword-length) -(defvar org-deadline-regexp nil - "Matches the DEADLINE keyword.") -(make-variable-buffer-local 'org-deadline-regexp) -(defvar org-deadline-time-regexp nil - "Matches the DEADLINE keyword together with a time stamp.") -(make-variable-buffer-local 'org-deadline-time-regexp) -(defvar org-deadline-time-hour-regexp nil - "Matches the DEADLINE keyword together with a time-and-hour stamp.") -(make-variable-buffer-local 'org-deadline-time-hour-regexp) -(defvar org-deadline-line-regexp nil - "Matches the DEADLINE keyword and the rest of the line.") -(make-variable-buffer-local 'org-deadline-line-regexp) -(defvar org-scheduled-regexp nil - "Matches the SCHEDULED keyword.") -(make-variable-buffer-local 'org-scheduled-regexp) -(defvar org-scheduled-time-regexp nil - "Matches the SCHEDULED keyword together with a time stamp.") -(make-variable-buffer-local 'org-scheduled-time-regexp) -(defvar org-scheduled-time-hour-regexp nil - "Matches the SCHEDULED keyword together with a time-and-hour stamp.") -(make-variable-buffer-local 'org-scheduled-time-hour-regexp) -(defvar org-closed-time-regexp nil - "Matches the CLOSED keyword together with a time stamp.") -(make-variable-buffer-local 'org-closed-time-regexp) - -(defvar org-keyword-time-regexp nil - "Matches any of the 4 keywords, together with the time stamp.") -(make-variable-buffer-local 'org-keyword-time-regexp) -(defvar org-keyword-time-not-clock-regexp nil - "Matches any of the 3 keywords, together with the time stamp.") -(make-variable-buffer-local 'org-keyword-time-not-clock-regexp) -(defvar org-maybe-keyword-time-regexp nil - "Matches a timestamp, possibly preceded by a keyword.") -(make-variable-buffer-local 'org-maybe-keyword-time-regexp) -(defvar org-all-time-keywords nil - "List of time keywords.") -(make-variable-buffer-local 'org-all-time-keywords) (defconst org-plain-time-of-day-regexp (concat @@ -4766,32 +4936,6 @@ in the #+STARTUP line), the corresponding variable, and the value to set this variable to if the option is found. An optional forth element PUSH means to push this value onto the list in the variable.") -(defun org-update-property-plist (key val props) - "Update PROPS with KEY and VAL." - (let* ((appending (string= "+" (substring key (- (length key) 1)))) - (key (if appending (substring key 0 (- (length key) 1)) key)) - (remainder (org-remove-if (lambda (p) (string= (car p) key)) props)) - (previous (cdr (assoc key props)))) - (if appending - (cons (cons key (if previous (concat previous " " val) val)) remainder) - (cons (cons key val) remainder)))) - -(defconst org-block-regexp - "^[ \t]*#\\+begin_?\\([^ \n]+\\)\\(\\([^\n]+\\)\\)?\n\\([^\000]+?\\)#\\+end_?\\1[ \t]*$" - "Regular expression for hiding blocks.") -(defconst org-heading-keyword-regexp-format - "^\\(\\*+\\)\\(?: +%s\\)\\(?: +\\(.*?\\)\\)?[ \t]*$" - "Printf format for a regexp matching a headline with some keyword. -This regexp will match the headline of any node which has the -exact keyword that is put into the format. The keyword isn't in -any group by default, but the stars and the body are.") -(defconst org-heading-keyword-maybe-regexp-format - "^\\(\\*+\\)\\(?: +%s\\)?\\(?: +\\(.*?\\)\\)?[ \t]*$" - "Printf format for a regexp matching a headline, possibly with some keyword. -This regexp can match any headline with the specified keyword, or -without a keyword. The keyword isn't in any group by default, -but the stars and the body are.") - (defcustom org-group-tags t "When non-nil (the default), use group tags. This can be turned on/off through `org-toggle-tags-groups'." @@ -4815,374 +4959,338 @@ Support for group tags is controlled by the option (message "Groups tags support has been turned %s" (if org-group-tags "on" "off"))) -(defun org-set-regexps-and-options-for-tags () - "Precompute variables used for tags." - (when (derived-mode-p 'org-mode) - (org-set-local 'org-file-tags nil) - (let ((re (org-make-options-regexp '("FILETAGS" "TAGS"))) - (splitre "[ \t]+") - (start 0) - tags ftags key value) - (save-excursion - (save-restriction - (widen) - (goto-char (point-min)) - (while (re-search-forward re nil t) - (setq key (upcase (org-match-string-no-properties 1)) - value (org-match-string-no-properties 2)) - (if (stringp value) (setq value (org-trim value))) - (cond - ((equal key "TAGS") - (setq tags (append tags (if tags '("\\n") nil) - (org-split-string value splitre)))) - ((equal key "FILETAGS") - (when (string-match "\\S-" value) - (setq ftags - (append - ftags - (apply 'append - (mapcar (lambda (x) (org-split-string x ":")) - (org-split-string value))))))))))) - ;; Process the file tags. - (and ftags (org-set-local 'org-file-tags - (mapcar 'org-add-prop-inherited ftags))) - (org-set-local 'org-tag-groups-alist nil) - ;; Process the tags. - (when (and (not tags) org-tag-alist) - (setq tags - (mapcar - (lambda (tg) (cond ((eq (car tg) :startgroup) "{") - ((eq (car tg) :endgroup) "}") - ((eq (car tg) :grouptags) ":") - ((eq (car tg) :newline) "\n") - (t (concat (car tg) - (if (characterp (cdr tg)) - (format "(%s)" (char-to-string (cdr tg))) ""))))) - org-tag-alist))) - (let (e tgs g) - (while (setq e (pop tags)) - (cond - ((equal e "{") - (progn (push '(:startgroup) tgs) - (when (equal (nth 1 tags) ":") - (push (list (replace-regexp-in-string - "(.+)$" "" (nth 0 tags))) - org-tag-groups-alist) - (setq g 0)))) - ((equal e ":") (push '(:grouptags) tgs)) - ((equal e "}") (push '(:endgroup) tgs) (if g (setq g nil))) - ((equal e "\\n") (push '(:newline) tgs)) - ((string-match (org-re "^\\([[:alnum:]_@#%]+\\)(\\(.\\))$") e) - (push (cons (match-string 1 e) - (string-to-char (match-string 2 e))) tgs) - (if (and g (> g 0)) - (setcar org-tag-groups-alist - (append (car org-tag-groups-alist) - (list (match-string 1 e))))) - (if g (setq g (1+ g)))) - (t (push (list e) tgs) - (if (and g (> g 0)) - (setcar org-tag-groups-alist - (append (car org-tag-groups-alist) (list e)))) - (if g (setq g (1+ g)))))) - (org-set-local 'org-tag-alist nil) - (while (setq e (pop tgs)) - (or (and (stringp (car e)) - (assoc (car e) org-tag-alist)) - (push e org-tag-alist))) - ;; Return a list with tag variables - (list org-file-tags org-tag-alist org-tag-groups-alist))))) - -(defvar org-ota nil) -(defun org-set-regexps-and-options () - "Precompute regular expressions used in the current buffer." +(defun org-set-regexps-and-options (&optional tags-only) + "Precompute regular expressions used in the current buffer. +When optional argument TAGS-ONLY is non-nil, only compute tags +related expressions." (when (derived-mode-p 'org-mode) - (org-set-local 'org-todo-kwd-alist nil) - (org-set-local 'org-todo-key-alist nil) - (org-set-local 'org-todo-key-trigger nil) - (org-set-local 'org-todo-keywords-1 nil) - (org-set-local 'org-done-keywords nil) - (org-set-local 'org-todo-heads nil) - (org-set-local 'org-todo-sets nil) - (org-set-local 'org-todo-log-states nil) - (org-set-local 'org-file-properties nil) - (let ((re (org-make-options-regexp - '("CATEGORY" "TODO" "COLUMNS" "STARTUP" "ARCHIVE" - "LINK" "PRIORITIES" "CONSTANTS" "PROPERTY" "DRAWERS" - "SETUPFILE" "OPTIONS") - "\\(?:[a-zA-Z][0-9a-zA-Z_]*_TODO\\)")) - (splitre "[ \t]+") - (scripts org-use-sub-superscripts) - kwds kws0 kwsa key log value cat arch const links hw dws - tail sep kws1 prio props drawers ext-setup-or-nil setup-contents - (start 0)) - (save-excursion - (save-restriction - (widen) - (goto-char (point-min)) - (while - (or (and - ext-setup-or-nil - (not org-ota) - (let (ret) - (with-temp-buffer - (insert ext-setup-or-nil) - (let ((major-mode 'org-mode) org-ota) - (setq ret (save-match-data - (org-set-regexps-and-options-for-tags))))) - ;; Append setupfile tags to existing tags - (setq org-ota t) - (setq org-file-tags - (delq nil (append org-file-tags (nth 0 ret))) - org-tag-alist - (delq nil (append org-tag-alist (nth 1 ret))) - org-tag-groups-alist - (delq nil (append org-tag-groups-alist (nth 2 ret)))))) - (and ext-setup-or-nil - (string-match re ext-setup-or-nil start) - (setq start (match-end 0))) - (and (setq ext-setup-or-nil nil start 0) - (re-search-forward re nil t))) - (setq key (upcase (match-string 1 ext-setup-or-nil)) - value (org-match-string-no-properties 2 ext-setup-or-nil)) - (if (stringp value) (setq value (org-trim value))) - (cond - ((equal key "CATEGORY") - (setq cat value)) - ((member key '("SEQ_TODO" "TODO")) - (push (cons 'sequence (org-split-string value splitre)) kwds)) - ((equal key "TYP_TODO") - (push (cons 'type (org-split-string value splitre)) kwds)) - ((string-match "\\`\\([a-zA-Z][0-9a-zA-Z_]*\\)_TODO\\'" key) - ;; general TODO-like setup - (push (cons (intern (downcase (match-string 1 key))) - (org-split-string value splitre)) kwds)) - ((equal key "COLUMNS") - (org-set-local 'org-columns-default-format value)) - ((equal key "LINK") - (when (string-match "^\\(\\S-+\\)[ \t]+\\(.+\\)" value) - (push (cons (match-string 1 value) - (org-trim (match-string 2 value))) - links))) - ((equal key "PRIORITIES") - (setq prio (org-split-string value " +"))) - ((equal key "PROPERTY") - (when (string-match "\\(\\S-+\\)\\s-+\\(.*\\)" value) - (setq props (org-update-property-plist (match-string 1 value) - (match-string 2 value) - props)))) - ((equal key "DRAWERS") - (setq drawers (delete-dups (append org-drawers (org-split-string value splitre))))) - ((equal key "CONSTANTS") - (org-table-set-constants)) - ((equal key "STARTUP") - (let ((opts (org-split-string value splitre)) - l var val) - (while (setq l (pop opts)) - (when (setq l (assoc l org-startup-options)) - (setq var (nth 1 l) val (nth 2 l)) - (if (not (nth 3 l)) - (set (make-local-variable var) val) - (if (not (listp (symbol-value var))) - (set (make-local-variable var) nil)) - (set (make-local-variable var) (symbol-value var)) - (add-to-list var val)))))) - ((equal key "ARCHIVE") - (setq arch value) - (remove-text-properties 0 (length arch) - '(face t fontified t) arch)) - ((equal key "OPTIONS") - (if (string-match "\\([ \t]\\|\\`\\)\\^:\\(t\\|nil\\|{}\\)" value) - (setq scripts (read (match-string 2 value))))) - ((and (equal key "SETUPFILE") - ;; Prevent checking in Gnus messages - (not buffer-read-only)) - (setq setup-contents (org-file-contents - (expand-file-name - (org-remove-double-quotes value)) - 'noerror)) - (if (not ext-setup-or-nil) - (setq ext-setup-or-nil setup-contents start 0) - (setq ext-setup-or-nil - (concat (substring ext-setup-or-nil 0 start) - "\n" setup-contents "\n" - (substring ext-setup-or-nil start))))))) - ;; search for property blocks - (goto-char (point-min)) - (while (re-search-forward org-block-regexp nil t) - (when (equal "PROPERTY" (upcase (match-string 1))) - (setq value (replace-regexp-in-string - "[\n\r]" " " (match-string 4))) - (when (string-match "\\(\\S-+\\)\\s-+\\(.*\\)" value) - (setq props (org-update-property-plist (match-string 1 value) - (match-string 2 value) - props))))))) - (org-set-local 'org-use-sub-superscripts scripts) - (when cat - (org-set-local 'org-category (intern cat)) - (push (cons "CATEGORY" cat) props)) - (when prio - (if (< (length prio) 3) (setq prio '("A" "C" "B"))) - (setq prio (mapcar 'string-to-char prio)) - (org-set-local 'org-highest-priority (nth 0 prio)) - (org-set-local 'org-lowest-priority (nth 1 prio)) - (org-set-local 'org-default-priority (nth 2 prio))) - (and props (org-set-local 'org-file-properties (nreverse props))) - (and drawers (org-set-local 'org-drawers drawers)) - (and arch (org-set-local 'org-archive-location arch)) - (and links (setq org-link-abbrev-alist-local (nreverse links))) - ;; Process the TODO keywords - (unless kwds - ;; Use the global values as if they had been given locally. - (setq kwds (default-value 'org-todo-keywords)) - (if (stringp (car kwds)) - (setq kwds (list (cons org-todo-interpretation - (default-value 'org-todo-keywords))))) - (setq kwds (reverse kwds))) - (setq kwds (nreverse kwds)) - (let (inter kws kw) - (while (setq kws (pop kwds)) - (let ((kws (or - (run-hook-with-args-until-success - 'org-todo-setup-filter-hook kws) - kws))) - (setq inter (pop kws) sep (member "|" kws) - kws0 (delete "|" (copy-sequence kws)) - kwsa nil - kws1 (mapcar - (lambda (x) - ;; 1 2 - (if (string-match "^\\(.*?\\)\\(?:(\\([^!@/]\\)?.*?)\\)?$" x) - (progn - (setq kw (match-string 1 x) - key (and (match-end 2) (match-string 2 x)) - log (org-extract-log-state-settings x)) - (push (cons kw (and key (string-to-char key))) kwsa) - (and log (push log org-todo-log-states)) - kw) - (error "Invalid TODO keyword %s" x))) - kws0) - kwsa (if kwsa (append '((:startgroup)) - (nreverse kwsa) - '((:endgroup)))) - hw (car kws1) - dws (if sep (org-remove-keyword-keys (cdr sep)) (last kws1)) - tail (list inter hw (car dws) (org-last dws)))) - (add-to-list 'org-todo-heads hw 'append) - (push kws1 org-todo-sets) - (setq org-done-keywords (append org-done-keywords dws nil)) - (setq org-todo-key-alist (append org-todo-key-alist kwsa)) - (mapc (lambda (x) (push (cons x tail) org-todo-kwd-alist)) kws1) - (setq org-todo-keywords-1 (append org-todo-keywords-1 kws1 nil))) + (let ((alist (org--setup-collect-keywords + (org-make-options-regexp + (append '("FILETAGS" "TAGS" "SETUPFILE") + (and (not tags-only) + '("ARCHIVE" "CATEGORY" "COLUMNS" "CONSTANTS" + "LINK" "OPTIONS" "PRIORITIES" "PROPERTY" + "SEQ_TODO" "STARTUP" "TODO" "TYP_TODO"))))))) + (org--setup-process-tags + (cdr (assq 'tags alist)) (cdr (assq 'filetags alist))) + (unless tags-only + ;; File properties. + (org-set-local 'org-file-properties (cdr (assq 'property alist))) + ;; Archive location. + (let ((archive (cdr (assq 'archive alist)))) + (when archive (org-set-local 'org-archive-location archive))) + ;; Category. + (let ((cat (org-string-nw-p (cdr (assq 'category alist))))) + (when cat + (org-set-local 'org-category (intern cat)) + (org-set-local 'org-file-properties + (org--update-property-plist + "CATEGORY" cat org-file-properties)))) + ;; Columns. + (let ((column (cdr (assq 'columns alist)))) + (when column (org-set-local 'org-columns-default-format column))) + ;; Constants. + (setq org-table-formula-constants-local (cdr (assq 'constants alist))) + ;; Link abbreviations. + (let ((links (cdr (assq 'link alist)))) + (when links (setq org-link-abbrev-alist-local (nreverse links)))) + ;; Priorities. + (let ((priorities (cdr (assq 'priorities alist)))) + (when priorities + (org-set-local 'org-highest-priority (nth 0 priorities)) + (org-set-local 'org-lowest-priority (nth 1 priorities)) + (org-set-local 'org-default-priority (nth 2 priorities)))) + ;; Scripts. + (let ((scripts (assq 'scripts alist))) + (when scripts + (org-set-local 'org-use-sub-superscripts (cdr scripts)))) + ;; Startup options. + (let ((startup (cdr (assq 'startup alist)))) + (dolist (option startup) + (let ((entry (assoc-string option org-startup-options t))) + (when entry + (let ((var (nth 1 entry)) + (val (nth 2 entry))) + (if (not (nth 3 entry)) (org-set-local var val) + (unless (listp (symbol-value var)) + (org-set-local var nil)) + (add-to-list var val))))))) + ;; TODO keywords. + (org-set-local 'org-todo-kwd-alist nil) + (org-set-local 'org-todo-key-alist nil) + (org-set-local 'org-todo-key-trigger nil) + (org-set-local 'org-todo-keywords-1 nil) + (org-set-local 'org-done-keywords nil) + (org-set-local 'org-todo-heads nil) + (org-set-local 'org-todo-sets nil) + (org-set-local 'org-todo-log-states nil) + (let ((todo-sequences + (or (nreverse (cdr (assq 'todo alist))) + (let ((d (default-value 'org-todo-keywords))) + (if (not (stringp (car d))) d + ;; XXX: Backward compatibility code. + (list (cons org-todo-interpretation d))))))) + (dolist (sequence todo-sequences) + (let* ((sequence (or (run-hook-with-args-until-success + 'org-todo-setup-filter-hook sequence) + sequence)) + (sequence-type (car sequence)) + (keywords (cdr sequence)) + (sep (member "|" keywords)) + names alist) + (dolist (k (remove "|" keywords)) + (unless (string-match "^\\(.*?\\)\\(?:(\\([^!@/]\\)?.*?)\\)?$" + k) + (error "Invalid TODO keyword %s" k)) + (let ((name (match-string 1 k)) + (key (match-string 2 k)) + (log (org-extract-log-state-settings k))) + (push name names) + (push (cons name (and key (string-to-char key))) alist) + (when log (push log org-todo-log-states)))) + (let* ((names (nreverse names)) + (done (if sep (org-remove-keyword-keys (cdr sep)) + (last names))) + (head (car names)) + (tail (list sequence-type head (car done) (org-last done)))) + (add-to-list 'org-todo-heads head 'append) + (push names org-todo-sets) + (setq org-done-keywords (append org-done-keywords done nil)) + (setq org-todo-keywords-1 (append org-todo-keywords-1 names nil)) + (setq org-todo-key-alist + (append org-todo-key-alist + (and alist + (append '((:startgroup)) + (nreverse alist) + '((:endgroup)))))) + (dolist (k names) (push (cons k tail) org-todo-kwd-alist)))))) (setq org-todo-sets (nreverse org-todo-sets) org-todo-kwd-alist (nreverse org-todo-kwd-alist) - org-todo-key-trigger (delq nil (mapcar 'cdr org-todo-key-alist)) - org-todo-key-alist (org-assign-fast-keys org-todo-key-alist))) - ;; Compute the regular expressions and other local variables. - ;; Using `org-outline-regexp-bol' would complicate them much, - ;; because of the fixed white space at the end of that string. - (if (not org-done-keywords) - (setq org-done-keywords (and org-todo-keywords-1 - (list (org-last org-todo-keywords-1))))) - (setq org-ds-keyword-length (+ 2 (max (length org-deadline-string) - (length org-scheduled-string) - (length org-clock-string) - (length org-closed-string))) - org-drawer-regexp - (concat "^[ \t]*:\\(" - (mapconcat 'regexp-quote org-drawers "\\|") - "\\):[ \t]*$") - org-not-done-keywords - (org-delete-all org-done-keywords (copy-sequence org-todo-keywords-1)) - org-todo-regexp - (concat "\\(" - (mapconcat 'regexp-quote org-todo-keywords-1 "\\|") - "\\)") - org-not-done-regexp - (concat "\\(" - (mapconcat 'regexp-quote org-not-done-keywords "\\|") - "\\)") - org-not-done-heading-regexp - (format org-heading-keyword-regexp-format org-not-done-regexp) - org-todo-line-regexp - (format org-heading-keyword-maybe-regexp-format org-todo-regexp) - org-complex-heading-regexp - (concat "^\\(\\*+\\)" - "\\(?: +" org-todo-regexp "\\)?" - "\\(?: +\\(\\[#.\\]\\)\\)?" - "\\(?: +\\(.*?\\)\\)??" - (org-re "\\(?:[ \t]+\\(:[[:alnum:]_@#%:]+:\\)\\)?") - "[ \t]*$") - org-complex-heading-regexp-format - (concat "^\\(\\*+\\)" - "\\(?: +" org-todo-regexp "\\)?" - "\\(?: +\\(\\[#.\\]\\)\\)?" - "\\(?: +" - ;; Stats cookies can be stuck to body. - "\\(?:\\[[0-9%%/]+\\] *\\)*" - "\\(%s\\)" - "\\(?: *\\[[0-9%%/]+\\]\\)*" - "\\)" - (org-re "\\(?:[ \t]+\\(:[[:alnum:]_@#%%:]+:\\)\\)?") - "[ \t]*$") - org-todo-line-tags-regexp - (concat "^\\(\\*+\\)" - "\\(?: +" org-todo-regexp "\\)?" - "\\(?: +\\(.*?\\)\\)??" - (org-re "\\(?:[ \t]+\\(:[[:alnum:]:_@#%]+:\\)\\)?") - "[ \t]*$") - org-deadline-regexp (concat "\\<" org-deadline-string) - org-deadline-time-regexp - (concat "\\<" org-deadline-string " *<\\([^>]+\\)>") - org-deadline-time-hour-regexp - (concat "\\<" org-deadline-string - " *<\\([^>]+[0-9]\\{1,2\\}:[0-9]\\{2\\}[0-9-+:hdwmy \t.]*\\)>") - org-deadline-line-regexp - (concat "\\<\\(" org-deadline-string "\\).*") - org-scheduled-regexp - (concat "\\<" org-scheduled-string) - org-scheduled-time-regexp - (concat "\\<" org-scheduled-string " *<\\([^>]+\\)>") - org-scheduled-time-hour-regexp - (concat "\\<" org-scheduled-string - " *<\\([^>]+[0-9]\\{1,2\\}:[0-9]\\{2\\}[0-9-+:hdwmy \t.]*\\)>") - org-closed-time-regexp - (concat "\\<" org-closed-string " *\\[\\([^]]+\\)\\]") - org-keyword-time-regexp - (concat "\\<\\(" org-scheduled-string - "\\|" org-deadline-string - "\\|" org-closed-string - "\\|" org-clock-string "\\)" - " *[[<]\\([^]>]+\\)[]>]") - org-keyword-time-not-clock-regexp - (concat "\\<\\(" org-scheduled-string - "\\|" org-deadline-string - "\\|" org-closed-string - "\\)" - " *[[<]\\([^]>]+\\)[]>]") - org-maybe-keyword-time-regexp - (concat "\\(\\<\\(" org-scheduled-string - "\\|" org-deadline-string - "\\|" org-closed-string - "\\|" org-clock-string "\\)\\)?" - " *\\([[<][0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\} ?[^]\r\n>]*?[]>]\\|<%%([^\r\n>]*>\\)") - org-all-time-keywords - (mapcar (lambda (w) (substring w 0 -1)) - (list org-scheduled-string org-deadline-string - org-clock-string org-closed-string))) - (setq org-ota nil) - (org-compute-latex-and-related-regexp)))) + org-todo-key-trigger (delq nil (mapcar #'cdr org-todo-key-alist)) + org-todo-key-alist (org-assign-fast-keys org-todo-key-alist)) + ;; Compute the regular expressions and other local variables. + ;; Using `org-outline-regexp-bol' would complicate them much, + ;; because of the fixed white space at the end of that string. + (if (not org-done-keywords) + (setq org-done-keywords + (and org-todo-keywords-1 (last org-todo-keywords-1)))) + (setq org-not-done-keywords + (org-delete-all org-done-keywords + (copy-sequence org-todo-keywords-1)) + org-todo-regexp (regexp-opt org-todo-keywords-1 t) + org-not-done-regexp (regexp-opt org-not-done-keywords t) + org-not-done-heading-regexp + (format org-heading-keyword-regexp-format org-not-done-regexp) + org-todo-line-regexp + (format org-heading-keyword-maybe-regexp-format org-todo-regexp) + org-complex-heading-regexp + (concat "^\\(\\*+\\)" + "\\(?: +" org-todo-regexp "\\)?" + "\\(?: +\\(\\[#.\\]\\)\\)?" + "\\(?: +\\(.*?\\)\\)??" + (org-re "\\(?:[ \t]+\\(:[[:alnum:]_@#%:]+:\\)\\)?") + "[ \t]*$") + org-complex-heading-regexp-format + (concat "^\\(\\*+\\)" + "\\(?: +" org-todo-regexp "\\)?" + "\\(?: +\\(\\[#.\\]\\)\\)?" + "\\(?: +" + ;; Stats cookies can be stuck to body. + "\\(?:\\[[0-9%%/]+\\] *\\)*" + "\\(%s\\)" + "\\(?: *\\[[0-9%%/]+\\]\\)*" + "\\)" + (org-re "\\(?:[ \t]+\\(:[[:alnum:]_@#%%:]+:\\)\\)?") + "[ \t]*$") + org-todo-line-tags-regexp + (concat "^\\(\\*+\\)" + "\\(?: +" org-todo-regexp "\\)?" + "\\(?: +\\(.*?\\)\\)??" + (org-re "\\(?:[ \t]+\\(:[[:alnum:]:_@#%]+:\\)\\)?") + "[ \t]*$")) + (org-compute-latex-and-related-regexp))))) + +(defun org--setup-collect-keywords (regexp &optional files alist) + "Return setup keywords values as an alist. + +REGEXP matches a subset of setup keywords. FILES is a list of +file names already visited. It is used to avoid circular setup +files. ALIST, when non-nil, is the alist computed so far. + +Return value contains the following keys: `archive', `category', +`columns', `constants', `filetags', `link', `priorities', +`property', `scripts', `startup', `tags' and `todo'." + (org-with-wide-buffer + (goto-char (point-min)) + (let ((case-fold-search t)) + (while (re-search-forward regexp nil t) + (let ((element (org-element-at-point))) + (when (eq (org-element-type element) 'keyword) + (let ((key (org-element-property :key element)) + (value (org-element-property :value element))) + (cond + ((equal key "ARCHIVE") + (when (org-string-nw-p value) + (push (cons 'archive value) alist))) + ((equal key "CATEGORY") (push (cons 'category value) alist)) + ((equal key "COLUMNS") (push (cons 'columns value) alist)) + ((equal key "CONSTANTS") + (let* ((constants (assq 'constants alist)) + (store (cdr constants))) + (dolist (pair (org-split-string value)) + (when (string-match "^\\([a-zA-Z0][_a-zA-Z0-9]*\\)=\\(.*\\)" + pair) + (let* ((name (match-string 1 pair)) + (value (match-string 2 pair)) + (old (assoc name store))) + (if old (setcdr old value) + (push (cons name value) store))))) + (if constants (setcdr constants store) + (push (cons 'constants store) alist)))) + ((equal key "FILETAGS") + (when (org-string-nw-p value) + (let ((old (assq 'filetags alist)) + (new (apply #'nconc + (mapcar (lambda (x) (org-split-string x ":")) + (org-split-string value))))) + (if old (setcdr old (append new (cdr old))) + (push (cons 'filetags new) alist))))) + ((equal key "LINK") + (when (string-match "\\`\\(\\S-+\\)[ \t]+\\(.+\\)" value) + (let ((links (assq 'link alist)) + (pair (cons (org-match-string-no-properties 1 value) + (org-match-string-no-properties 2 value)))) + (if links (push pair (cdr links)) + (push (list 'link pair) alist))))) + ((equal key "OPTIONS") + (when (and (org-string-nw-p value) + (string-match "\\^:\\(t\\|nil\\|{}\\)" value)) + (push (cons 'scripts (read (match-string 1 value))) alist))) + ((equal key "PRIORITIES") + (push (cons 'priorities + (let ((prio (org-split-string value))) + (if (< (length prio) 3) '(?A ?C ?B) + (mapcar #'string-to-char prio)))) + alist)) + ((equal key "PROPERTY") + (when (string-match "\\(\\S-+\\)[ \t]+\\(.*\\)" value) + (let* ((property (assq 'property alist)) + (value (org--update-property-plist + (org-match-string-no-properties 1 value) + (org-match-string-no-properties 2 value) + (cdr property)))) + (if property (setcdr property value) + (push (cons 'property value) alist))))) + ((equal key "STARTUP") + (let ((startup (assq 'startup alist))) + (if startup + (setcdr startup + (append (cdr startup) (org-split-string value))) + (push (cons 'startup (org-split-string value)) alist)))) + ((equal key "TAGS") + (let ((tag-cell (assq 'tags alist))) + (if tag-cell + (setcdr tag-cell + (append (cdr tag-cell) + '("\\n") + (org-split-string value))) + (push (cons 'tags (org-split-string value)) alist)))) + ((member key '("TODO" "SEQ_TODO" "TYP_TODO")) + (let ((todo (assq 'todo alist)) + (value (cons (if (equal key "TYP_TODO") 'type 'sequence) + (org-split-string value)))) + (if todo (push value (cdr todo)) + (push (list 'todo value) alist)))) + ((equal key "SETUPFILE") + (unless buffer-read-only ; Do not check in Gnus messages. + (let ((f (and (org-string-nw-p value) + (expand-file-name + (org-remove-double-quotes value))))) + (when (and f (file-readable-p f) (not (member f files))) + (with-temp-buffer + (setq default-directory (file-name-directory f)) + (insert-file-contents f) + (setq alist + ;; Fake Org mode to benefit from cache + ;; without recurring needlessly. + (let ((major-mode 'org-mode)) + (org--setup-collect-keywords + regexp (cons f files) alist))))))))))))))) + alist) + +(defun org--setup-process-tags (tags filetags) + "Precompute variables used for tags. +TAGS is a list of tags and tag group symbols, as strings. +FILETAGS is a list of tags, as strings." + ;; Process the file tags. + (org-set-local 'org-file-tags + (mapcar #'org-add-prop-inherited filetags)) + ;; Provide default tags if no local tags are found. + (when (and (not tags) org-tag-alist) + (setq tags + (mapcar (lambda (tag) + (case (car tag) + (:startgroup "{") + (:endgroup "}") + (:startgrouptag "[") + (:endgrouptag "]") + (:grouptags ":") + (:newline "\\n") + (otherwise (concat (car tag) + (and (characterp (cdr tag)) + (format "(%c)" (cdr tag))))))) + org-tag-alist))) + ;; Process the tags. + (org-set-local 'org-tag-groups-alist nil) + (org-set-local 'org-tag-alist nil) + (let (group-flag) + (while tags + (let ((e (car tags))) + (setq tags (cdr tags)) + (cond + ((equal e "{") + (push '(:startgroup) org-tag-alist) + (when (equal (nth 1 tags) ":") (setq group-flag t))) + ((equal e "}") + (push '(:endgroup) org-tag-alist) + (setq group-flag nil)) + ((equal e "[") + (push '(:startgrouptag) org-tag-alist) + (when (equal (nth 1 tags) ":") (setq group-flag t))) + ((equal e "]") + (push '(:endgrouptag) org-tag-alist) + (setq group-flag nil)) + ((equal e ":") + (push '(:grouptags) org-tag-alist) + (setq group-flag 'append)) + ((equal e "\\n") (push '(:newline) org-tag-alist)) + ((string-match + (org-re (concat "\\`\\([[:alnum:]_@#%]+" + "\\|{.+?}\\)" ; regular expression + "\\(?:(\\(.\\))\\)?\\'")) e) + (let ((tag (match-string 1 e)) + (key (and (match-beginning 2) + (string-to-char (match-string 2 e))))) + (cond ((eq group-flag 'append) + (setcar org-tag-groups-alist + (append (car org-tag-groups-alist) (list tag)))) + (group-flag (push (list tag) org-tag-groups-alist))) + ;; Push all tags in groups, no matter if they already exist. + (unless (and (not group-flag) (assoc tag org-tag-alist)) + (push (cons tag key) org-tag-alist)))))))) + (setq org-tag-alist (nreverse org-tag-alist))) (defun org-file-contents (file &optional noerror) "Return the contents of FILE, as a string." - (if (or (not file) (not (file-readable-p file))) - (if (not noerror) - (error "Cannot read file \"%s\"" file) - (message "Cannot read file \"%s\"" file) - "") - (with-temp-buffer - (insert-file-contents file) - (buffer-string)))) + (if (and file (file-readable-p file)) + (with-temp-buffer + (insert-file-contents file) + (buffer-string)) + (funcall (if noerror 'message 'error) + "Cannot read file \"%s\"%s" + file + (let ((from (buffer-file-name (buffer-base-buffer)))) + (if from (concat " (referenced in file \"" from "\")") ""))))) (defun org-extract-log-state-settings (x) "Extract the log state setting from a TODO keyword string. @@ -5279,6 +5387,7 @@ This variable is set by `org-before-change-function'. (require 'time-date) (unless (fboundp 'time-subtract) (defalias 'time-subtract 'subtract-time)) (require 'easymenu) +(autoload 'easy-menu-add "easymenu") (require 'overlay) ;; (require 'org-macs) moved higher up in the file before it is first used @@ -5329,8 +5438,9 @@ The following commands are available: (define-key org-mode-map [menu-bar show] 'undefined)) (org-load-modules-maybe) - (easy-menu-add org-org-menu) - (easy-menu-add org-tbl-menu) + (when (featurep 'xemacs) + (easy-menu-add org-org-menu) + (easy-menu-add org-tbl-menu)) (org-install-agenda-files-menu) (if org-descriptive-links (add-to-invisibility-spec '(org-link))) (add-to-invisibility-spec '(org-cwidth)) @@ -5349,10 +5459,9 @@ The following commands are available: org-display-table 4 (vconcat (mapcar (lambda (c) (make-glyph-code c (and (not (stringp org-ellipsis)) - org-ellipsis))) + org-ellipsis))) (if (stringp org-ellipsis) org-ellipsis "...")))) (setq buffer-display-table org-display-table)) - (org-set-regexps-and-options-for-tags) (org-set-regexps-and-options) (org-set-font-lock-defaults) (when (and org-tag-faces (not org-tags-special-faces-re)) @@ -5386,6 +5495,8 @@ The following commands are available: (org-setup-filling) ;; Comments. (org-setup-comments-handling) + ;; Initialize cache. + (org-element-cache-reset) ;; Beginning/end of defun (org-set-local 'beginning-of-defun-function 'org-backward-element) (org-set-local 'end-of-defun-function @@ -5413,7 +5524,7 @@ The following commands are available: (org-set-local 'align-mode-rules-list '((org-in-buffer-settings - (regexp . "^#\\+[A-Z_]+:\\(\\s-*\\)\\S-+") + (regexp . "^[ \t]*#\\+[A-Z_]+:\\(\\s-*\\)\\S-+") (modes . '(org-mode))))) ;; Imenu @@ -5455,9 +5566,10 @@ The following commands are available: (when org-startup-with-inline-images (org-display-inline-images)) (when org-startup-with-latex-preview - (org-preview-latex-fragment)) + (org-toggle-latex-fragment)) (unless org-inhibit-startup-visibility-stuff - (org-set-startup-visibility)))) + (org-set-startup-visibility)) + (org-refresh-effort-properties))) ;; Try to set org-hide correctly (let ((foreground (org-find-invisible-foreground))) (if foreground @@ -5467,10 +5579,10 @@ The following commands are available: (add-to-list 'customize-package-emacs-version-alist '(Org ("6.21b" . "23.1") ("6.33x" . "23.2") ("7.8.11" . "24.1") ("7.9.4" . "24.3") - ("8.2.6" . "24.4"))) + ("8.2.6" . "24.4") ("8.3" . "25.1"))) (defvar org-mode-transpose-word-syntax-table - (let ((st (make-syntax-table))) + (let ((st (make-syntax-table text-mode-syntax-table))) (mapc (lambda(c) (modify-syntax-entry (string-to-char (car c)) "w p" st)) org-emphasis-alist) @@ -5480,8 +5592,6 @@ The following commands are available: (abbrev-table-put org-mode-abbrev-table :parents (list text-mode-abbrev-table))) -(put 'org-mode 'flyspell-mode-predicate 'org-mode-flyspell-verify) - (defun org-find-invisible-foreground () (let ((candidates (remove "unspecified-bg" @@ -5534,8 +5644,9 @@ the rounding returns a past time." (require 'font-lock) (defconst org-non-link-chars "]\t\n\r<>") -(defvar org-link-types '("http" "https" "ftp" "mailto" "file" "news" - "shell" "elisp" "doi" "message")) +(defvar org-link-types '("http" "https" "ftp" "mailto" "file" "file+emacs" + "file+sys" "news" "shell" "elisp" "doi" "message" + "help")) (defvar org-link-types-re nil "Matches a link that has a url-like prefix like \"http:\"") (defvar org-link-re-with-space nil @@ -5584,21 +5695,20 @@ stacked delimiters is N. Escaping delimiters is not possible." next (concat "\\(?:" nothing left next right "\\)+" nothing))) (concat left "\\(" re "\\)" right))) -(defvar org-match-substring-regexp +(defconst org-match-substring-regexp (concat "\\(\\S-\\)\\([_^]\\)\\(" - "\\(" (org-create-multibrace-regexp "{" "}" org-match-sexp-depth) "\\)" + "\\(?:" (org-create-multibrace-regexp "{" "}" org-match-sexp-depth) "\\)" "\\|" - "\\(" (org-create-multibrace-regexp "(" ")" org-match-sexp-depth) "\\)" + "\\(?:" (org-create-multibrace-regexp "(" ")" org-match-sexp-depth) "\\)" "\\|" - "\\(\\(?:\\*\\|[-+]?[^-+*!@#$%^_ \t\r\n,:\"?<>~;./{}=()]+\\)\\)\\)") + "\\(?:\\*\\|[+-]?[[:alnum:].,\\]*[[:alnum:]]\\)\\)") "The regular expression matching a sub- or superscript.") -(defvar org-match-substring-with-braces-regexp +(defconst org-match-substring-with-braces-regexp (concat - "\\(\\S-\\)\\([_^]\\)\\(" - "\\(" (org-create-multibrace-regexp "{" "}" org-match-sexp-depth) "\\)" - "\\)") + "\\(\\S-\\)\\([_^]\\)" + "\\(" (org-create-multibrace-regexp "{" "}" org-match-sexp-depth) "\\)") "The regular expression matching a sub- or superscript, forcing braces.") (defun org-make-link-regexps () @@ -5622,10 +5732,8 @@ This should be called after the variable `org-link-types' has changed." "\\([^" org-non-link-chars " ]" "[^\t\n\r]*\\)") org-angle-link-re - (concat "<" types-re ":" - "\\([^" org-non-link-chars " ]" - "[^" org-non-link-chars "]*" - "\\)>") + (format "<%s:\\([^>\n]*\\(?:\n[ \t]*[^> \t\n][^>\n]*\\)*\\)>" + types-re) org-plain-link-re (concat "\\<" types-re ":" @@ -5656,39 +5764,10 @@ This should be called after the variable `org-link-types' has changed." (org-make-link-regexps) -(defconst org-ts-regexp "<\\([0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\} ?[^\r\n>]*?\\)>" - "Regular expression for fast time stamp matching.") -(defconst org-ts-regexp-both "[[<]\\([0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\} ?[^]\r\n>]*?\\)[]>]" - "Regular expression for fast time stamp matching.") -(defconst org-ts-regexp0 - "\\(\\([0-9]\\{4\\}\\)-\\([0-9]\\{2\\}\\)-\\([0-9]\\{2\\}\\)\\( +[^]+0-9>\r\n -]+\\)?\\( +\\([0-9]\\{1,2\\}\\):\\([0-9]\\{2\\}\\)\\)?\\)" - "Regular expression matching time strings for analysis. -This one does not require the space after the date, so it can be used -on a string that terminates immediately after the date.") -(defconst org-ts-regexp1 "\\(\\([0-9]\\{4\\}\\)-\\([0-9]\\{2\\}\\)-\\([0-9]\\{2\\}\\) *\\([^]+0-9>\r\n -]*\\)\\( \\([0-9]\\{1,2\\}\\):\\([0-9]\\{2\\}\\)\\)?\\)" - "Regular expression matching time strings for analysis.") -(defconst org-ts-regexp2 (concat "<" org-ts-regexp1 "[^>\n]\\{0,16\\}>") - "Regular expression matching time stamps, with groups.") -(defconst org-ts-regexp3 (concat "[[<]" org-ts-regexp1 "[^]>\n]\\{0,16\\}[]>]") - "Regular expression matching time stamps (also [..]), with groups.") -(defconst org-tr-regexp (concat org-ts-regexp "--?-?" org-ts-regexp) - "Regular expression matching a time stamp range.") -(defconst org-tr-regexp-both - (concat org-ts-regexp-both "--?-?" org-ts-regexp-both) - "Regular expression matching a time stamp range.") -(defconst org-tsr-regexp (concat org-ts-regexp "\\(--?-?" - org-ts-regexp "\\)?") - "Regular expression matching a time stamp or time stamp range.") -(defconst org-tsr-regexp-both - (concat org-ts-regexp-both "\\(--?-?" - org-ts-regexp-both "\\)?") - "Regular expression matching a time stamp or time stamp range. -The time stamps may be either active or inactive.") - (defvar org-emph-face nil) (defun org-do-emphasis-faces (limit) - "Run through the buffer and add overlays to emphasized strings." + "Run through the buffer and emphasize strings." (let (rtn a) (while (and (not rtn) (re-search-forward org-emph-re limit t)) (let* ((border (char-after (match-beginning 3))) @@ -5769,23 +5848,21 @@ prompted for." (add-text-properties (1- pos) pos (list 'rear-nonsticky org-nonsticky-props))) (defun org-activate-plain-links (limit) - "Run through the buffer and add overlays to links." - (let (f hl) - (when (and (re-search-forward (concat org-plain-link-re) limit t) - (not (org-in-src-block-p))) - (org-remove-flyspell-overlays-in (match-beginning 0) (match-end 0)) - (setq f (get-text-property (match-beginning 0) 'face)) - (setq hl (org-match-string-no-properties 0)) - (if (or (eq f 'org-tag) - (and (listp f) (memq 'org-tag f))) - nil + "Add link properties for plain links." + (when (and (re-search-forward org-plain-link-re limit t) + (not (org-in-src-block-p))) + (let ((face (get-text-property (max (1- (match-beginning 0)) (point-min)) + 'face)) + (link (org-match-string-no-properties 0))) + (unless (if (consp face) (memq 'org-tag face) (eq 'org-tag face)) + (org-remove-flyspell-overlays-in (match-beginning 0) (match-end 0)) (add-text-properties (match-beginning 0) (match-end 0) (list 'mouse-face 'highlight 'face 'org-link - 'htmlize-link `(:uri ,hl) + 'htmlize-link `(:uri ,link) 'keymap org-mouse-map)) - (org-rear-nonsticky-at (match-end 0))) - t))) + (org-rear-nonsticky-at (match-end 0)) + t)))) (defun org-activate-code (limit) (if (re-search-forward "^[ \t]*\\(:\\(?: .*\\|$\\)\n?\\)" limit t) @@ -5795,10 +5872,11 @@ prompted for." '(display t invisible t intangible t)) t))) -(defcustom org-src-fontify-natively nil +(defcustom org-src-fontify-natively t "When non-nil, fontify code in code blocks." :type 'boolean - :version "24.1" + :version "24.4" + :package-version '(Org . "8.3") :group 'org-appearance :group 'org-babel) @@ -5830,17 +5908,6 @@ by a #." (dc3 (downcase (match-string 3))) end end1 quoting block-type ovl) (cond - ((member dc1 '("+html:" "+ascii:" "+latex:")) - ;; a single line of backend-specific content - (org-remove-flyspell-overlays-in (match-beginning 0) (match-end 0)) - (remove-text-properties (match-beginning 0) (match-end 0) - '(display t invisible t intangible t)) - (add-text-properties (match-beginning 1) (match-end 3) - '(font-lock-fontified t face org-meta-line)) - (add-text-properties (match-beginning 6) (+ (match-end 6) 1) - '(font-lock-fontified t face org-block)) - ; for backend-specific code - t) ((and (match-end 4) (equal dc3 "+begin")) ;; Truly a block (setq block-type (downcase (match-string 5)) @@ -5852,26 +5919,20 @@ by a #." end1 (min (point-max) (1- (match-beginning 0)))) (setq block-end (match-beginning 0)) (when quoting + (org-remove-flyspell-overlays-in beg1 end1) (remove-text-properties beg end '(display t invisible t intangible t))) (add-text-properties - beg end - '(font-lock-fontified t font-lock-multiline t)) + beg end '(font-lock-fontified t font-lock-multiline t)) (add-text-properties beg beg1 '(face org-meta-line)) - (add-text-properties end1 (min (point-max) (1+ end)) - '(face org-meta-line)) ; for end_src + (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) (cond ((and lang (not (string= lang "")) org-src-fontify-natively) (org-src-font-lock-fontify-block lang block-start block-end) - ;; remove old background overlays - (mapc (lambda (ov) - (if (eq (overlay-get ov 'face) 'org-block-background) - (delete-overlay ov))) - (overlays-at (/ (+ beg1 block-end) 2))) - ;; add a background overlay - (setq ovl (make-overlay beg1 block-end)) - (overlay-put ovl 'face 'org-block-background) - (overlay-put ovl 'evaporate t)) ;; make it go away when empty + (add-text-properties beg1 block-end '(src-block t))) (quoting (add-text-properties beg1 (min (point-max) (1+ end1)) '(face org-block))) ; end of source block @@ -5880,11 +5941,14 @@ by a #." (add-text-properties beg1 (min (point-max) (1+ end1)) '(face org-quote))) ((string= block-type "verse") (add-text-properties beg1 (min (point-max) (1+ end1)) '(face org-verse)))) - (add-text-properties beg beg1 '(face org-block-begin-line)) - (add-text-properties (min (point-max) (1+ end)) (min (point-max) (1+ end1)) + (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)) t)) ((member dc1 '("+title:" "+author:" "+email:" "+date:")) + (org-remove-flyspell-overlays-in + (match-beginning 0) + (if (equal "+title:" dc1) (match-end 2) (match-end 0))) (add-text-properties beg (match-end 3) (if (member (intern (substring dc1 1 -1)) org-hidden-keywords) @@ -5893,60 +5957,91 @@ by a #." (add-text-properties (match-beginning 6) (min (point-max) (1+ (match-end 6))) (if (string-equal dc1 "+title:") - '(font-lock-fontified t face org-document-title) + '(font-lock-fontified t face org-document-title) '(font-lock-fontified t face org-document-info)))) - ((or (equal dc1 "+results") - (member dc1 '("+begin:" "+end:" "+caption:" "+label:" - "+orgtbl:" "+tblfm:" "+tblname:" "+results:" - "+call:" "+header:" "+headers:" "+name:")) - (and (match-end 4) (equal dc3 "+attr"))) - (add-text-properties - beg (match-end 0) - '(font-lock-fontified t face org-meta-line)) + ((equal dc1 "+caption:") + (org-remove-flyspell-overlays-in (match-end 2) (match-end 0)) + (remove-text-properties (match-beginning 0) (match-end 0) + '(display t invisible t intangible t)) + (add-text-properties (match-beginning 1) (match-end 3) + '(font-lock-fontified t face org-meta-line)) + (add-text-properties (match-beginning 6) (+ (match-end 6) 1) + '(font-lock-fontified t face org-block)) t) ((member dc3 '(" " "")) + (org-remove-flyspell-overlays-in beg (match-end 0)) (add-text-properties beg (match-end 0) '(font-lock-fontified t face font-lock-comment-face))) - ((not (member (char-after beg) '(?\ ?\t))) - ;; just any other in-buffer setting, but not indented - (add-text-properties - beg (match-end 0) - '(font-lock-fontified t face org-meta-line)) - t) - (t nil)))))) + (t ;; just any other in-buffer setting, but not indented + (org-remove-flyspell-overlays-in (match-beginning 0) (match-end 0)) + (remove-text-properties (match-beginning 0) (match-end 0) + '(display t invisible t intangible t)) + (add-text-properties beg (match-end 0) + '(font-lock-fontified t face org-meta-line)) + t)))))) + +(defun org-fontify-drawers (limit) + "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)) + t)) + +(defun org-fontify-macros (limit) + "Fontify macros." + (when (re-search-forward "\\({{{\\).+?\\(}}}\\)" limit t) + (add-text-properties + (match-beginning 0) (match-end 0) + '(font-lock-fontified t face org-macro)) + (when org-hide-macro-markers + (add-text-properties (match-end 2) (match-beginning 2) + '(invisible t)) + (add-text-properties (match-beginning 1) (match-end 1) + '(invisible t))) + (org-remove-flyspell-overlays-in (match-beginning 0) (match-end 0)) + t)) (defun org-activate-angle-links (limit) - "Run through the buffer and add overlays to links." + "Add text properties for angle links." (if (and (re-search-forward org-angle-link-re limit t) (not (org-in-src-block-p))) (progn (org-remove-flyspell-overlays-in (match-beginning 0) (match-end 0)) (add-text-properties (match-beginning 0) (match-end 0) (list 'mouse-face 'highlight - 'keymap org-mouse-map)) + 'keymap org-mouse-map + 'font-lock-multiline t)) (org-rear-nonsticky-at (match-end 0)) t))) (defun org-activate-footnote-links (limit) - "Run through the buffer and add overlays to footnotes." + "Add text properties for footnotes." (let ((fn (org-footnote-next-reference-or-definition limit))) (when fn - (let ((beg (nth 1 fn)) (end (nth 2 fn))) - (org-remove-flyspell-overlays-in beg end) + (let* ((beg (nth 1 fn)) + (end (nth 2 fn)) + (label (car fn)) + (referencep (/= (line-beginning-position) beg))) + (when (and referencep (nth 3 fn)) + (save-excursion + (goto-char beg) + (search-forward (or label "fn:")) + (org-remove-flyspell-overlays-in beg (match-end 0)))) (add-text-properties beg end (list 'mouse-face 'highlight 'keymap org-mouse-map 'help-echo - (if (= (point-at-bol) beg) - "Footnote definition" - "Footnote reference") + (if referencep "Footnote reference" + "Footnote definition") 'font-lock-fontified t 'font-lock-multiline t 'face 'org-footnote)))))) (defun org-activate-bracket-links (limit) - "Run through the buffer and add overlays to bracketed links." + "Add text properties for bracketed links." (if (and (re-search-forward org-bracket-link-regexp limit t) (not (org-in-src-block-p))) (let* ((hl (org-match-string-no-properties 1)) @@ -5981,7 +6076,7 @@ by a #." t))) (defun org-activate-dates (limit) - "Run through the buffer and add overlays to dates." + "Add text properties for dates." (if (and (re-search-forward org-tsr-regexp-both limit t) (not (equal (char-before (match-beginning 0)) 91))) (progn @@ -5999,35 +6094,82 @@ by a #." (defvar org-target-link-regexp nil "Regular expression matching radio targets in plain text.") (make-variable-buffer-local 'org-target-link-regexp) -(defvar org-target-regexp "<<\\([^<>\n\r]+\\)>>" + +(defconst org-target-regexp (let ((border "[^<>\n\r \t]")) + (format "<<\\(%s\\|%s[^<>\n\r]*%s\\)>>" + border border border)) "Regular expression matching a link target.") -(defvar org-radio-target-regexp "<<<\\([^<>\n\r]+\\)>>>" + +(defconst org-radio-target-regexp (format "<%s>" org-target-regexp) "Regular expression matching a radio target.") -(defvar org-any-target-regexp "<<\n\r]+\\)>>>?" ; FIXME, not exact, would match <<> as 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) - "Run through the buffer and add overlays to target matches." + "Add text properties for target matches." (when org-target-link-regexp (let ((case-fold-search t)) (if (re-search-forward org-target-link-regexp limit t) (progn - (org-remove-flyspell-overlays-in (match-beginning 0) (match-end 0)) - (add-text-properties (match-beginning 0) (match-end 0) + (org-remove-flyspell-overlays-in (match-beginning 1) (match-end 1)) + (add-text-properties (match-beginning 1) (match-end 1) (list 'mouse-face 'highlight 'keymap org-mouse-map 'help-echo "Radio target link" 'org-linked-text t)) - (org-rear-nonsticky-at (match-end 0)) + (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." + "Find all radio targets in this file and update the regular expression. +Also refresh fontification if needed." (interactive) - (when (memq 'radio org-activate-links) + (let ((old-regexp org-target-link-regexp) + (before-re "\\(?:^\\|[^[:alnum:]]\\)\\(") + (after-re "\\)\\(?:$\\|[^[:alnum:]]\\)") + (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) + (add-to-list 'rtn (org-element-property :value obj))))) + rtn)))) (setq org-target-link-regexp - (org-make-target-link-regexp (org-all-targets 'radio))) - (org-restart-font-lock))) + (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))))) (defun org-hide-wide-columns (limit) (let (s e) @@ -6041,8 +6183,6 @@ by a #." (defvar org-latex-and-related-regexp nil "Regular expression for highlighting LaTeX, entities and sub/superscript.") -(defvar org-match-substring-regexp) -(defvar org-match-substring-with-braces-regexp) (defun org-compute-latex-and-related-regexp () "Compute regular expression for LaTeX, entities and sub/superscript. @@ -6095,63 +6235,32 @@ done, nil otherwise." (font-lock-mode -1) (font-lock-mode 1))) -(defun org-all-targets (&optional radio) - "Return a list of all targets in this file. -When optional argument RADIO is non-nil, only find radio -targets." - (let ((re (if radio org-radio-target-regexp org-target-regexp)) rtn) - (save-excursion - (goto-char (point-min)) - (while (re-search-forward re nil t) - ;; Make sure point is really within the object. - (backward-char) - (let ((obj (org-element-context))) - (when (memq (org-element-type obj) '(radio-target target)) - (add-to-list 'rtn (downcase (org-element-property :value obj)))))) - rtn))) - -(defun org-make-target-link-regexp (targets) - "Make regular expression matching all strings in TARGETS. -The regular expression finds the targets also if there is a line break -between words." - (and targets - (concat - "\\_<\\(" - (mapconcat - (lambda (x) - (setq x (regexp-quote x)) - (while (string-match " +" x) - (setq x (replace-match "\\s-+" t t x))) - x) - targets - "\\|") - "\\)\\_>"))) - (defun org-activate-tags (limit) - (if (re-search-forward (org-re "^\\*+.*[ \t]\\(:[[:alnum:]_@#%:]+:\\)[ \r\n]") limit t) - (progn - (org-remove-flyspell-overlays-in (match-beginning 1) (match-end 1)) - (add-text-properties (match-beginning 1) (match-end 1) - (list 'mouse-face 'highlight - 'keymap org-mouse-map)) - (org-rear-nonsticky-at (match-end 1)) - t))) + (when (re-search-forward + (org-re "^\\*+.*[ \t]\\(:[[:alnum:]_@#%:]+:\\)[ \t]*$") limit t) + (org-remove-flyspell-overlays-in (match-beginning 1) (match-end 1)) + (add-text-properties (match-beginning 1) (match-end 1) + (list 'mouse-face 'highlight + 'keymap org-mouse-map)) + (org-rear-nonsticky-at (match-end 1)) + t)) (defun org-outline-level () "Compute the outline level of the heading at point. -If this is called at a normal headline, the level is the number of stars. -Use `org-reduced-level' to remove the effect of `org-odd-levels'." - (save-excursion - (if (not (condition-case nil - (org-back-to-heading t) - (error nil))) - 0 - (looking-at org-outline-regexp) - (1- (- (match-end 0) (match-beginning 0)))))) + +If this is called at a normal headline, the level is the number +of stars. Use `org-reduced-level' to remove the effect of +`org-odd-levels'. Unlike to `org-current-level', this function +takes into consideration inlinetasks." + (org-with-wide-buffer + (end-of-line) + (if (re-search-backward org-outline-regexp-bol nil t) + (1- (- (match-end 0) (match-beginning 0))) + 0))) (defvar org-font-lock-keywords nil) -(defsubst org-re-property (property &optional literal allow-null) +(defsubst org-re-property (property &optional literal allow-null value) "Return a regexp matching a PROPERTY line. When optional argument LITERAL is non-nil, do not quote PROPERTY. @@ -6159,17 +6268,25 @@ This is useful when PROPERTY is a regexp. When ALLOW-NULL is non-nil, match properties even without a value. Match group 3 is set to the value when it exists. If there is no -value and ALLOW-NULL is non-nil, it is set to the empty string." +value and ALLOW-NULL is non-nil, it is set to the empty string. + +With optional argument VALUE, match only property lines with +that value; in this case, ALLOW-NULL is ignored. VALUE is quoted +unless LITERAL is non-nil." (concat "^\\(?4:[ \t]*\\)" (format "\\(?1::\\(?2:%s\\):\\)" (if literal property (regexp-quote property))) - (if allow-null - "\\(?:\\(?3:$\\)\\|[ \t]+\\(?3:.*?\\)\\)\\(?5:[ \t]*\\)$" - "[ \t]+\\(?3:[^ \r\t\n]+.*?\\)\\(?5:[ \t]*\\)$"))) + (cond (value + (format "[ \t]+\\(?3:%s\\)\\(?5:[ \t]*\\)$" + (if literal value (regexp-quote value)))) + (allow-null + "\\(?:\\(?3:$\\)\\|[ \t]+\\(?3:.*?\\)\\)\\(?5:[ \t]*\\)$") + (t + "[ \t]+\\(?3:[^ \r\t\n]+.*?\\)\\(?5:[ \t]*\\)$")))) (defconst org-property-re - (org-re-property ".*?" 'literal t) + (org-re-property "\\S-+" 'literal t) "Regular expression matching a property line. There are four matching groups: 1: :PROPKEY: including the leading and trailing colon, @@ -6194,7 +6311,7 @@ needs to be inserted at a specific position in the font-lock sequence.") (defun org-set-font-lock-defaults () "Set font lock defaults for the current buffer." (let* ((em org-fontify-emphasized-text) - (lk org-activate-links) + (lk org-highlight-links) (org-font-lock-extra-keywords (list ;; Call the hook @@ -6215,8 +6332,7 @@ needs to be inserted at a specific position in the font-lock sequence.") '("^[ \t]*|\\( *\\([$!_^/]\\) *|.*\\)|" (1 'org-formula t)) '("| *\\(<[lrc]?[0-9]*>\\)" (1 'org-formula t)) ;; Drawers - (list org-drawer-regexp '(0 'org-special-keyword t)) - (list "^[ \t]*:END:" '(0 'org-special-keyword t)) + '(org-fontify-drawers) ;; Properties (list org-property-re '(1 'org-special-keyword t) @@ -6226,7 +6342,7 @@ needs to be inserted at a specific position in the font-lock sequence.") (if (memq 'angle lk) '(org-activate-angle-links (0 'org-link t))) (if (memq 'plain lk) '(org-activate-plain-links (0 'org-link t))) (if (memq 'bracket lk) '(org-activate-bracket-links (0 'org-link t))) - (if (memq 'radio lk) '(org-activate-target-links (0 'org-link t))) + (if (memq 'radio lk) '(org-activate-target-links (1 'org-link t))) (if (memq 'date lk) '(org-activate-dates (0 'org-date t))) (if (memq 'footnote lk) '(org-activate-footnote-links)) ;; Targets. @@ -6234,7 +6350,7 @@ needs to be inserted at a specific position in the font-lock sequence.") ;; Diary sexps. '("^&?%%(.*\\|<%%([^>\n]*?>" (0 'org-sexp-date t)) ;; Macro - '("{{{.+}}}" (0 'org-macro t)) + '(org-fontify-macros) '(org-hide-wide-columns (0 nil append)) ;; TODO keyword (list (format org-heading-keyword-regexp-format @@ -6290,11 +6406,11 @@ needs to be inserted at a specific position in the font-lock sequence.") ;; Code '(org-activate-code (1 'org-code t)) ;; COMMENT - (list (format org-heading-keyword-regexp-format - (concat "\\(" - org-comment-string "\\|" org-quote-string - "\\)")) - '(2 'org-special-keyword t)) + (list (format + "^\\*+\\(?: +%s\\)?\\(?: +\\[#[A-Z0-9]\\]\\)? +\\(?9:%s\\)\\(?: \\|$\\)" + org-todo-regexp + org-comment-string) + '(9 'org-special-keyword t)) ;; Blocks and meta lines '(org-fontify-meta-lines-and-blocks)))) (setq org-font-lock-extra-keywords (delq nil org-font-lock-extra-keywords)) @@ -6325,31 +6441,41 @@ needs to be inserted at a specific position in the font-lock sequence.") "Display or hide properties in `org-custom-properties'." (interactive) (if org-custom-properties-overlays - (progn (mapc 'delete-overlay org-custom-properties-overlays) + (progn (mapc #'delete-overlay org-custom-properties-overlays) (setq org-custom-properties-overlays nil)) - (unless (not org-custom-properties) - (save-excursion - (save-restriction - (widen) - (goto-char (point-min)) - (while (re-search-forward org-property-re nil t) - (mapc (lambda(p) - (when (equal p (substring (match-string 1) 1 -1)) - (let ((o (make-overlay (match-beginning 0) (1+ (match-end 0))))) - (overlay-put o 'invisible t) - (overlay-put o 'org-custom-property t) - (push o org-custom-properties-overlays)))) - org-custom-properties))))))) + (when org-custom-properties + (org-with-wide-buffer + (goto-char (point-min)) + (let ((regexp (org-re-property (regexp-opt org-custom-properties) t t))) + (while (re-search-forward regexp nil t) + (let ((end (cdr (save-match-data (org-get-property-block))))) + (when (and end (< (point) end)) + ;; Hide first custom property in current drawer. + (let ((o (make-overlay (match-beginning 0) (1+ (match-end 0))))) + (overlay-put o 'invisible t) + (overlay-put o 'org-custom-property t) + (push o org-custom-properties-overlays)) + ;; Hide additional custom properties in the same drawer. + (while (re-search-forward regexp end t) + (let ((o (make-overlay (match-beginning 0) (1+ (match-end 0))))) + (overlay-put o 'invisible t) + (overlay-put o 'org-custom-property t) + (push o org-custom-properties-overlays))))) + ;; Each entry is limited to a single property drawer. + (outline-next-heading))))))) (defun org-fontify-entities (limit) "Find an entity to fontify." (let (ee) (when org-pretty-entities (catch 'match + ;; "\_ "-family is left out on purpose. Only the first one, + ;; i.e., "\_ ", could be fontified anyway, and it would be + ;; confusing when adding a second white space character. (while (re-search-forward "\\\\\\(there4\\|sup[123]\\|frac[13][24]\\|[a-zA-Z]+\\)\\($\\|{}\\|[^[:alpha:]\n]\\)" limit t) - (if (and (not (org-in-indented-comment-line)) + (if (and (not (org-at-comment-p)) (setq ee (org-entity-get (match-string 1))) (= (length (nth 6 ee)) 1)) (let* @@ -6371,7 +6497,7 @@ needs to be inserted at a specific position in the font-lock sequence.") (insert s) (let ((org-odd-levels-only odd-levels)) (org-mode) - (font-lock-fontify-buffer) + (org-font-lock-ensure) (buffer-string)))) (defvar org-m nil) @@ -6389,6 +6515,14 @@ needs to be inserted at a specific position in the font-lock sequence.") ((eq n 2) org-f) (t (if org-level-color-stars-only nil org-f)))) +(defun org-face-from-face-or-color (context inherit face-or-color) + "Create a face list that inherits INHERIT, but sets the foreground color. +When FACE-OR-COLOR is not a string, just return it." + (if (stringp face-or-color) + (list :inherit inherit + (cdr (assoc context org-faces-easy-properties)) + face-or-color) + face-or-color)) (defun org-get-todo-face (kwd) "Get the right face for a TODO keyword KWD. @@ -6399,14 +6533,28 @@ If KWD is a number, get the corresponding match group." (and (member kwd org-done-keywords) 'org-done) 'org-todo)) -(defun org-face-from-face-or-color (context inherit face-or-color) - "Create a face list that inherits INHERIT, but sets the foreground color. -When FACE-OR-COLOR is not a string, just return it." - (if (stringp face-or-color) - (list :inherit inherit - (cdr (assoc context org-faces-easy-properties)) - face-or-color) - face-or-color)) +(defun org-get-priority-face (priority) + "Get the right face for PRIORITY. +PRIORITY is a character." + (or (org-face-from-face-or-color + 'priority 'org-priority (cdr (assq priority org-priority-faces))) + 'org-priority)) + +(defun org-get-tag-face (tag) + "Get the right face for TAG. +If TAG is a number, get the corresponding match group." + (let ((tag (if (wholenump tag) (match-string tag) tag))) + (or (org-face-from-face-or-color + 'tag 'org-tag (cdr (assoc tag org-tag-faces))) + 'org-tag))) + +(defun org-font-lock-add-priority-faces (limit) + "Add the special priority faces." + (while (re-search-forward "^\\*+ .*?\\(\\[#\\(.\\)\\]\\)" limit t) + (add-text-properties + (match-beginning 1) (match-end 1) + (list 'face (org-get-priority-face (string-to-char (match-string 2))) + 'font-lock-fontified t)))) (defun org-font-lock-add-tag-faces (limit) "Add the special tag faces." @@ -6417,27 +6565,6 @@ When FACE-OR-COLOR is not a string, just return it." 'font-lock-fontified t)) (backward-char 1)))) -(defun org-font-lock-add-priority-faces (limit) - "Add the special priority faces." - (while (re-search-forward "\\[#\\([A-Z0-9]\\)\\]" limit t) - (when (save-match-data (org-at-heading-p)) - (add-text-properties - (match-beginning 0) (match-end 0) - (list 'face (or (org-face-from-face-or-color - 'priority 'org-priority - (cdr (assoc (char-after (match-beginning 1)) - org-priority-faces))) - 'org-priority) - 'font-lock-fontified t))))) - -(defun org-get-tag-face (kwd) - "Get the right face for a TODO keyword KWD. -If KWD is a number, get the corresponding match group." - (if (numberp kwd) (setq kwd (match-string kwd))) - (or (org-face-from-face-or-color - 'tag 'org-tag (cdr (assoc kwd org-tag-faces))) - 'org-tag)) - (defun org-unfontify-region (beg end &optional maybe_loudly) "Remove fontification and activation overlays from links." (font-lock-default-unfontify-region beg end) @@ -6449,7 +6576,7 @@ If KWD is a number, get the corresponding match group." (remove-text-properties beg end '(mouse-face t keymap t org-linked-text t invisible t intangible t - org-no-flyspell t org-emphasis t)) + org-emphasis t)) (org-remove-font-lock-display-properties beg end))) (defconst org-script-display '(((raise -0.3) (height 0.7)) @@ -6541,11 +6668,12 @@ in special contexts. 1. OVERVIEW: Show only top-level headlines. 2. CONTENTS: Show all headlines of all levels, but no body text. 3. SHOW ALL: Show everything. - When called with two `C-u C-u' prefixes, switch to the startup visibility, + With a double \\[universal-argument] prefix argument, \ +switch to the startup visibility, determined by the variable `org-startup-folded', and by any VISIBILITY properties in the buffer. - When called with three `C-u C-u C-u' prefixed, show the entire buffer, - including any drawers. + With a triple \\[universal-argument] prefix argument, \ +show the entire buffer, including any drawers. - When inside a table, re-align the table and move to the next field. @@ -6574,7 +6702,7 @@ in special contexts. - Special case: if point is at the beginning of the buffer and there is no headline in line 1, this function will act as if called with prefix arg - (C-u TAB, same as S-TAB) also when called without prefix arg. + (\\[universal-argument] TAB, same as S-TAB) also when called without prefix arg. But only if also the variable `org-cycle-global-at-bob' is t." (interactive "P") (org-load-modules-maybe) @@ -6616,7 +6744,7 @@ in special contexts. (org-unlogged-message "Startup visibility, plus VISIBILITY properties")) ((equal arg '(64)) - (show-all) + (outline-show-all) (org-unlogged-message "Entire buffer visible, including drawers")) ;; Try cdlatex TAB completion @@ -6625,7 +6753,8 @@ in special contexts. ;; Table: enter it or move to the next field. ((org-at-table-p 'any) (if (org-at-table.el-p) - (message "Use C-c ' to edit table.el tables") + (message "%s" (substitute-command-keys "\\\ +Use \\[org-edit-special] to edit table.el tables")) (if arg (org-table-edit-field t) (org-table-justify-field-maybe) (call-interactively 'org-table-next-field)))) @@ -6637,11 +6766,10 @@ in special contexts. ((eq arg t) (org-cycle-internal-global)) ;; Drawers: delegate to `org-flag-drawer'. - ((and org-drawers org-drawer-regexp - (save-excursion - (beginning-of-line 1) - (looking-at org-drawer-regexp))) - (org-flag-drawer ; toggle block visibility + ((save-excursion + (beginning-of-line 1) + (looking-at org-drawer-regexp)) + (org-flag-drawer ; toggle block visibility (not (get-char-property (match-end 0) 'invisible)))) ;; Show-subtree, ARG levels up from here. @@ -6660,7 +6788,7 @@ in special contexts. ;; At an item/headline: delegate to `org-cycle-internal-local'. ((and (or (and org-cycle-include-plain-lists (org-at-item-p)) - (save-excursion (beginning-of-line 1) + (save-excursion (move-beginning-of-line 1) (looking-at org-outline-regexp))) (or (bolp) (not (eq org-cycle-emulate-tab 'exc-hl-bol)))) (org-cycle-internal-local)) @@ -6715,7 +6843,7 @@ in special contexts. (eq org-cycle-global-status 'contents)) ;; We just showed the table of contents - now show everything (run-hook-with-args 'org-pre-cycle-hook 'all) - (show-all) + (outline-show-all) (unless ga (org-unlogged-message "SHOW ALL")) (setq org-cycle-global-status 'all) (run-hook-with-args 'org-cycle-hook 'all)) @@ -6791,7 +6919,7 @@ in special contexts. (if (org-at-item-p) (org-list-set-item-visibility (point-at-bol) struct 'children) (org-show-entry) - (org-with-limited-levels (show-children)) + (org-with-limited-levels (outline-show-children)) ;; FIXME: This slows down the func way too much. ;; How keep drawers hidden in subtree anyway? ;; (when (memq 'org-cycle-hide-drawers org-cycle-hook) @@ -6849,8 +6977,8 @@ With a numeric prefix, show all headlines up to that level." (if (derived-mode-p 'org-mode) org-cycle-include-plain-lists nil))) (cond ((integerp arg) - (show-all) - (hide-sublevels arg) + (outline-show-all) + (outline-hide-sublevels arg) (setq org-cycle-global-status 'contents)) ((equal arg '(4)) (org-set-startup-visibility) @@ -6867,7 +6995,7 @@ With a numeric prefix, show all headlines up to that level." (org-content)) ((or (eq org-startup-folded 'showeverything) (eq org-startup-folded nil)) - (show-all))) + (outline-show-all))) (unless (eq org-startup-folded 'showeverything) (if org-hide-block-startup (org-hide-block-all)) (org-set-visibility-according-to-property 'no-cleanup) @@ -6878,34 +7006,33 @@ With a numeric prefix, show all headlines up to that level." (defun org-set-visibility-according-to-property (&optional no-cleanup) "Switch subtree visibilities according to :VISIBILITY: property." (interactive) - (let (org-show-entry-below state) - (save-excursion - (goto-char (point-min)) - (while (re-search-forward - "^[ \t]*:VISIBILITY:[ \t]+\\([a-z]+\\)" - nil t) - (setq state (match-string 1)) - (save-excursion - (org-back-to-heading t) - (hide-subtree) - (org-reveal) - (cond - ((equal state '("fold" "folded")) - (hide-subtree)) - ((equal state "children") - (org-show-hidden-entry) - (show-children)) - ((equal state "content") - (save-excursion - (save-restriction - (org-narrow-to-subtree) - (org-content)))) - ((member state '("all" "showall")) - (show-subtree))))) - (unless no-cleanup - (org-cycle-hide-archived-subtrees 'all) - (org-cycle-hide-drawers 'all) - (org-cycle-show-empty-lines 'all))))) + (let (org-show-entry-below) + (org-with-wide-buffer + (goto-char (point-min)) + (while (re-search-forward "^[ \t]*:VISIBILITY:" nil t) + (if (not (org-at-property-p)) (outline-next-heading) + (let ((state (match-string 3))) + (save-excursion + (org-back-to-heading t) + (outline-hide-subtree) + (org-reveal) + (cond + ((equal state "folded") + (outline-hide-subtree)) + ((equal state "children") + (org-show-hidden-entry) + (outline-show-children)) + ((equal state "content") + (save-excursion + (save-restriction + (org-narrow-to-subtree) + (org-content)))) + ((member state '("all" "showall")) + (outline-show-subtree))))))) + (unless no-cleanup + (org-cycle-hide-archived-subtrees 'all) + (org-cycle-hide-drawers 'all) + (org-cycle-show-empty-lines 'all))))) ;; This function uses outline-regexp instead of the more fundamental ;; org-outline-regexp so that org-cycle-global works outside of Org @@ -6925,7 +7052,7 @@ results." (progn (goto-char (match-beginning 0)) (funcall outline-level)))))) - (and level (hide-sublevels level))))) + (and level (outline-hide-sublevels level))))) (defun org-content (&optional arg) "Show all headlines in the buffer, like a table of contents. @@ -6943,8 +7070,8 @@ With numerical argument N, show content up to level N." t) (looking-at org-outline-regexp)) (if (integerp arg) - (show-children (1- arg)) - (show-branches)) + (outline-show-children (1- arg)) + (outline-show-branches)) (if (bobp) (throw 'exit nil)))))) (defun org-optimize-window-after-visibility-change (state) @@ -6995,7 +7122,7 @@ This function is the default value of the hook `org-cycle-hook'." (if (and (not (outline-invisible-p)) (save-excursion (goto-char (point-at-eol)) (outline-invisible-p))) - (hide-entry)))) + (outline-hide-entry)))) (org-cycle-show-empty-lines 'overview) (org-cycle-hide-drawers 'overview))))) @@ -7005,7 +7132,7 @@ The region to be covered depends on STATE when called through `org-cycle-hook'. Lisp program can use t for STATE to get the entire buffer covered. Note that an empty line is only shown if there are at least `org-cycle-separator-lines' empty lines before the headline." - (when (not (= org-cycle-separator-lines 0)) + (when (/= org-cycle-separator-lines 0) (save-excursion (let* ((n (abs org-cycle-separator-lines)) (re (cond @@ -7014,30 +7141,26 @@ are at least `org-cycle-separator-lines' empty lines before the headline." (t (let ((ns (number-to-string (- n 2)))) (concat "^\\(?:[ \t]*\n\\)\\{" ns "," ns "\\}" "[ \t]*\\(\n[ \t]*\n\\*+\\) "))))) - beg end b e) + beg end) (cond ((memq state '(overview contents t)) (setq beg (point-min) end (point-max))) ((memq state '(children folded)) - (setq beg (point) end (progn (org-end-of-subtree t t) - (beginning-of-line 2) - (point))))) + (setq beg (point) + end (progn (org-end-of-subtree t t) + (line-beginning-position 2))))) (when beg (goto-char beg) (while (re-search-forward re end t) (unless (get-char-property (match-end 1) 'invisible) - (setq e (match-end 1)) - (if (< org-cycle-separator-lines 0) - (setq b (save-excursion - (goto-char (match-beginning 0)) - (org-back-over-empty-lines) - (if (save-excursion - (goto-char (max (point-min) (1- (point)))) - (org-at-heading-p)) - (1- (point)) - (point)))) - (setq b (match-beginning 1))) - (outline-flag-region b e nil))))))) + (let ((e (match-end 1)) + (b (if (>= org-cycle-separator-lines 0) + (match-beginning 1) + (save-excursion + (goto-char (match-beginning 0)) + (skip-chars-backward " \t\n") + (line-end-position))))) + (outline-flag-region b e nil)))))))) ;; Never hide empty lines at the end of the file. (save-excursion (goto-char (point-max)) @@ -7068,14 +7191,16 @@ open and agenda-wise Org files." (defsubst org-entry-beginning-position () "Return the beginning position of the current entry." - (save-excursion (outline-back-to-heading t) (point))) + (save-excursion (org-back-to-heading t) (point))) (defsubst org-entry-end-position () "Return the end position of the current entry." (save-excursion (outline-next-heading) (point))) -(defun org-cycle-hide-drawers (state) - "Re-hide all drawers after a visibility state change." +(defun org-cycle-hide-drawers (state &optional exceptions) + "Re-hide all drawers after a visibility state change. +When non-nil, optional argument EXCEPTIONS is a list of strings +specifying which drawers should not be hidden." (when (and (derived-mode-p 'org-mode) (not (memq state '(overview folded contents)))) (save-excursion @@ -7086,36 +7211,38 @@ open and agenda-wise Org files." (save-excursion (outline-next-heading) (point)) (org-end-of-subtree t))))) (goto-char beg) - (while (re-search-forward org-drawer-regexp end t) - (org-flag-drawer t)))))) - -(defun org-cycle-hide-inline-tasks (state) - "Re-hide inline tasks when switching to 'contents or 'children -visibility state." - (case state - (contents - (when (org-bound-and-true-p org-inlinetask-min-level) - (hide-sublevels (1- org-inlinetask-min-level)))) - (children - (when (featurep 'org-inlinetask) - (save-excursion - (while (and (outline-next-heading) - (org-inlinetask-at-task-p)) - (org-inlinetask-toggle-visibility) - (org-inlinetask-goto-end))))))) - -(defun org-flag-drawer (flag) - "When FLAG is non-nil, hide the drawer we are within. -Otherwise make it visible." - (save-excursion - (beginning-of-line 1) - (when (looking-at "^[ \t]*:[a-zA-Z][a-zA-Z0-9]*:") - (let ((b (match-end 0))) - (if (re-search-forward - "^[ \t]*:END:" - (save-excursion (outline-next-heading) (point)) t) - (outline-flag-region b (point-at-eol) flag) - (user-error ":END: line missing at position %s" b)))))) + (while (re-search-forward org-drawer-regexp (max end (point)) t) + (unless (member-ignore-case (match-string 1) exceptions) + (let ((drawer (org-element-at-point))) + (when (memq (org-element-type drawer) '(drawer property-drawer)) + (org-flag-drawer t drawer) + ;; Make sure to skip drawer entirely or we might flag + ;; it another time when matching its ending line with + ;; `org-drawer-regexp'. + (goto-char (org-element-property :end drawer)))))))))) + +(defun org-flag-drawer (flag &optional element) + "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." + (when (save-excursion + (beginning-of-line) + (org-looking-at-p org-drawer-regexp)) + (let ((drawer (or element (org-element-at-point)))) + (when (memq (org-element-type drawer) '(drawer property-drawer)) + (let ((post (org-element-property :post-affiliated drawer))) + (save-excursion + (outline-flag-region + (progn (goto-char post) (line-end-position)) + (progn (goto-char (org-element-property :end drawer)) + (skip-chars-backward " \r\t\n") + (line-end-position)) + flag)) + ;; When the drawer is hidden away, make sure point lies in + ;; a visible part of the buffer. + (when (and flag (> (line-beginning-position) post)) + (goto-char post))))))) (defun org-subtree-end-visible-p () "Is the end of the current subtree visible?" @@ -7147,8 +7274,8 @@ If USE-MARKERS is set, return the positions as markers." end (overlay-end o)) (and beg end (> end beg) (if use-markers - (cons (move-marker (make-marker) beg) - (move-marker (make-marker) end)) + (cons (copy-marker beg) + (copy-marker end t)) (cons beg end))))) (overlays-in (point-min) (point-max)))))))) @@ -7159,7 +7286,7 @@ DATA should have been made by `org-outline-overlay-data'." (save-excursion (save-restriction (widen) - (show-all) + (outline-show-all) (mapc (lambda (c) (outline-flag-region (car c) (cdr c) t)) data))))) @@ -7185,13 +7312,13 @@ Optional arguments START and END can be used to limit the range." (defun org-hide-block-toggle-all () "Toggle the visibility of all blocks in the current buffer." - (org-block-map #'org-hide-block-toggle)) + (org-block-map 'org-hide-block-toggle)) (defun org-hide-block-all () "Fold all blocks in the current buffer." (interactive) (org-show-block-all) - (org-block-map #'org-hide-block-toggle-maybe)) + (org-block-map 'org-hide-block-toggle-maybe)) (defun org-show-block-all () "Unfold all blocks in the current buffer." @@ -7200,52 +7327,65 @@ Optional arguments START and END can be used to limit the range." (setq org-hide-block-overlays nil)) (defun org-hide-block-toggle-maybe () - "Toggle visibility of block at point." + "Toggle visibility of block at point. +Unlike to `org-hide-block-toggle', this function does not throw +an error. Return a non-nil value when toggling is successful." (interactive) - (let ((case-fold-search t)) - (if (save-excursion - (beginning-of-line 1) - (looking-at org-block-regexp)) - (progn (org-hide-block-toggle) - t) ;; to signal that we took action - nil))) ;; to signal that we did not + (ignore-errors (org-hide-block-toggle))) (defun org-hide-block-toggle (&optional force) - "Toggle the visibility of the current block." + "Toggle the visibility of the current block. +When optional argument FORCE is `off', make block visible. If it +is non-nil, hide it unconditionally. Throw an error when not at +a block. Return a non-nil value when toggling is successful." (interactive) - (save-excursion - (beginning-of-line) - (if (re-search-forward org-block-regexp nil t) - (let ((start (- (match-beginning 4) 1)) ;; beginning of body - (end (match-end 0)) ;; end of entire body - ov) - (if (memq t (mapcar (lambda (overlay) - (eq (overlay-get overlay 'invisible) - 'org-hide-block)) - (overlays-at start))) - (if (or (not force) (eq force 'off)) - (mapc (lambda (ov) - (when (member ov org-hide-block-overlays) - (setq org-hide-block-overlays - (delq ov org-hide-block-overlays))) - (when (eq (overlay-get ov 'invisible) - 'org-hide-block) - (delete-overlay ov))) - (overlays-at start))) - (setq ov (make-overlay start end)) - (overlay-put ov 'invisible 'org-hide-block) - ;; make the block accessible to isearch - (overlay-put - ov 'isearch-open-invisible - (lambda (ov) - (when (member ov org-hide-block-overlays) - (setq org-hide-block-overlays - (delq ov org-hide-block-overlays))) - (when (eq (overlay-get ov 'invisible) - 'org-hide-block) - (delete-overlay ov)))) - (push ov org-hide-block-overlays))) - (user-error "Not looking at a source block")))) + (let ((element (org-element-at-point))) + (unless (memq (org-element-type element) + '(center-block comment-block dynamic-block example-block + export-block quote-block special-block + src-block verse-block)) + (user-error "Not at a block")) + (let* ((start (save-excursion + (goto-char (org-element-property :post-affiliated element)) + (line-end-position))) + (end (save-excursion + (goto-char (org-element-property :end element)) + (skip-chars-backward " \r\t\n") + (line-end-position))) + (overlays (overlays-at start))) + (cond + ;; Do nothing when not before or at the block opening line or + ;; at the block closing line. + ((let ((eol (line-end-position))) (and (> eol start) (/= eol end))) nil) + ((and (not (eq force 'off)) + (not (memq t (mapcar + (lambda (o) + (eq (overlay-get o 'invisible) 'org-hide-block)) + overlays)))) + (let ((ov (make-overlay start end))) + (overlay-put ov 'invisible 'org-hide-block) + ;; Make the block accessible to `isearch'. + (overlay-put + ov 'isearch-open-invisible + (lambda (ov) + (when (memq ov org-hide-block-overlays) + (setq org-hide-block-overlays (delq ov org-hide-block-overlays))) + (when (eq (overlay-get ov 'invisible) 'org-hide-block) + (delete-overlay ov)))) + (push ov org-hide-block-overlays) + ;; When the block is hidden away, make sure point is left in + ;; a visible part of the buffer. + (when (> (line-beginning-position) start) + (goto-char start) + (beginning-of-line)) + ;; Signal successful toggling. + t)) + ((or (not force) (eq force 'off)) + (dolist (ov overlays t) + (when (memq ov org-hide-block-overlays) + (setq org-hide-block-overlays (delq ov org-hide-block-overlays))) + (when (eq (overlay-get ov 'invisible) 'org-hide-block) + (delete-overlay ov)))))))) ;; org-tab-after-check-for-cycling-hook (add-hook 'org-tab-first-hook 'org-hide-block-toggle-maybe) @@ -7264,9 +7404,8 @@ Optional arguments START and END can be used to limit the range." (setq org-goto-map (let ((map (make-sparse-keymap))) (let ((cmds '(isearch-forward isearch-backward kill-ring-save set-mark-command - mouse-drag-region universal-argument org-occur)) - cmd) - (while (setq cmd (pop cmds)) + mouse-drag-region universal-argument org-occur))) + (dolist (cmd cmds) (substitute-key-definition cmd cmd map global-map))) (suppress-keymap map) (org-defkey map "\C-m" 'org-goto-ret) @@ -7320,8 +7459,8 @@ returns to the original buffer in which the visibility is still unchanged. After RET it will also jump to the location selected in the indirect buffer and expose the headline hierarchy above. -With a prefix argument, use the alternative interface: e.g. if -`org-goto-interface' is 'outline use 'outline-path-completion." +With a prefix argument, use the alternative interface: e.g., if +`org-goto-interface' is `outline' use `outline-path-completion'." (interactive "P") (org-goto-map) (let* ((org-refile-targets `((nil . (:maxlevel . ,org-goto-max-level)))) @@ -7384,11 +7523,9 @@ or nil." (setq buffer-read-only t) (if (and (boundp 'org-goto-start-pos) (integer-or-marker-p org-goto-start-pos)) - (let ((org-show-hierarchy-above t) - (org-show-siblings t) - (org-show-following-heading t)) - (goto-char org-goto-start-pos) - (and (outline-invisible-p) (org-show-context))) + (progn (goto-char org-goto-start-pos) + (when (outline-invisible-p) + (org-show-set-visibility 'lineage))) (goto-char (point-min))) (let (org-special-ctrl-a/e) (org-beginning-of-line)) (message "Select location and press RET") @@ -7414,9 +7551,12 @@ or nil." (while (if isearch-forward (search-forward string bound noerror) (search-backward string bound noerror)) - (when (let ((context (mapcar 'car (save-match-data (org-context))))) - (and (member :headline context) - (not (member :tags context)))) + (when (save-match-data + (and (save-excursion + (beginning-of-line) + (looking-at org-complex-heading-regexp)) + (or (not (match-beginning 5)) + (< (point) (match-beginning 5))))) (throw 'return (point)))))) (defun org-goto-local-auto-isearch () @@ -7505,7 +7645,7 @@ frame is not changed." (not (eq org-indirect-buffer-display 'new-frame)) (not arg)) (kill-buffer org-last-indirect-buffer)) - (setq ibuf (org-get-indirect-buffer cbuf) + (setq ibuf (org-get-indirect-buffer cbuf heading) org-last-indirect-buffer ibuf) (cond ((or (eq org-indirect-buffer-display 'new-frame) @@ -7531,16 +7671,20 @@ frame is not changed." (if (featurep 'xemacs) (save-excursion (org-mode) (turn-on-font-lock))) (narrow-to-region beg end) - (show-all) + (outline-show-all) (goto-char pos) (run-hook-with-args 'org-cycle-hook 'all) (and (window-live-p cwin) (select-window cwin)))) -(defun org-get-indirect-buffer (&optional buffer) +(defun org-get-indirect-buffer (&optional buffer heading) (setq buffer (or buffer (current-buffer))) (let ((n 1) (base (buffer-name buffer)) bname) (while (buffer-live-p - (get-buffer (setq bname (concat base "-" (number-to-string n))))) + (get-buffer + (setq bname + (concat base "-" + (if heading (concat heading "-" (number-to-string n)) + (number-to-string n)))))) (setq n (1+ n))) (condition-case nil (make-indirect-buffer buffer bname 'clone) @@ -7565,7 +7709,7 @@ When NEXT is non-nil, check the next line instead." (save-match-data (looking-at "[ \t]*$"))))) -(defun org-insert-heading (&optional arg invisible-ok) +(defun org-insert-heading (&optional arg invisible-ok top-level) "Insert a new heading or an item with the same depth at point. If point is at the beginning of a heading or a list item, insert @@ -7577,7 +7721,7 @@ headline or the item and create a new headline/item with the text in the current line after point \(see `org-M-RET-may-split-line' on how to modify this behavior). -With one universal prefirx argument, set the user option +With one universal prefix argument, set the user option `org-insert-heading-respect-content' to t for the duration of the command. This modifies the behavior described above in this ways: on list items and at the beginning of normal lines, force @@ -7588,17 +7732,28 @@ end of the grandparent subtree. For example, if point is within a 2nd-level heading, then it will insert a 2nd-level heading at the end of the 1st-level parent heading. +If point is at the beginning of a headline, insert a sibling +before the current headline. If point is not at the beginning, +split the line and create a new headline with the text in the +current line after point \(see `org-M-RET-may-split-line' on how +to modify this behavior). + +If point is at the beginning of a normal line, turn this line +into a heading. + When INVISIBLE-OK is set, stop at invisible headlines when going back. This is important for non-interactive uses of the -command." +command. + +When optional argument TOP-LEVEL is non-nil, insert a level 1 +heading, unconditionally." (interactive "P") (if (org-called-interactively-p 'any) (org-reveal)) - (let ((itemp (org-in-item-p)) + (let ((itemp (and (not top-level) (org-in-item-p))) (may-split (org-get-alist-option org-M-RET-may-split-line 'headline)) (respect-content (or org-insert-heading-respect-content (equal arg '(4)))) - (initial-content "") - (adjust-empty-lines t)) + (initial-content "")) (cond @@ -7637,7 +7792,7 @@ command." (org-previous-line-empty-p) ;; We will decide later nil)) - ;; Get a level string to fall back on + ;; Get a level string to fall back on. (fix-level (if (org-before-first-heading-p) "*" (save-excursion @@ -7648,14 +7803,15 @@ command." (stars (save-excursion (condition-case nil - (progn + (if top-level "* " (org-back-to-heading invisible-ok) (when (and (not on-heading) (featurep 'org-inlinetask) (integerp org-inlinetask-min-level) (>= (length (match-string 0)) org-inlinetask-min-level)) - ;; Find a heading level before the inline task + ;; Find a heading level before the inline + ;; task. (while (and (setq level (org-up-heading-safe)) (>= level org-inlinetask-min-level))) (if (org-at-heading-p) @@ -7675,27 +7831,30 @@ command." (blank (if (eq blank-a 'auto) empty-line-p blank-a)) pos hide-previous previous-pos) - ;; If we insert after content, move there and clean up whitespace + ;; If we insert after content, move there and clean up + ;; whitespace. (when (and respect-content (not (org-looking-at-p org-outline-regexp-bol))) (if (not (org-before-first-heading-p)) (org-end-of-subtree nil t) (re-search-forward org-outline-regexp-bol) (beginning-of-line 0)) - (skip-chars-backward " \r\n") - (and (not (looking-back "^\*+")) + (skip-chars-backward " \r\t\n") + (and (not (org-looking-back "^\\*+" (line-beginning-position))) (looking-at "[ \t]+") (replace-match "")) (unless (eobp) (forward-char 1)) (when (looking-at "^\\*") (unless (bobp) (backward-char 1)) (insert "\n"))) - ;; If we are splitting, grab the text that should be moved to the new headline + ;; If we are splitting, grab the text that should be moved + ;; to the new headline. (when may-split (if (org-on-heading-p) - ;; This is a heading, we split intelligently (keeping tags) + ;; This is a heading: split intelligently (keeping + ;; tags). (let ((pos (point))) - (goto-char (point-at-bol)) + (beginning-of-line) (unless (looking-at org-complex-heading-regexp) (error "This should not happen")) (when (and (match-beginning 4) @@ -7706,31 +7865,35 @@ command." (delete-region (point) (match-end 4)) (if (looking-at "[ \t]*$") (replace-match "") - (insert (make-string (length initial-content) ?\ ))) + (insert (make-string (length initial-content) ?\s))) (setq initial-content (org-trim initial-content))) (goto-char pos)) - ;; a normal line + ;; A normal line. (setq initial-content - (org-trim (buffer-substring (point) (point-at-eol)))) - (delete-region (point) (point-at-eol)))) + (org-trim + (delete-and-extract-region (point) (line-end-position)))))) - ;; If we are at the beginning of the line, insert before it. Else after + ;; If we are at the beginning of the line, insert before it. + ;; Otherwise, after it. (cond ((and (bolp) (looking-at "[ \t]*$"))) - ((and (bolp) (not (looking-at "[ \t]*$"))) - (open-line 1)) - (t - (goto-char (point-at-eol)) - (insert "\n"))) + ((bolp) (save-excursion (insert "\n"))) + (t (end-of-line) + (insert "\n"))) ;; Insert the new heading (insert stars) (just-one-space) (insert initial-content) - (when adjust-empty-lines - (if (or (not blank) - (and blank (not (org-previous-line-empty-p)))) - (org-N-empty-lines-before-current (if blank 1 0)))) + (unless (and blank (org-previous-line-empty-p)) + (org-N-empty-lines-before-current (if blank 1 0))) + ;; Adjust visibility, which may be messed up if we removed + ;; blank lines while previous entry was hidden. + (let ((bol (line-beginning-position))) + (dolist (o (overlays-at (1- bol))) + (when (and (eq (overlay-get o 'invisible) 'outline) + (eq (overlay-end o) bol)) + (move-overlay o (overlay-start o) (1- bol))))) (run-hooks 'org-insert-heading-hook))))))) (defun org-N-empty-lines-before-current (N) @@ -7893,18 +8056,17 @@ See also `org-promote'." (org-fix-position-after-promote)) (defun org-demote-subtree () - "Demote the entire subtree. See `org-demote'. -See also `org-promote'." + "Demote the entire subtree. +See `org-demote' and `org-promote'." (interactive) (save-excursion (org-with-limited-levels (org-map-tree 'org-demote))) (org-fix-position-after-promote)) - (defun org-do-promote () "Promote the current heading higher up the tree. -If the region is active in `transient-mark-mode', promote all headings -in the region." +If the region is active in `transient-mark-mode', promote all +headings in the region." (interactive) (save-excursion (if (org-region-active-p) @@ -7914,8 +8076,8 @@ in the region." (defun org-do-demote () "Demote the current heading lower down the tree. -If the region is active in `transient-mark-mode', demote all headings -in the region." +If the region is active in `transient-mark-mode', demote all +headings in the region." (interactive) (save-excursion (if (org-region-active-p) @@ -7924,7 +8086,7 @@ in the region." (org-fix-position-after-promote)) (defun org-fix-position-after-promote () - "Make sure that after pro/demotion cursor position is right." + "Fix cursor position and indentation after demoting/promoting." (let ((pos (point))) (when (save-excursion (beginning-of-line 1) @@ -7936,11 +8098,12 @@ in the region." (defun org-current-level () "Return the level of the current entry, or nil if before the first headline. -The level is the number of stars at the beginning of the headline." - (save-excursion - (org-with-limited-levels - (if (ignore-errors (org-back-to-heading t)) - (funcall outline-level))))) +The level is the number of stars at the beginning of the +headline. Use `org-reduced-level' to remove the effect of +`org-odd-levels'. Unlike to `org-outline-level', this function +ignores inlinetasks." + (let ((level (org-with-limited-levels (org-outline-level)))) + (and (> level 0) level))) (defun org-get-previous-line-level () "Return the outline depth of the last headline before the current line. @@ -7984,42 +8147,38 @@ even level numbers will become the next higher odd number." 'org-get-valid-level "23.1"))) (defun org-promote () - "Promote the current heading higher up the tree. -If the region is active in `transient-mark-mode', promote all headings -in the region." - (org-back-to-heading t) - (let* ((level (save-match-data (funcall outline-level))) - (after-change-functions (remove 'flyspell-after-change-function - after-change-functions)) - (up-head (concat (make-string (org-get-valid-level level -1) ?*) " ")) - (diff (abs (- level (length up-head) -1)))) - (cond ((and (= level 1) org-called-with-limited-levels - org-allow-promoting-top-level-subtree) - (replace-match "# " nil t)) - ((= level 1) - (user-error "Cannot promote to level 0. UNDO to recover if necessary")) - (t (replace-match up-head nil t))) - ;; Fixup tag positioning - (unless (= level 1) - (and org-auto-align-tags (org-set-tags nil 'ignore-column)) - (if org-adapt-indentation (org-fixup-indentation (- diff)))) - (run-hooks 'org-after-promote-entry-hook))) + "Promote the current heading higher up the tree." + (org-with-wide-buffer + (org-back-to-heading t) + (let* ((after-change-functions (remq 'flyspell-after-change-function + after-change-functions)) + (level (save-match-data (funcall outline-level))) + (up-head (concat (make-string (org-get-valid-level level -1) ?*) " ")) + (diff (abs (- level (length up-head) -1)))) + (cond + ((and (= level 1) org-allow-promoting-top-level-subtree) + (replace-match "# " nil t)) + ((= level 1) + (user-error "Cannot promote to level 0. UNDO to recover if necessary")) + (t (replace-match up-head nil t))) + (unless (= level 1) + (when org-auto-align-tags (org-set-tags nil 'ignore-column)) + (when org-adapt-indentation (org-fixup-indentation (- diff)))) + (run-hooks 'org-after-promote-entry-hook)))) (defun org-demote () - "Demote the current heading lower down the tree. -If the region is active in `transient-mark-mode', demote all headings -in the region." - (org-back-to-heading t) - (let* ((level (save-match-data (funcall outline-level))) - (after-change-functions (remove 'flyspell-after-change-function - after-change-functions)) - (down-head (concat (make-string (org-get-valid-level level 1) ?*) " ")) - (diff (abs (- level (length down-head) -1)))) - (replace-match down-head nil t) - ;; Fixup tag positioning - (and org-auto-align-tags (org-set-tags nil 'ignore-column)) - (if org-adapt-indentation (org-fixup-indentation diff)) - (run-hooks 'org-after-demote-entry-hook))) + "Demote the current heading lower down the tree." + (org-with-wide-buffer + (org-back-to-heading t) + (let* ((after-change-functions (remq 'flyspell-after-change-function + after-change-functions)) + (level (save-match-data (funcall outline-level))) + (down-head (concat (make-string (org-get-valid-level level 1) ?*) " ")) + (diff (abs (- level (length down-head) -1)))) + (replace-match down-head nil t) + (when org-auto-align-tags (org-set-tags nil 'ignore-column)) + (when org-adapt-indentation (org-fixup-indentation diff)) + (run-hooks 'org-after-demote-entry-hook)))) (defun org-cycle-level () "Cycle the level of an empty headline through possible states. @@ -8084,27 +8243,111 @@ After top level, it switches back to sibling level." (not (eobp))) (funcall fun))))) -(defvar org-property-end-re) ; silence byte-compiler (defun org-fixup-indentation (diff) "Change the indentation in the current entry by DIFF. -However, if any line in the current entry has no indentation, or if it -would end up with no indentation after the change, nothing at all is done." - (save-excursion - (let ((end (save-excursion (outline-next-heading) - (point-marker))) - (prohibit (if (> diff 0) - "^\\S-" - (concat "^ \\{0," (int-to-string (- diff)) "\\}\\S-"))) - col) - (unless (save-excursion (end-of-line 1) - (re-search-forward prohibit end t)) - (while (and (< (point) end) - (re-search-forward "^[ \t]+" end t)) - (goto-char (match-end 0)) - (setq col (current-column)) - (if (< diff 0) (replace-match "")) - (org-indent-to-column (+ diff col)))) - (move-marker end nil)))) + +DIFF is an integer. Indentation is done according to the +following rules: + + - Planning information and property drawers are always indented + according to the new level of the headline; + + - Footnote definitions and their contents are ignored; + + - Inlinetasks' boundaries are not shifted; + + - Empty lines are ignored; + + - Other lines' indentation are shifted by DIFF columns, unless + it would introduce a structural change in the document, in + which case no shifting is done at all. + +Assume point is at a heading or an inlinetask beginning." + (org-with-wide-buffer + (narrow-to-region (line-beginning-position) + (save-excursion + (if (org-with-limited-levels (org-at-heading-p)) + (org-with-limited-levels (outline-next-heading)) + (org-inlinetask-goto-end)) + (point))) + (forward-line) + ;; Indent properly planning info and property drawer. + (when (org-looking-at-p org-planning-line-re) + (org-indent-line) + (forward-line)) + (when (looking-at org-property-drawer-re) + (goto-char (match-end 0)) + (forward-line) + (save-excursion (org-indent-region (match-beginning 0) (match-end 0)))) + (catch 'no-shift + (when (zerop diff) (throw 'no-shift nil)) + ;; If DIFF is negative, first check if a shift is possible at all + ;; (e.g., it doesn't break structure). This can only happen if + ;; some contents are not properly indented. + (let ((case-fold-search t)) + (when (< diff 0) + (let ((diff (- diff)) + (forbidden-re (concat org-outline-regexp + "\\|" + (substring org-footnote-definition-re 1)))) + (save-excursion + (while (not (eobp)) + (cond + ((org-looking-at-p "[ \t]*$") (forward-line)) + ((and (org-looking-at-p org-footnote-definition-re) + (let ((e (org-element-at-point))) + (and (eq (org-element-type e) 'footnote-definition) + (goto-char (org-element-property :end e)))))) + ((org-looking-at-p org-outline-regexp) (forward-line)) + ;; Give up if shifting would move before column 0 or + ;; if it would introduce a headline or a footnote + ;; definition. + (t + (skip-chars-forward " \t") + (let ((ind (current-column))) + (when (or (< ind diff) + (and (= ind diff) (org-looking-at-p forbidden-re))) + (throw 'no-shift nil))) + ;; Ignore contents of example blocks and source + ;; blocks if their indentation is meant to be + ;; preserved. Jump to block's closing line. + (beginning-of-line) + (or (and (org-looking-at-p "[ \t]*#\\+BEGIN_\\(EXAMPLE\\|SRC\\)") + (let ((e (org-element-at-point))) + (and (memq (org-element-type e) + '(example-block src-block)) + (or org-src-preserve-indentation + (org-element-property :preserve-indent e)) + (goto-char (org-element-property :end e)) + (progn (skip-chars-backward " \r\t\n") + (beginning-of-line) + t)))) + (forward-line)))))))) + ;; Shift lines but footnote definitions, inlinetasks boundaries + ;; by DIFF. Also skip contents of source or example blocks + ;; when indentation is meant to be preserved. + (while (not (eobp)) + (cond + ((and (org-looking-at-p org-footnote-definition-re) + (let ((e (org-element-at-point))) + (and (eq (org-element-type e) 'footnote-definition) + (goto-char (org-element-property :end e)))))) + ((org-looking-at-p org-outline-regexp) (forward-line)) + ((org-looking-at-p "[ \t]*$") (forward-line)) + (t + (org-indent-line-to (+ (org-get-indentation) diff)) + (beginning-of-line) + (or (and (org-looking-at-p "[ \t]*#\\+BEGIN_\\(EXAMPLE\\|SRC\\)") + (let ((e (org-element-at-point))) + (and (memq (org-element-type e) + '(example-block src-block)) + (or org-src-preserve-indentation + (org-element-property :preserve-indent e)) + (goto-char (org-element-property :end e)) + (progn (skip-chars-backward " \r\t\n") + (beginning-of-line) + t)))) + (forward-line))))))))) (defun org-convert-to-odd-levels () "Convert an org-mode file with all levels allowed to one with odd levels. @@ -8132,7 +8375,7 @@ case." (goto-char (point-min)) ;; First check if there are no even levels (when (re-search-forward "^\\(\\*\\*\\)+ " nil t) - (org-show-context t) + (org-show-set-visibility 'canonical) (error "Not all levels are odd in this file. Conversion not possible")) (when (yes-or-no-p "Are you sure you want to globally change levels to odd-even? ") (let ((outline-regexp org-outline-regexp) @@ -8228,9 +8471,9 @@ case." (insert (make-string (- ne-ins ne-beg) ?\n))) (move-marker ins-point nil) (if folded - (hide-subtree) + (outline-hide-subtree) (org-show-entry) - (show-children) + (outline-show-children) (org-cycle-hide-drawers 'children)) (org-clean-visibility-after-subtree-move) ;; move back to the initial column we were at @@ -8272,10 +8515,13 @@ useful if the caller implements cut-and-paste as copy-then-paste-then-cut." (outline-next-heading) (save-excursion (outline-end-of-heading) (setq folded (outline-invisible-p))) - (condition-case nil - (org-forward-heading-same-level (1- n) t) - (error nil)) + (ignore-errors (org-forward-heading-same-level (1- n) t)) (org-end-of-subtree t t))) + ;; Include the end of an inlinetask + (when (and (featurep 'org-inlinetask) + (looking-at-p (concat (org-inlinetask-outline-regexp) + "END[ \t]*$"))) + (end-of-line)) (setq end (point)) (goto-char beg0) (when (> end beg) @@ -8288,7 +8534,7 @@ useful if the caller implements cut-and-paste as copy-then-paste-then-cut." (if cut "Cut" "Copied") (length org-subtree-clip))))) -(defun org-paste-subtree (&optional level tree for-yank) +(defun org-paste-subtree (&optional level tree for-yank remove) "Paste the clipboard as a subtree, with modification of headline level. The entire subtree is promoted or demoted in order to match a new headline level. @@ -8311,13 +8557,15 @@ If optional TREE is given, use this text instead of the kill ring. When FOR-YANK is set, this is called by `org-yank'. In this case, do not move back over whitespace before inserting, and move point to the end of -the inserted text when done." +the inserted text when done. + +When REMOVE is non-nil, remove the subtree from the clipboard." (interactive "P") (setq tree (or tree (and kill-ring (current-kill 0)))) (unless (org-kill-is-subtree-p tree) (user-error "%s" - (substitute-command-keys - "The kill is not a (set of) tree(s) - please use \\[yank] to yank anyway"))) + (substitute-command-keys + "The kill is not a (set of) tree(s) - please use \\[yank] to yank anyway"))) (org-with-limited-levels (let* ((visp (not (outline-invisible-p))) (txt tree) @@ -8394,8 +8642,9 @@ the inserted text when done." (eq org-subtree-clip (current-kill 0)) org-subtree-clip-folded) ;; The tree was folded before it was killed/copied - (hide-subtree)) - (and for-yank (goto-char newend))))) + (outline-hide-subtree)) + (and for-yank (goto-char newend)) + (and remove (setq kill-ring (cdr kill-ring)))))) (defun org-kill-is-subtree-p (&optional txt) "Check if the current kill is an outline subtree, or a set of trees. @@ -8478,10 +8727,6 @@ If yes, remember the marker and the distance to BEG." (narrow-to-region (car blockp) (cdr blockp)) (user-error "Not in a block")))) -(eval-when-compile - (defvar org-property-drawer-re)) - -(defvar org-property-start-re) ;; defined below (defun org-clone-subtree-with-time-shift (n &optional shift) "Clone the task (subtree) at point N times. The clones will be inserted as siblings. @@ -8508,7 +8753,12 @@ the following will happen: - the start days in the repeater in the original entry will be shifted to past the last clone. In this way you can spell out a number of instances of a repeating task, -and still retain the repeater to cover future instances of the task." +and still retain the repeater to cover future instances of the task. + +As described above, N+1 clones are produced when the original +subtree has a repeater. Setting N to 0, then, can be used to +remove the repeater from a subtree and create a shifted clone +with the original repeater." (interactive "nNumber of clones to produce: ") (let ((shift (or shift @@ -8523,14 +8773,15 @@ and still retain the repeater to cover future instances of the task." ""))) ;; No time shift (n-no-remove -1) (drawer-re org-drawer-regexp) + (org-clock-re (format "^[ \t]*%s.*$" org-clock-string)) beg end template task idprop shift-n shift-what doshift nmin nmax) - (if (not (and (integerp n) (> n 0))) - (error "Invalid number of replications %s" n)) + (unless (wholenump n) + (user-error "Invalid number of replications %s" n)) (if (and (setq doshift (and (stringp shift) (string-match "\\S-" shift))) (not (string-match "\\`[ \t]*\\+?\\([0-9]+\\)\\([hdwmy]\\)[ \t]*\\'" shift))) - (error "Invalid shift specification %s" shift)) + (user-error "Invalid shift specification %s" shift)) (when doshift (setq shift-n (string-to-number (match-string 1 shift)) shift-what (cdr (assoc (match-string 2 shift) @@ -8562,12 +8813,11 @@ and still retain the repeater to cover future instances of the task." (org-entry-delete nil "ID") (org-id-get-create t))) (unless (= n 0) - (while (re-search-forward "^[ \t]*CLOCK:.*$" nil t) + (while (re-search-forward org-clock-re nil t) (kill-whole-line)) (goto-char (point-min)) (while (re-search-forward drawer-re nil t) - (mapc (lambda (d) - (org-remove-empty-drawer-at d (point))) org-drawers))) + (org-remove-empty-drawer-at (point)))) (goto-char (point-min)) (when doshift (while (re-search-forward org-ts-regexp-both nil t) @@ -8601,7 +8851,8 @@ Optional argument WITH-CASE means sort case-sensitively." (while (string-match org-bracket-link-regexp s) (setq s (replace-match (if (match-end 2) (match-string 3 s) - (match-string 1 s)) t t s))) + (match-string 1 s)) + t t s))) (let ((st (format " %s " s))) (while (string-match org-emph-re st) (setq st (replace-match (format " %s " (match-string 4 st)) t t st))) @@ -8617,7 +8868,7 @@ hook gets called. When a region or a plain list is sorted, the cursor will be in the first entry of the sorted region/list.") (defun org-sort-entries - (&optional with-case sorting-type getkey-func compare-func property) + (&optional with-case sorting-type getkey-func compare-func property) "Sort entries on a certain level of an outline tree. If there is an active region, the entries in the region are sorted. Else, if the cursor is before the first entry, sort the top-level items. @@ -8628,20 +8879,21 @@ a time stamp, by a property, by priority order, or by a custom function. The command prompts for the sorting type unless it has been given to the function through the SORTING-TYPE argument, which needs to be a character, -\(?n ?N ?a ?A ?t ?T ?s ?S ?d ?D ?p ?P ?o ?O ?r ?R ?f ?F). Here is the -precise meaning of each character: +\(?n ?N ?a ?A ?t ?T ?s ?S ?d ?D ?p ?P ?o ?O ?r ?R ?f ?F ?k ?K). Here is +the precise meaning of each character: -n Numerically, by converting the beginning of the entry/item to a number. a Alphabetically, ignoring the TODO keyword and the priority, if any. -o By order of TODO keywords. -t By date/time, either the first active time stamp in the entry, or, if - none exist, by the first inactive one. -s By the scheduled date/time. -d By deadline date/time. c By creation time, which is assumed to be the first inactive time stamp at the beginning of a line. +d By deadline date/time. +k By clocking time. +n Numerically, by converting the beginning of the entry/item to a number. +o By order of TODO keywords. p By priority according to the cookie. r By the value of a property. +s By scheduled date/time. +t By date/time, either the first active time stamp in the entry, or, if + none exist, by the first inactive one. Capital letters will reverse the sort order. @@ -8653,7 +8905,9 @@ Comparing entries ignores case by default. However, with an optional argument WITH-CASE, the sorting considers case as well. Sorting is done against the visible part of the headlines, it ignores hidden -links." +links. + +When sorting is done, call `org-after-sorting-entries-or-items-hook'." (interactive "P") (let ((case-func (if with-case 'identity 'downcase)) (cmstr @@ -8662,7 +8916,8 @@ links." (when (equal (marker-buffer org-clock-marker) (current-buffer)) (save-excursion (goto-char org-clock-marker) - (looking-back "^.*") (match-string-no-properties 0)))) + (buffer-substring-no-properties (line-beginning-position) + (point))))) start beg end stars re re2 txt what tmp) ;; Find beginning and end of region to sort @@ -8675,7 +8930,7 @@ links." (if (not (org-at-heading-p)) (outline-next-heading)) (setq start (point))) ((or (org-at-heading-p) - (condition-case nil (progn (org-back-to-heading) t) (error nil))) + (ignore-errors (progn (org-back-to-heading) t))) ;; we will sort the children of the current headline (org-back-to-heading) (setq start (point) @@ -8686,7 +8941,7 @@ links." (point)) what "children") (goto-char start) - (show-subtree) + (outline-show-subtree) (outline-next-heading)) (t ;; we will sort the top-level entries in this file @@ -8702,7 +8957,7 @@ links." (setq end (point-max)) (setq what "top-level") (goto-char start) - (show-all))) + (outline-show-all))) (setq beg (point)) (when (>= beg end) (goto-char start) (user-error "Nothing to sort")) @@ -8719,8 +8974,8 @@ links." (unless sorting-type (message "Sort %s: [a]lpha [n]umeric [p]riority p[r]operty todo[o]rder [f]unc - [t]ime [s]cheduled [d]eadline [c]reated - A/N/P/R/O/F/T/S/D/C means reversed:" + [t]ime [s]cheduled [d]eadline [c]reated cloc[k]ing + A/N/P/R/O/F/T/S/D/C/K means reversed:" what) (setq sorting-type (read-char-exclusive)) @@ -8738,6 +8993,7 @@ links." (mapcar 'list (org-buffer-property-keys t)) nil t)))) + (when (member sorting-type '(?k ?K)) (org-clock-sum)) (message "Sorting entries...") (save-restriction @@ -8772,6 +9028,8 @@ links." (if (looking-at org-complex-heading-regexp) (funcall case-func (org-sort-remove-invisible (match-string 4))) nil)) + ((= dcst ?k) + (or (get-text-property (point) :org-clock-minutes) 0)) ((= dcst ?t) (let ((end (save-excursion (outline-next-heading) (point)))) (if (or (re-search-forward org-ts-regexp end t) @@ -8803,8 +9061,9 @@ links." (or (org-entry-get nil property) "")) ((= dcst ?o) (if (looking-at org-complex-heading-regexp) - (- 9999 (length (member (match-string 2) - org-todo-keywords-1))))) + (let* ((m (match-string 2)) + (s (if (member m org-done-keywords) '- '+))) + (- 99 (funcall s (length (member m org-todo-keywords-1))))))) ((= dcst ?f) (if getkey-func (progn @@ -8817,7 +9076,7 @@ links." (cond ((= dcst ?a) 'string<) ((= dcst ?f) compare-func) - ((member dcst '(?p ?t ?s ?d ?c)) '<))))) + ((member dcst '(?p ?t ?s ?d ?c ?k)) '<))))) (run-hooks 'org-after-sorting-entries-or-items-hook) ;; Reset the clock marker if needed (when cmstr @@ -8827,48 +9086,6 @@ links." (move-marker org-clock-marker (point)))) (message "Sorting entries...done"))) -(defun org-do-sort (table what &optional with-case sorting-type) - "Sort TABLE of WHAT according to SORTING-TYPE. -The user will be prompted for the SORTING-TYPE if the call to this -function does not specify it. WHAT is only for the prompt, to indicate -what is being sorted. The sorting key will be extracted from -the car of the elements of the table. -If WITH-CASE is non-nil, the sorting will be case-sensitive." - (unless sorting-type - (message - "Sort %s: [a]lphabetic, [n]umeric, [t]ime. A/N/T means reversed:" - what) - (setq sorting-type (read-char-exclusive))) - (let ((dcst (downcase sorting-type)) - extractfun comparefun) - ;; Define the appropriate functions - (cond - ((= dcst ?n) - (setq extractfun 'string-to-number - comparefun (if (= dcst sorting-type) '< '>))) - ((= dcst ?a) - (setq extractfun (if with-case (lambda(x) (org-sort-remove-invisible x)) - (lambda(x) (downcase (org-sort-remove-invisible x)))) - comparefun (if (= dcst sorting-type) - 'string< - (lambda (a b) (and (not (string< a b)) - (not (string= a b))))))) - ((= dcst ?t) - (setq extractfun - (lambda (x) - (if (or (string-match org-ts-regexp x) - (string-match org-ts-regexp-both x)) - (org-float-time - (org-time-string-to-time (match-string 0 x))) - 0)) - comparefun (if (= dcst sorting-type) '< '>))) - (t (error "Invalid sorting type `%c'" sorting-type))) - - (sort (mapcar (lambda (x) (cons (funcall extractfun (car x)) (cdr x))) - table) - (lambda (a b) (funcall comparefun (car a) (car b)))))) - - ;;; The orgstruct minor mode ;; Define a minor mode which can be used in other modes in order to @@ -9021,7 +9238,7 @@ buffer. It will also recognize item context in multiline items." outline-previous-visible-heading outline-promote outline-up-heading - show-children)) + outline-show-children)) (let ((f (or (car-safe cell) cell)) (disable-when-heading-prefix (cdr-safe cell))) (when (fboundp f) @@ -9044,11 +9261,11 @@ buffer. It will also recognize item context in multiline items." (dolist (binding new-bindings) (let ((key (lookup-key orgstruct-mode-map binding))) (when (or (not key) (numberp key)) - (condition-case nil - (org-defkey orgstruct-mode-map - binding - (orgstruct-make-binding f binding disable-when-heading-prefix)) - (error nil))))))))) + (ignore-errors + (org-defkey orgstruct-mode-map + binding + (orgstruct-make-binding + f binding disable-when-heading-prefix)))))))))) (run-hooks 'orgstruct-setup-hook)) (defun orgstruct-make-binding (fun key disable-when-heading-prefix) @@ -9150,10 +9367,11 @@ definitions." (list (car c) (car c) (cadr c))) ((string= "" (cadr c)) (list (car c) (car c) (caddr c))) - (t c))) contexts)) - (a alist) c r s) + (t c))) + contexts)) + (a alist) r s) ;; loop over all commands or templates - (while (setq c (pop a)) + (dolist (c a) (let (vrules repl) (cond ((not (assoc (car c) contexts)) @@ -9163,7 +9381,8 @@ definitions." (car c) contexts))) (mapc (lambda (vr) (when (not (equal (car vr) (cadr vr))) - (setq repl vr))) vrules) + (setq repl vr))) + vrules) (if (not repl) (push c r) (push (cadr repl) s) (push @@ -9180,34 +9399,36 @@ definitions." (let ((tpl (car x))) (when (not (delq nil - (mapcar (lambda(y) - (equal y tpl)) s))) x))) + (mapcar (lambda (y) + (equal y tpl)) + s))) + x))) (reverse r)))))) (defun org-contextualize-validate-key (key contexts) "Check CONTEXTS for agenda or capture KEY." - (let (r rr res) - (while (setq r (pop contexts)) + (let (rr res) + (dolist (r contexts) (mapc (lambda (rr) (when - (and (equal key (car r)) - (if (functionp rr) (funcall rr) - (or (and (eq (car rr) 'in-file) - (buffer-file-name) - (string-match (cdr rr) (buffer-file-name))) - (and (eq (car rr) 'in-mode) - (string-match (cdr rr) (symbol-name major-mode))) - (and (eq (car rr) 'in-buffer) - (string-match (cdr rr) (buffer-name))) - (when (and (eq (car rr) 'not-in-file) - (buffer-file-name)) - (not (string-match (cdr rr) (buffer-file-name)))) - (when (eq (car rr) 'not-in-mode) - (not (string-match (cdr rr) (symbol-name major-mode)))) - (when (eq (car rr) 'not-in-buffer) - (not (string-match (cdr rr) (buffer-name))))))) - (push r res))) + (and (equal key (car r)) + (if (functionp rr) (funcall rr) + (or (and (eq (car rr) 'in-file) + (buffer-file-name) + (string-match (cdr rr) (buffer-file-name))) + (and (eq (car rr) 'in-mode) + (string-match (cdr rr) (symbol-name major-mode))) + (and (eq (car rr) 'in-buffer) + (string-match (cdr rr) (buffer-name))) + (when (and (eq (car rr) 'not-in-file) + (buffer-file-name)) + (not (string-match (cdr rr) (buffer-file-name)))) + (when (eq (car rr) 'not-in-mode) + (not (string-match (cdr rr) (symbol-name major-mode)))) + (when (eq (car rr) 'not-in-buffer) + (not (string-match (cdr rr) (buffer-name))))))) + (push r res))) (car (last r)))) (delete-dups (delq nil res)))) @@ -9278,8 +9499,6 @@ call CMD." (eval `(let ,binds (call-interactively (quote ,cmd)))))) -;;;; Archiving - (defun org-get-category (&optional pos force-refresh) "Get the category applying to position POS." (save-match-data @@ -9289,56 +9508,109 @@ call CMD." (progn (org-refresh-category-properties) (get-text-property pos 'org-category)))))) -(defun org-refresh-category-properties () - "Refresh category text properties in the buffer." +;;; Refresh properties + +(defun org-refresh-properties (dprop tprop) + "Refresh buffer text properties. +DPROP is the drawer property and TPROP is either the +corresponding text property to set, or an alist with each element +being a text property (as a symbol) and a function to apply to +the value of the drawer property." (let ((case-fold-search t) - (inhibit-read-only t) - (def-cat (cond - ((null org-category) - (if buffer-file-name - (file-name-sans-extension - (file-name-nondirectory buffer-file-name)) - "???")) - ((symbolp org-category) (symbol-name org-category)) - (t org-category))) - beg end cat pos optionp) + (inhibit-read-only t)) (org-with-silent-modifications (save-excursion (save-restriction (widen) (goto-char (point-min)) - (put-text-property (point) (point-max) 'org-category def-cat) - (while (re-search-forward - "^\\(#\\+CATEGORY:\\|[ \t]*:CATEGORY:\\)\\(.*\\)" nil t) - (setq pos (match-end 0) - optionp (equal (char-after (match-beginning 0)) ?#) - cat (org-trim (match-string 2))) - (if optionp - (setq beg (point-at-bol) end (point-max)) - (org-back-to-heading t) - (setq beg (point) end (org-end-of-subtree t t))) - (put-text-property beg end 'org-category cat) - (put-text-property beg end 'org-category-position beg) - (goto-char pos))))))) + (while (re-search-forward (concat "^[ \t]*:" dprop ": +\\(.*\\)[ \t]*$") nil t) + (org-refresh-property tprop (org-match-string-no-properties 1)))))))) -(defun org-refresh-properties (dprop tprop) - "Refresh buffer text properties. -DPROP is the drawer property and TPROP is the corresponding text -property to set." +(defun org-refresh-property (tprop p) + "Refresh the buffer text property TPROP from the drawer property P. +The refresh happens only for the current tree (not subtree)." + (unless (org-before-first-heading-p) + (save-excursion + (org-back-to-heading t) + (if (symbolp tprop) + ;; TPROP is a text property symbol + (put-text-property + (point) (or (outline-next-heading) (point-max)) tprop p) + ;; TPROP is an alist with (properties . function) elements + (dolist (al tprop) + (save-excursion + (put-text-property + (line-beginning-position) (or (outline-next-heading) (point-max)) + (car al) + (funcall (cdr al) p)))))))) + +(defun org-refresh-category-properties () + "Refresh category text properties in the buffer." (let ((case-fold-search t) - (inhibit-read-only t) p) + (inhibit-read-only t) + (default-category + (cond ((null org-category) + (if buffer-file-name + (file-name-sans-extension + (file-name-nondirectory buffer-file-name)) + "???")) + ((symbolp org-category) (symbol-name org-category)) + (t org-category)))) + (org-with-silent-modifications + (org-with-wide-buffer + ;; Set buffer-wide category. Search last #+CATEGORY keyword. + ;; This is the default category for the buffer. If none is + ;; found, fall-back to `org-category' or buffer file name. + (put-text-property + (point-min) (point-max) + 'org-category + (catch 'buffer-category + (goto-char (point-max)) + (while (re-search-backward "^[ \t]*#\\+CATEGORY:" (point-min) t) + (let ((element (org-element-at-point))) + (when (eq (org-element-type element) 'keyword) + (throw 'buffer-category + (org-element-property :value element))))) + default-category)) + ;; Set sub-tree specific categories. + (goto-char (point-min)) + (let ((regexp (org-re-property "CATEGORY"))) + (while (re-search-forward regexp nil t) + (let ((value (org-match-string-no-properties 3))) + (when (org-at-property-p) + (put-text-property + (save-excursion (org-back-to-heading t) (point)) + (save-excursion (org-end-of-subtree t t) (point)) + 'org-category + value))))))))) + +(defun org-refresh-stats-properties () + "Refresh stats text properties in the buffer." + (let (stats) (org-with-silent-modifications (save-excursion (save-restriction (widen) (goto-char (point-min)) - (while (re-search-forward (concat "^[ \t]*:" dprop ": +\\(.*\\)[ \t]*$") nil t) - (setq p (org-match-string-no-properties 1)) - (save-excursion - (org-back-to-heading t) - (put-text-property - (point-at-bol) (or (outline-next-heading) (point-max)) tprop p)))))))) - + (while (re-search-forward + (concat org-outline-regexp-bol ".*" + "\\(?:\\[\\([0-9]+\\)%\\|\\([0-9]+\\)/\\([0-9]+\\)\\]\\)") + nil t) + (setq stats (cond ((equal (match-string 3) "0") 0) + ((match-string 2) + (/ (* (string-to-number (match-string 2)) 100) + (string-to-number (match-string 3)))) + (t (string-to-number (match-string 1))))) + (org-back-to-heading t) + (put-text-property (point) (progn (org-end-of-subtree t t) (point)) + 'org-stats stats))))))) + +(defun org-refresh-effort-properties () + "Refresh effort properties" + (org-refresh-properties + org-effort-property + '((effort . identity) + (effort-minutes . org-duration-string-to-minutes)))) ;;;; Link Stuff @@ -9415,20 +9687,20 @@ EXPORT should format the link path for export to one of the export formats. It should be a function accepting three arguments: path the path of the link, the text after the prefix (like \"http:\") - desc the description of the link, if any, or a description added by - org-export-normalize-links if there is none - format the export format, a symbol like `html' or `latex' or `ascii'.. + desc the description of the link, if any + format the export format, a symbol like `html' or `latex' or `ascii'. The function may use the FORMAT information to return different values depending on the format. The return value will be put literally into the exported file. If the return value is nil, this means Org should do what it normally does with links which do not have EXPORT defined. -Org-mode has a built-in default for exporting links. If you are happy with +Org mode has a built-in default for exporting links. If you are happy with this default, there is no need to define an export function for the link type. For a simple example of an export function, see `org-bbdb.el'." (add-to-list 'org-link-types type t) (org-make-link-regexps) + (org-element-update-syntax) (if (assoc type org-link-protocols) (setcdr (assoc type org-link-protocols) (list follow export)) (push (list type follow export) org-link-protocols))) @@ -9440,16 +9712,16 @@ type. For a simple example of an export function, see `org-bbdb.el'." (defun org-store-link (arg) "\\Store an org-link to the current location. This link is added to `org-stored-links' and can later be inserted -into an org-buffer with \\[org-insert-link]. +into an Org buffer with \\[org-insert-link]. -For some link types, a prefix arg is interpreted. -For links to Usenet articles, arg negates `org-gnus-prefer-web-links'. -For file links, arg negates `org-context-in-file-links'. +For some link types, a prefix ARG is interpreted. +For links to Usenet articles, ARG negates `org-gnus-prefer-web-links'. +For file links, ARG negates `org-context-in-file-links'. -A double prefix arg force skipping storing functions that are not +A double prefix ARG force skipping storing functions that are not part of Org's core. -A triple prefix arg force storing a link for each line in the +A triple prefix ARG force storing a link for each line in the active region." (interactive "P") (org-load-modules-maybe) @@ -9486,27 +9758,35 @@ active region." (funcall (caar sfuns))) (setq link (plist-get org-store-link-plist :link) desc (or (plist-get org-store-link-plist - :description) link)))) + :description) + link)))) - ;; Store a link from a source code buffer + ;; Store a link from a source code buffer. ((org-src-edit-buffer-p) - (let (label gc) - (while (or (not label) - (save-excursion - (save-restriction - (widen) - (goto-char (point-min)) - (re-search-forward - (regexp-quote (format org-coderef-label-format label)) - nil t)))) - (when label (message "Label exists already") (sit-for 2)) - (setq label (read-string "Code line label: " label))) - (end-of-line 1) - (setq link (format org-coderef-label-format label)) - (setq gc (- 79 (length link))) - (if (< (current-column) gc) (org-move-to-column gc t) (insert " ")) - (insert link) - (setq link (concat "(" label ")") desc nil))) + (cond + ((save-excursion + (beginning-of-line) + (looking-at (concat (format org-coderef-label-format "\\(.*?\\)") + "[ \t]*$"))) + (setq link (format "(%s)" (org-match-string-no-properties 1)))) + ((org-called-interactively-p 'any) + (let (label) + (while (or (not label) + (org-with-wide-buffer + (goto-char (point-min)) + (re-search-forward + (regexp-quote (format org-coderef-label-format label)) + nil t))) + (when label (message "Label exists already") (sit-for 2)) + (setq label (read-string "Code line label: " label))) + (end-of-line) + (setq link (format org-coderef-label-format label)) + (let ((gc (- 79 (length link)))) + (if (< (current-column) gc) (org-move-to-column gc t) + (insert " "))) + (insert link) + (setq link (concat "(" label ")") desc nil))) + (t (setq link nil)))) ;; We are in the agenda, link to referenced location ((equal (org-bound-and-true-p org-agenda-buffer-name) (buffer-name)) @@ -9551,7 +9831,7 @@ active region." (org-store-link-props :type "image" :file buffer-file-name)) ;; In dired, store a link to the file of the current line - ((eq major-mode 'dired-mode) + ((derived-mode-p 'dired-mode) (let ((file (dired-get-filename nil t))) (setq file (if file (abbreviate-file-name @@ -9666,7 +9946,8 @@ active region." ;; Return the link (if (not (and (or (org-called-interactively-p 'any) - executing-kbd-macro) link)) + executing-kbd-macro) + 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)) @@ -9752,44 +10033,42 @@ according to FMT (default from `org-email-link-description-format')." (defun org-make-link-string (link &optional description) "Make a link with brackets, consisting of LINK and DESCRIPTION." - (unless (string-match "\\S-" link) - (error "Empty link")) - (when (and description - (stringp description) - (not (string-match "\\S-" description))) - (setq description nil)) - (when (stringp description) - ;; Remove brackets from the description, they are fatal. - (while (string-match "\\[" description) - (setq description (replace-match "{" t t description))) - (while (string-match "\\]" description) - (setq description (replace-match "}" t t description)))) - (when (equal link description) - ;; No description needed, it is identical - (setq description nil)) - (when (and (not description) - (not (string-match (org-image-file-name-regexp) link)) - (not (equal link (org-link-escape link)))) - (setq description (org-extract-attributes link))) - (setq link - (cond ((string-match (org-image-file-name-regexp) link) link) - ((string-match org-link-types-re link) - (concat (match-string 1 link) - (org-link-escape (substring link (match-end 1))))) - (t (org-link-escape link)))) - (concat "[[" link "]" - (if description (concat "[" 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))))) + ;; For readability, url-encode internal links only + ;; when absolutely needed (i.e, when they contain + ;; square brackets). File links however, are + ;; encoded since, e.g., spaces are significant. + ((or (file-name-absolute-p link) + (org-string-match-p "\\`\\.\\.?/\\|[][]" link)) + (org-link-escape link)) + (t link))) + (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) "")))) (defconst org-link-escape-chars - '(?\ ?\[ ?\] ?\; ?\= ?\+) - "List of characters that should be escaped in link. + ;;%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.") (defconst org-link-escape-chars-browser - '(?\ ?\") - "List of escapes for characters that are problematic in links. -This is the list that is used before handing over to the browser.") + ;;%20 %22 + '(?\s ?\") + "List of characters to be escaped before handing over to the browser. +If you consider using this constant then you probably want to use +the function `org-link-escape-browser' instead. See there why +this constant is a candidate to be removed once Org drops support +for Emacs 24.1 and 24.2.") (defun org-link-escape (text &optional table merge) "Return percent escaped representation of TEXT. @@ -9798,35 +10077,52 @@ 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'." - (cond - ((and table merge) - (mapc (lambda (defchr) - (unless (member defchr table) - (setq table (cons defchr table)))) org-link-escape-chars)) - ((null table) - (setq table org-link-escape-chars))) - (mapconcat - (lambda (char) - (if (or (member char table) - (and (or (< char 32) (= char 37) (> char 126)) - org-url-hexify-p)) - (mapconcat (lambda (sequence-element) - (format "%%%.2X" sequence-element)) - (or (encode-coding-char char 'utf-8) - (error "Unable to percent escape character: %s" - (char-to-string char))) "") - (char-to-string char))) text "")) + (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-escape-browser (text) + "Escape some characters before handing over to the browser. +This function is a candidate to be removed together with the +constant `org-link-escape-chars-browser' once Org drops support +for Emacs 24.1 and 24.2. All calls to this function will have to +be replaced with `url-encode-url' which is available since Emacs +24.3.1." + ;; Example with the Org link + ;; [[http://lists.gnu.org/archive/cgi-bin/namazu.cgi?idxname=emacs-orgmode&query=%252Bsubject:"Release+8.2"]] + ;; to open the browser with +subject:"Release 8.2" filled into the + ;; query field: In this case the variable TEXT contains the + ;; unescaped [...]=%2Bsubject:"Release+8.2". Then `url-encode-url' + ;; converts correctly to [...]=%2Bsubject:%22Release+8.2%22 or + ;; `org-link-escape' with `org-link-escape-chars-browser' converts + ;; wrongly to [...]=%252Bsubject:%22Release+8.2%22. + (if (fboundp 'url-encode-url) + (url-encode-url text) + (if (org-string-match-p + (concat "[[:nonascii:]" org-link-escape-chars-browser "]") + text) + (org-link-escape text org-link-escape-chars-browser) + text))) (defun org-link-unescape (str) - "Unhex hexified Unicode strings as returned from the JavaScript function -encodeURIComponent. E.g. `%C3%B6' is the german o-Umlaut." - (unless (and (null str) (string= "" str)) - (let ((pos 0) (case-fold-search t) unhexed) - (while (setq pos (string-match "\\(%[0-9a-f][0-9a-f]\\)+" str pos)) - (setq unhexed (org-link-unescape-compound (match-string 0 str))) - (setq str (replace-match unhexed t t str)) - (setq pos (+ pos (length unhexed)))))) - 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. @@ -9858,9 +10154,8 @@ Note: this function also decodes single byte encodings like (setq ret (concat ret (org-char-to-string sum))) (setq sum 0)) ((not bytes) ; single byte(s) - (setq ret (org-link-unescape-single-byte-sequence hex)))) - )) ;; end (while bytes - ret ))) + (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." @@ -9890,8 +10185,8 @@ Note: this function also decodes single byte encodings like (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." +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) ""))) (concat (format "%-45s" (substring desc 0 (min (length desc) 40))) "<" (car link) ">"))) @@ -9904,14 +10199,33 @@ This command can be called in any mode to insert a link in Org-mode syntax." (org-load-modules-maybe) (org-run-like-in-org-mode 'org-insert-link)) -(defun org-insert-all-links (&optional keep) - "Insert all links in `org-stored-links'." +(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 ((links (copy-sequence org-stored-links)) l) - (while (setq l (if keep (pop links) (pop org-stored-links))) - (insert "- ") - (org-insert-link nil (car l) (or (cadr l) "")) - (insert "\n")))) + (let ((org-keep-stored-link-after-insertion (equal arg '(4))) + (links (copy-seq 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) "")) + (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'." @@ -10125,7 +10439,9 @@ Use TAB to complete link prefixes, then RET for type-specific completion support (unless (string-match "\\S-" desc) (setq desc nil)) (if remove (apply 'delete-region remove)) - (insert (org-make-link-string link desc)))) + (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." @@ -10136,24 +10452,22 @@ Use TAB to complete link prefixes, then RET for type-specific completion support (defun org-file-complete-link (&optional arg) "Create a file link using completion." - (let (file link) - (setq file (org-iread-file-name "File: ")) - (let ((pwd (file-name-as-directory (expand-file-name "."))) - (pwd1 (file-name-as-directory (abbreviate-file-name - (expand-file-name "."))))) - (cond - ((equal arg '(16)) - (setq link (concat - "file:" - (abbreviate-file-name (expand-file-name file))))) - ((string-match (concat "^" (regexp-quote pwd1) "\\(.+\\)") file) - (setq link (concat "file:" (match-string 1 file)))) - ((string-match (concat "^" (regexp-quote pwd) "\\(.+\\)") - (expand-file-name file)) - (setq link (concat - "file:" (match-string 1 (expand-file-name file))))) - (t (setq link (concat "file:" file))))) - link)) + (let ((file (org-iread-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-iread-file-name (&rest args) "Read-file-name using `ido-mode' speedup if available. @@ -10162,11 +10476,11 @@ See `read-file-name' for a description of parameters." (org-without-partial-completion (if (and org-completion-use-ido (fboundp 'ido-read-file-name) - (boundp 'ido-mode) ido-mode - (listp (second args))) + (org-bound-and-true-p ido-mode) + (listp (nth 1 args))) (let ((ido-enter-matching-directory nil)) - (apply 'ido-read-file-name args)) - (apply 'read-file-name args)))) + (apply #'ido-read-file-name args)) + (apply #'read-file-name args)))) (defun org-completing-read (&rest args) "Completing-read with SPACE being a normal character." @@ -10193,40 +10507,24 @@ from." (iswitchb-read-buffer prompt))) (defun org-icompleting-read (&rest args) - "Completing-read using `ido-mode' or `iswitchb' speedups if available." + "Completing-read using `ido-mode' or `iswitchb' speedups if available. +Should be called like `completing-read'." (org-without-partial-completion - (if (and org-completion-use-ido - (fboundp 'ido-completing-read) - (boundp 'ido-mode) ido-mode - (listp (second args))) - (let ((ido-enter-matching-directory nil)) - (apply 'ido-completing-read (concat (car args)) - (if (consp (car (nth 1 args))) - (mapcar 'car (nth 1 args)) - (nth 1 args)) - (cddr args))) - (if (and org-completion-use-iswitchb - (boundp 'iswitchb-mode) iswitchb-mode - (listp (second args))) - (apply 'org-iswitchb-completing-read (concat (car args)) - (if (consp (car (nth 1 args))) - (mapcar 'car (nth 1 args)) - (nth 1 args)) - (cddr args)) - (apply 'completing-read args))))) - -(defun org-extract-attributes (s) - "Extract the attributes cookie from a string and set as text property." - (let (a attr (start 0) key value) - (save-match-data - (when (string-match "{{\\([^}]+\\)}}$" s) - (setq a (match-string 1 s) s (substring s 0 (match-beginning 0))) - (while (string-match "\\([a-zA-Z]+\\)=\"\\([^\"]*\\)\"" a start) - (setq key (match-string 1 a) value (match-string 2 a) - start (match-end 0) - attr (plist-put attr (intern key) value)))) - (org-add-props s nil 'org-attr attr)) - s)) + (if (not (listp (nth 1 args))) + ;; Ido only supports lists as the COLLECTION argument. Use + ;; default completion function when second argument is not + ;; a list. + (apply #'completing-read args) + (let ((ido-enter-matching-directory nil)) + (apply (cond ((and org-completion-use-ido + (fboundp 'ido-completing-read) + (org-bound-and-true-p ido-mode)) + #'ido-completing-read) + ((and org-completion-use-iswitchb + (org-bound-and-true-p iswitchb-mode)) + #'org-iswitchb-completing-read) + (t #'completing-read)) + args))))) ;;; Opening/following a link @@ -10281,14 +10579,9 @@ If the link is in hidden text, expose it." (defun org-translate-link (s) "Translate a link string if a translation function has been defined." - (if (and org-link-translation-function - (fboundp org-link-translation-function) - (string-match "\\([a-zA-Z0-9]+\\):\\(.*\\)" s)) - (progn - (setq s (funcall org-link-translation-function - (match-string 1 s) (match-string 2 s))) - (concat (car s) ":" (cdr s))) - s)) + (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. @@ -10330,9 +10623,6 @@ 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.") -(defvar org-open-link-marker (make-marker) - "Marker pointing to the location where `org-open-at-point' was called.") - ;;;###autoload (defun org-open-at-point-global () "Follow a link like Org-mode does. @@ -10367,264 +10657,238 @@ they must return nil.") (defvar org-link-search-inhibit-query nil) ;; dynamically scoped (defvar clean-buffer-list-kill-buffer-names) ; Defined in midnight.el (defun org-open-at-point (&optional arg reference-buffer) - "Open link at or after point. -If there is no link at point, this function will search forward up to -the end of the current line. -Normally, files will be opened by an appropriate application. If the -optional prefix argument ARG is non-nil, Emacs will visit the file. -With a double prefix argument, try to open outside of Emacs, in the -application the system uses for this file type." - (interactive "P") - ;; if in a code block, then open the block's results - (unless (call-interactively #'org-babel-open-src-block-result) - (org-load-modules-maybe) - (move-marker org-open-link-marker (point)) - (setq org-window-config-before-follow-link (current-window-configuration)) - (org-remove-occur-highlights nil nil t) - (cond - ((and (org-at-heading-p) - (not (org-at-timestamp-p t)) - (not (org-in-regexp - (concat org-plain-link-re "\\|" - org-bracket-link-regexp "\\|" - org-angle-link-re "\\|" - "[ \t]:[^ \t\n]+:[ \t]*$"))) - (not (get-text-property (point) 'org-linked-text))) - (or (let* ((lkall (org-offer-links-in-entry (current-buffer) (point) arg)) - (lk0 (car lkall)) - (lk (if (stringp lk0) (list lk0) lk0)) - (lkend (cdr lkall))) - (mapcar (lambda(l) - (search-forward l nil lkend) - (goto-char (match-beginning 0)) - (org-open-at-point)) - lk)) - (progn (require 'org-attach) (org-attach-reveal 'if-exists)))) - ((run-hook-with-args-until-success 'org-open-at-point-functions)) - ((and (org-at-timestamp-p t) - (not (org-in-regexp org-bracket-link-regexp))) - (org-follow-timestamp-link)) - ((and (or (org-footnote-at-reference-p) (org-footnote-at-definition-p)) - (not (org-in-regexp org-any-link-re))) - (org-footnote-action)) - (t - (let (type path link line search (pos (point))) - (catch 'match - (save-excursion - (or (org-in-regexp org-plain-link-re) - (skip-chars-forward "^]\n\r")) - (when (org-in-regexp org-bracket-link-regexp 1) - (setq link (org-extract-attributes - (org-link-unescape (org-match-string-no-properties 1)))) - (while (string-match " *\n *" link) - (setq link (replace-match " " t t link))) - (setq link (org-link-expand-abbrev link)) - (cond - ((or (file-name-absolute-p link) - (string-match "^\\.\\.?/" link)) - (setq type "file" path link)) - ((string-match org-link-re-with-space3 link) - (setq type (match-string 1 link) path (match-string 2 link))) - ((string-match "^help:+\\(.+\\)" link) - (setq type "help" path (match-string 1 link))) - (t (setq type "thisfile" path link))) - (throw 'match t))) - - (when (get-text-property (point) 'org-linked-text) - (setq type "thisfile" - pos (if (get-text-property (1+ (point)) 'org-linked-text) - (1+ (point)) (point)) - path (buffer-substring - (or (previous-single-property-change pos 'org-linked-text) - (point-min)) - (or (next-single-property-change pos 'org-linked-text) - (point-max))) - ;; Ensure we will search for a <<>> link, not - ;; a simple reference like <> - path (concat "<" path)) - (throw 'match t)) + "Open link, timestamp, footnote or tags at point. - (save-excursion - (when (or (org-in-regexp org-angle-link-re) - (let ((match (org-in-regexp org-plain-link-re))) - ;; Check a plain link is not within a bracket link - (and match - (save-excursion - (save-match-data - (progn - (goto-char (car match)) - (not (org-in-regexp org-bracket-link-regexp))))))) - (let ((line_ending (save-excursion (end-of-line) (point)))) - ;; We are in a line before a plain or bracket link - (or (re-search-forward org-plain-link-re line_ending t) - (re-search-forward org-bracket-link-regexp line_ending t)))) - (setq type (match-string 1) - path (org-link-unescape (match-string 2))) - (throw 'match t))) - (save-excursion - (when (org-in-regexp (org-re "\\(:[[:alnum:]_@#%:]+\\):[ \t]*$")) - (setq type "tags" - path (match-string 1)) - (while (string-match ":" path) - (setq path (replace-match "+" t t path))) - (throw 'match t))) - (when (org-in-regexp "<\\([^><\n]+\\)>") - (setq type "tree-match" - path (match-string 1)) - (throw 'match t))) - (unless path - (user-error "No link found")) +When point is on a link, follow it. Normally, files will be +opened by an appropriate application. If the optional prefix +argument ARG is non-nil, Emacs will visit the file. With +a double prefix argument, try to open outside of Emacs, in the +application the system uses for this file type. - ;; switch back to reference buffer - ;; needed when if called in a temporary buffer through - ;; org-open-link-from-string - (with-current-buffer (or reference-buffer (current-buffer)) +When point is on a timestamp, open the agenda at the day +specified. - ;; Remove any trailing spaces in path - (if (string-match " +\\'" path) - (setq path (replace-match "" t t path))) - (if (and org-link-translation-function - (fboundp org-link-translation-function)) - ;; Check if we need to translate the link - (let ((tmp (funcall org-link-translation-function type path))) - (setq type (car tmp) path (cdr tmp)))) +When point is a footnote definition, move to the first reference +found. If it is on a reference, move to the associated +definition. - (cond +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. - ((assoc type org-link-protocols) - (funcall (nth 1 (assoc type org-link-protocols)) path)) - - ((equal type "help") - (let ((f-or-v (intern path))) - (cond ((fboundp f-or-v) - (describe-function f-or-v)) - ((boundp f-or-v) - (describe-variable f-or-v)) - (t (error "Not a known function or variable"))))) - - ((equal type "mailto") - (let ((cmd (car org-link-mailto-program)) - (args (cdr org-link-mailto-program)) args1 - (address path) (subject "") a) - (if (string-match "\\(.*\\)::\\(.*\\)" path) - (setq address (match-string 1 path) - subject (org-link-escape (match-string 2 path)))) - (while args - (cond - ((not (stringp (car args))) (push (pop args) args1)) - (t (setq a (pop args)) - (if (string-match "%a" a) - (setq a (replace-match address t t a))) - (if (string-match "%s" a) - (setq a (replace-match subject t t a))) - (push a args1)))) - (apply cmd (nreverse args1)))) - - ((member type '("http" "https" "ftp" "news")) - (browse-url - (concat type ":" - (if (org-string-match-p - (concat "[[:nonascii:]" - org-link-escape-chars-browser "]") - path) - (org-link-escape path org-link-escape-chars-browser) - path)))) - - ((string= type "doi") - (browse-url - (concat org-doi-server-url - (if (org-string-match-p - (concat "[[:nonascii:]" - org-link-escape-chars-browser "]") - path) - (org-link-escape path org-link-escape-chars-browser) - path)))) - - ((member type '("message")) - (browse-url (concat type ":" path))) - - ((string= type "tags") - (org-tags-view arg path)) - - ((string= type "tree-match") - (org-occur (concat "\\[" (regexp-quote path) "\\]"))) - - ((string= type "file") - (if (string-match "::\\([0-9]+\\)\\'" path) - (setq line (string-to-number (match-string 1 path)) - path (substring path 0 (match-beginning 0))) - (if (string-match "::\\(.+\\)\\'" path) - (setq search (match-string 1 path) - path (substring path 0 (match-beginning 0))))) - (if (string-match "[*?{]" (file-name-nondirectory path)) - (dired path) - (org-open-file path arg line search))) - - ((string= type "shell") - (let ((buf (generate-new-buffer "*Org Shell Output")) - (cmd path)) - (if (or (and (not (string= 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) - (if (featurep 'midnight) - (setq clean-buffer-list-kill-buffer-names - (cons buf clean-buffer-list-kill-buffer-names)))) - (error "Abort")))) - - ((string= type "elisp") - (let ((cmd path)) - (if (or (and (not (string= org-confirm-elisp-link-not-regexp "")) - (string-match 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 (equal (string-to-char cmd) ?\() - (eval (read cmd)) - (call-interactively (read cmd)))) - (error "Abort")))) - - ((and (string= type "thisfile") - (or (run-hook-with-args-until-success - 'org-open-link-functions path) - (and link - (string-match "^id:" link) - (or (featurep 'org-id) (require 'org-id)) - (progn - (funcall (nth 1 (assoc "id" org-link-protocols)) - (substring path 3)) - t))))) - - ((string= type "thisfile") - (if arg - (switch-to-buffer-other-window - (org-get-buffer-for-internal-link (current-buffer))) - (org-mark-ring-push)) - (let ((cmd `(org-link-search - ,path - ,(cond ((equal arg '(4)) ''occur) - ((equal arg '(16)) ''org-occur)) - ,pos))) - (condition-case nil (let ((org-link-search-inhibit-query t)) - (eval cmd)) - (error (progn (widen) (eval cmd)))))) - - (t (browse-url-at-point))))))) - (move-marker org-open-link-marker nil) - (run-hook-with-args 'org-follow-link-hook))) +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'. -(defsubst org-uniquify (list) - "Non-destructively remove duplicate elements from LIST." - (let ((res (copy-sequence list))) (delete-dups res))) +On top of syntactically correct links, this function will open +the link at point in comments or comment blocks and the first +link in a property drawer line." + (interactive "P") + ;; On a code block, open block's results. + (unless (call-interactively 'org-babel-open-src-block-result) + (org-load-modules-maybe) + (setq org-window-config-before-follow-link (current-window-configuration)) + (org-remove-occur-highlights nil nil t) + (unless (run-hook-with-args-until-success 'org-open-at-point-functions) + (let* ((context + ;; Only consider supported types, even if they are not + ;; the closest one. + (org-element-lineage + (org-element-context) + '(clock comment comment-block footnote-definition + footnote-reference headline inlinetask keyword link + node-property timestamp) + t)) + (type (org-element-type context)) + (value (org-element-property :value context))) + (cond + ((not context) (user-error "No link found")) + ;; Exception: open timestamps and links in properties + ;; drawers, keywords and comments. + ((memq type '(comment comment-block keyword node-property)) + (cond ((org-in-regexp org-any-link-re) + (org-open-link-from-string (match-string-no-properties 0))) + ((or (org-at-timestamp-p t) (org-at-date-range-p t)) + (org-follow-timestamp-link)) + (t (user-error "No link found")))) + ;; On a headline or an inlinetask, but not on a timestamp, + ;; a link, a footnote reference or on tags. + ((and (memq type '(headline inlinetask)) + ;; Not on tags. + (progn (save-excursion (beginning-of-line) + (looking-at org-complex-heading-regexp)) + (or (not (match-beginning 5)) + (< (point) (match-beginning 5))))) + (let* ((data (org-offer-links-in-entry (current-buffer) (point) arg)) + (links (car data)) + (links-end (cdr data))) + (if links + (dolist (link (if (stringp links) (list links) links)) + (search-forward link nil links-end) + (goto-char (match-beginning 0)) + (org-open-at-point)) + (require 'org-attach) + (org-attach-reveal 'if-exists)))) + ;; On a clock line, make sure point is on the timestamp + ;; before opening it. + ((and (eq type 'clock) + value + (>= (point) (org-element-property :begin value)) + (<= (point) (org-element-property :end value))) + (org-follow-timestamp-link)) + ;; Do nothing on white spaces after an object, unless point + ;; is right after it. + ((> (point) + (save-excursion + (goto-char (org-element-property :end context)) + (skip-chars-backward " \t") + (point))) + (user-error "No link found")) + ((eq type 'timestamp) (org-follow-timestamp-link)) + ;; On tags within a headline or an inlinetask. + ((and (memq type '(headline inlinetask)) + (progn (save-excursion (beginning-of-line) + (looking-at org-complex-heading-regexp)) + (and (match-beginning 5) + (>= (point) (match-beginning 5))))) + (org-tags-view arg (substring (match-string 5) 0 -1))) + ((eq type 'link) + ;; When link is located within the description of another + ;; link (e.g., an inline image), always open the parent + ;; link. + (let*((link (let ((up (org-element-property :parent context))) + (if (eq (org-element-type up) 'link) up context))) + (type (org-element-property :type link)) + (path (org-link-unescape (org-element-property :path link)))) + ;; 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-protocols' 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'. + ;; + ;; Note : "file+emacs" and "file+sys" types are + ;; hard-coded in order to escape the previous + ;; limitation. + (let* ((option (org-element-property :search-option link)) + (app (org-element-property :application link)) + (dedicated-function + (nth 1 (assoc app org-link-protocols)))) + (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) + ((org-string-match-p "\\`[0-9]+\\'" option) + (list (string-to-number option))) + (t (list nil + (org-link-unescape option))))))))) + ((assoc type org-link-protocols) + (funcall (nth 1 (assoc type org-link-protocols)) path)) + ((equal type "help") + (let ((f-or-v (intern path))) + (cond ((fboundp f-or-v) (describe-function f-or-v)) + ((boundp f-or-v) (describe-variable f-or-v)) + (t (error "Not a known function or variable"))))) + ((member type '("http" "https" "ftp" "mailto" "news")) + (browse-url (org-link-escape-browser (concat type ":" path)))) + ((equal type "doi") + (browse-url + (org-link-escape-browser (concat org-doi-server-url path)))) + ((equal type "message") (browse-url (concat type ":" path))) + ((equal type "shell") + (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")))) + ((equal type "elisp") + (let ((cmd path)) + (if (or (and (org-string-nw-p + org-confirm-elisp-link-not-regexp) + (org-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")))) + ((equal type "id") + (require 'org-id) + (funcall (nth 1 (assoc "id" org-link-protocols)) 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 link)) + (org-link-search + (if (member type '("custom-id" "coderef")) + (org-element-property :raw-link link) + 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)))))) + ;; On a footnote reference or at a footnote definition's label. + ((or (eq type 'footnote-reference) + (and (eq type 'footnote-definition) + (save-excursion + ;; Do not validate action when point is on the + ;; spaces right after the footnote label, in + ;; order to be on par with behaviour on links. + (skip-chars-forward " \t") + (let ((begin + (org-element-property :contents-begin context))) + (if begin (< (point) begin) + (= (org-element-property :post-affiliated context) + (line-beginning-position))))))) + (org-footnote-action)) + (t (user-error "No link found"))))) + (run-hook-with-args 'org-follow-link-hook))) (defun org-offer-links-in-entry (buffer marker &optional nth zero) "Offer links in the current entry and return the selected link. @@ -10637,10 +10901,7 @@ there is one, return it." (save-restriction (widen) (goto-char marker) - (let ((re (concat "\\(" org-bracket-link-regexp "\\)\\|" - "\\(" org-angle-link-re "\\)\\|" - "\\(" org-plain-link-re "\\)")) - (cnt ?0) + (let ((cnt ?0) (in-emacs (if (integerp nth) nil nth)) have-zero end links link c) (when (and (stringp zero) (string-match org-bracket-link-regexp zero)) @@ -10649,7 +10910,7 @@ there is one, return it." (save-excursion (org-back-to-heading t) (setq end (save-excursion (outline-next-heading) (point))) - (while (re-search-forward re end t) + (while (re-search-forward org-any-link-re end t) (push (match-string 0) links)) (setq links (org-uniquify (reverse links)))) (cond @@ -10678,7 +10939,7 @@ there is one, return it." (message "Select link to open, RET to open all:") (setq c (read-char-exclusive)) (and (get-buffer "*Select Link*") (kill-buffer "*Select Link*")))) - (when (equal c ?q) (error "Abort")) + (when (equal c ?q) (user-error "Abort")) (if (equal c ?\C-m) (setq link links) (setq nth (- c ?0)) @@ -10688,10 +10949,8 @@ there is one, return it." (setq link (nth (1- nth) links))))) (cons link end)))))) -;; Add special file links that specify the way of opening - -(org-add-link-type "file+sys" 'org-open-file-with-system) -(org-add-link-type "file+emacs" 'org-open-file-with-emacs) +;; TODO: These functions are deprecated since `org-open-at-point' +;; hard-codes behaviour 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)) @@ -10746,173 +11005,205 @@ the window configuration before `org-open-at-point' was called using: (set-window-configuration org-window-config-before-follow-link)") -(defun org-link-search (s &optional type avoid-pos stealth) - "Search for a link search option. -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. If AVOID-POS is given, ignore matches near that position. +(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 + (org-split-string target "[ \t\n]+") + "[ \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-hierarchy-above', `org-show-following-heading' and -`org-show-siblings' variables." - (let ((case-fold-search t) - (s0 (mapconcat 'identity (org-split-string s "[ \t\r\n]+") " ")) - (markers (concat "\\(?:" (mapconcat (lambda (x) (regexp-quote (car x))) - (append '(("") (" ") ("\t") ("\n")) - org-emphasis-alist) - "\\|") "\\)")) - (pos (point)) - (pre nil) (post nil) - words re0 re1 re2 re3 re4_ re4 re5 re2a re2a_ reall) +visibility around point, thus ignoring `org-show-context-detail' +variable. + +Search is case-insensitive and ignores white spaces. Return type +of matched result, with 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)) + (words (org-split-string s "[ \t\n]+")) + (s-multi-re (mapconcat #'regexp-quote words "[ \t]+\\(?:\n[ \t]*\\)?")) + (s-single-re (mapconcat #'regexp-quote words "[ \t]+")) + type) (cond - ;; First check if there are any special search functions + ;; Check if there are any special search functions. ((run-hook-with-args-until-success 'org-execute-file-search-functions s)) - ;; Now try the builtin stuff - ((and (equal (string-to-char s0) ?#) - (> (length s0) 1) - (save-excursion - (goto-char (point-min)) - (and - (re-search-forward - (concat "^[ \t]*:CUSTOM_ID:[ \t]+" - (regexp-quote (substring s0 1)) "[ \t]*$") nil t) - (setq type 'dedicated - pos (match-beginning 0)))) - ;; There is an exact target for this - (goto-char pos) - (org-back-to-heading t))) - ((save-excursion - (goto-char (point-min)) - (and - (re-search-forward - (concat "<<" (regexp-quote s0) ">>") nil t) - (setq type 'dedicated - pos (match-beginning 0)))) - ;; There is an exact target for this - (goto-char pos)) - ((save-excursion + ((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)) - (and - (re-search-forward - (format "^[ \t]*#\\+NAME: %s" (regexp-quote s0)) nil t) - (setq type 'dedicated pos (match-beginning 0)))) - ;; Found an element with a matching #+name affiliated keyword. - (goto-char pos)) - ((and (string-match "^(\\(.*\\))$" s0) - (save-excursion - (goto-char (point-min)) - (and - (re-search-forward - (concat "[^[]" (regexp-quote - (format org-coderef-label-format - (match-string 1 s0)))) - nil t) - (setq type 'dedicated - pos (1+ (match-beginning 0)))))) - ;; There is a coderef target for this - (goto-char pos)) - ((string-match "^/\\(.*\\)/$" s) - ;; A regular expression - (cond - ((derived-mode-p 'org-mode) - (org-occur (match-string 1 s))) - (t (org-do-occur (match-string 1 s))))) - ((and (derived-mode-p 'org-mode) org-link-search-must-match-exact-headline) - (and (equal (string-to-char s) ?*) (setq s (substring s 1))) - (goto-char (point-min)) - (cond - ((let (case-fold-search) - (re-search-forward (format org-complex-heading-regexp-format - (regexp-quote s)) - nil t)) - ;; OK, found a match - (setq type 'dedicated) - (goto-char (match-beginning 0))) - ((and (not org-link-search-inhibit-query) - (eq org-link-search-must-match-exact-headline 'query-to-create) - (y-or-n-p "No match - create this as a new heading? ")) - (goto-char (point-max)) - (or (bolp) (newline)) - (insert "* " s "\n") - (beginning-of-line 0)) - (t - (goto-char pos) - (error "No match")))) + (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)) + ;; Build proper regexp according to current + ;; block's label format. + (let ((label-fmt + (regexp-quote + (or (org-element-property :label-fmt element) + org-coderef-label-format)))) + (save-excursion + (beginning-of-line) + (looking-at (format ".*?\\(%s\\)[ \t]*$" + (format label-fmt coderef)))))) + (setq type 'dedicated) + (goto-char (match-beginning 1)) + (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))) + ;; Fuzzy links. (t - ;; A normal search string - (when (equal (string-to-char s) ?*) - ;; Anchor on headlines, post may include tags. - (setq pre "^\\*+[ \t]+\\(?:\\sw+\\)?[ \t]*" - post (org-re "[ \t]*\\(?:[ \t]+:[[:alnum:]_@#%:+]:[ \t]*\\)?$") - s (substring s 1))) - (remove-text-properties - 0 (length s) - '(face nil mouse-face nil keymap nil fontified nil) s) - ;; Make a series of regular expressions to find a match - (setq words (org-split-string s "[ \n\r\t]+") - - re0 (concat "\\(<<" (regexp-quote s0) ">>\\)") - re2 (concat markers "\\(" (mapconcat 'downcase words "[ \t]+") - "\\)" markers) - re2a_ (concat "\\(" (mapconcat 'downcase words - "[ \t\r\n]+") "\\)[ \t\r\n]") - re2a (concat "[ \t\r\n]" re2a_) - re4_ (concat "\\(" (mapconcat 'downcase words - "[^a-zA-Z_\r\n]+") "\\)[^a-zA-Z_]") - re4 (concat "[^a-zA-Z_]" re4_) - - re1 (concat pre re2 post) - re3 (concat pre (if pre re4_ re4) post) - re5 (concat pre ".*" re4) - re2 (concat pre re2) - re2a (concat pre (if pre re2a_ re2a)) - re4 (concat pre (if pre re4_ re4)) - reall (concat "\\(" re0 "\\)\\|\\(" re1 "\\)\\|\\(" re2 - "\\)\\|\\(" re3 "\\)\\|\\(" re4 "\\)\\|\\(" - re5 "\\)")) - (cond - ((eq type 'org-occur) (org-occur reall)) - ((eq type 'occur) (org-do-occur (downcase reall) 'cleanup)) - (t (goto-char (point-min)) - (setq type 'fuzzy) - (if (or (and (org-search-not-self 1 re0 nil t) - (setq type 'dedicated)) - (org-search-not-self 1 re1 nil t) - (org-search-not-self 1 re2 nil t) - (org-search-not-self 1 re2a nil t) - (org-search-not-self 1 re3 nil t) - (org-search-not-self 1 re4 nil t) - (org-search-not-self 1 re5 nil t)) - (goto-char (match-beginning 1)) - (goto-char pos) - (error "No match")))))) - (and (derived-mode-p 'org-mode) - (not stealth) - (org-show-context 'link-search)) + (let* ((starred (eq (string-to-char normalized) ?*)) + (headline-search (and (derived-mode-p 'org-mode) + (or org-link-search-must-match-exact-headline + starred)))) + (cond + ;; 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 (org-split-string + (org-element-property :name element) + "[ \t]+") + words) + (setq type 'dedicated) + (beginning-of-line) + (throw :name-match t)))) + nil)))) + ;; Regular text search. Prefer headlines in Org mode + ;; buffers. + ((and (derived-mode-p 'org-mode) + (let* ((wspace "[ \t]") + (wspaceopt (concat wspace "*")) + (cookie (concat "\\(?:" + wspaceopt + "\\[[0-9]*\\(?:%\\|/[0-9]*\\)\\]" + wspaceopt + "\\)")) + (sep (concat "\\(?:\\(?:" wspace "\\|" cookie "\\)+\\)")) + (re (concat + org-outline-regexp-bol + "\\(?:" org-todo-regexp "[ \t]+\\)?" + "\\(?:\\[#.\\][ \t]+\\)?" + "\\(?:" org-comment-string "[ \t]+\\)?" + sep "?" + (let ((title (mapconcat #'regexp-quote + words + sep))) + (if starred (substring title 1) title)) + sep "?" + (org-re "\\(?:[ \t]+:[[:alnum:]_@#%%:]+:\\)?") + "[ \t]*$"))) + (goto-char (point-min)) + (re-search-forward re nil t))) + (goto-char (match-beginning 0)) + (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-search-not-self (group &rest args) - "Execute `re-search-forward', but only accept matches that do not -enclose the position of `org-open-link-marker'." - (let ((m org-open-link-marker)) - (catch 'exit - (while (apply 're-search-forward args) - (unless (get-text-property (match-end group) 'intangible) ; Emacs 21 - (goto-char (match-end group)) - (if (and (or (not (eq (marker-buffer m) (current-buffer))) - (> (match-beginning 0) (marker-position m)) - (< (match-end 0) (marker-position m))) - (save-match-data - (or (not (org-in-regexp - org-bracket-link-analytic-regexp 1)) - (not (match-end 4)) ; no description - (and (<= (match-beginning 4) (point)) - (>= (match-end 4) (point)))))) - (throw 'exit (point)))))))) - (defun org-get-buffer-for-internal-link (buffer) "Return a buffer to be used for displaying the link target of internal links." (cond @@ -11158,7 +11449,9 @@ If the file does not exist, an error is thrown." (eq cmd 'emacs)) (funcall (cdr (assq 'file org-link-frame-setup)) file) (widen) - (if line (org-goto-line line) + (if line (progn (org-goto-line line) + (if (derived-mode-p 'org-mode) + (org-reveal))) (if search (org-link-search search)))) ((consp cmd) (let ((file (convert-standard-filename file))) @@ -11179,7 +11472,7 @@ 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 +`%1', i.e. using at least one subexpression match as a parameter." (let ((selector (car entry)) (action (cdr entry))) @@ -11250,12 +11543,9 @@ on the system \"/user@host:\"." ((eq t org-reverse-note-order) t) ((not (listp org-reverse-note-order)) nil) (t (catch 'exit - (let ((all org-reverse-note-order) - entry) - (while (setq entry (pop all)) - (if (string-match (car entry) buffer-file-name) - (throw 'exit (cdr entry)))) - nil))))) + (dolist (entry org-reverse-note-order) + (if (string-match (car entry) buffer-file-name) + (throw 'exit (cdr entry)))))))) (defvar org-refile-target-table nil "The list of refile targets, created by `org-refile'.") @@ -11320,10 +11610,10 @@ on the system \"/user@host:\"." (let ((case-fold-search nil) ;; otherwise org confuses "TODO" as a kw and "Todo" as a word (entries (or org-refile-targets '((nil . (:level . 1))))) - targets tgs txt re files f desc descre fast-path-p level pos0) + targets tgs txt re files desc descre fast-path-p level pos0) (message "Getting targets...") (with-current-buffer (or default-buffer (current-buffer)) - (while (setq entry (pop entries)) + (dolist (entry entries) (setq files (car entry) desc (cdr entry)) (setq fast-path-p nil) (cond @@ -11356,7 +11646,7 @@ on the system \"/user@host:\"." (cdr desc))) "\\}[ \t]"))) (t (error "Bad refiling target description %s" desc))) - (while (setq f (pop files)) + (dolist (f files) (with-current-buffer (if (bufferp f) f (org-get-agenda-file-buffer f)) (or @@ -11384,7 +11674,7 @@ on the system \"/user@host:\"." (setq level (org-reduced-level (- (match-end 1) (match-beginning 1))) txt (org-link-display-format (match-string 4)) - txt (replace-regexp-in-string "\\( *\[[0-9]+/?[0-9]*%?\]\\)+$" "" txt) + txt (replace-regexp-in-string "\\( *[[0-9]+/?[0-9]*%?]\\)+$" "" txt) re (format org-complex-heading-regexp-format (regexp-quote (match-string 4)))) (when org-refile-use-outline-path @@ -11459,38 +11749,28 @@ such as the file name. SEPARATOR is inserted between the different parts of the path, the default is \"/\"." (setq width (or width 79)) - (if prefix (setq width (- width (length prefix)))) - (if (not path) - (or prefix "") - (let* ((nsteps (length path)) - (total-width (+ nsteps (apply '+ (mapcar 'length path)))) - (maxwidth (if (<= total-width width) - 10000 ;; everything fits - ;; we need to shorten the level headings - (/ (- width nsteps) nsteps))) - (org-odd-levels-only nil) - (n 0) - (total (1+ (length prefix)))) - (setq maxwidth (max maxwidth 10)) - (concat prefix - (if prefix (or separator "/")) - (mapconcat - (lambda (h) - (setq n (1+ n)) - (if (and (= n nsteps) (< maxwidth 10000)) - (setq maxwidth (- total-width total))) - (if (< (length h) maxwidth) - (progn (setq total (+ total (length h) 1)) h) - (setq h (substring h 0 (- maxwidth 2)) - total (+ total maxwidth 1)) - (if (string-match "[ \t]+\\'" h) - (setq h (substring h 0 (match-beginning 0)))) - (setq h (concat h ".."))) - (org-add-props h nil 'face - (nth (% (1- n) org-n-level-faces) - org-level-faces)) - h) - path (or separator "/")))))) + (setq path (delq nil path)) + (unless (> width 0) + (user-error "Argument `width' must be positive")) + (setq separator (or separator "/")) + (let* ((org-odd-levels-only nil) + (fpath (concat + prefix (and prefix path separator) + (mapconcat + (lambda (s) (replace-regexp-in-string "[ \t]+\\'" "" s)) + (loop for head in path + for n from 0 + collect (org-add-props + head nil 'face + (nth (% n org-n-level-faces) org-level-faces))) + separator)))) + (when (> (length fpath) width) + (if (< width 7) + ;; It's unlikely that `width' will be this small, but don't + ;; waste characters by adding ".." if it is. + (setq fpath (substring fpath 0 width)) + (setf (substring fpath (- width 2)) ".."))) + fpath)) (defun org-display-outline-path (&optional file current separator just-return-string) "Display the current outline path in the echo area. @@ -11538,30 +11818,29 @@ the *old* location.") (let ((org-refile-keep t)) (funcall 'org-refile nil nil nil "Copy"))) -(defun org-refile (&optional goto default-buffer rfloc msg) +(defun org-refile (&optional arg default-buffer rfloc msg) "Move the entry or entries at point to another heading. The list of target headings is compiled using the information in `org-refile-targets', which see. -At the target location, the entry is filed as a subitem of the target -heading. Depending on `org-reverse-note-order', the new subitem will -either be the first or the last subitem. +At the target location, the entry is filed as a subitem of the +target heading. Depending on `org-reverse-note-order', the new +subitem will either be the first or the last subitem. -If there is an active region, all entries in that region will be moved. -However, the region must fulfill the requirement that the first heading -is the first one sets the top-level of the moved text - at most siblings -below it are allowed. +If there is an active region, all entries in that region will be +refiled. However, the region must fulfill the requirement that +the first heading sets the top-level of the moved text. -With prefix arg GOTO, the command will only visit the target location -and not actually move anything. +With prefix arg ARG, the command will only visit the target +location and not actually move anything. -With a double prefix arg \\[universal-argument] \\[universal-argument], \ -go to the location where the last refiling operation has put the subtree. +With a double prefix arg \\[universal-argument] \\[universal-argument], go to the location where the last +refiling operation has put the subtree. With a numeric prefix argument of `2', refile to the running clock. With a numeric prefix argument of `3', emulate `org-refile-keep' -being set to `t' and copy to the target location, don't move it. +being set to t and copy to the target location, don't move it. Beware that keeping refiled entries may result in duplicated ID properties. @@ -11572,23 +11851,22 @@ another verb. E.g. `org-copy' sets this parameter to \"Copy\". See also `org-refile-use-outline-path' and `org-completion-use-ido'. -If you are using target caching (see `org-refile-use-cache'), -you have to clear the target cache in order to find new targets. +If you are using target caching (see `org-refile-use-cache'), you +have to clear the target cache in order to find new targets. This can be done with a 0 prefix (`C-0 C-c C-w') or a triple prefix argument (`C-u C-u C-u C-c C-w')." - (interactive "P") - (if (member goto '(0 (64))) + (if (member arg '(0 (64))) (org-refile-cache-clear) (let* ((actionmsg (cond (msg msg) - ((equal goto 3) "Refile (and keep)") + ((equal arg 3) "Refile (and keep)") (t "Refile"))) (cbuf (current-buffer)) (regionp (org-region-active-p)) (region-start (and regionp (region-beginning))) (region-end (and regionp (region-end))) (filename (buffer-file-name (buffer-base-buffer cbuf))) - (org-refile-keep (if (equal goto 3) t org-refile-keep)) + (org-refile-keep (if (equal arg 3) t org-refile-keep)) pos it nbuf file re level reversed) (setq last-command nil) (when regionp @@ -11602,10 +11880,10 @@ prefix argument (`C-u C-u C-u C-c C-w')." (org-toggle-heading) (setq region-end (+ (- (point-at-eol) s) region-end))))) (user-error "The region is not a (sequence of) subtree(s)"))) - (if (equal goto '(16)) + (if (equal arg '(16)) (org-refile-goto-last-stored) (when (or - (and (equal goto 2) + (and (equal arg 2) org-clock-hd-marker (marker-buffer org-clock-hd-marker) (prog1 (setq it (list (or org-clock-heading "running clock") @@ -11613,28 +11891,30 @@ prefix argument (`C-u C-u C-u C-c C-w')." (marker-buffer org-clock-hd-marker)) "" (marker-position org-clock-hd-marker))) - (setq goto nil))) + (setq arg nil))) (setq it (or rfloc (let (heading-text) (save-excursion - (unless (and goto (listp goto)) + (unless (and arg (listp arg)) (org-back-to-heading t) (setq heading-text - (nth 4 (org-heading-components)))) - + (replace-regexp-in-string + org-bracket-link-regexp + "\\3" + (nth 4 (org-heading-components))))) (org-refile-get-location - (cond ((and goto (listp goto)) "Goto") + (cond ((and arg (listp arg)) "Goto") (regionp (concat actionmsg " region to")) (t (concat actionmsg " subtree \"" heading-text "\" to"))) default-buffer - (and (not (equal '(4) goto)) + (and (not (equal '(4) arg)) org-refile-allow-creating-parent-nodes) - goto)))))) + arg)))))) (setq file (nth 1 it) re (nth 2 it) pos (nth 3 it)) - (if (and (not goto) + (if (and (not arg) pos (equal (buffer-file-name) file) (if regionp @@ -11644,10 +11924,9 @@ prefix argument (`C-u C-u C-u C-c C-w')." (< pos (save-excursion (org-end-of-subtree t t)))))) (error "Cannot refile to position inside the tree or region")) - (setq nbuf (or (find-buffer-visiting file) (find-file-noselect file))) - (if (and goto (not (equal goto 3))) + (if (and arg (not (equal arg 3))) (progn (org-pop-to-buffer-same-window nbuf) (goto-char pos) @@ -11680,7 +11959,7 @@ prefix argument (`C-u C-u C-u C-c C-w')." (goto-char (point-min)) (or (outline-next-heading) (goto-char (point-max))))) (if (not (bolp)) (newline)) - (org-paste-subtree level) + (org-paste-subtree level nil nil t) (when org-log-refile (org-add-log-setup 'refile nil nil 'findpos org-log-refile) (unless (eq org-log-refile 'note) @@ -11692,7 +11971,7 @@ prefix argument (`C-u C-u C-u C-c C-w')." :last-refile))) (when bookmark-name (with-demoted-errors - (bookmark-set bookmark-name)))) + (bookmark-set bookmark-name)))) ;; If we are refiling for capture, make sure that the ;; last-capture pointers point here (when (org-bound-and-true-p org-refile-for-capture) @@ -11700,7 +11979,7 @@ prefix argument (`C-u C-u C-u C-c C-w')." :last-capture-marker))) (when bookmark-name (with-demoted-errors - (bookmark-set bookmark-name)))) + (bookmark-set bookmark-name)))) (move-marker org-capture-last-stored-marker (point))) (if (fboundp 'deactivate-mark) (deactivate-mark)) (run-hooks 'org-after-refile-insert-hook)))) @@ -11718,7 +11997,7 @@ prefix argument (`C-u C-u C-u C-c C-w')." (defun org-refile-goto-last-stored () "Go to the location where the last refile was stored." (interactive) - (bookmark-jump "org-refile-last-stored") + (bookmark-jump (plist-get org-bookmark-names-plist :last-refile)) (message "This is the location of the last refile")) (defun org-refile--get-location (refloc tbl) @@ -11819,7 +12098,7 @@ this is used for the GOTO interface." (pos (nth 3 refile-pointer)) buffer) (if (and (not (markerp pos)) (not file)) - (user-error "Please save the buffer to a file before refiling") + (user-error "Please indicate a target file in the refile path") (when (org-string-nw-p re) (setq buffer (if (markerp pos) (marker-buffer pos) @@ -11865,31 +12144,25 @@ this is used for the GOTO interface." (let ((thetable collection) (org-completion-use-ido nil) ; does not work with ido. (org-completion-use-iswitchb nil)) ; or iswitchb - (apply - 'org-icompleting-read prompt - (lambda (string predicate &optional flag) - (let (rtn r f (l (length string))) - (cond - ((eq flag nil) - ;; try completion - (try-completion string thetable)) - ((eq flag t) - ;; all-completions - (setq rtn (all-completions string thetable predicate)) - (mapcar - (lambda (x) - (setq r (substring x l)) - (if (string-match " ([^)]*)$" x) - (setq f (match-string 0 x)) - (setq f "")) - (if (string-match "/" r) - (concat string (substring r 0 (match-end 0)) f) - x)) - rtn)) - ((eq flag 'lambda) - ;; exact match? - (assoc string thetable))))) - args))) + (apply #'org-icompleting-read + prompt + (lambda (string predicate &optional flag) + (cond + ((eq flag nil) (try-completion string thetable)) + ((eq flag t) + (let ((l (length string))) + (mapcar (lambda (x) + (let ((r (substring x l)) + (f (if (string-match " ([^)]*)$" x) + (match-string 0 x) + ""))) + (if (string-match "/" r) + (concat string (substring r 0 (match-end 0)) f) + x))) + (all-completions string thetable predicate)))) + ;; Exact match? + ((eq flag 'lambda) (assoc string thetable)))) + args))) ;;;; Dynamic blocks @@ -11905,16 +12178,9 @@ If not found, stay at current position and return nil." (if pos (goto-char pos)) pos)) -(defconst org-dblock-start-re - "^[ \t]*#\\+\\(?:BEGIN\\|begin\\):[ \t]+\\(\\S-+\\)\\([ \t]+\\(.*\\)\\)?" - "Matches the start line of a dynamic block, with parameters.") - -(defconst org-dblock-end-re "^[ \t]*#\\+\\(?:END\\|end\\)\\([: \t\r\n]\\|$\\)" - "Matches the end of a dynamic block.") - (defun org-create-dblock (plist) "Create a dynamic block section, with parameters taken from PLIST. -PLIST must contain a :name entry which is used as name of the block." +PLIST must contain a :name entry which is used as the name of the block." (when (string-match "\\S-" (buffer-substring (point-at-bol) (point-at-eol))) (end-of-line 1) (newline)) @@ -12042,7 +12308,7 @@ Export keywords include options, block names, attributes and keywords relative to each registered export back-end." (let (keywords) (dolist (backend - (org-bound-and-true-p org-export--registered-backends) + (org-bound-and-true-p org-export-registered-backends) (delq nil keywords)) ;; Back-end name (for keywords, like #+LATEX:) (push (upcase (symbol-name (org-export-backend-name backend))) keywords) @@ -12058,29 +12324,26 @@ keywords relative to each registered export back-end." "TITLE:" "TODO:" "TYP_TODO:" "SELECT_TAGS:" "EXCLUDE_TAGS:")) (defcustom org-structure-template-alist - '(("s" "#+BEGIN_SRC ?\n\n#+END_SRC" "\n\n") - ("e" "#+BEGIN_EXAMPLE\n?\n#+END_EXAMPLE" "\n?\n") - ("q" "#+BEGIN_QUOTE\n?\n#+END_QUOTE" "\n?\n") - ("v" "#+BEGIN_VERSE\n?\n#+END_VERSE" "\n?\n") - ("V" "#+BEGIN_VERBATIM\n?\n#+END_VERBATIM" "\n?\n") - ("c" "#+BEGIN_CENTER\n?\n#+END_CENTER" "
\n?\n
") - ("l" "#+BEGIN_LaTeX\n?\n#+END_LaTeX" - "\n?\n") - ("L" "#+LaTeX: " "?") - ("h" "#+BEGIN_HTML\n?\n#+END_HTML" - "\n?\n") - ("H" "#+HTML: " "?") - ("a" "#+BEGIN_ASCII\n?\n#+END_ASCII" "") - ("A" "#+ASCII: " "") - ("i" "#+INDEX: ?" "#+INDEX: ?") - ("I" "#+INCLUDE: %file ?" - "")) + '(("s" "#+BEGIN_SRC ?\n\n#+END_SRC") + ("e" "#+BEGIN_EXAMPLE\n?\n#+END_EXAMPLE") + ("q" "#+BEGIN_QUOTE\n?\n#+END_QUOTE") + ("v" "#+BEGIN_VERSE\n?\n#+END_VERSE") + ("V" "#+BEGIN_VERBATIM\n?\n#+END_VERBATIM") + ("c" "#+BEGIN_CENTER\n?\n#+END_CENTER") + ("l" "#+BEGIN_LaTeX\n?\n#+END_LaTeX") + ("L" "#+LaTeX: ") + ("h" "#+BEGIN_HTML\n?\n#+END_HTML") + ("H" "#+HTML: ") + ("a" "#+BEGIN_ASCII\n?\n#+END_ASCII") + ("A" "#+ASCII: ") + ("i" "#+INDEX: ?") + ("I" "#+INCLUDE: %file ?")) "Structure completion elements. This is a list of abbreviation keys and values. The value gets inserted if you type `<' followed by the key and then press the completion key, -usually `M-TAB'. %file will be replaced by a file name after prompting +usually `TAB'. %file will be replaced by a file name after prompting for the file using completion. The cursor will be placed at the position -of the `?` in the template. +of the `?' in the template. There are two templates for each key, the first uses the original Org syntax, the second uses Emacs Muse-like syntax tags. These Muse-like tags become the default when the /org-mtags.el/ module has been loaded. See also the @@ -12089,8 +12352,9 @@ variable `org-mtags-prefer-muse-templates'." :type '(repeat (list (string :tag "Key") - (string :tag "Template") - (string :tag "Muse Template")))) + (string :tag "Template"))) + :version "25.1" + :package-version '(Org . "8.3")) (defun org-try-structure-completion () "Try to complete a structure template before point. @@ -12107,11 +12371,10 @@ expands them." (defun org-complete-expand-structure-template (start cell) "Expand a structure template." - (let* ((musep (org-bound-and-true-p org-mtags-prefer-muse-templates)) - (rpl (nth (if musep 2 1) cell)) - (ind "")) + (let ((rpl (nth 1 cell)) + (ind "")) (delete-region start (point)) - (when (string-match "\\`#\\+" rpl) + (when (string-match "\\`[ \t]*#\\+" rpl) (cond ((bolp)) ((not (string-match "\\S-" (buffer-substring (point-at-bol) (point)))) @@ -12138,17 +12401,17 @@ expands them." (interactive) (save-excursion (org-back-to-heading) - (let (case-fold-search) - (cond - ((looking-at (format org-heading-keyword-regexp-format - org-comment-string)) - (goto-char (match-end 1)) - (looking-at (concat " +" org-comment-string)) - (replace-match "" t t) - (when (eolp) (insert " "))) - ((looking-at org-outline-regexp) - (goto-char (match-end 0)) - (insert org-comment-string " ")))))) + (looking-at org-complex-heading-regexp) + (goto-char (or (match-end 3) (match-end 2) (match-end 1))) + (skip-chars-forward " \t") + (unless (memq (char-before) '(?\s ?\t)) (insert " ")) + (if (org-in-commented-heading-p t) + (delete-region (point) + (progn (search-forward " " (line-end-position) 'move) + (skip-chars-forward " \t") + (point))) + (insert org-comment-string) + (unless (eolp) (insert " "))))) (defvar org-last-todo-state-is-todo nil "This is non-nil when the last TODO state change led to a TODO state. @@ -12187,7 +12450,8 @@ nil or a string to be used for the todo mark." ) (interactive "P") (if (eq major-mode 'org-agenda-mode) (apply 'org-agenda-todo-yesterday arg) - (let* ((hour (third (decode-time + (let* ((org-use-effective-time t) + (hour (third (decode-time (org-current-time)))) (org-extend-today-until (1+ hour))) (org-todo arg)))) @@ -12195,6 +12459,21 @@ nil or a string to be used for the todo mark." ) (defvar org-block-entry-blocking "" "First entry preventing the TODO state change.") +(defun org-cancel-repeater () + "Cancel a repeater by setting its numeric value to zero." + (interactive) + (save-excursion + (org-back-to-heading t) + (let ((bound1 (point)) + (bound0 (save-excursion (outline-next-heading) (point)))) + (when (re-search-forward + (concat "\\(" org-scheduled-time-regexp "\\)\\|\\(" + org-deadline-time-regexp "\\)\\|\\(" + org-ts-regexp "\\)") + bound0 t) + (if (re-search-backward "[ \t]+\\(?:[.+]\\)?\\+\\([0-9]+\\)[hdwmy]" bound1 t) + (replace-match "0" t nil nil 1)))))) + (defun org-todo (&optional arg) "Change the TODO state of an item. The state of an item is given by a keyword at the start of the heading, @@ -12215,13 +12494,14 @@ With a double \\[universal-argument] prefix, switch to the next set of TODO \ keywords (nextset). With a triple \\[universal-argument] prefix, circumvent any state blocking. 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. -For calling through lisp, arg is also interpreted in the following way: -'none -> empty state +When called through ELisp, arg is also interpreted in the following way: +`none' -> empty state \"\"(empty string) -> switch to empty state -'done -> switch to DONE -'nextset -> switch to the next set of keywords -'previousset -> switch to the previous set of keywords +`done' -> switch to DONE +`nextset' -> switch to the next set of keywords +`previousset' -> switch to the previous set of keywords \"WAITING\" -> switch to the specified keyword, but only if it really is a member of `org-todo-keywords'." (interactive "P") @@ -12234,6 +12514,7 @@ For calling through lisp, arg is also interpreted in the following way: org-loop-over-headlines-in-active-region cl (if (outline-invisible-p) (org-end-of-subtree nil t)))) (if (equal arg '(16)) (setq arg 'nextset)) + (when (equal arg -1) (org-cancel-repeater) (setq arg nil)) (let ((org-blocker-hook org-blocker-hook) commentp case-fold-search) @@ -12246,7 +12527,7 @@ For calling through lisp, arg is also interpreted in the following way: (save-excursion (catch 'exit (org-back-to-heading t) - (when (looking-at (concat "^\\*+ " org-comment-string)) + (when (org-in-commented-heading-p t) (org-toggle-comment) (setq commentp t)) (if (looking-at org-outline-regexp) (goto-char (1- (match-end 0)))) @@ -12356,8 +12637,10 @@ For calling through lisp, arg is also interpreted in the following way: (throw 'exit nil)))) (store-match-data match-data) (replace-match next t t) - (unless (pos-visible-in-window-p hl-pos) - (message "TODO state changed to %s" (org-trim next))) + (cond ((equal this org-state) + (message "TODO state was already %s" (org-trim next))) + ((pos-visible-in-window-p hl-pos) + (message "TODO state changed to %s" (org-trim next)))) (unless head (setq head (org-get-todo-sequence-head org-state) ass (assoc head org-todo-kwd-alist) @@ -12527,7 +12810,7 @@ See variable `org-track-ordered-property-with-tag'." (org-back-to-heading) (if (org-entry-get nil "ORDERED") (progn - (org-delete-property "ORDERED" "PROPERTIES") + (org-delete-property "ORDERED") (and tag (org-toggle-tag tag 'off)) (message "Subtasks can be completed in arbitrary order")) (org-entry-put nil "ORDERED" "t") @@ -12570,16 +12853,15 @@ changes because there are unchecked boxes in this entry." t))) ; do not block (defun org-entry-blocked-p () - "Is the current entry blocked?" - (org-with-silent-modifications - (if (org-entry-get nil "NOBLOCKING") - nil ;; Never block this entry - (not (run-hook-with-args-until-failure - 'org-blocker-hook - (list :type 'todo-state-change - :position (point) - :from 'todo - :to 'done)))))) + "Non-nil if entry at point is blocked." + (and (not (org-entry-get nil "NOBLOCKING")) + (member (org-entry-get nil "TODO") org-not-done-keywords) + (not (run-hook-with-args-until-failure + 'org-blocker-hook + (list :type 'todo-state-change + :position (point) + :from 'todo + :to 'done))))) (defun org-update-statistics-cookies (all) "Update the statistics cookie, either from TODO or from checkboxes. @@ -12671,18 +12953,35 @@ statistics everywhere." (setq kwd (and (or recursive (= l1 ltoggle)) (match-string 2))) (if (or (eq org-provide-todo-statistics 'all-headlines) + (and (eq org-provide-todo-statistics t) + (or (member kwd org-done-keywords))) (and (listp org-provide-todo-statistics) + (stringp (car org-provide-todo-statistics)) (or (member kwd org-provide-todo-statistics) - (member kwd org-done-keywords)))) + (member kwd org-done-keywords))) + (and (listp org-provide-todo-statistics) + (listp (car org-provide-todo-statistics)) + (or (member kwd (car org-provide-todo-statistics)) + (and (member kwd org-done-keywords) + (member kwd (cadr org-provide-todo-statistics)))))) (setq cnt-all (1+ cnt-all)) (if (eq org-provide-todo-statistics t) (and kwd (setq cnt-all (1+ cnt-all))))) - (and (member kwd org-done-keywords) - (setq cnt-done (1+ cnt-done))) + (when (or (and (member org-provide-todo-statistics '(t all-headlines)) + (member kwd org-done-keywords)) + (and (listp org-provide-todo-statistics) + (listp (car org-provide-todo-statistics)) + (member kwd org-done-keywords) + (member kwd (cadr org-provide-todo-statistics))) + (and (listp org-provide-todo-statistics) + (stringp (car org-provide-todo-statistics)) + (member kwd org-done-keywords))) + (setq cnt-done (1+ cnt-done))) (outline-next-heading))) (setq new (if is-percent - (format "[%d%%]" (/ (* 100 cnt-done) (max 1 cnt-all))) + (format "[%d%%]" (floor (* 100.0 cnt-done) + (max 1 cnt-all))) (format "[%d/%d]" cnt-done cnt-all)) ndel (- (match-end 0) checkbox-beg)) ;; handle overlays when updating cookie from column view @@ -12737,20 +13036,19 @@ This hook runs even if there is no statistics cookie present, in which case (defun org-local-logging (value) "Get logging settings from a property VALUE." - (let* (words w a) - ;; directly set the variables, they are already local. - (setq org-log-done nil - org-log-repeat nil - org-todo-log-states nil) - (setq words (org-split-string value)) - (while (setq w (pop words)) + ;; Directly set the variables, they are already local. + (setq org-log-done nil + org-log-repeat nil + org-todo-log-states nil) + (dolist (w (org-split-string value)) + (let (a) (cond ((setq a (assoc w org-startup-options)) - (and (member (nth 1 a) '(org-log-done org-log-repeat)) - (set (nth 1 a) (nth 2 a)))) + (and (member (nth 1 a) '(org-log-done org-log-repeat)) + (set (nth 1 a) (nth 2 a)))) ((setq a (org-extract-log-state-settings w)) - (and (member (car a) org-todo-keywords-1) - (push a org-todo-log-states))))))) + (and (member (car a) org-todo-keywords-1) + (push a org-todo-log-states))))))) (defun org-get-todo-sequence-head (kwd) "Return the head of the TODO sequence to which KWD belongs. @@ -12850,7 +13148,14 @@ Returns the new TODO keyword, or nil if no state change should occur." (match-string 2)))) (defun org-at-date-range-p (&optional inactive-ok) - "Is the cursor inside a date range?" + "Non-nil if point is inside a date range. + +When optional argument INACTIVE-OK is non-nil, also consider +inactive time ranges. + +When this function returns a non-nil value, match data is set +according to `org-tr-regexp-both' or `org-tr-regexp', depending +on INACTIVE-OK." (interactive) (save-excursion (catch 'exit @@ -12882,7 +13187,7 @@ Returns the new TODO keyword, or nil if no state change should occur." (defvar org-last-inserted-timestamp) (defvar org-log-post-message) (defvar org-log-note-purpose) -(defvar org-log-note-how) +(defvar org-log-note-how nil) (defvar org-log-note-extra) (defun org-auto-repeat-maybe (done-word) "Check if the current headline contains a repeated deadline/schedule. @@ -12899,7 +13204,7 @@ This function is run automatically after each state change to a DONE state." (org-log-done nil) (org-todo-log-states nil) re type n what ts time to-state) - (when repeat + (when (and repeat (not (zerop (string-to-number (substring repeat 1))))) (if (eq org-log-repeat t) (setq org-log-repeat 'state)) (setq to-state (or (org-entry-get nil "REPEAT_TO_STATE") org-todo-repeat-to-state)) @@ -12952,7 +13257,7 @@ This function is run automatically after each state change to a DONE state." (time-to-days (current-time)))) (when (= (incf nshift) nshiftmax) (or (y-or-n-p (message "%d repeater intervals were not enough to shift date past today. Continue? " nshift)) - (error "Abort"))) + (user-error "Abort"))) (org-timestamp-change n (cdr (assoc what whata))) (org-at-timestamp-p t) (setq ts (match-string 1)) @@ -13041,11 +13346,12 @@ can either be an Org date like \"2011-07-24\" or a delta like \"+2d\"." (user-error "No deadline information to update")))) (t (org-add-planning-info 'deadline time 'closed) - (when (and old-date org-log-redeadline - (not (equal old-date - (substring org-last-inserted-timestamp 1 -1)))) - (org-add-log-setup 'redeadline nil old-date 'findpos - org-log-redeadline)) + (when (and old-date + org-log-redeadline + (not (equal old-date org-last-inserted-timestamp))) + (org-add-log-setup + 'redeadline org-last-inserted-timestamp old-date 'findpos + org-log-redeadline)) (when repeater (save-excursion (org-back-to-heading t) @@ -13112,11 +13418,12 @@ either be an Org date like \"2011-07-24\" or a delta like \"+2d\"." (user-error "No scheduled information to update")))) (t (org-add-planning-info 'scheduled time 'closed) - (when (and old-date org-log-reschedule - (not (equal old-date - (substring org-last-inserted-timestamp 1 -1)))) - (org-add-log-setup 'reschedule nil old-date 'findpos - org-log-reschedule)) + (when (and old-date + org-log-reschedule + (not (equal old-date org-last-inserted-timestamp))) + (org-add-log-setup + 'reschedule org-last-inserted-timestamp old-date 'findpos + org-log-reschedule)) (when repeater (save-excursion (org-back-to-heading t) @@ -13169,16 +13476,28 @@ nil." (defvar org-time-was-given) ; dynamically scoped parameter (defvar org-end-time-was-given) ; dynamically scoped parameter -(defun org-add-planning-info (what &optional time &rest remove) - "Insert new timestamp with keyword in the line directly after the headline. -WHAT indicates what kind of time stamp to add. TIME indicates the time to use. -If non is given, the user is prompted for a date. -REMOVE indicates what kind of entries to remove. An old WHAT entry will also -be removed." - (interactive) - (let (org-time-was-given org-end-time-was-given ts - end default-time default-input) +(defun org-at-planning-p () + "Non-nil when point is on a planning info line." + ;; This is as accurate and faster than `org-element-at-point' since + ;; planning info location is fixed in the section. + (org-with-wide-buffer + (beginning-of-line) + (and (org-looking-at-p org-planning-line-re) + (eq (point) + (ignore-errors + (if (and (featurep 'org-inlinetask) (org-inlinetask-in-task-p)) + (org-back-to-heading t) + (org-with-limited-levels (org-back-to-heading t))) + (line-beginning-position 2)))))) +(defun org-add-planning-info (what &optional time &rest remove) + "Insert new timestamp with keyword in the planning line. +WHAT indicates what kind of time stamp to add. It is a symbol +among `closed', `deadline', `scheduled' and nil. TIME indicates +the time to use. If none is given, the user is prompted for +a date. REMOVE indicates what kind of entries to remove. An old +WHAT entry will also be removed." + (let (org-time-was-given org-end-time-was-given default-time default-input) (catch 'exit (when (and (memq what '(scheduled deadline)) (or (not time) @@ -13187,101 +13506,91 @@ be removed." ;; Try to get a default date/time from existing timestamp (save-excursion (org-back-to-heading t) - (setq end (save-excursion (outline-next-heading) (point))) - (when (re-search-forward (if (eq what 'scheduled) - org-scheduled-time-regexp - org-deadline-time-regexp) - end t) - (setq ts (match-string 1) - default-time - (apply 'encode-time (org-parse-time-string ts)) - default-input (and ts (org-get-compact-tod ts)))))) + (let ((end (save-excursion (outline-next-heading) (point))) ts) + (when (re-search-forward (if (eq what 'scheduled) + org-scheduled-time-regexp + org-deadline-time-regexp) + end t) + (setq ts (match-string 1) + default-time (apply 'encode-time (org-parse-time-string ts)) + default-input (and ts (org-get-compact-tod ts))))))) (when what (setq time (if (stringp time) - ;; This is a string (relative or absolute), set proper date - (apply 'encode-time + ;; This is a string (relative or absolute), set + ;; proper date. + (apply #'encode-time (org-read-date-analyze time default-time (decode-time default-time))) ;; If necessary, get the time from the user (or time (org-read-date nil 'to-time nil nil default-time default-input))))) - (when (and org-insert-labeled-timestamps-at-point - (member what '(scheduled deadline))) - (insert - (if (eq what 'scheduled) org-scheduled-string org-deadline-string) " ") - (org-insert-time-stamp time org-time-was-given - nil nil nil (list org-end-time-was-given)) - (setq what nil)) - (save-excursion - (save-restriction - (let (col list elt ts buffer-invisibility-spec) - (org-back-to-heading t) - (looking-at (concat org-outline-regexp "\\( *\\)[^\r\n]*")) - (goto-char (match-end 1)) - (setq col (current-column)) - (goto-char (match-end 0)) - (if (eobp) (insert "\n") (forward-char 1)) - (when (and (not what) - (not (looking-at - (concat "[ \t]*" - org-keyword-time-not-clock-regexp)))) - ;; Nothing to add, nothing to remove...... :-) - (throw 'exit nil)) - (if (and (not (looking-at org-outline-regexp)) - (looking-at (concat "[^\r\n]*?" org-keyword-time-regexp - "[^\r\n]*")) - (not (equal (match-string 1) org-clock-string))) - (narrow-to-region (match-beginning 0) (match-end 0)) - (insert-before-markers "\n") - (backward-char 1) - (narrow-to-region (point) (point)) - (and org-adapt-indentation (org-indent-to-column col))) - ;; Check if we have to remove something. - (setq list (cons what remove)) - (while list - (setq elt (pop list)) - (when (or (and (eq elt 'scheduled) - (re-search-forward org-scheduled-time-regexp nil t)) - (and (eq elt 'deadline) - (re-search-forward org-deadline-time-regexp nil t)) - (and (eq elt 'closed) - (re-search-forward org-closed-time-regexp nil t))) - (replace-match "") - (if (looking-at "--+<[^>]+>") (replace-match "")))) - (and (looking-at "[ \t]+") (replace-match "")) - (and org-adapt-indentation (bolp) (org-indent-to-column col)) - (when what - (insert - (if (not (or (bolp) (eq (char-before) ?\ ))) " " "") - (cond ((eq what 'scheduled) org-scheduled-string) - ((eq what 'deadline) org-deadline-string) - ((eq what 'closed) org-closed-string)) - " ") - (setq ts (org-insert-time-stamp - time - (or org-time-was-given - (and (eq what 'closed) org-log-done-with-time)) - (eq what 'closed) - nil nil (list org-end-time-was-given))) - (insert - (if (not (or (bolp) (eq (char-before) ?\ ) - (memq (char-after) '(32 10)) - (eobp))) " " "")) - (end-of-line 1)) - (goto-char (point-min)) - (widen) - (if (and (looking-at "[ \t]*\n") - (equal (char-before) ?\n)) - (delete-region (1- (point)) (point-at-eol))) - ts)))))) + (org-with-wide-buffer + (org-back-to-heading t) + (forward-line) + (unless (bolp) (insert "\n")) + (cond ((org-looking-at-p org-planning-line-re) + ;; Move to current indentation. + (skip-chars-forward " \t") + ;; Check if we have to remove something. + (dolist (type (if what (cons what remove) remove)) + (save-excursion + (when (re-search-forward + (case type + (closed org-closed-time-regexp) + (deadline org-deadline-time-regexp) + (scheduled org-scheduled-time-regexp) + (otherwise + (error "Invalid planning type: %s" type))) + (line-end-position) t) + ;; Delete until next keyword or end of line. + (delete-region + (match-beginning 0) + (if (re-search-forward org-keyword-time-not-clock-regexp + (line-end-position) + t) + (match-beginning 0) + (line-end-position)))))) + ;; If there is nothing more to add and no more keyword + ;; is left, remove the line completely. + (if (and (org-looking-at-p "[ \t]*$") (not what)) + (delete-region (line-beginning-position) + (line-beginning-position 2)) + ;; If we removed last keyword, do not leave trailing + ;; white space at the end of line. + (let ((p (point))) + (save-excursion + (end-of-line) + (unless (= (skip-chars-backward " \t" p) 0) + (delete-region (point) (line-end-position))))))) + ((not what) (throw 'exit nil)) ; Nothing to do. + (t (insert-before-markers "\n") + (backward-char 1) + (when org-adapt-indentation + (org-indent-to-column (1+ (org-outline-level)))))) + (when what + ;; Insert planning keyword. + (insert (case what + (closed org-closed-string) + (deadline org-deadline-string) + (scheduled org-scheduled-string) + (otherwise (error "Invalid planning type: %s" what))) + " ") + ;; Insert associated timestamp. + (let ((ts (org-insert-time-stamp + time + (or org-time-was-given + (and (eq what 'closed) org-log-done-with-time)) + (eq what 'closed) + nil nil (list org-end-time-was-given)))) + (unless (eolp) (insert " ")) + ts)))))) (defvar org-log-note-marker (make-marker)) (defvar org-log-note-purpose nil) (defvar org-log-note-state nil) (defvar org-log-note-previous-state nil) -(defvar org-log-note-how nil) (defvar org-log-note-extra nil) (defvar org-log-note-window-configuration nil) (defvar org-log-note-return-to (make-marker)) @@ -13300,73 +13609,89 @@ This is done in the same way as adding a state change note." (interactive) (org-add-log-setup 'note nil nil 'findpos nil)) -(defvar org-property-end-re) -(defun org-add-log-setup (&optional purpose state prev-state - findpos how extra) +(defun org-log-beginning (&optional create) + "Return expected start of log notes in current entry. +When optional argument CREATE is non-nil, the function creates +a drawer to store notes, if necessary. Returned position ignores +narrowing." + (org-with-wide-buffer + (org-end-of-meta-data) + (let ((end (if (org-at-heading-p) (point) + (save-excursion (outline-next-heading) (point)))) + (drawer (org-log-into-drawer))) + (cond + (drawer + (let ((regexp (concat "^[ \t]*:" (regexp-quote drawer) ":[ \t]*$")) + (case-fold-search t)) + (catch 'exit + ;; Try to find existing drawer. + (while (re-search-forward regexp end t) + (let ((element (org-element-at-point))) + (when (eq (org-element-type element) 'drawer) + (let ((cend (org-element-property :contents-end element))) + (when (and (not org-log-states-order-reversed) cend) + (goto-char cend))) + (throw 'exit nil)))) + ;; No drawer found. Create one, if permitted. + (when create + (unless (bolp) (insert "\n")) + (let ((beg (point))) + (insert ":" drawer ":\n:END:\n") + (org-indent-region beg (point))) + (end-of-line -1))))) + (org-log-state-notes-insert-after-drawers + (while (and (looking-at org-drawer-regexp) + (progn (goto-char (match-end 0)) + (re-search-forward org-property-end-re end t))) + (forward-line))))) + (if (bolp) (point) (line-beginning-position 2)))) + +(defun org-add-log-setup (&optional purpose state prev-state findpos how extra) "Set up the post command hook to take a note. If this is about to TODO state change, the new state is expected in STATE. When FINDPOS is non-nil, find the correct position for the note in the current entry. If not, assume that it can be inserted at point. HOW is an indicator what kind of note should be created. EXTRA is additional text that will be inserted into the notes buffer." - (let* ((org-log-into-drawer (org-log-into-drawer)) - (drawer (cond ((stringp org-log-into-drawer) - org-log-into-drawer) - (org-log-into-drawer "LOGBOOK")))) - (save-restriction - (save-excursion - (when findpos - (org-back-to-heading t) - (narrow-to-region (point) (save-excursion - (outline-next-heading) (point))) - (looking-at (concat org-outline-regexp "\\( *\\)[^\r\n]*" - "\\(\n[^\r\n]*?" org-keyword-time-not-clock-regexp - "[^\r\n]*\\)?")) - (goto-char (match-end 0)) - (cond - (drawer - (if (re-search-forward (concat "^[ \t]*:" drawer ":[ \t]*$") - nil t) - (progn - (goto-char (match-end 0)) - (or org-log-states-order-reversed - (and (re-search-forward org-property-end-re nil t) - (goto-char (1- (match-beginning 0)))))) - (insert "\n:" drawer ":\n:END:") - (beginning-of-line 0) - (org-indent-line) - (beginning-of-line 2) - (org-indent-line) - (end-of-line 0))) - ((and org-log-state-notes-insert-after-drawers - (save-excursion - (forward-line) (looking-at org-drawer-regexp))) - (forward-line) - (while (looking-at org-drawer-regexp) - (goto-char (match-end 0)) - (re-search-forward org-property-end-re (point-max) t) - (forward-line)) - (forward-line -1))) - (unless org-log-states-order-reversed - (and (= (char-after) ?\n) (forward-char 1)) - (org-skip-over-state-notes) - (skip-chars-backward " \t\n\r"))) - (move-marker org-log-note-marker (point)) - (setq org-log-note-purpose purpose - org-log-note-state state - org-log-note-previous-state prev-state - org-log-note-how how - org-log-note-extra extra - org-log-note-effective-time (org-current-effective-time)) - (add-hook 'post-command-hook 'org-add-log-note 'append))))) + (org-with-wide-buffer + (when findpos + (goto-char (org-log-beginning t)) + (unless org-log-states-order-reversed + (org-skip-over-state-notes) + (skip-chars-backward " \t\n\r") + (forward-line))) + (move-marker org-log-note-marker (point)) + ;; Preserve position even if a property drawer is inserted in the + ;; process. + (set-marker-insertion-type org-log-note-marker t) + (setq org-log-note-purpose purpose + org-log-note-state state + org-log-note-previous-state prev-state + org-log-note-how how + org-log-note-extra extra + org-log-note-effective-time (org-current-effective-time)) + (add-hook 'post-command-hook 'org-add-log-note 'append))) (defun org-skip-over-state-notes () "Skip past the list of State notes in an entry." - (if (looking-at "\n[ \t]*- State") (forward-char 1)) (when (ignore-errors (goto-char (org-in-item-p))) (let* ((struct (org-list-struct)) - (prevs (org-list-prevs-alist struct))) - (while (looking-at "[ \t]*- State") + (prevs (org-list-prevs-alist struct)) + (regexp + (concat "[ \t]*- +" + (replace-regexp-in-string + " +" " +" + (org-replace-escapes + (regexp-quote (cdr (assq 'state org-log-note-headings))) + `(("%d" . ,org-ts-regexp-inactive) + ("%D" . ,org-ts-regexp) + ("%s" . "\"\\S-+\"") + ("%S" . "\"\\S-+\"") + ("%t" . ,org-ts-regexp-inactive) + ("%T" . ,org-ts-regexp) + ("%u" . ".*?") + ("%U" . ".*?"))))))) + (while (org-looking-at-p regexp) (goto-char (or (org-list-get-next-item (point) struct prevs) (org-list-get-item-end (point) struct))))))) @@ -13414,80 +13739,84 @@ EXTRA is additional text that will be inserted into the notes buffer." "Finish taking a log note, and insert it to where it belongs." (let ((txt (buffer-string))) (kill-buffer (current-buffer)) - (let ((note (cdr (assq org-log-note-purpose org-log-note-headings))) - lines ind bul) - (while (string-match "\\`# .*\n[ \t\n]*" txt) - (setq txt (replace-match "" t t txt))) - (if (string-match "\\s-+\\'" txt) + (let ((note (cdr (assq org-log-note-purpose org-log-note-headings))) lines) + (while (string-match "\\`# .*\n[ \t\n]*" txt) (setq txt (replace-match "" t t txt))) - (setq lines (org-split-string txt "\n")) - (when (and note (string-match "\\S-" note)) - (setq note - (org-replace-escapes - note - (list (cons "%u" (user-login-name)) - (cons "%U" user-full-name) - (cons "%t" (format-time-string - (org-time-stamp-format 'long 'inactive) - org-log-note-effective-time)) - (cons "%T" (format-time-string - (org-time-stamp-format 'long nil) - org-log-note-effective-time)) - (cons "%d" (format-time-string - (org-time-stamp-format nil 'inactive) - org-log-note-effective-time)) - (cons "%D" (format-time-string - (org-time-stamp-format nil nil) - org-log-note-effective-time)) - (cons "%s" (if org-log-note-state - (concat "\"" org-log-note-state "\"") - "")) - (cons "%S" (if org-log-note-previous-state - (concat "\"" org-log-note-previous-state "\"") - "\"\""))))) - (if lines (setq note (concat note " \\\\"))) - (push note lines)) - (when (or current-prefix-arg org-note-abort) - (when org-log-into-drawer - (org-remove-empty-drawer-at - (if (stringp org-log-into-drawer) org-log-into-drawer "LOGBOOK") - org-log-note-marker)) - (setq lines nil)) - (when lines - (with-current-buffer (marker-buffer org-log-note-marker) - (save-excursion - (goto-char org-log-note-marker) - (move-marker org-log-note-marker nil) - (end-of-line 1) - (if (not (bolp)) (let ((inhibit-read-only t)) (insert "\n"))) - (setq ind (save-excursion - (if (ignore-errors (goto-char (org-in-item-p))) - (let ((struct (org-list-struct))) - (org-list-get-ind - (org-list-get-top-point struct) struct)) - (skip-chars-backward " \r\t\n") - (cond - ((and (org-at-heading-p) - org-adapt-indentation) - (1+ (org-current-level))) - ((org-at-heading-p) 0) - (t (org-get-indentation)))))) - (setq bul (org-list-bullet-string "-")) - (org-indent-line-to ind) - (insert bul (pop lines)) - (let ((ind-body (+ (length bul) ind))) - (while lines - (insert "\n") - (org-indent-line-to ind-body) - (insert (pop lines)))) - (message "Note stored") - (org-back-to-heading t) - (org-cycle-hide-drawers 'children)) - ;; Fix `buffer-undo-list' when `org-store-log-note' is called - ;; from within `org-add-log-note' because `buffer-undo-list' - ;; is then modified outside of `org-with-remote-undo'. - (when (eq this-command 'org-agenda-todo) - (setcdr buffer-undo-list (cddr buffer-undo-list))))))) + (if (string-match "\\s-+\\'" txt) + (setq txt (replace-match "" t t txt))) + (setq lines (org-split-string txt "\n")) + (when (and note (string-match "\\S-" note)) + (setq note + (org-replace-escapes + note + (list (cons "%u" (user-login-name)) + (cons "%U" user-full-name) + (cons "%t" (format-time-string + (org-time-stamp-format 'long 'inactive) + org-log-note-effective-time)) + (cons "%T" (format-time-string + (org-time-stamp-format 'long nil) + org-log-note-effective-time)) + (cons "%d" (format-time-string + (org-time-stamp-format nil 'inactive) + org-log-note-effective-time)) + (cons "%D" (format-time-string + (org-time-stamp-format nil nil) + org-log-note-effective-time)) + (cons "%s" (cond + ((not org-log-note-state) "") + ((org-string-match-p org-ts-regexp + org-log-note-state) + (format "\"[%s]\"" + (substring org-log-note-state 1 -1))) + (t (format "\"%s\"" org-log-note-state)))) + (cons "%S" + (cond + ((not org-log-note-previous-state) "") + ((org-string-match-p org-ts-regexp + org-log-note-previous-state) + (format "\"[%s]\"" + (substring + org-log-note-previous-state 1 -1))) + (t (format "\"%s\"" + org-log-note-previous-state))))))) + (when lines (setq note (concat note " \\\\"))) + (push note lines)) + (when (or current-prefix-arg org-note-abort) + (when (org-log-into-drawer) + (org-remove-empty-drawer-at org-log-note-marker)) + (setq lines nil)) + (when lines + (with-current-buffer (marker-buffer org-log-note-marker) + (org-with-wide-buffer + (goto-char org-log-note-marker) + (move-marker org-log-note-marker nil) + ;; Make sure point is at the beginning of an empty line. + (cond ((not (bolp)) (let ((inhibit-read-only t)) (insert "\n"))) + ((looking-at "[ \t]*\\S-") (save-excursion (insert "\n")))) + ;; In an existing list, add a new item at the top level. + ;; Otherwise, indent line like a regular one. + (let ((itemp (org-in-item-p))) + (if itemp + (org-indent-line-to + (let ((struct (save-excursion + (goto-char itemp) (org-list-struct)))) + (org-list-get-ind (org-list-get-top-point struct) struct))) + (org-indent-line))) + (insert (org-list-bullet-string "-") (pop lines)) + (let ((ind (org-list-item-body-column (line-beginning-position)))) + (dolist (line lines) + (insert "\n") + (org-indent-line-to ind) + (insert line))) + (message "Note stored") + (org-back-to-heading t) + (org-cycle-hide-drawers 'children)) + ;; Fix `buffer-undo-list' when `org-store-log-note' is called + ;; from within `org-add-log-note' because `buffer-undo-list' + ;; is then modified outside of `org-with-remote-undo'. + (when (eq this-command 'org-agenda-todo) + (setcdr buffer-undo-list (cddr buffer-undo-list))))))) ;; Don't add undo information when called from `org-agenda-todo' (let ((buffer-undo-list (eq this-command 'org-agenda-todo))) (set-window-configuration org-log-note-window-configuration) @@ -13496,17 +13825,20 @@ EXTRA is additional text that will be inserted into the notes buffer." (move-marker org-log-note-return-to nil) (and org-log-post-message (message "%s" org-log-post-message)))) -(defun org-remove-empty-drawer-at (drawer pos) - "Remove an empty drawer DRAWER at position POS. +(defun org-remove-empty-drawer-at (pos) + "Remove an empty drawer at position POS. POS may also be a marker." (with-current-buffer (if (markerp pos) (marker-buffer pos) (current-buffer)) - (save-excursion - (save-restriction - (widen) - (goto-char pos) - (if (org-in-regexp - (concat "^[ \t]*:" drawer ":[ \t]*\n[ \t]*:END:[ \t]*\n?") 2) - (replace-match "")))))) + (org-with-wide-buffer + (goto-char pos) + (let ((drawer (org-element-at-point))) + (when (and (memq (org-element-type drawer) '(drawer property-drawer)) + (not (org-element-property :contents-begin drawer))) + (delete-region (org-element-property :begin drawer) + (progn (goto-char (org-element-property :end drawer)) + (skip-chars-backward " \r\t\n") + (forward-line) + (point)))))))) (defvar org-ts-type nil) (defun org-sparse-tree (&optional arg type) @@ -13536,7 +13868,6 @@ D Show deadlines and scheduled items between a date range." (deadline "only deadline") (active "only active timestamps") (inactive "only inactive timestamps") - (scheduled-or-deadline "scheduled/deadline") (closed "with a closed time-stamp") (otherwise "scheduled/deadline"))) (let ((answer (read-char-exclusive))) @@ -13544,24 +13875,24 @@ D Show deadlines and scheduled items between a date range." (?c (org-sparse-tree arg - (cadr (memq type '(scheduled-or-deadline all scheduled deadline active - inactive closed))))) - (?d (call-interactively #'org-check-deadlines)) - (?b (call-interactively #'org-check-before-date)) - (?a (call-interactively #'org-check-after-date)) - (?D (call-interactively #'org-check-dates-range)) - (?t (call-interactively #'org-show-todo-tree)) + (cadr + (memq type '(nil all scheduled deadline active inactive closed))))) + (?d (call-interactively 'org-check-deadlines)) + (?b (call-interactively 'org-check-before-date)) + (?a (call-interactively 'org-check-after-date)) + (?D (call-interactively 'org-check-dates-range)) + (?t (call-interactively 'org-show-todo-tree)) (?T (org-show-todo-tree '(4))) - (?m (call-interactively #'org-match-sparse-tree)) + (?m (call-interactively 'org-match-sparse-tree)) ((?p ?P) (let* ((kwd (org-icompleting-read - "Property: " (mapcar #'list (org-buffer-property-keys)))) + "Property: " (mapcar 'list (org-buffer-property-keys)))) (value (org-icompleting-read - "Value: " (mapcar #'list (org-property-values kwd))))) + "Value: " (mapcar 'list (org-property-values kwd))))) (unless (string-match "\\`{.*}\\'" value) (setq value (concat "\"" value "\""))) (org-match-sparse-tree arg (concat kwd "=" value)))) - ((?r ?R ?/) (call-interactively #'org-occur)) + ((?r ?R ?/) (call-interactively 'org-occur)) (otherwise (user-error "No such sparse tree command \"%c\"" answer))))) (defvar org-occur-highlights nil @@ -13603,6 +13934,7 @@ that the match should indeed be shown." ;; hide everything (org-overview)) (while (re-search-forward regexp nil t) + (backward-char) ;; FIXME: Match timestamps at the end of a headline (when (or (not callback) (save-match-data (funcall callback))) (setq cnt (1+ cnt)) @@ -13635,7 +13967,7 @@ starting point when no match is found." (while (setq p1 (funcall search-func (point) 'org-type)) (when (equal p1 limit) (goto-char pos) - (error "No more matches")) + (user-error "No more matches")) (when (equal (get-char-property p1 'org-type) 'org-occur) (setq n (1- n)) (when (= n 0) @@ -13643,65 +13975,71 @@ starting point when no match is found." (throw 'exit (point)))) (goto-char p1)) (goto-char p1) - (error "No more matches")))) + (user-error "No more matches")))) (defun org-show-context (&optional key) "Make sure point and context are visible. -How much context is shown depends upon the variables -`org-show-hierarchy-above', `org-show-following-heading', -`org-show-entry-below' and `org-show-siblings'." - (let ((heading-p (org-at-heading-p t)) - (hierarchy-p (org-get-alist-option org-show-hierarchy-above key)) - (following-p (org-get-alist-option org-show-following-heading key)) - (entry-p (org-get-alist-option org-show-entry-below key)) - (siblings-p (org-get-alist-option org-show-siblings key))) - ;; Show heading or entry text - (if (and heading-p (not entry-p)) - (org-flag-heading nil) ; only show the heading - (and (or entry-p (outline-invisible-p) (org-invisible-p2)) - (org-show-hidden-entry))) ; show entire entry - (when following-p - ;; Show next sibling, or heading below text - (save-excursion - (and (if heading-p (org-goto-sibling) (outline-next-heading)) - (org-flag-heading nil)))) - (when siblings-p (org-show-siblings)) - (when hierarchy-p - ;; show all higher headings, possibly with siblings +Optional argument KEY, when non-nil, is a symbol. See +`org-show-context-detail' for allowed values and how much is to +be shown." + (org-show-set-visibility + (cond ((symbolp org-show-context-detail) org-show-context-detail) + ((cdr (assq key org-show-context-detail))) + (t (cdr (assq 'default org-show-context-detail)))))) + +(defun org-show-set-visibility (detail) + "Set visibility around point according to DETAIL. +DETAIL is either nil, `minimal', `local', `ancestors', `lineage', +`tree', `canonical' or t. See `org-show-context-detail' for more +information." + (unless (org-before-first-heading-p) + ;; Show current heading and possibly its entry, following headline + ;; or all children. + (if (and (org-at-heading-p) (not (eq detail 'local))) + (org-flag-heading nil) + (org-show-entry) + (org-with-limited-levels + (case detail + ((tree canonical t) (outline-show-children)) + ((nil minimal ancestors)) + (t (save-excursion + (outline-next-heading) + (org-flag-heading nil)))))) + ;; Show all siblings. + (when (eq detail 'lineage) (org-show-siblings)) + ;; Show ancestors, possibly with their children. + (when (memq detail '(ancestors lineage tree canonical t)) (save-excursion - (while (and (condition-case nil - (progn (org-up-heading-all 1) t) - (error nil)) - (not (bobp))) + (while (org-up-heading-safe) (org-flag-heading nil) - (when siblings-p (org-show-siblings))))))) + (when (memq detail '(canonical t)) (org-show-entry)) + (when (memq detail '(tree canonical t)) (outline-show-children))))))) (defvar org-reveal-start-hook nil "Hook run before revealing a location.") (defun org-reveal (&optional siblings) "Show current entry, hierarchy above it, and the following headline. -This can be used to show a consistent set of context around locations -exposed with `org-show-hierarchy-above' or `org-show-following-heading' -not t for the search context. + +This can be used to show a consistent set of context around +locations exposed with `org-show-context'. With optional argument SIBLINGS, on each level of the hierarchy all siblings are shown. This repairs the tree structure to what it would look like when opened with hierarchical calls to `org-cycle'. + With double optional argument \\[universal-argument] \\[universal-argument], \ go to the parent and show the entire tree." (interactive "P") (run-hooks 'org-reveal-start-hook) - (let ((org-show-hierarchy-above t) - (org-show-following-heading t) - (org-show-siblings (if siblings t org-show-siblings))) - (org-show-context nil)) - (when (equal siblings '(16)) - (save-excursion - (when (org-up-heading-safe) - (org-show-subtree) - (run-hook-with-args 'org-cycle-hook 'subtree))))) + (cond ((equal siblings '(4)) (org-show-set-visibility 'canonical)) + ((equal siblings '(16)) + (save-excursion + (when (org-up-heading-safe) + (org-show-subtree) + (run-hook-with-args 'org-cycle-hook 'subtree)))) + (t (org-show-set-visibility 'lineage)))) (defun org-highlight-new-match (beg end) "Highlight from BEG to END and mark the highlight is an occur headline." @@ -13746,83 +14084,83 @@ ACTION can be `set', `up', `down', or a character." (interactive "P") (if (equal action '(4)) (org-show-priority) - (unless org-enable-priority-commands - (user-error "Priority commands are disabled")) - (setq action (or action 'set)) - (let (current new news have remove) - (save-excursion - (org-back-to-heading t) - (if (looking-at org-priority-regexp) - (setq current (string-to-char (match-string 2)) - have t)) - (cond - ((eq action 'remove) - (setq remove t new ?\ )) - ((or (eq action 'set) - (if (featurep 'xemacs) (characterp action) (integerp action))) - (if (not (eq action 'set)) - (setq new action) - (message "Priority %c-%c, SPC to remove: " - org-highest-priority org-lowest-priority) - (save-match-data - (setq new (read-char-exclusive)))) - (if (and (= (upcase org-highest-priority) org-highest-priority) - (= (upcase org-lowest-priority) org-lowest-priority)) - (setq new (upcase new))) - (cond ((equal new ?\ ) (setq remove t)) - ((or (< (upcase new) org-highest-priority) (> (upcase new) org-lowest-priority)) - (user-error "Priority must be between `%c' and `%c'" - org-highest-priority org-lowest-priority)))) - ((eq action 'up) - (setq new (if have - (1- current) ; normal cycling - ;; last priority was empty - (if (eq last-command this-command) - org-lowest-priority ; wrap around empty to lowest - ;; default - (if org-priority-start-cycle-with-default - org-default-priority - (1- org-default-priority)))))) - ((eq action 'down) - (setq new (if have - (1+ current) ; normal cycling - ;; last priority was empty - (if (eq last-command this-command) - org-highest-priority ; wrap around empty to highest - ;; default - (if org-priority-start-cycle-with-default - org-default-priority - (1+ org-default-priority)))))) - (t (user-error "Invalid action"))) - (if (or (< (upcase new) org-highest-priority) - (> (upcase new) org-lowest-priority)) - (if (and (memq action '(up down)) - (not have) (not (eq last-command this-command))) - ;; `new' is from default priority - (error - "The default can not be set, see `org-default-priority' why") - ;; normal cycling: `new' is beyond highest/lowest priority - ;; and is wrapped around to the empty priority - (setq remove t))) - (setq news (format "%c" new)) - (if have + (unless org-enable-priority-commands + (user-error "Priority commands are disabled")) + (setq action (or action 'set)) + (let (current new news have remove) + (save-excursion + (org-back-to-heading t) + (if (looking-at org-priority-regexp) + (setq current (string-to-char (match-string 2)) + have t)) + (cond + ((eq action 'remove) + (setq remove t new ?\ )) + ((or (eq action 'set) + (if (featurep 'xemacs) (characterp action) (integerp action))) + (if (not (eq action 'set)) + (setq new action) + (message "Priority %c-%c, SPC to remove: " + org-highest-priority org-lowest-priority) + (save-match-data + (setq new (read-char-exclusive)))) + (if (and (= (upcase org-highest-priority) org-highest-priority) + (= (upcase org-lowest-priority) org-lowest-priority)) + (setq new (upcase new))) + (cond ((equal new ?\ ) (setq remove t)) + ((or (< (upcase new) org-highest-priority) (> (upcase new) org-lowest-priority)) + (user-error "Priority must be between `%c' and `%c'" + org-highest-priority org-lowest-priority)))) + ((eq action 'up) + (setq new (if have + (1- current) ; normal cycling + ;; last priority was empty + (if (eq last-command this-command) + org-lowest-priority ; wrap around empty to lowest + ;; default + (if org-priority-start-cycle-with-default + org-default-priority + (1- org-default-priority)))))) + ((eq action 'down) + (setq new (if have + (1+ current) ; normal cycling + ;; last priority was empty + (if (eq last-command this-command) + org-highest-priority ; wrap around empty to highest + ;; default + (if org-priority-start-cycle-with-default + org-default-priority + (1+ org-default-priority)))))) + (t (user-error "Invalid action"))) + (if (or (< (upcase new) org-highest-priority) + (> (upcase new) org-lowest-priority)) + (if (and (memq action '(up down)) + (not have) (not (eq last-command this-command))) + ;; `new' is from default priority + (error + "The default can not be set, see `org-default-priority' why") + ;; normal cycling: `new' is beyond highest/lowest priority + ;; and is wrapped around to the empty priority + (setq remove t))) + (setq news (format "%c" new)) + (if have + (if remove + (replace-match "" t t nil 1) + (replace-match news t t nil 2)) (if remove - (replace-match "" t t nil 1) - (replace-match news t t nil 2)) - (if remove - (user-error "No priority cookie found in line") - (let ((case-fold-search nil)) - (looking-at org-todo-line-regexp)) - (if (match-end 2) - (progn - (goto-char (match-end 2)) - (insert " [#" news "]")) - (goto-char (match-beginning 3)) - (insert "[#" news "] ")))) - (org-preserve-lc (org-set-tags nil 'align))) - (if remove - (message "Priority removed") - (message "Priority of current item set to %s" news))))) + (user-error "No priority cookie found in line") + (let ((case-fold-search nil)) + (looking-at org-todo-line-regexp)) + (if (match-end 2) + (progn + (goto-char (match-end 2)) + (insert " [#" news "]")) + (goto-char (match-beginning 3)) + (insert "[#" news "] ")))) + (org-set-tags nil 'align)) + (if remove + (message "Priority removed") + (message "Priority of current item set to %s" news))))) (defun org-show-priority () "Show the priority of the current item. @@ -13909,7 +14247,8 @@ headlines matching this string." lspos tags tags-list (tags-alist (list (cons 0 org-file-tags))) (llast 0) rtn rtn1 level category i txt - todo marker entry priority) + todo marker entry priority + ts-date ts-date-type ts-date-pair) (when (not (or (member action '(agenda sparse-tree)) (functionp action))) (setq action (list 'lambda nil action))) (save-excursion @@ -13926,6 +14265,10 @@ headlines matching this string." (goto-char (setq lspos (match-beginning 0))) (setq level (org-reduced-level (org-outline-level)) category (org-get-category)) + (when (eq action 'agenda) + (setq ts-date-pair (org-agenda-entry-get-agenda-timestamp (point)) + ts-date (car ts-date-pair) + ts-date-type (cdr ts-date-pair))) (setq i llast llast level) ;; remove tag lists from same and sublevels (while (>= i level) @@ -13989,7 +14332,8 @@ headlines matching this string." (if (eq org-tags-match-list-sublevels 'indented) (make-string (1- level) ?.) "") (org-get-heading)) - level category + (make-string level ?\s) + category tags-list) priority (org-get-priority txt)) (goto-char lspos) @@ -13997,7 +14341,9 @@ headlines matching this string." (org-add-props txt props 'org-marker marker 'org-hd-marker marker 'org-category category 'todo-state todo - 'priority priority 'type "tagsmatch") + 'ts-date ts-date + 'priority priority + 'type (concat "tagsmatch" ts-date-type)) (push txt rtn)) ((functionp action) (setq org-map-continue-from nil) @@ -14056,15 +14402,17 @@ also TODO lines." (defun org-cached-entry-get (pom property) (if (or (eq t org-use-property-inheritance) (and (stringp org-use-property-inheritance) - (string-match org-use-property-inheritance property)) + (let ((case-fold-search t)) + (org-string-match-p org-use-property-inheritance property))) (and (listp org-use-property-inheritance) - (member property org-use-property-inheritance))) - ;; Caching is not possible, check it directly + (member-ignore-case property org-use-property-inheritance))) + ;; Caching is not possible, check it directly. (org-entry-get pom property 'inherit) - ;; Get all properties, so that we can do complicated checks easily - (cdr (assoc property (or org-cached-props - (setq org-cached-props - (org-entry-properties pom))))))) + ;; Get all properties, so we can do complicated checks easily. + (cdr (assoc-string property + (or org-cached-props + (setq org-cached-props (org-entry-properties pom))) + t)))) (defun org-global-tags-completion-table (&optional files) "Return the list of all tags in all agenda buffer/files. @@ -14101,7 +14449,7 @@ must be bound around the form's evaluation: todo, the TODO keyword at the entry (or nil of none); and tags-list, the list of all tags at the entry including inherited ones. Additionally, the category of the entry (if any) must be specified as the text property -'org-category on the headline. +`org-category' on the headline. See also `org-scan-tags'. " @@ -14214,7 +14562,7 @@ See also `org-scan-tags'. (if (or (not todomatch) (not (string-match "\\S-" todomatch))) (setq todomatcher t) (setq orterms (org-split-string todomatch "|") orlist nil) - (while (setq term (pop orterms)) + (dolist (term orterms) (while (string-match re term) (setq minus (and (match-end 1) (equal (match-string 1 term) "-")) @@ -14243,16 +14591,16 @@ See also `org-scan-tags'. matcher))) (cons match0 matcher))) -(defun org-tags-expand (match &optional single-as-list downcased) +(defun org-tags-expand (match &optional single-as-list downcased tags-already-expanded) "Expand group tags in MATCH. This replaces every group tag in MATCH with a regexp tag search. For example, a group tag \"Work\" defined as { Work : Lab Conf } will be replaced like this: - Work => {\\(?:Work\\|Lab\\|Conf\\)} - +Work => +{\\(?:Work\\|Lab\\|Conf\\)} - -Work => -{\\(?:Work\\|Lab\\|Conf\\)} + Work => {\\<\\(?:Work\\|Lab\\|Conf\\)\\>} + +Work => +{\\<\\(?:Work\\|Lab\\|Conf\\)\\>} + -Work => -{\\<\\(?:Work\\|Lab\\|Conf\\)\\>} Replacing by a regexp preserves the structure of the match. E.g., this expansion @@ -14262,6 +14610,12 @@ E.g., this expansion will match anything tagged with \"Lab\" and \"Home\", or tagged with \"Conf\" and \"Home\" or tagged with \"Work\" and \"home\". +A group tag in MATCH can contain regular expressions of its own. +For example, a group tag \"Proj\" defined as { Proj : {P@.+} } +will be replaced like this: + + Proj => {\\<\\(?:Proj\\)\\>\\|P@.+} + When the optional argument SINGLE-AS-LIST is non-nil, MATCH is assumed to be a single group tag, and the function will return the list of tags in this group. @@ -14270,33 +14624,113 @@ When DOWNCASE is non-nil, expand downcased TAGS." (if org-group-tags (let* ((case-fold-search t) (stable org-mode-syntax-table) - (tal (or org-tag-groups-alist-for-agenda - org-tag-groups-alist)) - (tal (if downcased - (mapcar (lambda(tg) (mapcar 'downcase tg)) tal) tal)) - (tml (mapcar 'car tal)) - (rtnmatch match) rpl) - ;; @ and _ are allowed as word-components in tags + (taggroups (or org-tag-groups-alist-for-agenda org-tag-groups-alist)) + (taggroups (if downcased + (mapcar (lambda (tg) (mapcar #'downcase tg)) + taggroups) + taggroups)) + (taggroups-keys (mapcar #'car taggroups)) + (return-match (if downcased (downcase match) match)) + (count 0) + (work-already-expanded tags-already-expanded) + regexps-in-match tags-in-group regexp-in-group regexp-in-group-escaped) + ;; @ and _ are allowed as word-components in tags. (modify-syntax-entry ?@ "w" stable) (modify-syntax-entry ?_ "w" stable) - (while (and tml + ;; Temporarily replace regexp-expressions in the match-expression. + (while (string-match "{.+?}" return-match) + (incf count) + (push (match-string 0 return-match) regexps-in-match) + (setq return-match (replace-match (format "<%d>" count) t nil return-match))) + (while (and taggroups-keys (with-syntax-table stable (string-match (concat "\\(?1:[+-]?\\)\\(?2:\\<" - (regexp-opt tml) "\\>\\)") rtnmatch))) - (let* ((dir (match-string 1 rtnmatch)) - (tag (match-string 2 rtnmatch)) + (regexp-opt taggroups-keys) "\\>\\)") + return-match))) + (let* ((dir (match-string 1 return-match)) + (tag (match-string 2 return-match)) (tag (if downcased (downcase tag) tag))) - (setq tml (delete tag tml)) - (when (not (get-text-property 0 'grouptag (match-string 2 rtnmatch))) - (setq rpl (append (org-uniquify rpl) (assoc tag tal))) - (setq rpl (concat dir "{\\<" (regexp-opt rpl) "\\>}")) - (if (stringp rpl) (org-add-props rpl '(grouptag t))) - (setq rtnmatch (replace-match rpl t t rtnmatch))))) + (unless (or (get-text-property 0 'grouptag (match-string 2 return-match)) + (member tag work-already-expanded)) + (setq tags-in-group (assoc tag taggroups)) + (push tag work-already-expanded) + ;; Recursively expand each tag in the group, if the tag hasn't + ;; already been expanded. Restore the match-data after all recursive calls. + (save-match-data + (let (tags-expanded) + (dolist (x (cdr tags-in-group)) + (if (and (member x taggroups-keys) + (not (member x work-already-expanded))) + (setq tags-expanded + (delete-dups + (append + (org-tags-expand x t downcased + work-already-expanded) + tags-expanded))) + (setq tags-expanded + (append (list x) tags-expanded))) + (setq work-already-expanded + (delete-dups + (append tags-expanded + work-already-expanded)))) + (setq tags-in-group + (delete-dups (cons (car tags-in-group) + tags-expanded))))) + ;; Filter tag-regexps from tags. + (setq regexp-in-group-escaped + (delq nil (mapcar (lambda (x) + (if (stringp x) + (and (equal "{" (substring x 0 1)) + (equal "}" (substring x -1)) + x) + x)) + tags-in-group)) + regexp-in-group + (mapcar (lambda (x) + (substring x 1 -1)) + regexp-in-group-escaped) + tags-in-group + (delq nil (mapcar (lambda (x) + (if (stringp x) + (and (not (equal "{" (substring x 0 1))) + (not (equal "}" (substring x -1))) + x) + x)) + tags-in-group))) + ;; If single-as-list, do no more in the while-loop. + (if (not single-as-list) + (progn + (when regexp-in-group + (setq regexp-in-group + (concat "\\|" + (mapconcat 'identity regexp-in-group + "\\|")))) + (setq tags-in-group + (concat dir + "{\\<" + (regexp-opt tags-in-group) + "\\>" + regexp-in-group + "}")) + (when (stringp tags-in-group) + (org-add-props tags-in-group '(grouptag t))) + (setq return-match + (replace-match tags-in-group t t return-match))) + (setq tags-in-group + (append regexp-in-group-escaped tags-in-group)))) + (setq taggroups-keys (delete tag taggroups-keys)))) + ;; Add the regular expressions back into the match-expression again. + (while regexps-in-match + (setq return-match (replace-regexp-in-string (format "<%d>" count) + (pop regexps-in-match) + return-match t t)) + (decf count)) (if single-as-list - (or (reverse rpl) (list rtnmatch)) - rtnmatch)) - (if single-as-list (list (if downcased (downcase match) match)) + (if tags-in-group tags-in-group (list return-match)) + return-match)) + (if single-as-list + (list (if downcased (downcase match) match)) match))) (defun org-op-to-function (op &optional stringp) @@ -14419,7 +14853,8 @@ ignore inherited ones." (reverse (delete-dups (reverse (append (org-remove-uninherited-tags - org-file-tags) tags))))))))) + org-file-tags) + tags))))))))) (defun org-add-prop-inherited (s) (add-text-properties 0 (length s) '(inherited t) s) @@ -14541,102 +14976,108 @@ When JUST-ALIGN is non-nil, only align tags." (interactive "P") (if (and (org-region-active-p) org-loop-over-headlines-in-active-region) (let ((cl (if (eq org-loop-over-headlines-in-active-region 'start-level) - 'region-start-level 'region)) - org-loop-over-headlines-in-active-region) - (org-map-entries - ;; We don't use ARG and JUST-ALIGN here because these args - ;; are not useful when looping over headlines. - `(org-set-tags) - org-loop-over-headlines-in-active-region - cl (if (outline-invisible-p) (org-end-of-subtree nil t)))) - (let* ((re org-outline-regexp-bol) - (current (unless arg (org-get-tags-string))) - (col (current-column)) - (org-setting-tags t) - table current-tags inherited-tags ; computed below when needed - tags p0 c0 c1 rpl di tc level) + 'region-start-level + 'region)) + org-loop-over-headlines-in-active-region) + (org-map-entries + ;; We don't use ARG and JUST-ALIGN here because these args + ;; are not useful when looping over headlines. + #'org-set-tags + org-loop-over-headlines-in-active-region + cl + '(when (outline-invisible-p) (org-end-of-subtree nil t)))) + (let ((org-setting-tags t)) (if arg - (save-excursion - (goto-char (point-min)) - (let ((buffer-invisibility-spec (org-inhibit-invisibility))) - (while (re-search-forward re nil t) - (org-set-tags nil t) - (end-of-line 1))) - (message "All tags realigned to column %d" org-tags-column)) - (if just-align - (setq tags current) - ;; Get a new set of tags from the user - (save-excursion - (setq table (append org-tag-persistent-alist - (or org-tag-alist (org-get-buffer-tags)) - (and - org-complete-tags-always-offer-all-agenda-tags - (org-global-tags-completion-table - (org-agenda-files)))) - org-last-tags-completion-table table - current-tags (org-split-string current ":") - inherited-tags (nreverse - (nthcdr (length current-tags) - (nreverse (org-get-tags-at)))) - tags - (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 - (if org-fast-tag-selection-include-todo - org-todo-key-alist)) - (let ((org-add-colon-after-tag-completion (< 1 (length table)))) - (org-trim - (org-icompleting-read "Tags: " - 'org-tags-completion-function - nil nil current 'org-tags-history)))))) - (while (string-match "[-+&]+" tags) - ;; No boolean logic, just a list - (setq tags (replace-match ":" t t tags)))) - - (setq tags (replace-regexp-in-string "[,]" ":" tags)) - - (if org-tags-sort-function - (setq tags (mapconcat 'identity - (sort (org-split-string - tags (org-re "[^[:alnum:]_@#%]+")) - org-tags-sort-function) ":"))) - - (if (string-match "\\`[\t ]*\\'" tags) - (setq tags "") - (unless (string-match ":$" tags) (setq tags (concat tags ":"))) - (unless (string-match "^:" tags) (setq tags (concat ":" tags)))) - - ;; Insert new tags at the correct column - (beginning-of-line 1) - (setq level (or (and (looking-at org-outline-regexp) - (- (match-end 0) (point) 1)) - 1)) - (cond - ((and (equal current "") (equal tags ""))) - ((re-search-forward - (concat "\\([ \t]*" (regexp-quote current) "\\)[ \t]*$") - (point-at-eol) t) - (if (equal tags "") - (setq rpl "") - (goto-char (match-beginning 0)) - (setq c0 (current-column) - ;; compute offset for the case of org-indent-mode active - di (if (org-bound-and-true-p org-indent-mode) - (* (1- org-indent-indentation-per-level) (1- level)) - 0) - p0 (if (equal (char-before) ?*) (1+ (point)) (point)) - tc (+ org-tags-column (if (> org-tags-column 0) (- di) di)) - c1 (max (1+ c0) (if (> tc 0) tc (- (- tc) (length tags)))) - rpl (concat (make-string (max 0 (- c1 c0)) ?\ ) tags))) - (replace-match rpl t t) - (and (not (featurep 'xemacs)) c0 indent-tabs-mode (tabify p0 (point))) - tags) - (t (error "Tags alignment failed"))) - (org-move-to-column col) - (unless just-align - (run-hooks 'org-after-tags-change-hook)))))) + (save-excursion + (goto-char (point-min)) + (let ((buffer-invisibility-spec (org-inhibit-invisibility))) + (while (re-search-forward org-outline-regexp-bol nil t) + (org-set-tags nil t) + (end-of-line))) + (message "All tags realigned to column %d" org-tags-column)) + (let* ((current (org-get-tags-string)) + (col (current-column)) + (tags + (if just-align current + ;; Get a new set of tags from the user. + (save-excursion + (let* ((table + (setq + org-last-tags-completion-table + (append + org-tag-persistent-alist + (or org-tag-alist (org-get-buffer-tags)) + (and + org-complete-tags-always-offer-all-agenda-tags + (org-global-tags-completion-table + (org-agenda-files)))))) + (current-tags (org-split-string current ":")) + (inherited-tags + (nreverse (nthcdr (length current-tags) + (nreverse (org-get-tags-at)))))) + (replace-regexp-in-string + "\\([-+&]+\\|,\\)" + ":" + (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 current 'org-tags-history)))))))))) + + (when org-tags-sort-function + (setq tags + (mapconcat + #'identity + (sort (org-split-string tags (org-re "[^[:alnum:]_@#%]+")) + org-tags-sort-function) + ":"))) + + (if (not (org-string-nw-p tags)) (setq tags "") + (unless (string-match ":\\'" tags) (setq tags (concat tags ":"))) + (unless (string-match "\\`:" tags) (setq tags (concat ":" tags)))) + + ;; Insert new tags at the correct column + (beginning-of-line) + (let ((level (if (looking-at org-outline-regexp) + (- (match-end 0) (point) 1) + 1))) + (cond + ((and (equal current "") (equal tags ""))) + ((re-search-forward + (concat "\\([ \t]*" (regexp-quote current) "\\)[ \t]*$") + (line-end-position) + t) + (if (equal tags "") (replace-match "" t t) + (goto-char (match-beginning 0)) + (let* ((c0 (current-column)) + ;; Compute offset for the case of org-indent-mode + ;; active. + (di (if (org-bound-and-true-p org-indent-mode) + (* (1- org-indent-indentation-per-level) + (1- level)) + 0)) + (p0 (if (eq (char-before) ?*) (1+ (point)) (point))) + (tc (+ org-tags-column + (if (> org-tags-column 0) (- di) di))) + (c1 (max (1+ c0) + (if (> tc 0) tc + (- (- tc) (string-width tags))))) + (rpl (concat (make-string (max 0 (- c1 c0)) ?\s) tags))) + (replace-match rpl t t) + (when (and (not (featurep 'xemacs)) indent-tabs-mode) + (tabify p0 (point)))))) + (t (error "Tags alignment failed")))) + (org-move-to-column col)) + (unless just-align (run-hooks 'org-after-tags-change-hook)))))) (defun org-change-tag-in-region (beg end tag off) "Add or remove TAG for each entry in the region. @@ -14755,7 +15196,7 @@ Returns the new tags string, or nil to not change the current settings." ov-start ov-end ov-prefix (exit-after-next org-fast-tag-selection-single-key) (done-keywords org-done-keywords) - groups ingroup) + groups ingroup intaggroup) (save-excursion (beginning-of-line 1) (if (looking-at @@ -14788,24 +15229,33 @@ Returns the new tags string, or nil to not change the current settings." (setq tbl fulltable char ?a cnt 0) (while (setq e (pop tbl)) (cond - ((equal (car e) :startgroup) + ((eq (car e) :startgroup) (push '() groups) (setq ingroup t) - (when (not (= cnt 0)) + (unless (zerop cnt) (setq cnt 0) (insert "\n")) (insert (if (cdr e) (format "%s: " (cdr e)) "") "{ ")) - ((equal (car e) :endgroup) + ((eq (car e) :endgroup) (setq ingroup nil cnt 0) (insert "}" (if (cdr e) (format " (%s) " (cdr e)) "") "\n")) + ((eq (car e) :startgrouptag) + (setq intaggroup t) + (unless (zerop cnt) + (setq cnt 0) + (insert "\n")) + (insert "[ ")) + ((eq (car e) :endgrouptag) + (setq intaggroup nil cnt 0) + (insert "]\n")) ((equal e '(:newline)) - (when (not (= cnt 0)) + (unless (zerop cnt) (setq cnt 0) (insert "\n") (setq e (car tbl)) (while (equal (car tbl) '(:newline)) (insert "\n") (setq tbl (cdr tbl))))) - ((equal e '(:grouptags)) nil) + ((equal e '(:grouptags)) (insert " : ")) (t (setq tg (copy-sequence (car e)) c2 nil) (if (cdr e) @@ -14819,27 +15269,27 @@ Returns the new tags string, or nil to not change the current settings." (setq char (1+ char))) (setq c2 c1)) (setq c (or c2 char))) - (if ingroup (push tg (car groups))) + (when ingroup (push tg (car groups))) (setq tg (org-add-props tg nil 'face (cond ((not (assoc tg table)) (org-get-todo-face tg)) ((member tg current) c-face) ((member tg inherited) i-face)))) - (if (equal (caar tbl) :grouptags) - (org-add-props tg nil 'face 'org-tag-group)) - (if (and (= cnt 0) (not ingroup)) (insert " ")) + (when (equal (caar tbl) :grouptags) + (org-add-props tg nil 'face 'org-tag-group)) + (when (and (zerop cnt) (not ingroup) (not intaggroup)) (insert " ")) (insert "[" c "] " tg (make-string (- fwidth 4 (length tg)) ?\ )) (push (cons tg c) ntable) - (when (= (setq cnt (1+ cnt)) ncol) + (when (= (incf cnt) ncol) (insert "\n") - (if ingroup (insert " ")) + (when (or ingroup intaggroup) (insert " ")) (setq cnt 0))))) (setq ntable (nreverse ntable)) (insert "\n") (goto-char (point-min)) - (if (not expert) (org-fit-window-to-buffer)) + (unless expert (org-fit-window-to-buffer)) (setq rtn (catch 'exit (while t @@ -14869,42 +15319,41 @@ Returns the new tags string, or nil to not change the current settings." (setq quit-flag t)) ((= c ?\ ) (setq current nil) - (if exit-after-next (setq exit-after-next 'now))) + (when exit-after-next (setq exit-after-next 'now))) ((= c ?\t) (condition-case nil (setq tg (org-icompleting-read "Tag: " (or buffer-tags (with-current-buffer buf - (org-get-buffer-tags))))) + (setq buffer-tags + (org-get-buffer-tags)))))) (quit (setq tg ""))) (when (string-match "\\S-" tg) (add-to-list 'buffer-tags (list tg)) (if (member tg current) (setq current (delete tg current)) (push tg current))) - (if exit-after-next (setq exit-after-next 'now))) + (when exit-after-next (setq exit-after-next 'now))) ((setq e (rassoc c todo-table) tg (car e)) (with-current-buffer buf (save-excursion (org-todo tg))) - (if exit-after-next (setq exit-after-next 'now))) + (when exit-after-next (setq exit-after-next 'now))) ((setq e (rassoc c ntable) tg (car e)) (if (member tg current) (setq current (delete tg current)) (loop for g in groups do - (if (member tg g) - (mapc (lambda (x) - (setq current (delete x current))) - g))) + (when (member tg g) + (dolist (x g) (setq current (delete x current))))) (push tg current)) - (if exit-after-next (setq exit-after-next 'now)))) + (when exit-after-next (setq exit-after-next 'now)))) ;; Create a sorted list (setq current (sort current (lambda (a b) (assoc b (cdr (memq (assoc a ntable) ntable)))))) - (if (eq exit-after-next 'now) (throw 'exit t)) + (when (eq exit-after-next 'now) (throw 'exit t)) (goto-char (point-min)) (beginning-of-line 2) (delete-region (point) (point-at-eol)) @@ -14942,16 +15391,16 @@ Returns the new tags string, or nil to not change the current settings." (defun org-get-buffer-tags () "Get a table of all tags used in the buffer, for completion." - (let (tags) - (save-excursion - (goto-char (point-min)) - (while (re-search-forward - (org-re "[ \t]:\\([[:alnum:]_@#%:]+\\):[ \t\r\n]") nil t) - (when (equal (char-after (point-at-bol 0)) ?*) - (mapc (lambda (x) (add-to-list 'tags x)) - (org-split-string (org-match-string-no-properties 1) ":"))))) - (mapc (lambda (s) (add-to-list 'tags s)) org-file-tags) - (mapcar 'list tags))) + (org-with-wide-buffer + (goto-char (point-min)) + (let ((tag-re (concat org-outline-regexp-bol + "\\(?:.*?[ \t]\\)?" + (org-re ":\\([[:alnum:]_@#%:]+\\):[ \t]*$"))) + tags) + (while (re-search-forward tag-re nil t) + (dolist (tag (org-split-string (org-match-string-no-properties 1) ":")) + (push tag tags))) + (mapcar #'list (append org-file-tags (org-uniquify tags)))))) ;;;; The mapping API @@ -15028,7 +15477,6 @@ a *different* entry, you cannot use these techniques." org-todo-keywords-for-agenda org-done-keywords-for-agenda org-todo-keyword-alist-for-agenda - org-drawers-for-agenda org-tag-alist-for-agenda todo-only) @@ -15062,7 +15510,7 @@ a *different* entry, you cannot use these techniques." (if (not scope) (progn (org-agenda-prepare-buffers - (list (buffer-file-name (current-buffer)))) + (and buffer-file-name (list buffer-file-name))) (setq res (org-scan-tags func matcher todo-only start-level))) ;; Get the right scope (cond @@ -15074,11 +15522,11 @@ a *different* entry, you cannot use these techniques." (setq scope (org-agenda-files t)) (setq scope (org-add-archive-files scope))) ((eq scope 'file) - (setq scope (list (buffer-file-name)))) + (setq scope (and buffer-file-name (list buffer-file-name)))) ((eq scope 'file-with-archives) (setq scope (org-add-archive-files (list (buffer-file-name)))))) (org-agenda-prepare-buffers scope) - (while (setq file (pop scope)) + (dolist (file scope) (with-current-buffer (org-find-base-buffer-visiting file) (save-excursion (save-restriction @@ -15087,15 +15535,12 @@ a *different* entry, you cannot use these techniques." (setq res (append res (org-scan-tags func matcher todo-only)))))))))) res))) -;;;; Properties - -;;; Setting and retrieving properties +;;; Properties API (defconst org-special-properties - '("TODO" "TAGS" "ALLTAGS" "DEADLINE" "SCHEDULED" "CLOCK" "CLOSED" "PRIORITY" - "TIMESTAMP" "TIMESTAMP_IA" "BLOCKED" "FILE" "CLOCKSUM" "CLOCKSUM_T") - "The special properties valid in Org-mode. - + '("ALLTAGS" "BLOCKED" "CLOCKSUM" "CLOCKSUM_T" "CLOSED" "DEADLINE" "FILE" + "ITEM" "PRIORITY" "SCHEDULED" "TAGS" "TIMESTAMP" "TIMESTAMP_IA" "TODO") + "The special properties valid in Org mode. These are properties that are not defined in the property drawer, but in some other way.") @@ -15104,59 +15549,86 @@ but in some other way.") "LOCATION" "LOGGING" "COLUMNS" "VISIBILITY" "TABLE_EXPORT_FORMAT" "TABLE_EXPORT_FILE" "EXPORT_OPTIONS" "EXPORT_TEXT" "EXPORT_FILE_NAME" - "EXPORT_TITLE" "EXPORT_AUTHOR" "EXPORT_DATE" + "EXPORT_TITLE" "EXPORT_AUTHOR" "EXPORT_DATE" "UNNUMBERED" "ORDERED" "NOBLOCKING" "COOKIE_DATA" "LOG_INTO_DRAWER" "REPEAT_TO_STATE" "CLOCK_MODELINE_TOTAL" "STYLE" "HTML_CONTAINER_CLASS") - "Some properties that are used by Org-mode for various purposes. + "Some properties that are used by Org mode for various purposes. Being in this list makes sure that they are offered for completion.") -(defconst org-property-start-re "^[ \t]*:PROPERTIES:[ \t]*$" - "Regular expression matching the first line of a property drawer.") - -(defconst org-property-end-re "^[ \t]*:END:[ \t]*$" - "Regular expression matching the last line of a property drawer.") - -(defconst org-clock-drawer-start-re "^[ \t]*:CLOCK:[ \t]*$" - "Regular expression matching the first line of a property drawer.") - -(defconst org-clock-drawer-end-re "^[ \t]*:END:[ \t]*$" - "Regular expression matching the first line of a property drawer.") - -(defconst org-property-drawer-re - (concat "\\(" org-property-start-re "\\)[^\000]*\\(" - org-property-end-re "\\)\n?") - "Matches an entire property drawer.") +(defun org--valid-property-p (property) + "Non nil when string PROPERTY is a valid property name." + (not + (or (equal property "") + (org-string-match-p "\\s-" property)))) + +(defun org--update-property-plist (key val props) + "Associate KEY to VAL in alist PROPS. +Modifications are made by side-effect. Return new alist." + (let* ((appending (string= (substring key -1) "+")) + (key (if appending (substring key 0 -1) key)) + (old (assoc-string key props t))) + (if (not old) (cons (cons key val) props) + (setcdr old (if appending (concat (cdr old) " " val) val)) + props))) + +(defun org-get-property-block (&optional beg force) + "Return the (beg . end) range of the body of the property drawer. +BEG is the beginning of the current subtree, or of the part +before the first headline. If it is not given, it will be found. +If the drawer does not exist, create it if FORCE is non-nil, or +return nil." + (org-with-wide-buffer + (when beg (goto-char beg)) + (unless (org-before-first-heading-p) + (let ((beg (cond (beg) + ((or (not (featurep 'org-inlinetask)) + (org-inlinetask-in-task-p)) + (org-back-to-heading t)) + (t (org-with-limited-levels (org-back-to-heading t)))))) + (forward-line) + (when (org-looking-at-p org-planning-line-re) (forward-line)) + (cond ((looking-at org-property-drawer-re) + (forward-line) + (cons (point) (progn (goto-char (match-end 0)) + (line-beginning-position)))) + (force + (goto-char beg) + (org-insert-property-drawer) + (let ((pos (save-excursion (search-forward ":END:") + (line-beginning-position)))) + (cons pos pos)))))))) -(defconst org-clock-drawer-re - (concat "\\(" org-clock-drawer-start-re "\\)[^\000]*\\(" - org-property-end-re "\\)\n?") - "Matches an entire clock drawer.") +(defun org-at-property-p () + "Non-nil when point is inside a property drawer. +See `org-property-re' for match data, if applicable." + (save-excursion + (beginning-of-line) + (and (looking-at org-property-re) + (let ((property-drawer (save-match-data (org-get-property-block)))) + (and property-drawer + (>= (point) (car property-drawer)) + (< (point) (cdr property-drawer))))))) (defun org-property-action () "Do an action on properties." (interactive) - (let (c) - (org-at-property-p) - (message "Property Action: [s]et [d]elete [D]elete globally [c]ompute") - (setq c (read-char-exclusive)) - (cond - ((equal c ?s) - (call-interactively 'org-set-property)) - ((equal c ?d) - (call-interactively 'org-delete-property)) - ((equal c ?D) - (call-interactively 'org-delete-property-globally)) - ((equal c ?c) - (call-interactively 'org-compute-property-at-point)) - (t (user-error "No such property action %c" c))))) + (unless (org-at-property-p) (user-error "Not at a property")) + (message "Property Action: [s]et [d]elete [D]elete globally [c]ompute") + (let ((c (read-char-exclusive))) + (case c + (?s (call-interactively #'org-set-property)) + (?d (call-interactively #'org-delete-property)) + (?D (call-interactively #'org-delete-property-globally)) + (?c (call-interactively #'org-compute-property-at-point)) + (otherwise (user-error "No such property action %c" c))))) (defun org-inc-effort () "Increment the value of the effort property in the current entry." (interactive) (org-set-effort nil t)) -(defvar org-clock-effort) ;; Defined in org-clock.el -(defvar org-clock-current-task) ;; Defined in org-clock.el +(defvar org-clock-effort) ; Defined in org-clock.el. +(defvar org-clock-current-task) ; Defined in org-clock.el. (defun org-set-effort (&optional value increment) "Set the effort property of the current entry. With numerical prefix arg, use the nth allowed value, 0 stands for the @@ -15201,218 +15673,272 @@ When INCREMENT is non-nil, set the property to the next allowed value." existing nil nil "" nil cur)))))) (unless (equal (org-entry-get nil prop) val) (org-entry-put nil prop val)) - (save-excursion - (org-back-to-heading t) - (put-text-property (point-at-bol) (point-at-eol) 'org-effort val)) + (org-refresh-property + '((effort . identity) + (effort-minutes . org-duration-string-to-minutes)) + val) (when (string= heading org-clock-current-task) - (setq org-clock-effort (get-text-property (point-at-bol) 'org-effort)) + (setq org-clock-effort (get-text-property (point-at-bol) 'effort)) (org-clock-update-mode-line)) (message "%s is now %s" prop val))) -(defun org-at-property-p () - "Is cursor inside a property drawer?" - (save-excursion - (when (equal 'node-property (car (org-element-at-point))) - (beginning-of-line 1) - (looking-at org-property-re)))) +(defun org-entry-properties (&optional pom which) + "Get all properties of the current entry. + +When POM is a buffer position, get all properties from the entry +there instead. + +This includes the TODO keyword, the tags, time strings for +deadline, scheduled, and clocking, and any additional properties +defined in the entry. -(defun org-get-property-block (&optional beg end force) - "Return the (beg . end) range of the body of the property drawer. -BEG and END are the beginning and end of the current subtree, or of -the part before the first headline. If they are not given, they will -be found. If the drawer does not exist and FORCE is non-nil, create -the drawer." - (catch 'exit - (save-excursion - (let* ((beg (or beg (and (org-before-first-heading-p) (point-min)) - (progn (org-back-to-heading t) (point)))) - (end (or end (and (not (outline-next-heading)) (point-max)) - (point)))) - (goto-char beg) - (if (re-search-forward org-property-start-re end t) - (setq beg (1+ (match-end 0))) - (if force - (save-excursion - (org-insert-property-drawer) - (setq end (progn (outline-next-heading) (point)))) - (throw 'exit nil)) - (goto-char beg) - (if (re-search-forward org-property-start-re end t) - (setq beg (1+ (match-end 0))))) - (if (re-search-forward org-property-end-re end t) - (setq end (match-beginning 0)) - (or force (throw 'exit nil)) - (goto-char beg) - (setq end beg) - (org-indent-line) - (insert ":END:\n")) - (cons beg end))))) - -(defun org-entry-properties (&optional pom which specific) - "Get all properties of the entry at point-or-marker POM. -This includes the TODO keyword, the tags, time strings for deadline, -scheduled, and clocking, and any additional properties defined in the -entry. The return value is an alist, keys may occur multiple times -if the property key was used several times. -POM may also be nil, in which case the current entry is used. If WHICH is nil or `all', get all properties. If WHICH is -`special' or `standard', only get that subclass. If WHICH -is a string only get exactly this property. SPECIFIC can be a string, the -specific property we are interested in. Specifying it can speed -things up because then unnecessary parsing is avoided." - (setq which (or which 'all)) - (org-with-wide-buffer - (org-with-point-at pom - (let ((clockstr (substring org-clock-string 0 -1)) - (excluded '("TODO" "TAGS" "ALLTAGS" "PRIORITY" "BLOCKED")) - (case-fold-search nil) - beg end range props sum-props key key1 value string clocksum clocksumt) - (when (and (derived-mode-p 'org-mode) - (ignore-errors (org-back-to-heading t))) - (setq beg (point)) - (setq sum-props (get-text-property (point) 'org-summaries)) - (setq clocksum (get-text-property (point) :org-clock-minutes) - clocksumt (get-text-property (point) :org-clock-minutes-today)) - (outline-next-heading) - (setq end (point)) - (when (memq which '(all special)) - ;; Get the special properties, like TODO and tags - (goto-char beg) - (when (and (or (not specific) (string= specific "TODO")) - (looking-at org-todo-line-regexp) (match-end 2)) - (push (cons "TODO" (org-match-string-no-properties 2)) props)) - (when (and (or (not specific) (string= specific "PRIORITY")) - (looking-at org-priority-regexp)) - (push (cons "PRIORITY" (org-match-string-no-properties 2)) props)) - (when (or (not specific) (string= specific "FILE")) - (push (cons "FILE" buffer-file-name) props)) - (when (and (or (not specific) (string= specific "TAGS")) - (setq value (org-get-tags-string)) - (string-match "\\S-" value)) - (push (cons "TAGS" value) props)) - (when (and (or (not specific) (string= specific "ALLTAGS")) - (setq value (org-get-tags-at))) - (push (cons "ALLTAGS" (concat ":" (mapconcat 'identity value ":") - ":")) - props)) - (when (or (not specific) (string= specific "BLOCKED")) - (push (cons "BLOCKED" (if (org-entry-blocked-p) "t" "")) props)) - (when (or (not specific) - (member specific - '("SCHEDULED" "DEADLINE" "CLOCK" "CLOSED" - "TIMESTAMP" "TIMESTAMP_IA"))) - (catch 'match - (while (and (re-search-forward org-maybe-keyword-time-regexp end t) - (not (text-property-any 0 (length (match-string 0)) - 'face 'font-lock-comment-face - (match-string 0)))) - (setq key (if (match-end 1) - (substring (org-match-string-no-properties 1) - 0 -1)) - string (if (equal key clockstr) - (org-trim - (buffer-substring-no-properties - (match-beginning 3) (goto-char - (point-at-eol)))) - (substring (org-match-string-no-properties 3) - 1 -1))) - ;; Get the correct property name from the key. This is - ;; necessary if the user has configured time keywords. - (setq key1 (concat key ":")) - (cond - ((not key) - (setq key - (if (= (char-after (match-beginning 3)) ?\[) - "TIMESTAMP_IA" "TIMESTAMP"))) - ((equal key1 org-scheduled-string) (setq key "SCHEDULED")) - ((equal key1 org-deadline-string) (setq key "DEADLINE")) - ((equal key1 org-closed-string) (setq key "CLOSED")) - ((equal key1 org-clock-string) (setq key "CLOCK"))) - (if (and specific (equal key specific) (not (equal key "CLOCK"))) - (progn - (push (cons key string) props) - ;; no need to search further if match is found - (throw 'match t)) - (when (or (equal key "CLOCK") (not (assoc key props))) - (push (cons key string) props))))))) - - (when (memq which '(all standard)) - ;; Get the standard properties, like :PROP: ... - (setq range (org-get-property-block beg end)) - (when range - (goto-char (car range)) - (while (re-search-forward org-property-re - (cdr range) t) - (setq key (org-match-string-no-properties 2) - value (org-trim (or (org-match-string-no-properties 3) ""))) - (unless (member key excluded) - (push (cons key (or value "")) props))))) - (if clocksum - (push (cons "CLOCKSUM" - (org-columns-number-to-string (/ (float clocksum) 60.) - 'add_times)) - props)) - (if clocksumt - (push (cons "CLOCKSUM_T" - (org-columns-number-to-string (/ (float clocksumt) 60.) - 'add_times)) - props)) - (unless (assoc "CATEGORY" props) - (push (cons "CATEGORY" (org-get-category)) props)) - (append sum-props (nreverse props))))))) +`special' or `standard', only get that subclass. If WHICH is +a string, only get that property. + +Return value is an alist. Keys are properties, as upcased +strings." + (org-with-point-at pom + (when (and (derived-mode-p 'org-mode) + (ignore-errors (org-back-to-heading t))) + (catch 'exit + (let* ((beg (point)) + (specific (and (stringp which) (upcase which))) + (which (cond ((not specific) which) + ((member specific org-special-properties) 'special) + (t 'standard))) + props) + ;; Get the special properties, like TODO and TAGS. + (when (memq which '(nil all special)) + (when (or (not specific) (string= specific "CLOCKSUM")) + (let ((clocksum (get-text-property (point) :org-clock-minutes))) + (when clocksum + (push (cons "CLOCKSUM" + (org-columns-number-to-string + (/ (float clocksum) 60.) 'add_times)) + props))) + (when specific (throw 'exit props))) + (when (or (not specific) (string= specific "CLOCKSUM_T")) + (let ((clocksumt (get-text-property (point) + :org-clock-minutes-today))) + (when clocksumt + (push (cons "CLOCKSUM_T" + (org-columns-number-to-string + (/ (float clocksumt) 60.) 'add_times)) + props))) + (when specific (throw 'exit props))) + (when (or (not specific) (string= specific "ITEM")) + (when (looking-at org-complex-heading-regexp) + (push (cons "ITEM" + (concat + (org-match-string-no-properties 1) + (let ((title (org-match-string-no-properties 4))) + (when (org-string-nw-p title) + (concat " " (org-remove-tabs title)))))) + props)) + (when specific (throw 'exit props))) + (when (or (not specific) (string= specific "TODO")) + (let ((case-fold-search nil)) + (when (and (looking-at org-todo-line-regexp) (match-end 2)) + (push (cons "TODO" (org-match-string-no-properties 2)) props))) + (when specific (throw 'exit props))) + (when (or (not specific) (string= specific "PRIORITY")) + (push (cons "PRIORITY" + (if (looking-at org-priority-regexp) + (org-match-string-no-properties 2) + (char-to-string org-default-priority))) + props) + (when specific (throw 'exit props))) + (when (or (not specific) (string= specific "FILE")) + (push (cons "FILE" (buffer-file-name (buffer-base-buffer))) + props) + (when specific (throw 'exit props))) + (when (or (not specific) (string= specific "TAGS")) + (let ((value (org-string-nw-p (org-get-tags-string)))) + (when value (push (cons "TAGS" value) props))) + (when specific (throw 'exit props))) + (when (or (not specific) (string= specific "ALLTAGS")) + (let ((value (org-get-tags-at))) + (when value + (push (cons "ALLTAGS" + (format ":%s:" (mapconcat #'identity value ":"))) + props))) + (when specific (throw 'exit props))) + (when (or (not specific) (string= specific "BLOCKED")) + (push (cons "BLOCKED" (if (org-entry-blocked-p) "t" "")) props) + (when specific (throw 'exit props))) + (when (or (not specific) + (member specific '("CLOSED" "DEADLINE" "SCHEDULED"))) + (forward-line) + (when (org-looking-at-p org-planning-line-re) + (end-of-line) + (let ((bol (line-beginning-position)) + ;; Backward compatibility: time keywords used to + ;; be configurable (before 8.3). Make sure we + ;; get the correct keyword. + (key-assoc `(("CLOSED" . ,org-closed-string) + ("DEADLINE" . ,org-deadline-string) + ("SCHEDULED" . ,org-scheduled-string)))) + (dolist (pair (if specific (list (assoc specific key-assoc)) + key-assoc)) + (save-excursion + (when (search-backward (cdr pair) bol t) + (goto-char (match-end 0)) + (skip-chars-forward " \t") + (and (looking-at org-ts-regexp-both) + (push (cons (car pair) + (org-match-string-no-properties 0)) + props))))))) + (when specific (throw 'exit props))) + (when (or (not specific) + (member specific '("TIMESTAMP" "TIMESTAMP_IA"))) + (let ((find-ts + (lambda (end ts) + (let ((regexp (cond + ((string= specific "TIMESTAMP") + org-ts-regexp) + ((string= specific "TIMESTAMP_IA") + org-ts-regexp-inactive) + ((assoc "TIMESTAMP_IA" ts) + org-ts-regexp) + ((assoc "TIMESTAMP" ts) + org-ts-regexp-inactive) + (t org-ts-regexp-both)))) + (catch 'next + (while (re-search-forward regexp end t) + (backward-char) + (let ((object (org-element-context))) + ;; Accept to match timestamps in node + ;; properties, too. + (when (memq (org-element-type object) + '(node-property timestamp)) + (let ((type + (org-element-property :type object))) + (cond + ((and (memq type '(active active-range)) + (not (equal specific "TIMESTAMP_IA"))) + (unless (assoc "TIMESTAMP" ts) + (push (cons "TIMESTAMP" + (org-element-property + :raw-value object)) + ts) + (when specific (throw 'exit ts)))) + ((and (memq type '(inactive inactive-range)) + (not (string= specific "TIMESTAMP"))) + (unless (assoc "TIMESTAMP_IA" ts) + (push (cons "TIMESTAMP_IA" + (org-element-property + :raw-value object)) + ts) + (when specific (throw 'exit ts)))))) + ;; Both timestamp types are found, + ;; move to next part. + (when (= (length ts) 2) (throw 'next ts))))) + ts))))) + (goto-char beg) + ;; First look for timestamps within headline. + (let ((ts (funcall find-ts (line-end-position) nil))) + (if (= (length ts) 2) (setq props (nconc ts props)) + (forward-line) + ;; Then find timestamps in the section, skipping + ;; planning line. + (when (org-looking-at-p org-planning-line-re) + (forward-line)) + (let ((end (save-excursion (outline-next-heading)))) + (setq props (nconc (funcall find-ts end ts) props)))))))) + ;; Get the standard properties, like :PROP:. + (when (memq which '(nil all standard)) + ;; If we are looking after a specific property, delegate + ;; to `org-entry-get', which is faster. However, make an + ;; exception for "CATEGORY", since it can be also set + ;; through keywords (i.e. #+CATEGORY). + (if (and specific (not (equal specific "CATEGORY"))) + (let ((value (org-entry-get beg specific nil t))) + (throw 'exit (and value (list (cons specific value))))) + (let ((range (org-get-property-block beg))) + (when range + (let ((end (cdr range)) seen-base) + (goto-char (car range)) + ;; Unlike to `org--update-property-plist', we + ;; handle the case where base values is found + ;; after its extension. We also forbid standard + ;; properties to be named as special properties. + (while (re-search-forward org-property-re end t) + (let* ((key (upcase (org-match-string-no-properties 2))) + (extendp (org-string-match-p "\\+\\'" key)) + (key-base (if extendp (substring key 0 -1) key)) + (value (org-match-string-no-properties 3))) + (cond + ((member-ignore-case key-base org-special-properties)) + (extendp + (setq props + (org--update-property-plist key value props))) + ((member key seen-base)) + (t (push key seen-base) + (let ((p (assoc-string key props t))) + (if p (setcdr p (concat value " " (cdr p))) + (push (cons key value) props)))))))))))) + (unless (assoc "CATEGORY" props) + (push (cons "CATEGORY" (org-get-category beg)) props) + (when (string= specific "CATEGORY") (throw 'exit props))) + ;; Return value. + props))))) + +(defun org-property--local-values (property literal-nil) + "Return value for PROPERTY in current entry. +Value is a list whose care is the base value for PROPERTY and cdr +a list of accumulated values. Return nil if neither is found in +the entry. Also return nil when PROPERTY is set to \"nil\", +unless LITERAL-NIL is non-nil." + (let ((range (org-get-property-block))) + (when range + (goto-char (car range)) + (let* ((case-fold-search t) + (end (cdr range)) + (value + ;; Base value. + (save-excursion + (let ((v (and (re-search-forward + (org-re-property property nil t) end t) + (org-match-string-no-properties 3)))) + (list (if literal-nil v (org-not-nil v))))))) + ;; Find additional values. + (let* ((property+ (org-re-property (concat property "+") nil t))) + (while (re-search-forward property+ end t) + (push (org-match-string-no-properties 3) value))) + ;; Return final values. + (and (not (equal value '(nil))) (nreverse value)))))) (defun org-entry-get (pom property &optional inherit literal-nil) "Get value of PROPERTY for entry or content at point-or-marker POM. -If INHERIT is non-nil and the entry does not have the property, -then also check higher levels of the hierarchy. -If INHERIT is the symbol `selective', use inheritance only if the setting -in `org-use-property-inheritance' selects PROPERTY for inheritance. -If the property is present but empty, the return value is the empty string. -If the property is not present at all, nil is returned. -Return the value as a string. - -If LITERAL-NIL is set, return the string value \"nil\" as a string, -do not interpret it as the list atom nil. This is used for inheritance -when a \"nil\" value can supersede a non-nil value higher up the hierarchy." +If INHERIT is non-nil and the entry does not have the property, +then also check higher levels of the hierarchy. If INHERIT is +the symbol `selective', use inheritance only if the setting in +`org-use-property-inheritance' selects PROPERTY for inheritance. + +If the property is present but empty, the return value is the +empty string. If the property is not present at all, nil is +returned. In any other case, return the value as a string. +Search is case-insensitive. + +If LITERAL-NIL is set, return the string value \"nil\" as +a string, do not interpret it as the list atom nil. This is used +for inheritance when a \"nil\" value can supersede a non-nil +value higher up the hierarchy." (org-with-point-at pom - (if (and inherit (if (eq inherit 'selective) - (org-property-inherit-p property) - t)) - (org-entry-get-with-inheritance property literal-nil) - (if (member property org-special-properties) - ;; We need a special property. Use `org-entry-properties' - ;; to retrieve it, but specify the wanted property - (cdr (assoc property (org-entry-properties nil 'special property))) - (org-with-wide-buffer - (let ((range (org-get-property-block))) - (when (and range (not (eq (car range) (cdr range))) - (save-excursion - (goto-char (car range)) - (re-search-forward - (concat (org-re-property property) "\\|" - (org-re-property (concat property "+"))) - (cdr range) t))) - (let* ((props - (list (or (assoc property org-file-properties) - (assoc property org-global-properties) - (assoc property org-global-properties-fixed)))) - (ap (lambda (key) - (when (re-search-forward - (org-re-property key) (cdr range) t) - (setq props - (org-update-property-plist - key - (if (match-end 3) - (org-match-string-no-properties 3) "") - props))))) - val) - (goto-char (car range)) - (funcall ap property) - (goto-char (car range)) - (while (funcall ap (concat property "+"))) - (setq val (cdr (assoc property props))) - (when val (if literal-nil val (org-not-nil val))))))))))) + (cond + ((member-ignore-case property (cons "CATEGORY" org-special-properties)) + ;; We need a special property. Use `org-entry-properties' to + ;; retrieve it, but specify the wanted property. + (cdr (assoc-string property (org-entry-properties nil property)))) + ((and inherit + (or (not (eq inherit 'selective)) (org-property-inherit-p property))) + (org-entry-get-with-inheritance property literal-nil)) + (t + (let* ((local (org-property--local-values property literal-nil)) + (value (and local (mapconcat #'identity (delq nil local) " ")))) + (if literal-nil value (org-not-nil value))))))) (defun org-property-or-variable-value (var &optional inherit) "Check if there is a property fixing the value of VAR. @@ -15422,26 +15948,28 @@ If yes, return this value. If not, return the current value of the variable." (read prop) (symbol-value var)))) -(defun org-entry-delete (pom property &optional delete-empty-drawer) - "Delete the property PROPERTY from entry at point-or-marker POM. -When optional argument DELETE-EMPTY-DRAWER is a string, it defines -an empty drawer to delete." - (org-with-point-at pom - (if (member property org-special-properties) - nil ; cannot delete these properties. +(defun org-entry-delete (pom property) + "Delete PROPERTY from entry at point-or-marker POM. +Accumulated properties, i.e. PROPERTY+, are also removed. Return +non-nil when a property was removed." + (unless (member property org-special-properties) + (org-with-point-at pom (let ((range (org-get-property-block))) - (if (and range - (goto-char (car range)) - (re-search-forward - (org-re-property property nil t) - (cdr range) t)) - (progn - (delete-region (match-beginning 0) (1+ (point-at-eol))) - (and delete-empty-drawer - (org-remove-empty-drawer-at - delete-empty-drawer (car range))) - t) - nil))))) + (when range + (let* ((begin (car range)) + (origin (cdr range)) + (end (copy-marker origin)) + (re (org-re-property + (concat (regexp-quote property) "\\+?") t t))) + (goto-char begin) + (while (re-search-forward re end t) + (delete-region (match-beginning 0) (line-beginning-position 2))) + ;; If drawer is empty, remove it altogether. + (when (= begin end) + (delete-region (line-beginning-position 0) + (line-beginning-position 2))) + ;; Return non-nil if some property was removed. + (prog1 (/= end origin) (set-marker end nil)))))))) ;; Multi-values properties are properties that contain multiple values ;; These values are assumed to be single words, separated by whitespace. @@ -15518,24 +16046,32 @@ If the value found is \"nil\", return nil to show that the property should be considered as undefined (this is the meaning of nil here). However, if LITERAL-NIL is set, return the string value \"nil\" instead." (move-marker org-entry-property-inherited-from nil) - (let (tmp) - (save-excursion - (save-restriction - (widen) - (catch 'ex - (while t - (when (setq tmp (org-entry-get nil property nil literal-nil)) - (or (ignore-errors (org-back-to-heading t)) - (goto-char (point-min))) - (move-marker org-entry-property-inherited-from (point)) - (throw 'ex tmp)) - (or (ignore-errors (org-up-heading-safe)) - (throw 'ex nil)))))) - (setq tmp (or tmp - (cdr (assoc property org-file-properties)) - (cdr (assoc property org-global-properties)) - (cdr (assoc property org-global-properties-fixed)))) - (if literal-nil tmp (org-not-nil tmp)))) + (org-with-wide-buffer + (let (value) + (catch 'exit + (while t + (let ((v (org-property--local-values property literal-nil))) + (when v + (setq value + (concat (mapconcat #'identity (delq nil v) " ") + (and value " ") + value))) + (cond + ((car v) + (org-back-to-heading t) + (move-marker org-entry-property-inherited-from (point)) + (throw 'exit nil)) + ((org-up-heading-safe)) + (t + (let ((global + (cdr (or (assoc-string property org-file-properties t) + (assoc-string property org-global-properties t) + (assoc-string property org-global-properties-fixed t))))) + (cond ((not global)) + (value (setq value (concat global " " value))) + (t (setq value global)))) + (throw 'exit nil)))))) + (if literal-nil value (org-not-nil value))))) (defvar org-property-changed-functions nil "Hook called when the value of a property has changed. @@ -15544,177 +16080,183 @@ and the new value.") (defun org-entry-put (pom property value) "Set PROPERTY to VALUE for entry at point-or-marker POM. -If the value is `nil', it is converted to the empty string. -If it is not a string, an error is raised." + +If the value is nil, it is converted to the empty string. If it +is not a string, an error is raised. Also raise an error on +invalid property names. + +PROPERTY can be any regular property (see +`org-special-properties'). It can also be \"TODO\", +\"PRIORITY\", \"SCHEDULED\" and \"DEADLINE\". + +For the last two properties, VALUE may have any of the special +values \"earlier\" and \"later\". The function then increases or +decreases scheduled or deadline date by one day." (cond ((null value) (setq value "")) - ((not (stringp value)) - (error "Properties values should be strings."))) + ((not (stringp value)) (error "Properties values should be strings")) + ((not (org--valid-property-p property)) + (user-error "Invalid property name: \"%s\"" property))) (org-with-point-at pom - (org-back-to-heading t) - (let ((beg (point)) (end (save-excursion (outline-next-heading) (point))) - range) + (if (or (not (featurep 'org-inlinetask)) (org-inlinetask-in-task-p)) + (org-back-to-heading t) + (org-with-limited-levels (org-back-to-heading t))) + (let ((beg (point))) (cond ((equal property "TODO") - (when (and (string-match "\\S-" value) - (not (member value org-todo-keywords-1))) - (user-error "\"%s\" is not a valid TODO state" value)) - (if (or (not value) - (not (string-match "\\S-" value))) - (setq value 'none)) + (cond ((not (org-string-nw-p value)) (setq value 'none)) + ((not (member value org-todo-keywords-1)) + (user-error "\"%s\" is not a valid TODO state" value))) (org-todo value) (org-set-tags nil 'align)) ((equal property "PRIORITY") - (org-priority (if (and value (string-match "\\S-" value)) - (string-to-char value) ?\ )) + (org-priority (if (org-string-nw-p value) (string-to-char value) ?\s)) (org-set-tags nil 'align)) - ((equal property "CLOCKSUM") - (if (not (re-search-forward - (concat org-clock-string ".*\\]--\\(\\[[^]]+\\]\\)") nil t)) - (error "Cannot find a clock log") - (goto-char (- (match-end 1) 2)) - (cond - ((eq value 'earlier) (org-timestamp-down)) - ((eq value 'later) (org-timestamp-up))) - (org-clock-sum-current-item))) ((equal property "SCHEDULED") - (if (re-search-forward org-scheduled-time-regexp end t) - (cond - ((eq value 'earlier) (org-timestamp-change -1 'day)) - ((eq value 'later) (org-timestamp-change 1 'day)) - (t (call-interactively 'org-schedule))) - (call-interactively 'org-schedule))) + (forward-line) + (if (and (org-looking-at-p org-planning-line-re) + (re-search-forward + org-scheduled-time-regexp (line-end-position) t)) + (cond ((string= value "earlier") (org-timestamp-change -1 'day)) + ((string= value "later") (org-timestamp-change 1 'day)) + ((string= value "") (org-schedule '(4))) + (t (org-schedule nil value))) + (if (member value '("earlier" "later" "")) + (call-interactively #'org-schedule) + (org-schedule nil value)))) ((equal property "DEADLINE") - (if (re-search-forward org-deadline-time-regexp end t) - (cond - ((eq value 'earlier) (org-timestamp-change -1 'day)) - ((eq value 'later) (org-timestamp-change 1 'day)) - (t (call-interactively 'org-deadline))) - (call-interactively 'org-deadline))) + (forward-line) + (if (and (org-looking-at-p org-planning-line-re) + (re-search-forward + org-deadline-time-regexp (line-end-position) t)) + (cond ((string= value "earlier") (org-timestamp-change -1 'day)) + ((string= value "later") (org-timestamp-change 1 'day)) + ((string= value "") (org-deadline '(4))) + (t (org-deadline nil value))) + (if (member value '("earlier" "later" "")) + (call-interactively #'org-deadline) + (org-deadline nil value)))) ((member property org-special-properties) - (error "The %s property can not yet be set with `org-entry-put'" - property)) - (t ; a non-special property - (let ((buffer-invisibility-spec (org-inhibit-invisibility))) ; Emacs 21 - (setq range (org-get-property-block beg end 'force)) + (error "The %s property cannot be set with `org-entry-put'" property)) + (t + (let* ((range (org-get-property-block beg 'force)) + (end (cdr range)) + (case-fold-search t)) (goto-char (car range)) - (if (re-search-forward - (org-re-property property nil t) (cdr range) t) - (progn - (delete-region (match-beginning 0) (match-end 0)) - (goto-char (match-beginning 0))) - (goto-char (cdr range)) + (if (re-search-forward (org-re-property property nil t) end t) + (progn (delete-region (match-beginning 0) (match-end 0)) + (goto-char (match-beginning 0))) + (goto-char end) (insert "\n") - (backward-char 1) - (org-indent-line)) + (backward-char)) (insert ":" property ":") - (and value (insert " " value)) + (when value (insert " " value)) (org-indent-line))))) (run-hook-with-args 'org-property-changed-functions property value))) -(defun org-buffer-property-keys (&optional include-specials include-defaults include-columns) +(defun org-buffer-property-keys (&optional specials defaults columns) "Get all property keys in the current buffer. -With INCLUDE-SPECIALS, also list the special properties that reflect things -like tags and TODO state. -With INCLUDE-DEFAULTS, also include properties that has special meaning -internally: ARCHIVE, CATEGORY, SUMMARY, DESCRIPTION, LOCATION, and LOGGING -and others. -With INCLUDE-COLUMNS, also include property names given in COLUMN -formats in the current buffer." - (let (rtn range cfmt s p) - (save-excursion - (save-restriction - (widen) - (goto-char (point-min)) - (while (re-search-forward org-property-start-re nil t) - (setq range (org-get-property-block)) - (goto-char (car range)) - (while (re-search-forward org-property-re - (cdr range) t) - (add-to-list 'rtn (org-match-string-no-properties 2))) - (outline-next-heading)))) - (when include-specials - (setq rtn (append org-special-properties rtn))) +When SPECIALS is non-nil, also list the special properties that +reflect things like tags and TODO state. - (when include-defaults - (mapc (lambda (x) (add-to-list 'rtn x)) org-default-properties) - (add-to-list 'rtn org-effort-property)) +When DEFAULTS is non-nil, also include properties that has +special meaning internally: ARCHIVE, CATEGORY, SUMMARY, +DESCRIPTION, LOCATION, and LOGGING and others. - (when include-columns - (save-excursion - (save-restriction - (widen) - (goto-char (point-min)) - (while (re-search-forward - "^\\(#\\+COLUMNS:\\|[ \t]*:COLUMNS:\\)[ \t]*\\(.*\\)" - nil t) - (setq cfmt (match-string 2) s 0) - (while (string-match (org-re "%[0-9]*\\([-[:alnum:]_]+\\)") - cfmt s) - (setq s (match-end 0) - p (match-string 1 cfmt)) - (unless (or (equal p "ITEM") - (member p org-special-properties)) - (add-to-list 'rtn (match-string 1 cfmt)))))))) - - (sort rtn (lambda (a b) (string< (upcase a) (upcase b)))))) +When COLUMNS in non-nil, also include property names given in +COLUMN formats in the current buffer." + (let ((case-fold-search t) + (props (append + (and specials org-special-properties) + (and defaults (cons org-effort-property org-default-properties)) + nil))) + (org-with-wide-buffer + (goto-char (point-min)) + (while (re-search-forward org-property-start-re nil t) + (let ((range (org-get-property-block))) + (catch 'skip + (unless range + (when (and (not (org-before-first-heading-p)) + (y-or-n-p (format "Malformed drawer at %d, repair?" + (line-beginning-position)))) + (org-get-property-block nil t)) + (throw 'skip nil)) + (goto-char (car range)) + (let ((begin (car range)) + (end (cdr range))) + ;; Make sure that found property block is not located + ;; before current point, as it would generate an infloop. + ;; It can happen, for example, in the following + ;; situation: + ;; + ;; * Headline + ;; :PROPERTIES: + ;; ... + ;; :END: + ;; *************** Inlinetask + ;; #+BEGIN_EXAMPLE + ;; :PROPERTIES: + ;; #+END_EXAMPLE + ;; + (if (< begin (point)) (throw 'skip nil) (goto-char begin)) + (while (< (point) end) + (let ((p (progn (looking-at org-property-re) + (org-match-string-no-properties 2)))) + ;; Only add true property name, not extension symbol. + (add-to-list 'props + (if (not (org-string-match-p "\\+\\'" p)) p + (substring p 0 -1)))) + (forward-line)))) + (outline-next-heading))) + (when columns + (goto-char (point-min)) + (while (re-search-forward "^[ \t]*\\(?:#\\+\\|:\\)COLUMNS:" nil t) + (let ((element (org-element-at-point))) + (when (memq (org-element-type element) '(keyword node-property)) + (let ((value (org-element-property :value element)) + (start 0)) + (while (string-match "%[0-9]*\\(\\S-+\\)" value start) + (setq start (match-end 0)) + (let ((p (org-match-string-no-properties 1 value))) + (unless (member-ignore-case p org-special-properties) + (add-to-list 'props p)))))))))) + (sort props (lambda (a b) (string< (upcase a) (upcase b)))))) (defun org-property-values (key) - "Return a list of all values of property KEY in the current buffer." - (save-excursion - (save-restriction - (widen) - (goto-char (point-min)) - (let ((re (org-re-property key)) - values) - (while (re-search-forward re nil t) - (add-to-list 'values (org-trim (match-string 3)))) - (delete "" values))))) + "List all non-nil values of property KEY in current buffer." + (org-with-wide-buffer + (goto-char (point-min)) + (let ((case-fold-search t) + (re (org-re-property key)) + values) + (while (re-search-forward re nil t) + (add-to-list 'values (org-entry-get (point) key))) + values))) (defun org-insert-property-drawer () "Insert a property drawer into the current entry." - (org-back-to-heading t) - (looking-at org-outline-regexp) - (let ((indent (if org-adapt-indentation - (- (match-end 0) (match-beginning 0)) - 0)) - (beg (point)) - (re (concat "^[ \t]*" org-keyword-time-regexp)) - end hiddenp) - (outline-next-heading) - (setq end (point)) - (goto-char beg) - (while (re-search-forward re end t)) - (setq hiddenp (outline-invisible-p)) - (end-of-line 1) - (and (equal (char-after) ?\n) (forward-char 1)) - (while (looking-at "^[ \t]*\\(:CLOCK:\\|:LOGBOOK:\\|CLOCK:\\|:END:\\)") - (if (member (match-string 1) '("CLOCK:" ":END:")) - ;; just skip this line - (beginning-of-line 2) - ;; Drawer start, find the end - (re-search-forward "^\\*+ \\|^[ \t]*:END:" nil t) - (beginning-of-line 1))) - (org-skip-over-state-notes) - (skip-chars-backward " \t\n\r") - (if (and (eq (char-before) ?*) (not (eq (char-after) ?\n))) - (forward-char 1)) - (goto-char (point-at-eol)) - (let ((inhibit-read-only t)) (insert "\n:PROPERTIES:\n:END:")) - (beginning-of-line 0) - (org-indent-to-column indent) - (beginning-of-line 2) - (org-indent-to-column indent) - (beginning-of-line 0) - (if hiddenp - (save-excursion - (org-back-to-heading t) - (hide-entry)) - (org-flag-drawer t)))) + (org-with-wide-buffer + (if (or (not (featurep 'org-inlinetask)) (org-inlinetask-in-task-p)) + (org-back-to-heading t) + (org-with-limited-levels (org-back-to-heading t))) + (forward-line) + (when (org-looking-at-p org-planning-line-re) (forward-line)) + (unless (org-looking-at-p org-property-drawer-re) + ;; Make sure we start editing a line from current entry, not from + ;; next one. It prevents extending text properties or overlays + ;; belonging to the latter. + (when (bolp) (backward-char)) + (let ((begin (1+ (point))) + (inhibit-read-only t)) + (insert "\n:PROPERTIES:\n:END:") + (when (eobp) (insert "\n")) + (org-indent-region begin (point)))))) (defun org-insert-drawer (&optional arg drawer) "Insert a drawer at point. +When optional argument ARG is non-nil, insert a property drawer. + Optional argument DRAWER, when non-nil, is a string representing drawer's name. Otherwise, the user is prompted for a name. @@ -15723,23 +16265,14 @@ instead. Point is left between drawer's boundaries." (interactive "P") - (let* ((logbook (if (stringp org-log-into-drawer) org-log-into-drawer - "LOGBOOK")) - ;; SYSTEM-DRAWERS is a list of drawer names that are used - ;; internally by Org. They are meant to be inserted - ;; automatically. - (system-drawers `("CLOCK" ,logbook "PROPERTIES")) - ;; Remove system drawers from list. Note: For some reason, - ;; `org-completing-read' ignores the predicate while - ;; `completing-read' handles it fine. - (drawer (if arg "PROPERTIES" - (or drawer - (completing-read - "Drawer: " org-drawers - (lambda (d) (not (member d system-drawers)))))))) + (let* ((drawer (if arg "PROPERTIES" + (or drawer (read-from-minibuffer "Drawer: "))))) (cond ;; With C-u, fall back on `org-insert-property-drawer' (arg (org-insert-property-drawer)) + ;; Check validity of suggested drawer's name. + ((not (org-string-match-p org-drawer-regexp (format ":%s:" drawer))) + (user-error "Invalid drawer name")) ;; With an active region, insert a drawer at point. ((not (org-region-active-p)) (progn @@ -15815,28 +16348,16 @@ This is computed according to `org-property-set-functions-alist'." (defvar org-last-set-property-value nil) (defun org-read-property-name () "Read a property name." - (let* ((completion-ignore-case t) - (keys (org-buffer-property-keys nil t t)) - (default-prop (or (save-excursion - (save-match-data - (beginning-of-line) - (and (looking-at "^\\s-*:\\([^:\n]+\\):") - (null (string= (match-string 1) "END")) - (match-string 1)))) - org-last-set-property)) - (property (org-icompleting-read - (concat "Property" - (if default-prop (concat " [" default-prop "]") "") - ": ") - (mapcar 'list keys) - nil nil nil nil - default-prop))) - (if (member property keys) - property - (or (cdr (assoc (downcase property) - (mapcar (lambda (x) (cons (downcase x) x)) - keys))) - property)))) + (let ((completion-ignore-case t) + (default-prop (or (and (org-at-property-p) + (org-match-string-no-properties 2)) + org-last-set-property))) + (org-completing-read + (concat "Property" + (if default-prop (concat " [" default-prop "]") "") + ": ") + (mapcar #'list (org-buffer-property-keys nil t t)) + nil nil nil nil default-prop))) (defun org-set-property-and-value (use-last) "Allow to set [PROPERTY]: [value] direction from prompt. @@ -15857,26 +16378,52 @@ When use-default, don't even ask, just use the last (defun org-set-property (property value) "In the current entry, set PROPERTY to VALUE. + When called interactively, this will prompt for a property name, offering completion on existing and default properties. And then it will prompt for a value, offering completion either on allowed values (via an inherited xxx_ALL property) or on existing values in other instances of this property -in the current file." +in the current file. + +Throw an error when trying to set a property with an invalid name." (interactive (list nil nil)) - (let* ((property (or property (org-read-property-name))) - (value (or value (org-read-property-value property))) - (fn (cdr (assoc property org-properties-postprocess-alist)))) - (setq org-last-set-property property) - (setq org-last-set-property-value (concat property ": " value)) - ;; Possibly postprocess the inserted value: - (when fn (setq value (funcall fn value))) - (unless (equal (org-entry-get nil property) value) - (org-entry-put nil property value)))) - -(defun org-delete-property (property &optional delete-empty-drawer) - "In the current entry, delete PROPERTY. -When optional argument DELETE-EMPTY-DRAWER is a string, it defines -an empty drawer to delete." + (let ((property (or property (org-read-property-name)))) + ;; `org-entry-put' also makes the following check, but this one + ;; avoids polluting `org-last-set-property' and + ;; `org-last-set-property-value' needlessly. + (unless (org--valid-property-p property) + (user-error "Invalid property name: \"%s\"" property)) + (let ((value (or value (org-read-property-value property))) + (fn (cdr (assoc-string property org-properties-postprocess-alist t)))) + (setq org-last-set-property property) + (setq org-last-set-property-value (concat property ": " value)) + ;; Possibly postprocess the inserted value: + (when fn (setq value (funcall fn value))) + (unless (equal (org-entry-get nil property) value) + (org-entry-put nil property value))))) + +(defun org-find-property (property &optional value) + "Find first entry in buffer that sets PROPERTY. + +When optional argument VALUE is non-nil, only consider an entry +if it contains PROPERTY set to this value. If PROPERTY should be +explicitly set to nil, use string \"nil\" for VALUE. + +Return position where the entry begins, or nil if there is no +such entry. If narrowing is in effect, only search the visible +part of the buffer." + (save-excursion + (goto-char (point-min)) + (let ((case-fold-search t) + (re (org-re-property property nil (not value) value))) + (catch 'exit + (while (re-search-forward re nil t) + (when (if value (org-at-property-p) + (org-entry-get (point) property nil t)) + (throw 'exit (progn (org-back-to-heading t) (point))))))))) + +(defun org-delete-property (property) + "In the current entry, delete PROPERTY." (interactive (let* ((completion-ignore-case t) (cat (org-entry-get (point) "CATEGORY")) @@ -15889,28 +16436,25 @@ an empty drawer to delete." (list prop))) (if (not property) (message "No property to delete in this entry") - (org-entry-delete nil property delete-empty-drawer) + (org-entry-delete nil property) (message "Property \"%s\" deleted" property))) (defun org-delete-property-globally (property) - "Remove PROPERTY globally, from all entries." + "Remove PROPERTY globally, from all entries. +This function ignores narrowing, if any." (interactive (let* ((completion-ignore-case t) (prop (org-icompleting-read "Globally remove property: " - (mapcar 'list (org-buffer-property-keys))))) + (mapcar #'list (org-buffer-property-keys))))) (list prop))) - (save-excursion - (save-restriction - (widen) - (goto-char (point-min)) - (let ((cnt 0)) - (while (re-search-forward - (org-re-property property) - nil t) - (setq cnt (1+ cnt)) - (delete-region (match-beginning 0) (1+ (point-at-eol)))) - (message "Property \"%s\" removed from %d entries" property cnt))))) + (org-with-wide-buffer + (goto-char (point-min)) + (let ((count 0) + (re (org-re-property (concat (regexp-quote property) "\\+?") t t))) + (while (re-search-forward re nil t) + (when (org-entry-delete (point) property) (incf count))) + (message "Property \"%s\" removed from %d entries" property count)))) (defvar org-columns-current-fmt-compiled) ; defined in org-colview.el @@ -15950,6 +16494,7 @@ completion." (while (>= n org-highest-priority) (push (char-to-string n) vals) (setq n (1- n))))) + ((equal property "CATEGORY")) ((member property org-special-properties)) ((setq vals (run-hook-with-args-until-success 'org-property-allowed-value-functions property))) @@ -16000,9 +16545,10 @@ completion." (beginning-of-line 1) (skip-chars-forward " \t") (when (equal prop org-effort-property) - (save-excursion - (org-back-to-heading t) - (put-text-property (point-at-bol) (point-at-eol) 'org-effort nval)) + (org-refresh-property + '((effort . identity) + (effort-minutes . org-duration-string-to-minutes)) + nval) (when (string= org-clock-current-task heading) (setq org-clock-effort nval) (org-clock-update-mode-line))) @@ -16035,7 +16581,7 @@ only headings." (widen) (setq limit (point-max)) (goto-char (point-min)) - (while (setq heading (pop path)) + (dolist (heading path) (setq re (format org-complex-heading-regexp-format (regexp-quote heading))) (setq cnt 0 pos (point)) @@ -16077,10 +16623,10 @@ a priority cookie and tags in the standard locations." "Find Org node headline HEADING in all .org files in directory DIR. When the target headline is found, return a marker to this location." (let ((files (directory-files (or dir default-directory) - nil "\\`[^.#].*\\.org\\'")) - file visiting m buffer) + t "\\`[^.#].*\\.org\\'")) + visiting m buffer) (catch 'found - (while (setq file (pop files)) + (dolist (file files) (message "trying %s" file) (setq visiting (org-find-base-buffer-visiting file)) (setq buffer (or visiting (find-file-noselect file))) @@ -16097,19 +16643,10 @@ Return the position where this entry starts, or nil if there is no such entry." (interactive "sID: ") (let ((id (cond ((stringp ident) ident) - ((symbol-name ident) (symbol-name ident)) + ((symbolp ident) (symbol-name ident)) ((numberp ident) (number-to-string ident)) - (t (error "IDENT %s must be a string, symbol or number" ident)))) - (case-fold-search nil)) - (save-excursion - (save-restriction - (widen) - (goto-char (point-min)) - (when (re-search-forward - (concat "^[ \t]*:ID:[ \t]+" (regexp-quote id) "[ \t]*$") - nil t) - (org-back-to-heading t) - (point)))))) + (t (error "IDENT %s must be a string, symbol or number" ident))))) + (org-with-wide-buffer (org-find-property "ID" id)))) ;;;; Timestamps @@ -16120,17 +16657,16 @@ Return the position where this entry starts, or nil if there is no such entry." (defun org-time-stamp (arg &optional inactive) "Prompt for a date/time and insert a time stamp. + If the user specifies a time like HH:MM or if this command is called with at least one prefix argument, the time stamp contains -the date and the time. Otherwise, only the date is be included. +the date and the time. Otherwise, only the date is included. -All parts of a date not specified by the user is filled in from -the current date/time. So if you just press return without -typing anything, the time stamp will represent the current -date/time. +All parts of a date not specified by the user are filled in from +the timestamp at point, if any, or the current date/time +otherwise. -If there is already a timestamp at the cursor, it will be -modified. +If there is already a timestamp at the cursor, it is replaced. With two universal prefix arguments, insert an active timestamp with the current time without prompting the user. @@ -16138,57 +16674,56 @@ with the current time without prompting the user. When called from lisp, the timestamp is inactive if INACTIVE is non-nil." (interactive "P") - (let* ((ts nil) - (default-time - ;; Default time is either today, or, when entering a range, - ;; the range start. - (if (or (and (org-at-timestamp-p t) (setq ts (match-string 0))) - (save-excursion - (re-search-backward - (concat org-ts-regexp "--?-?\\=") ; 1-3 minuses - (- (point) 20) t))) - (apply 'encode-time (org-parse-time-string (match-string 1))) - (current-time))) - (default-input (and ts (org-get-compact-tod ts))) - (repeater (save-excursion - (save-match-data - (beginning-of-line) - (when (re-search-forward - "\\([.+-]+[0-9]+[hdwmy] ?\\)+" ;;\\(?:[/ ][-+]?[0-9]+[hdwmy]\\)?\\) ?" - (save-excursion (progn (end-of-line) (point))) t) - (match-string 0))))) - org-time-was-given org-end-time-was-given time) + (let* ((ts (cond + ((org-at-date-range-p t) + (match-string (if (< (point) (- (match-beginning 2) 2)) 1 2))) + ((org-at-timestamp-p t) (match-string 0)))) + ;; Default time is either the timestamp at point or today. + ;; When entering a range, only the range start is considered. + (default-time (if (not ts) (current-time) + (apply #'encode-time (org-parse-time-string ts)))) + (default-input (and ts (org-get-compact-tod ts))) + (repeater (and ts + (string-match "\\([.+-]+[0-9]+[hdwmy] ?\\)+" ts) + (match-string 0 ts))) + org-time-was-given + org-end-time-was-given + (time + (and (if (equal arg '(16)) (current-time) + ;; Preserve `this-command' and `last-command'. + (let ((this-command this-command) + (last-command last-command)) + (org-read-date + arg 'totime nil nil default-time default-input + inactive)))))) (cond - ((and (org-at-timestamp-p t) - (memq last-command '(org-time-stamp org-time-stamp-inactive)) - (memq this-command '(org-time-stamp org-time-stamp-inactive))) + ((and ts + (memq last-command '(org-time-stamp org-time-stamp-inactive)) + (memq this-command '(org-time-stamp org-time-stamp-inactive))) (insert "--") - (setq time (let ((this-command this-command)) - (org-read-date arg 'totime nil nil - default-time default-input inactive))) (org-insert-time-stamp time (or org-time-was-given arg) inactive)) - ((org-at-timestamp-p t) - (setq time (let ((this-command this-command)) - (org-read-date arg 'totime nil nil default-time default-input inactive))) - (when (org-at-timestamp-p t) ; just to get the match data - ; (setq inactive (eq (char-after (match-beginning 0)) ?\[)) - (replace-match "") + (ts + ;; Make sure we're on a timestamp. When in the middle of a date + ;; range, move arbitrarily to range end. + (unless (org-at-timestamp-p t) + (skip-chars-forward "-") + (org-at-timestamp-p t)) + (replace-match "") + (setq org-last-changed-timestamp + (org-insert-time-stamp + time (or org-time-was-given arg) + inactive nil nil (list org-end-time-was-given))) + (when repeater + (backward-char) + (insert " " repeater) (setq org-last-changed-timestamp - (org-insert-time-stamp - time (or org-time-was-given arg) - inactive nil nil (list org-end-time-was-given))) - (when repeater (goto-char (1- (point))) (insert " " repeater) - (setq org-last-changed-timestamp - (concat (substring org-last-inserted-timestamp 0 -1) - " " repeater ">")))) + (concat (substring org-last-inserted-timestamp 0 -1) + " " repeater ">"))) (message "Timestamp updated")) - ((equal arg '(16)) - (org-insert-time-stamp (current-time) t inactive)) - (t - (setq time (let ((this-command this-command)) - (org-read-date arg 'totime nil nil default-time default-input inactive))) - (org-insert-time-stamp time (or org-time-was-given arg) inactive - nil nil (list org-end-time-was-given)))))) + ((equal arg '(16)) (org-insert-time-stamp time t inactive)) + (t (org-insert-time-stamp + time (or org-time-was-given arg) inactive nil nil + (list org-end-time-was-given)))))) ;; FIXME: can we use this for something else, like computing time differences? (defun org-get-compact-tod (s) @@ -16235,13 +16770,14 @@ So these are more for recording a certain time/date." (defvar org-read-date-inactive) (defvar org-read-date-minibuffer-local-map - (let* ((org-replace-disputed-keys nil) - (map (make-sparse-keymap))) + (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 "^[^:]+: ") + (if (org-looking-back "^[^:]+: " + (let ((inhibit-field-text-motion t)) + (line-beginning-position))) (org-eval-in-calendar '(calendar-goto-today)) (insert ".")))) (org-defkey map (kbd "C-.") @@ -16348,7 +16884,7 @@ While prompting, a calendar is popped up - you can also select the date with the mouse (button 1). The calendar shows a period of three months. To scroll it to other months, use the keys `>' and `<'. If you don't like the calendar, turn it off with - \(setq org-read-date-popup-calendar nil) + (setq org-read-date-popup-calendar nil) With optional argument TO-TIME, the date will immediately be converted to an internal time. @@ -16374,9 +16910,10 @@ user." (setcar (nthcdr 1 org-defdecode) 59) (setq org-def (apply 'encode-time org-defdecode) org-defdecode (decode-time org-def))))) + (cur-frame (selected-frame)) (mouse-autoselect-window nil) ; Don't let the mouse jump (calendar-frame-setup nil) - (calendar-setup nil) + (calendar-setup (when (eq calendar-setup 'calendar-only) 'calendar-only)) (calendar-move-hook nil) (calendar-view-diary-initially-flag nil) (calendar-view-holidays-initially-flag nil) @@ -16384,7 +16921,7 @@ user." (if org-with-time "%Y-%m-%d %H:%M" "%Y-%m-%d") org-def)) (prompt (concat (if prompt (concat prompt " ") "") (format "Date+time [%s]: " timestr))) - ans (org-ans0 "") org-ans1 org-ans2 final) + ans (org-ans0 "") org-ans1 org-ans2 final cal-frame) (cond (from-string (setq ans from-string)) @@ -16392,9 +16929,13 @@ user." (save-excursion (save-window-excursion (calendar) + (when (eq calendar-setup 'calendar-only) + (setq cal-frame + (window-frame (get-buffer-window "*Calendar*" 'visible))) + (select-frame cal-frame)) (org-eval-in-calendar '(setq cursor-type nil) t) - (unwind-protect - (progn + (unwind-protect + (progn (calendar-forward-day (- (time-to-days org-def) (calendar-absolute-from-gregorian (calendar-current-date)))) @@ -16421,8 +16962,11 @@ user." (use-local-map old-map) (when org-read-date-overlay (delete-overlay org-read-date-overlay) - (setq org-read-date-overlay nil))))) - (bury-buffer "*Calendar*"))))) + (setq org-read-date-overlay nil))))) + (bury-buffer "*Calendar*") + (when cal-frame + (delete-frame cal-frame) + (select-frame-set-input-focus cur-frame)))))) (t ; Naked prompt only (unwind-protect @@ -16494,6 +17038,9 @@ user." (defun org-read-date-analyze (ans org-def org-defdecode) "Analyze the combined answer of the date prompt." ;; FIXME: cleanup and comment + ;; Pass `current-time' result to `decode-time' (instead of calling + ;; without arguments) so that only `current-time' has to be + ;; overriden in tests. (let ((nowdecode (decode-time (current-time))) delta deltan deltaw deltadef year month day hour minute second wday pm h2 m2 tl wday1 @@ -16597,16 +17144,35 @@ user." (setq tl (parse-time-string ans) day (or (nth 3 tl) (nth 3 org-defdecode)) - month (or (nth 4 tl) - (if (and org-read-date-prefer-future - (nth 3 tl) (< (nth 3 tl) (nth 3 nowdecode))) - (prog1 (1+ (nth 4 nowdecode)) (setq futurep t)) - (nth 4 org-defdecode))) - year (or (and (not kill-year) (nth 5 tl)) - (if (and org-read-date-prefer-future - (nth 4 tl) (< (nth 4 tl) (nth 4 nowdecode))) - (prog1 (1+ (nth 5 nowdecode)) (setq futurep t)) - (nth 5 org-defdecode))) + month + (cond ((nth 4 tl)) + ((not org-read-date-prefer-future) (nth 4 org-defdecode)) + ;; Day was specified. Make sure DAY+MONTH + ;; combination happens in the future. + ((nth 3 tl) + (setq futurep t) + (if (< day (nth 3 nowdecode)) (1+ (nth 4 nowdecode)) + (nth 4 nowdecode))) + (t (nth 4 org-defdecode))) + year + (cond ((and (not kill-year) (nth 5 tl))) + ((not org-read-date-prefer-future) (nth 5 org-defdecode)) + ;; Month was guessed in the future and is at least + ;; equal to NOWDECODE's. Fix year accordingly. + (futurep + (if (or (> month (nth 4 nowdecode)) + (>= day (nth 3 nowdecode))) + (nth 5 nowdecode) + (1+ (nth 5 nowdecode)))) + ;; Month was specified. Make sure MONTH+YEAR + ;; combination happens in the future. + ((nth 4 tl) + (setq futurep t) + (cond ((> month (nth 4 nowdecode)) (nth 5 nowdecode)) + ((< month (nth 4 nowdecode)) (1+ (nth 5 nowdecode))) + ((< day (nth 3 nowdecode)) (1+ (nth 5 nowdecode))) + (t (nth 5 nowdecode)))) + (t (nth 5 org-defdecode))) hour (or (nth 2 tl) (nth 2 org-defdecode)) minute (or (nth 1 tl) (nth 1 org-defdecode)) second (or (nth 0 tl) 0) @@ -16652,6 +17218,9 @@ user." (deltan (setq futurep nil) (unless deltadef + ;; Pass `current-time' result to `decode-time' (instead of + ;; calling without arguments) so that only `current-time' has + ;; to be overriden in tests. (let ((now (decode-time (current-time)))) (setq day (nth 3 now) month (nth 4 now) year (nth 5 now)))) (cond ((member deltaw '("d" "")) (setq day (+ day deltan))) @@ -16769,6 +17338,7 @@ This is used by `org-read-date' in a temporary keymap for the calendar buffer." (defun org-insert-time-stamp (time &optional with-hm inactive pre post extra) "Insert a date stamp for the date given by the internal TIME. +See `format-time-string' for the format of TIME. WITH-HM means use the stamp format that includes the time of the day. INACTIVE means use square brackets instead of angular ones, so that the stamp will not contribute to the agenda. @@ -16841,33 +17411,6 @@ The command returns the inserted time stamp." (put-text-property beg end 'end-glyph (make-glyph str))) (put-text-property beg end 'display str)))) -(defun org-translate-time (string) - "Translate all timestamps in STRING to custom format. -But do this only if the variable `org-display-custom-times' is set." - (when org-display-custom-times - (save-match-data - (let* ((start 0) - (re org-ts-regexp-both) - t1 with-hm inactive tf time str beg end) - (while (setq start (string-match re string start)) - (setq beg (match-beginning 0) - end (match-end 0) - t1 (save-match-data - (org-parse-time-string (substring string beg end) t)) - with-hm (and (nth 1 t1) (nth 2 t1)) - inactive (equal (substring string beg (1+ beg)) "[") - tf (funcall (if with-hm 'cdr 'car) - org-time-stamp-custom-formats) - time (org-fix-decoded-time t1) - str (format-time-string - (concat - (if inactive "[" "<") (substring tf 1 -1) - (if inactive "]" ">")) - (apply 'encode-time time)) - string (replace-match str t t string) - start (+ start (length str))))))) - string) - (defun org-fix-decoded-time (time) "Set 0 instead of nil for the first 6 elements of time. Don't touch the rest." @@ -16940,7 +17483,6 @@ days. If the prefix is a raw \\[universal-argument] prefix, all deadlines are s (regexp (concat "\\<" org-deadline-string " *<\\([^>]+\\)>")) (callback (lambda () (org-deadline-close (match-string 1) org-warn-days)))) - (message "%d deadlines past-due or due within %d days" (org-occur regexp nil callback) org-warn-days))) @@ -16958,14 +17500,17 @@ Allowed values for TYPE are: When TYPE is nil, fall back on returning a regexp that matches both scheduled and deadline timestamps." - (cond ((eq type 'all) "\\([0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\}\\(?: +[^]+0-9> \n -]+\\)?\\(?: +[0-9]\\{1,2\\}:[0-9]\\{2\\}\\)?\\)") - ((eq type 'active) org-ts-regexp) - ((eq type 'inactive) "\\[\\([0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\} ?[^ \n>]*?\\)\\]") - ((eq type 'scheduled) (concat "\\<" org-scheduled-string " *<\\([^>]+\\)>")) - ((eq type 'deadline) (concat "\\<" org-deadline-string " *<\\([^>]+\\)>")) - ((eq type 'closed) (concat org-closed-string " \\[\\([0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\} ?[^ \n>]*?\\)\\]")) - ((eq type 'scheduled-or-deadline) - (concat "\\<\\(?:" org-deadline-string "\\|" org-scheduled-string "\\) *<\\([^>]+\\)>")))) + (case type + (all org-ts-regexp-both) + (active org-ts-regexp) + (inactive org-ts-regexp-inactive) + (scheduled org-scheduled-time-regexp) + (deadline org-deadline-time-regexp) + (closed org-closed-time-regexp) + (otherwise + (concat "\\<" + (regexp-opt (list org-deadline-string org-scheduled-string)) + " *<\\([^>]+\\)>")))) (defun org-check-before-date (date) "Check if there are deadlines or scheduled entries before DATE." @@ -16973,9 +17518,14 @@ both scheduled and deadline timestamps." (let ((case-fold-search nil) (regexp (org-re-timestamp org-ts-type)) (callback - (lambda () (time-less-p - (org-time-string-to-time (match-string 1)) - (org-time-string-to-time date))))) + `(lambda () + (let ((match (match-string 1))) + (and ,(if (memq org-ts-type '(active inactive all)) + '(eq (org-element-type (org-element-context)) 'timestamp) + '(org-at-planning-p)) + (time-less-p + (org-time-string-to-time match) + (org-time-string-to-time date))))))) (message "%d entries before %s" (org-occur regexp nil callback) date))) @@ -16985,10 +17535,14 @@ both scheduled and deadline timestamps." (let ((case-fold-search nil) (regexp (org-re-timestamp org-ts-type)) (callback - (lambda () (not - (time-less-p - (org-time-string-to-time (match-string 1)) - (org-time-string-to-time date)))))) + `(lambda () + (let ((match (match-string 1))) + (and ,(if (memq org-ts-type '(active inactive all)) + '(eq (org-element-type (org-element-context)) 'timestamp) + '(org-at-planning-p)) + (not (time-less-p + (org-time-string-to-time match) + (org-time-string-to-time date)))))))) (message "%d entries after %s" (org-occur regexp nil callback) date))) @@ -16999,15 +17553,18 @@ both scheduled and deadline timestamps." (let ((case-fold-search nil) (regexp (org-re-timestamp org-ts-type)) (callback - (lambda () - (let ((match (match-string 1))) - (and - (not (time-less-p - (org-time-string-to-time match) - (org-time-string-to-time start-date))) - (time-less-p - (org-time-string-to-time match) - (org-time-string-to-time end-date))))))) + `(lambda () + (let ((match (match-string 1))) + (and + ,(if (memq org-ts-type '(active inactive all)) + '(eq (org-element-type (org-element-context)) 'timestamp) + '(org-at-planning-p)) + (not (time-less-p + (org-time-string-to-time match) + (org-time-string-to-time start-date))) + (time-less-p + (org-time-string-to-time match) + (org-time-string-to-time end-date))))))) (message "%d entries between %s and %s" (org-occur regexp nil callback) start-date end-date))) @@ -17095,7 +17652,7 @@ days in order to avoid rounding problems." (error (error "Bad timestamp `%s'%s\nError was: %s" s (if (not (and buffer pos)) "" - (format " at %d in buffer `%s'" pos buffer)) + (format-message " at %d in buffer `%s'" pos buffer)) (cdr errdata))))) (defun org-time-string-to-seconds (s) @@ -17113,7 +17670,8 @@ The variable `date' is bound by the calendar when this is called." (if (org-diary-sexp-entry (match-string 1 s) "" date) daynr (+ daynr 1000))) - ((and daynr (string-match "\\+[0-9]+[hdwmy]" s)) + ((and daynr (string-match "\\+\\([0-9]+\\)[hdwmy]" s) + (> (string-to-number (match-string 1 s)) 0)) (org-closest-date s (if (and (boundp 'daynr) (integerp daynr)) daynr (time-to-days (current-time))) (match-string 0 s) prefer show-all)) @@ -17123,7 +17681,7 @@ The variable `date' is bound by the calendar when this is called." (error (error "Bad timestamp `%s'%s\nError was: %s" s (if (not (and buffer pos)) "" - (format " at %d in buffer `%s'" pos buffer)) + (format-message " at %d in buffer `%s'" pos buffer)) (cdr errdata)))))))) (defun org-days-to-iso-week (days) @@ -17133,14 +17691,15 @@ The variable `date' is bound by the calendar when this is called." (defun org-small-year-to-year (year) "Convert 2-digit years into 4-digit years. -38-99 are mapped into 1938-1999. 1-37 are mapped into 2001-2037. -The year 2000 cannot be abbreviated. Any year larger than 99 -is returned unchanged." - (if (< year 38) - (setq year (+ 2000 year)) - (if (< year 100) - (setq year (+ 1900 year)))) - year) +YEAR is expanded into one of the 30 next years, if possible, or +into a past one. Any year larger than 99 is returned unchanged." + (if (>= year 100) year + (let* ((current (string-to-number (format-time-string "%Y" (current-time)))) + (century (/ current 100)) + (offset (- year (% current 100)))) + (cond ((> offset 30) (+ (* (1- century) 100) year)) + ((> offset -70) (+ (* century 100) year)) + (t (+ (* (1+ century) 100) year)))))) (defun org-time-from-absolute (d) "Return the time corresponding to date D. @@ -17228,9 +17787,10 @@ When SHOW-ALL is nil, only return the current occurrence of a time stamp." (if (<= cday sday) (throw 'exit sday)) - (if (string-match "\\(\\+[0-9]+\\)\\([hdwmy]\\)" change) - (setq dn (string-to-number (match-string 1 change)) - dw (cdr (assoc (match-string 2 change) a1))) + (when (string-match "\\(\\+[0-9]+\\)\\([hdwmy]\\)" change) + (setq dn (string-to-number (match-string 1 change)) + dw (cdr (assoc (match-string 2 change) a1)))) + (unless (and dn (> dn 0)) (user-error "Invalid change specifier: %s" change)) (if (eq dw 'week) (setq dw 'day dn (* 7 dn))) (cond @@ -17347,7 +17907,14 @@ With prefix ARG, change that many days." (org-timestamp-change (- (prefix-numeric-value arg)) 'day) 'updown)) (defun org-at-timestamp-p (&optional inactive-ok) - "Determine if the cursor is in or at a timestamp." + "Non-nil if point is inside a timestamp. + +When optional argument INACTIVE-OK is non-nil, also consider +inactive timestamps. + +When this function returns a non-nil value, match data is set +according to `org-ts-regexp3' or `org-ts-regexp2', depending on +INACTIVE-OK." (interactive) (let* ((tsr (if inactive-ok org-ts-regexp3 org-ts-regexp2)) (pos (point)) @@ -17396,7 +17963,7 @@ With prefix ARG, change that many days." "Is the cursor on the clock log line?" (save-excursion (move-beginning-of-line 1) - (looking-at "^[ \t]*CLOCK:"))) + (looking-at org-clock-line-re))) (defvar org-clock-history) ; defined in org-clock.el (defvar org-clock-adjust-closest nil) ; defined in org-clock.el @@ -17503,7 +18070,8 @@ When SUPPRESS-TMP-DELAY is non-nil, suppress delays like \"--2d\"." (message "No clock to adjust") (cond ((save-excursion ; fix previous clock? (re-search-backward org-ts-regexp0 nil t) - (org-looking-back (concat org-clock-string " \\["))) + (org-looking-back (concat org-clock-string " \\[") + (line-beginning-position))) (setq fixnext 1 clrgx (concat org-ts-regexp0 "\\] =>.*$"))) ((save-excursion ; fix next clock? (re-search-backward org-ts-regexp0 nil t) @@ -17514,7 +18082,7 @@ When SUPPRESS-TMP-DELAY is non-nil, suppress delays like \"--2d\"." (let* ((p (save-excursion (org-back-to-heading t))) (cl (mapcar (lambda(c) (abs (- (marker-position c) p))) org-clock-history)) (clfixnth - (+ fixnext (- (length cl) (or (length (member (apply #'min cl) cl)) 100)))) + (+ fixnext (- (length cl) (or (length (member (apply 'min cl) cl)) 100)))) (clfixpos (if (> 0 clfixnth) nil (nth clfixnth org-clock-history)))) (if (not clfixpos) (message "No clock to adjust") @@ -17552,7 +18120,7 @@ When SUPPRESS-TMP-DELAY is non-nil, suppress delays like \"--2d\"." (setq m (+ m n))) (if (< m 0) (setq m (+ m 60) h (1- h))) (if (> m 59) (setq m (- m 60) h (1+ h))) - (setq h (min 24 (max 0 h))) + (setq h (mod h 24)) (setq ng 1 new (format "-%02d:%02d" h m))) ((org-pos-in-match-range pos 6) (setq ng 6 new (car (rassoc (+ n (cdr (assoc (match-string 6 s) idx))) idx)))) @@ -17618,7 +18186,8 @@ 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-effort-durations - `(("h" . 60) + `(("min" . 1) + ("h" . 60) ("d" . ,(* 60 8)) ("w" . ,(* 60 8 5)) ("m" . ,(* 60 8 5 4)) @@ -17634,7 +18203,8 @@ minutes. For example, if the value of this variable is ((\"hours\" . 60)), then an effort string \"2hours\" is equivalent to 120 minutes." :group 'org-agenda - :version "24.1" + :version "25.1" + :package-version '(Org . "8.3") :type '(alist :key-type (string :tag "Modifier") :value-type (number :tag "Minutes"))) @@ -17752,7 +18322,7 @@ If no number is found, the return value is 0." (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 set to t, always use the image width. When set to a number, use imagemagick (when available) to set the image's width to this value. @@ -17779,26 +18349,32 @@ This requires Emacs >= 24.1, build with imagemagick support." (defcustom org-agenda-inhibit-startup nil "Inhibit startup when preparing agenda buffers. -When this variable is `t', the initialization of the Org agenda +When this variable is t, the initialization of the Org agenda buffers is inhibited: e.g. the visibility state is not set, the tables are not re-aligned, etc." :type 'boolean :version "24.3" :group 'org-agenda) -(defcustom org-agenda-ignore-drawer-properties nil +(define-obsolete-variable-alias + 'org-agenda-ignore-drawer-properties + 'org-agenda-ignore-properties "25.1") + +(defcustom org-agenda-ignore-properties nil "Avoid updating text properties when building the agenda. -Properties are used to prepare buffers for effort estimates, appointments, -and subtree-local categories. -If you don't use these in the agenda, you can add them to this list and -agenda building will be a bit faster. +Properties are used to prepare buffers for effort estimates, +appointments, statistics and subtree-local categories. +If you don't use these in the agenda, you can add them to this +list and agenda building will be a bit faster. The value is a list, with zero or more of the symbols `effort', `appt', -or `category'." +`stats' or `category'." :type '(set :greedy t (const effort) (const appt) + (const stats) (const category)) - :version "24.3" + :version "25.1" + :package-version '(Org . "8.3") :group 'org-agenda) (defun org-duration-string-to-minutes (s &optional output-to-string) @@ -17905,7 +18481,7 @@ If EXCLUDE-TMP is non-nil, ignore temporary buffers." ((eq predicate 'files) (lambda (b) (with-current-buffer b (derived-mode-p 'org-mode)))) ((eq predicate 'export) - (lambda (b) (string-match "\*Org .*Export" (buffer-name b)))) + (lambda (b) (string-match "\\*Org .*Export" (buffer-name b)))) ((eq predicate 'agenda) (lambda (b) (with-current-buffer b @@ -17914,7 +18490,7 @@ If EXCLUDE-TMP is non-nil, ignore temporary buffers." (member (file-truename bfn) agenda-files))))) (t (lambda (b) (with-current-buffer b (or (derived-mode-p 'org-mode) - (string-match "\*Org .*Export" + (string-match "\\*Org .*Export" (buffer-name b))))))))) (delq nil (mapcar @@ -17961,8 +18537,10 @@ used by the agenda files. If ARCHIVE is `ifmode', do this only if "Return non-nil, if FILE is an agenda file. If FILE is omitted, use the file associated with the current buffer." - (member (or file (buffer-file-name)) - (org-agenda-files t))) + (let ((fname (or file (buffer-file-name)))) + (and fname + (member (file-truename fname) + (mapcar #'file-truename (org-agenda-files t)))))) (defun org-edit-agenda-file-list () "Edit the list of agenda files. @@ -18032,18 +18610,15 @@ un-expanded file names." If the current buffer visits an agenda file, find the next one in the list. If the current buffer does not, find the first agenda file." (interactive) - (let* ((fs (org-agenda-files t)) - (files (append fs (list (car fs)))) - (tcf (if buffer-file-name (file-truename buffer-file-name))) + (let* ((fs (or (org-agenda-files t) + (user-error "No agenda files"))) + (files (copy-sequence fs)) + (tcf (and buffer-file-name (file-truename buffer-file-name))) file) - (unless files (user-error "No agenda files")) - (catch 'exit - (while (setq file (pop files)) - (if (equal (file-truename file) tcf) - (when (car files) - (find-file (car files)) - (throw 'exit t)))) - (find-file (car fs))) + (when tcf + (while (and (setq file (pop files)) + (not (equal (file-truename file) tcf))))) + (find-file (car (or files fs))) (if (buffer-base-buffer) (org-pop-to-buffer-same-window (buffer-base-buffer))))) (defun org-agenda-file-to-front (&optional to-end) @@ -18107,11 +18682,12 @@ Optional argument FILE means use this file instead of the current." ((equal r ?r) (org-remove-file file) (throw 'nextfile t)) - (t (error "Abort")))))) + (t (user-error "Abort")))))) (defun org-get-agenda-file-buffer (file) - "Get a buffer visiting FILE. If the buffer needs to be created, add -it to the list of buffers which might be released later." + "Get an agenda buffer visiting FILE. +If the buffer needs to be created, add it to the list of buffers +which might be released later." (let ((buf (org-find-base-buffer-visiting file))) (if buf buf ; just return it @@ -18124,8 +18700,8 @@ it to the list of buffers which might be released later." "Release all buffers in list, asking the user for confirmation when needed. When a buffer is unmodified, it is just killed. When modified, it is saved \(if the user agrees) and then killed." - (let (buf file) - (while (setq buf (pop blist)) + (let (file) + (dolist (buf blist) (setq file (buffer-file-name buf)) (when (and (buffer-modified-p buf) file @@ -18147,27 +18723,22 @@ When a buffer is unmodified, it is just killed. When modified, it is saved org-tag-groups-alist-for-agenda nil) (save-excursion (save-restriction - (while (setq file (pop files)) + (dolist (file files) (catch 'nextfile (if (bufferp file) (set-buffer file) (org-check-agenda-file file) (set-buffer (org-get-agenda-file-buffer file))) (widen) - (org-set-regexps-and-options-for-tags) + (org-set-regexps-and-options 'tags-only) (setq pos (point)) - (goto-char (point-min)) - (let ((case-fold-search t)) - (when (search-forward "#+setupfile" nil t) - ;; Don't set all regexps and options systematically as - ;; this is only run for setting agenda tags from setup - ;; file - (org-set-regexps-and-options))) - (or (memq 'category org-agenda-ignore-drawer-properties) + (or (memq 'category org-agenda-ignore-properties) (org-refresh-category-properties)) - (or (memq 'effort org-agenda-ignore-drawer-properties) - (org-refresh-properties org-effort-property 'org-effort)) - (or (memq 'appt org-agenda-ignore-drawer-properties) + (or (memq 'stats org-agenda-ignore-properties) + (org-refresh-stats-properties)) + (or (memq 'effort org-agenda-ignore-properties) + (org-refresh-effort-properties)) + (or (memq 'appt org-agenda-ignore-properties) (org-refresh-properties "APPT_WARNTIME" 'org-appt-warntime)) (setq org-todo-keywords-for-agenda (append org-todo-keywords-for-agenda org-todo-keywords-1)) @@ -18175,17 +18746,19 @@ When a buffer is unmodified, it is just killed. When modified, it is saved (append org-done-keywords-for-agenda org-done-keywords)) (setq org-todo-keyword-alist-for-agenda (append org-todo-keyword-alist-for-agenda org-todo-key-alist)) - (setq org-drawers-for-agenda - (append org-drawers-for-agenda org-drawers)) (setq org-tag-alist-for-agenda (org-uniquify (append org-tag-alist-for-agenda org-tag-alist org-tag-persistent-alist))) - (if org-group-tags - (setq org-tag-groups-alist-for-agenda - (org-uniquify-alist - (append org-tag-groups-alist-for-agenda org-tag-groups-alist)))) + ;; Merge current file's tag groups into global + ;; `org-tag-groups-alist-for-agenda'. + (when org-group-tags + (dolist (alist org-tag-groups-alist) + (let ((old (assoc (car alist) org-tag-groups-alist-for-agenda))) + (if old + (setcdr old (org-uniquify (append (cdr old) (cdr alist)))) + (push alist org-tag-groups-alist-for-agenda))))) (org-with-silent-modifications (save-excursion (remove-text-properties (point-min) (point-max) pall) @@ -18195,11 +18768,11 @@ When a buffer is unmodified, it is just killed. When modified, it is saved (if (org-at-heading-p t) (add-text-properties (point-at-bol) (org-end-of-subtree t) pa)))) (goto-char (point-min)) - (setq re (format org-heading-keyword-regexp-format - org-comment-string)) + (setq re (format "^\\*+ .*\\<%s\\>" org-comment-string)) (while (re-search-forward re nil t) - (add-text-properties - (match-beginning 0) (org-end-of-subtree t) pc)))) + (when (save-match-data (org-in-commented-heading-p t)) + (add-text-properties + (match-beginning 0) (org-end-of-subtree t) pc))))) (goto-char pos))))) (setq org-todo-keywords-for-agenda (org-uniquify org-todo-keywords-for-agenda)) @@ -18216,7 +18789,7 @@ When a buffer is unmodified, it is just killed. When modified, it is saved (org-defkey org-cdlatex-mode-map "^" 'org-cdlatex-underscore-caret) (org-defkey org-cdlatex-mode-map "`" 'cdlatex-math-symbol) (org-defkey org-cdlatex-mode-map "'" 'org-cdlatex-math-modify) -(org-defkey org-cdlatex-mode-map "\C-c{" 'cdlatex-environment) +(org-defkey org-cdlatex-mode-map "\C-c{" 'org-cdlatex-environment-indent) (defvar org-cdlatex-texmathp-advice-is-done nil "Flag remembering if we have applied the advice to texmathp already.") @@ -18294,21 +18867,66 @@ Revert to the normal definition outside of these fragments." (let (org-cdlatex-mode) (call-interactively (key-binding (vector last-input-event)))))) +(defun org-cdlatex-environment-indent (&optional environment item) + "Execute `cdlatex-environment' and indent the inserted environment. + +ENVIRONMENT and ITEM are passed to `cdlatex-environment'. + +The inserted environment is indented to current indentation +unless point is at the beginning of the line, in which the +environment remains unintended." + (interactive) + ;; cdlatex-environment always return nil. Therefore, capture output + ;; first and determine if an environment was selected. + (let* ((beg (point-marker)) + (end (copy-marker (point) t)) + (inserted (progn + (ignore-errors (cdlatex-environment environment item)) + (< beg end))) + ;; Figure out how many lines to move forward after the + ;; environment has been inserted. + (lines (when inserted + (save-excursion + (- (loop while (< beg (point)) + with x = 0 + do (forward-line -1) + (incf x) + finally return x) + (if (progn (goto-char beg) + (and (progn (skip-chars-forward " \t") (eolp)) + (progn (skip-chars-backward " \t") (bolp)))) + 1 0))))) + (env (org-trim (delete-and-extract-region beg end)))) + (when inserted + ;; Get indentation of next line unless at column 0. + (let ((ind (if (bolp) 0 + (save-excursion + (org-return-indent) + (prog1 (org-get-indentation) + (when (progn (skip-chars-forward " \t") (eolp)) + (delete-region beg (point))))))) + (bol (progn (skip-chars-backward " \t") (bolp)))) + ;; Insert a newline before environment unless at column zero + ;; to "escape" the current line. Insert a newline if + ;; something is one the same line as \end{ENVIRONMENT}. + (insert + (concat (unless bol "\n") env + (when (and (skip-chars-forward " \t") (not (eolp))) "\n"))) + (unless (zerop ind) + (save-excursion + (goto-char beg) + (while (< (point) end) + (unless (eolp) (org-indent-line-to ind)) + (forward-line)))) + (goto-char beg) + (forward-line lines) + (org-indent-line-to ind))) + (set-marker beg nil) + (set-marker end nil))) ;;;; LaTeX fragments -(defvar org-latex-regexps - '(("begin" "^[ \t]*\\(\\\\begin{\\([a-zA-Z0-9\\*]+\\)[^\000]+?\\\\end{\\2}\\)" 1 t) - ;; ("$" "\\([ (]\\|^\\)\\(\\(\\([$]\\)\\([^ \r\n,.$].*?\\(\n.*?\\)\\{0,5\\}[^ \r\n,.$]\\)\\4\\)\\)\\([ .,?;:'\")]\\|$\\)" 2 nil) - ;; \000 in the following regex is needed for org-inside-LaTeX-fragment-p - ("$1" "\\([^$]\\|^\\)\\(\\$[^ \r\n,;.$]\\$\\)\\([- .,?;:'\")\000]\\|$\\)" 2 nil) - ("$" "\\([^$]\\|^\\)\\(\\(\\$\\([^ \r\n,;.$][^$\n\r]*?\\(\n[^$\n\r]*?\\)\\{0,2\\}[^ \r\n,.$]\\)\\$\\)\\)\\([- .,?;:'\")\000]\\|$\\)" 2 nil) - ("\\(" "\\\\([^\000]*?\\\\)" 0 nil) - ("\\[" "\\\\\\[[^\000]*?\\\\\\]" 0 nil) - ("$$" "\\$\\$[^\000]*?\\$\\$" 0 nil)) - "Regular expressions for matching embedded LaTeX.") - (defun org-inside-LaTeX-fragment-p () "Test if point is inside a LaTeX fragment. I.e. after a \\begin, \\(, \\[, $, or $$, without the corresponding closing @@ -18359,179 +18977,230 @@ looks only before point, not after." (org-in-regexp "\\\\[a-zA-Z]+\\*?\\(\\(\\[[^][\n{}]*\\]\\)\\|\\({[^{}\n]*}\\)\\)*"))) -(defvar org-latex-fragment-image-overlays nil - "List of overlays carrying the images of latex fragments.") -(make-variable-buffer-local 'org-latex-fragment-image-overlays) - -(defun org-remove-latex-fragment-image-overlays () - "Remove all overlays with LaTeX fragment images in current buffer." - (mapc 'delete-overlay org-latex-fragment-image-overlays) - (setq org-latex-fragment-image-overlays nil)) +(defun org--format-latex-make-overlay (beg end image) + "Build an overlay between BEG and END using IMAGE file." + (let ((ov (make-overlay beg end))) + (overlay-put ov 'org-overlay-type 'org-latex-overlay) + (overlay-put ov 'evaporate t) + (overlay-put ov + 'modification-hooks + (list (lambda (o _flag _beg _end &optional _l) + (delete-overlay o)))) + (if (featurep 'xemacs) + (progn + (overlay-put ov 'invisible t) + (overlay-put ov 'end-glyph (make-glyph (vector 'png :file image)))) + (overlay-put ov + 'display + (list 'image :type 'png :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." + (org-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) + "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))) + (mapc #'delete-overlay overlays) + overlays)) -(defun org-preview-latex-fragment (&optional subtree) +(define-obsolete-function-alias + 'org-preview-latex-fragment 'org-toggle-latex-fragment "24.4") +(defun org-toggle-latex-fragment (&optional arg) "Preview the LaTeX fragment at point, or all locally or globally. -If the cursor is in a LaTeX fragment, create the image and overlay -it over the source code. If there is no fragment at point, display -all fragments in the current text, from one headline to the next. With -prefix SUBTREE, display all fragments in the current subtree. With a -double prefix arg \\[universal-argument] \\[universal-argument], or when \ -the cursor is before the first headline, -display all fragments in the buffer. -The images can be removed again with \\[org-ctrl-c-ctrl-c]." + +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. + +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 double prefix ARG \\[universal-argument] \ +\\[universal-argument] preview or clear images +for all fragments in the buffer." (interactive "P") - (unless buffer-file-name + (unless (buffer-file-name (buffer-base-buffer)) (user-error "Can't preview LaTeX fragment in a non-file buffer")) (when (display-graphic-p) - (org-remove-latex-fragment-image-overlays) - (save-excursion - (save-restriction - (let (beg end at msg) - (cond - ((or (equal subtree '(16)) - (not (save-excursion - (re-search-backward org-outline-regexp-bol nil t)))) - (setq beg (point-min) end (point-max) - msg "Creating images for buffer...%s")) - ((equal subtree '(4)) - (org-back-to-heading) - (setq beg (point) end (org-end-of-subtree t) - msg "Creating images for subtree...%s")) - (t - (if (setq at (org-inside-LaTeX-fragment-p)) - (goto-char (max (point-min) (- (cdr at) 2))) - (org-back-to-heading)) - (setq beg (point) end (progn (outline-next-heading) (point)) - msg (if at "Creating image...%s" - "Creating images for entry...%s")))) - (message msg "") - (narrow-to-region beg end) - (goto-char beg) - (org-format-latex - (concat org-latex-preview-ltxpng-directory (file-name-sans-extension - (file-name-nondirectory - buffer-file-name))) - default-directory 'overlays msg at 'forbuffer - org-latex-create-formula-image-program) - (message msg "done. Use `C-c C-c' to remove images.")))))) - -(defun org-format-latex (prefix &optional dir overlays msg at - forbuffer processing-type) + (catch 'exit + (save-excursion + (let ((window-start (window-start)) msg) + (save-restriction + (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)) + (let ((beg (point)) + (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...") + (narrow-to-region beg end)))) + ((let ((datum (org-element-context))) + (when (memq (org-element-type datum) + '(latex-environment latex-fragment)) + (let* ((beg (org-element-property :begin datum)) + (end (org-element-property :end datum))) + (if (org-remove-latex-fragment-image-overlays beg end) + (progn (message "LaTeX fragment image removed") + (throw 'exit nil)) + (narrow-to-region beg end) + (setq msg "Creating image...")))))) + (t + (org-with-limited-levels + (let ((beg (if (org-at-heading-p) (line-beginning-position) + (outline-previous-heading) + (point))) + (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...") + (narrow-to-region beg end)))))) + (let ((file (buffer-file-name (buffer-base-buffer)))) + (org-format-latex + (concat org-latex-preview-ltxpng-directory + (file-name-sans-extension (file-name-nondirectory file))) + ;; Emacs cannot overlay images from remote hosts. + ;; Create it in `temporary-file-directory' instead. + (if (file-remote-p file) temporary-file-directory + default-directory) + 'overlays msg 'forbuffer + org-latex-create-formula-image-program))) + ;; Work around a bug that doesn't restore window's start + ;; when widening back the buffer. + (set-window-start nil window-start) + (message (concat msg "done"))))))) + +(defun org-format-latex + (prefix &optional dir overlays msg forbuffer processing-type) "Replace LaTeX fragments with links to an image, and produce images. + +When optional argument OVERLAYS is non-nil, display the image on +top of the fragment instead of replacing it. + +PROCESSING-TYPE is the conversion method to use, as a symbol. + Some of the options can be changed using the variable -`org-format-latex-options'." - (if (and overlays (fboundp 'clear-image-cache)) (clear-image-cache)) - (let* ((prefixnodir (file-name-nondirectory prefix)) - (absprefix (expand-file-name prefix dir)) - (todir (file-name-directory absprefix)) - (opt org-format-latex-options) - (optnew org-format-latex-options) - (matchers (plist-get opt :matchers)) - (re-list org-latex-regexps) - (cnt 0) txt hash link beg end re e checkdir - string - m n block-type block linkfile movefile ov) - ;; Check the different regular expressions - (while (setq e (pop re-list)) - (setq m (car e) re (nth 1 e) n (nth 2 e) block-type (nth 3 e) - block (if block-type "\n\n" "")) - (when (member m matchers) - (goto-char (point-min)) - (while (re-search-forward re nil t) - (when (and (or (not at) (equal (cdr at) (match-beginning n))) - (or (not overlays) - (not (eq (get-char-property (match-beginning n) - 'org-overlay-type) - 'org-latex-overlay)))) - (cond - ((eq processing-type 'verbatim)) - ((eq processing-type 'mathjax) - ;; Prepare for MathJax processing. - (setq string (match-string n)) - (when (member m '("$" "$1")) - (save-excursion - (delete-region (match-beginning n) (match-end n)) - (goto-char (match-beginning n)) - (insert (concat "\\(" (substring string 1 -1) "\\)"))))) - ((or (eq processing-type 'dvipng) - (eq processing-type 'imagemagick)) - ;; Process to an image. - (setq txt (match-string n) - beg (match-beginning n) end (match-end n) - cnt (1+ cnt)) - (let ((face (face-at-point)) - (fg (plist-get opt :foreground)) - (bg (plist-get opt :background)) - ;; Ensure full list is printed. - print-length print-level) - (when forbuffer - ;; Get the colors from the face at point. - (goto-char beg) - (when (eq fg 'auto) - (setq fg (face-attribute face :foreground nil 'default))) - (when (eq bg 'auto) - (setq bg (face-attribute face :background nil 'default))) - (setq optnew (copy-sequence opt)) - (plist-put optnew :foreground fg) - (plist-put optnew :background bg)) - (setq hash (sha1 (prin1-to-string - (list org-format-latex-header - org-latex-default-packages-alist - org-latex-packages-alist - org-format-latex-options - forbuffer txt fg bg))) - linkfile (format "%s_%s.png" prefix hash) - movefile (format "%s_%s.png" absprefix hash))) - (setq link (concat block "[[file:" linkfile "]]" block)) - (if msg (message msg cnt)) - (goto-char beg) - (unless checkdir ; Ensure the directory exists. - (setq checkdir t) - (or (file-directory-p todir) (make-directory todir t))) - (unless (file-exists-p movefile) - (org-create-formula-image - txt movefile optnew forbuffer processing-type)) - (if overlays - (progn - (mapc (lambda (o) - (if (eq (overlay-get o 'org-overlay-type) - 'org-latex-overlay) - (delete-overlay o))) - (overlays-in beg end)) - (setq ov (make-overlay beg end)) - (overlay-put ov 'org-overlay-type 'org-latex-overlay) - (if (featurep 'xemacs) - (progn - (overlay-put ov 'invisible t) - (overlay-put - ov 'end-glyph - (make-glyph (vector 'png :file movefile)))) - (overlay-put - ov 'display - (list 'image :type 'png :file movefile :ascent 'center))) - (push ov org-latex-fragment-image-overlays) - (goto-char end)) - (delete-region beg end) - (insert (org-add-props link +`org-format-latex-options', which see." + (when (and overlays (fboundp 'clear-image-cache)) (clear-image-cache)) + (unless (eq processing-type 'verbatim) + (let* ((math-regexp "\\$\\|\\\\[([]\\|^[ \t]*\\\\begin{[A-Za-z0-9*]+}") + (cnt 0) + checkdir-flag) + (goto-char (point-min)) + ;; Optimize overlay creation: (info "(elisp) Managing Overlays"). + (when (and overlays (memq processing-type '(dvipng imagemagick))) + (overlay-recenter (point-max))) + (while (re-search-forward math-regexp nil t) + (unless (and overlays + (eq (get-char-property (point) 'org-overlay-type) + 'org-latex-overlay)) + (let* ((context (org-element-context)) + (type (org-element-type context))) + (when (memq type '(latex-environment latex-fragment)) + (let ((block-type (eq type 'latex-environment)) + (value (org-element-property :value context)) + (beg (org-element-property :begin context)) + (end (save-excursion + (goto-char (org-element-property :end context)) + (skip-chars-backward " \r\t\n") + (point)))) + (case processing-type + (mathjax + ;; Prepare for MathJax processing. + (if (not (string-match "\\`\\$\\$?" value)) + (goto-char end) + (delete-region beg end) + (if (string= (match-string 0 value) "$$") + (insert "\\[" (substring value 2 -2) "\\]") + (insert "\\(" (substring value 1 -1) "\\)")))) + ((dvipng imagemagick) + ;; Process to an image. + (incf cnt) + (goto-char beg) + (let* ((face (face-at-point)) + ;; Get the colors from the face at point. + (fg + (let ((color (plist-get org-format-latex-options + :foreground))) + (if (and forbuffer (eq color 'auto)) + (face-attribute face :foreground nil 'default) + color))) + (bg + (let ((color (plist-get org-format-latex-options + :background))) + (if (and forbuffer (eq color 'auto)) + (face-attribute face :background nil 'default) + color))) + (hash (sha1 (prin1-to-string + (list org-format-latex-header + org-latex-default-packages-alist + org-latex-packages-alist + org-format-latex-options + forbuffer value fg bg)))) + (absprefix (expand-file-name prefix dir)) + (linkfile (format "%s_%s.png" prefix hash)) + (movefile (format "%s_%s.png" absprefix hash)) + (sep (and block-type "\n\n")) + (link (concat sep "[[file:" linkfile "]]" sep)) + (options + (org-combine-plists + org-format-latex-options + `(:foreground ,fg :background ,bg)))) + (when msg (message msg cnt)) + (unless checkdir-flag ; Ensure the directory exists. + (setq checkdir-flag t) + (let ((todir (file-name-directory absprefix))) + (unless (file-directory-p todir) + (make-directory todir t)))) + (unless (file-exists-p movefile) + (org-create-formula-image + value movefile options forbuffer processing-type)) + (if overlays + (progn + (dolist (o (overlays-in beg end)) + (when (eq (overlay-get o 'org-overlay-type) + 'org-latex-overlay) + (delete-overlay o))) + (org--format-latex-make-overlay beg end movefile) + (goto-char end)) + (delete-region beg end) + (insert + (org-add-props link (list 'org-latex-src - (replace-regexp-in-string - "\"" "" txt) - 'org-latex-src-embed-type - (if block-type 'paragraph 'character)))))) - ((eq processing-type 'mathml) - ;; Process to MathML - (unless (save-match-data (org-format-latex-mathml-available-p)) - (user-error "LaTeX to MathML converter not configured")) - (setq txt (match-string n) - beg (match-beginning n) end (match-end n) - cnt (1+ cnt)) - (if msg (message msg cnt)) - (goto-char beg) - (delete-region beg end) - (insert (org-format-latex-as-mathml - txt block-type prefix dir))) - (t - (error "Unknown conversion type %s for LaTeX fragments" - processing-type))))))))) + (replace-regexp-in-string "\"" "" value) + 'org-latex-src-embed-type + (if block-type 'paragraph 'character))))))) + (mathml + ;; Process to MathML. + (unless (org-format-latex-mathml-available-p) + (user-error "LaTeX to MathML converter not configured")) + (incf cnt) + (when msg (message msg cnt)) + (goto-char beg) + (delete-region beg end) + (insert (org-format-latex-as-mathml + value block-type prefix dir))) + (otherwise + (error "Unknown conversion type %s for LaTeX fragments" + processing-type))))))))))) (defun org-create-math-formula (latex-frag &optional mathml-file) "Convert LATEX-FRAG to MathML and store it in MATHML-FILE. @@ -18546,7 +19215,7 @@ inspection." (buffer-substring-no-properties (region-beginning) (region-end))))) (read-string "LaTeX Fragment: " frag nil frag)))) - (unless latex-frag (error "Invalid LaTeX fragment")) + (unless latex-frag (user-error "Invalid LaTeX fragment")) (let* ((tmp-in-file (file-relative-name (make-temp-name (expand-file-name "ltxmathml-in")))) (ignore (write-region latex-frag nil tmp-in-file)) @@ -18554,9 +19223,12 @@ inspection." (make-temp-name (expand-file-name "ltxmathml-out")))) (cmd (format-spec org-latex-to-mathml-convert-command - `((?j . ,(shell-quote-argument - (expand-file-name org-latex-to-mathml-jar-file))) + `((?j . ,(and org-latex-to-mathml-jar-file + (shell-quote-argument + (expand-file-name + org-latex-to-mathml-jar-file)))) (?I . ,(shell-quote-argument tmp-in-file)) + (?i . ,latex-frag) (?o . ,(shell-quote-argument tmp-out-file))))) mathml shell-command-output) (when (org-called-interactively-p 'any) @@ -18571,9 +19243,11 @@ inspection." (when (re-search-forward (concat (regexp-quote - "") + "]*?>" "\\(.\\|\n\\)*" - (regexp-quote "")) nil t) + "") + nil t) (prog1 (match-string 0) (kill-buffer)))))) (cond (mathml @@ -18633,11 +19307,11 @@ share a good deal of logic." "latex" "needed to convert LaTeX fragments to images") (funcall (case (or type org-latex-create-formula-image-program) - ('dvipng + (dvipng (org-check-external-command "dvipng" "needed to convert LaTeX fragments to images") #'org-create-formula-image-with-dvipng) - ('imagemagick + (imagemagick (org-check-external-command "convert" "you need to install imagemagick") #'org-create-formula-image-with-imagemagick) @@ -18665,6 +19339,16 @@ share a good deal of logic." (plist-get info :latex-header))) info))) +(defun org--get-display-dpi () + "Get the DPI of the display. + +Assumes that the display has the same pixel width in the +horizontal and vertical directions." + (if (display-graphic-p) + (round (/ (display-pixel-height) + (/ (display-mm-height) 25.4))) + (error "Attempt to calculate the dpi of a non-graphic display"))) + ;; This function borrows from Ganesh Swami's latex2png.el (defun org-create-formula-image-with-dvipng (string tofile options buffer) "This calls dvipng." @@ -18677,11 +19361,10 @@ share a good deal of logic." (texfile (concat texfilebase ".tex")) (dvifile (concat texfilebase ".dvi")) (pngfile (concat texfilebase ".png")) - (fnh (if (featurep 'xemacs) - (font-height (face-font 'default)) - (face-attribute 'default :height nil))) (scale (or (plist-get options (if buffer :scale :html-scale)) 1.0)) - (dpi (number-to-string (* scale (floor (* 0.9 (if buffer fnh 140.)))))) + ;; This assumes that the display has the same pixel width in + ;; the horizontal and vertical directions + (dpi (number-to-string (* scale (if buffer (org--get-display-dpi) 120)))) (fg (or (plist-get options (if buffer :foreground :html-foreground)) "Black")) (bg (or (plist-get options (if buffer :background :html-background)) @@ -18695,29 +19378,26 @@ share a good deal of logic." (insert latex-header) (insert "\n\\begin{document}\n" string "\n\\end{document}\n"))) (let ((dir default-directory)) - (condition-case nil - (progn - (cd tmpdir) - (call-process "latex" nil nil nil texfile)) - (error nil)) + (ignore-errors + (cd tmpdir) + (call-process "latex" nil nil nil texfile)) (cd dir)) (if (not (file-exists-p dvifile)) (progn (message "Failed to create dvi file from %s" texfile) nil) - (condition-case nil - (if (featurep 'xemacs) - (call-process "dvipng" nil nil nil - "-fg" fg "-bg" bg - "-T" "tight" - "-o" pngfile - dvifile) + (ignore-errors + (if (featurep 'xemacs) (call-process "dvipng" nil nil nil "-fg" fg "-bg" bg - "-D" dpi - ;;"-x" scale "-y" scale "-T" "tight" "-o" pngfile - dvifile)) - (error nil)) + dvifile) + (call-process "dvipng" nil nil nil + "-fg" fg "-bg" bg + "-D" dpi + ;;"-x" scale "-y" scale + "-T" "tight" + "-o" pngfile + dvifile))) (if (not (file-exists-p pngfile)) (if org-format-latex-signal-error (error "Failed to create png file from %s" texfile) @@ -18742,11 +19422,8 @@ share a good deal of logic." (texfile (concat texfilebase ".tex")) (pdffile (concat texfilebase ".pdf")) (pngfile (concat texfilebase ".png")) - (fnh (if (featurep 'xemacs) - (font-height (face-font 'default)) - (face-attribute 'default :height nil))) (scale (or (plist-get options (if buffer :scale :html-scale)) 1.0)) - (dpi (number-to-string (* scale (floor (if buffer fnh 120.))))) + (dpi (number-to-string (* scale (if buffer (org--get-display-dpi) 120)))) (fg (or (plist-get options (if buffer :foreground :html-foreground)) "black")) (bg (or (plist-get options (if buffer :background :html-background)) @@ -18770,25 +19447,24 @@ share a good deal of logic." (org-latex-compile texfile t) (if (not (file-exists-p pdffile)) (progn (message "Failed to create pdf file from %s" texfile) nil) - (condition-case nil - (if (featurep 'xemacs) - (call-process "convert" nil nil nil - "-density" "96" - "-trim" - "-antialias" - pdffile - "-quality" "100" - ;; "-sharpen" "0x1.0" - pngfile) + (ignore-errors + (if (featurep 'xemacs) (call-process "convert" nil nil nil - "-density" dpi + "-density" "96" "-trim" "-antialias" pdffile "-quality" "100" ;; "-sharpen" "0x1.0" - pngfile)) - (error nil)) + pngfile) + (call-process "convert" nil nil nil + "-density" dpi + "-trim" + "-antialias" + pdffile + "-quality" "100" + ;; "-sharpen" "0x1.0" + pngfile))) (if (not (file-exists-p pngfile)) (if org-format-latex-signal-error (error "Failed to create png file from %s" texfile) @@ -18875,7 +19551,7 @@ SNIPPETS-P indicates if this is run to create snippet images for HTML." "Convert COLOR-NAME to a RGB color value for dvipng." (apply 'format "rgb %s %s %s" (mapcar 'org-normalize-color - (color-values color-name)))) + (color-values color-name)))) (defun org-latex-color (attr) "Return a RGB color for the LaTeX color package." @@ -18912,13 +19588,14 @@ INCLUDE-LINKED is passed to `org-display-inline-images'." (if org-inline-image-overlays (progn (org-remove-inline-images) - (message "Inline image display turned off")) + (when (org-called-interactively-p 'interactive) + (message "Inline image display turned off"))) (org-display-inline-images include-linked) - (if (and (org-called-interactively-p) - org-inline-image-overlays) - (message "%d images displayed inline" - (length org-inline-image-overlays)) - (message "No images to display inline")))) + (when (org-called-interactively-p 'interactive) + (message (if org-inline-image-overlays + (format "%d images displayed inline" + (length org-inline-image-overlays)) + "No images to display inline"))))) (defun org-redisplay-inline-images () "Refresh the display of inline images." @@ -18930,63 +19607,114 @@ INCLUDE-LINKED is passed to `org-display-inline-images'." (defun org-display-inline-images (&optional include-linked refresh beg end) "Display inline images. -Normally only links without a description part are inlined, because this -is how it will work for export. When INCLUDE-LINKED is set, also links -with a description part will be inlined. This can be nice for a quick -look at those images, but it does not reflect what exported files will look -like. -When REFRESH is set, refresh existing images between BEG and END. -This will create new image displays only if necessary. -BEG and END default to the buffer boundaries." + +An inline image is a link which follows either of these +conventions: + + 1. Its path is a file with an extension matching return value + from `image-file-name-regexp' and it has no contents. + + 2. Its description consists in a single link of the previous + type. + +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 +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." (interactive "P") (when (display-graphic-p) (unless refresh (org-remove-inline-images) - (if (fboundp 'clear-image-cache) (clear-image-cache))) - (save-excursion - (save-restriction - (widen) - (setq beg (or beg (point-min)) end (or end (point-max))) - (goto-char beg) - (let ((re (concat "\\[\\[\\(\\(file:\\)\\|\\([./~]\\)\\)\\([^]\n]+?" - (substring (org-image-file-name-regexp) 0 -2) - "\\)\\]" (if include-linked "" "\\]"))) - (case-fold-search t) - old file ov img type attrwidth width) - (while (re-search-forward re end t) - (setq old (get-char-property-and-overlay (match-beginning 1) - 'org-image-overlay) - file (expand-file-name - (concat (or (match-string 3) "") (match-string 4)))) - (when (image-type-available-p 'imagemagick) - (setq attrwidth (if (or (listp org-image-actual-width) - (null org-image-actual-width)) - (save-excursion - (save-match-data - (when (re-search-backward - "#\\+attr.*:width[ \t]+\\([^ ]+\\)" - (save-excursion - (re-search-backward "^[ \t]*$\\|\\`" nil t)) t) - (string-to-number (match-string 1)))))) - width (cond ((eq org-image-actual-width t) nil) - ((null org-image-actual-width) attrwidth) - ((numberp org-image-actual-width) - org-image-actual-width) - ((listp org-image-actual-width) - (or attrwidth (car org-image-actual-width)))) - type (if width 'imagemagick))) - (when (file-exists-p file) - (if (and (car-safe old) refresh) - (image-refresh (overlay-get (cdr old) 'display)) - (setq img (save-match-data (create-image file type nil :width width))) - (when img - (setq ov (make-overlay (match-beginning 0) (match-end 0))) - (overlay-put ov 'display img) - (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)))))))))) + (when (fboundp 'clear-image-cache) (clear-image-cache))) + (org-with-wide-buffer + (goto-char (or beg (point-min))) + (let ((case-fold-search t) + (file-extension-re (org-image-file-name-regexp))) + (while (re-search-forward "[][]\\[\\(?:file\\|[./~]\\)" end t) + (let ((link (save-match-data (org-element-context)))) + ;; Check if we're at an inline image. + (when (and (equal (org-element-property :type link) "file") + (or include-linked + (not (org-element-property :contents-begin link))) + (let ((parent (org-element-property :parent link))) + (or (not (eq (org-element-type parent) 'link)) + (not (cdr (org-element-contents parent))))) + (org-string-match-p file-extension-re + (org-element-property :path link))) + (let ((file (expand-file-name + (org-link-unescape + (org-element-property :path link))))) + (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* ((link + ;; If inline image is the description + ;; of another link, be sure to + ;; consider the latter as the one to + ;; apply the overlay on. + (let ((parent + (org-element-property :parent link))) + (if (eq (org-element-type parent) 'link) + parent + link))) + (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))))))))))))))) (define-obsolete-function-alias 'org-display-inline-modification-hook 'org-display-inline-remove-overlay "24.3") @@ -19009,44 +19737,48 @@ BEG and END default to the buffer boundaries." ;; Outline functions from `outline-mode-prefix-map' ;; that can be remapped in Org: (define-key org-mode-map [remap outline-mark-subtree] 'org-mark-subtree) -(define-key org-mode-map [remap show-subtree] 'org-show-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 show-branches] +(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) ;; Outline functions from `outline-mode-prefix-map' that can not ;; be remapped in Org: -;; + ;; - the column "key binding" shows whether the Outline function is still ;; available in Org mode on the same key that it has been bound to in ;; Outline mode: ;; - "overridden": key used for a different functionality in Org mode ;; - else: key still bound to the same Outline function in Org mode -;; -;; | Outline function | key binding | Org replacement | -;; |------------------------------------+-------------+-----------------------| -;; | `outline-next-visible-heading' | `C-c C-n' | still same function | -;; | `outline-previous-visible-heading' | `C-c C-p' | still same function | -;; | `outline-up-heading' | `C-c C-u' | still same function | -;; | `outline-move-subtree-up' | overridden | better: org-shiftup | -;; | `outline-move-subtree-down' | overridden | better: org-shiftdown | -;; | `show-entry' | overridden | no replacement | -;; | `show-children' | `C-c C-i' | visibility cycling | -;; | `show-branches' | `C-c C-k' | still same function | -;; | `show-subtree' | overridden | visibility cycling | -;; | `show-all' | overridden | no replacement | -;; | `hide-subtree' | overridden | visibility cycling | -;; | `hide-body' | overridden | no replacement | -;; | `hide-entry' | overridden | visibility cycling | -;; | `hide-leaves' | overridden | no replacement | -;; | `hide-sublevels' | overridden | no replacement | -;; | `hide-other' | overridden | no replacement | + +;; | Outline function | key binding | Org replacement | +;; |------------------------------------+-------------+--------------------------| +;; | `outline-next-visible-heading' | `C-c C-n' | better: skip inlinetasks | +;; | `outline-previous-visible-heading' | `C-c C-p' | better: skip inlinetasks | +;; | `outline-up-heading' | `C-c C-u' | still same function | +;; | `outline-move-subtree-up' | overridden | better: org-shiftup | +;; | `outline-move-subtree-down' | overridden | better: org-shiftdown | +;; | `show-entry' | overridden | no replacement | +;; | `show-children' | `C-c C-i' | visibility cycling | +;; | `show-branches' | `C-c C-k' | still same function | +;; | `show-subtree' | overridden | visibility cycling | +;; | `show-all' | overridden | no replacement | +;; | `hide-subtree' | overridden | visibility cycling | +;; | `hide-body' | overridden | no replacement | +;; | `hide-entry' | overridden | visibility cycling | +;; | `hide-leaves' | overridden | no replacement | +;; | `hide-sublevels' | overridden | no replacement | +;; | `hide-other' | overridden | no replacement | ;; Make `C-c C-x' a prefix key (org-defkey org-mode-map "\C-c\C-x" (make-sparse-keymap)) @@ -19055,7 +19787,7 @@ BEG and END default to the buffer boundaries." (org-defkey org-mode-map "\C-i" 'org-cycle) (org-defkey org-mode-map [(tab)] 'org-cycle) (org-defkey org-mode-map [(control tab)] 'org-force-cycle-archived) -(org-defkey org-mode-map "\M-\t" 'pcomplete) +(org-defkey org-mode-map "\M-\t" #'pcomplete) ;; The following line is necessary under Suse GNU/Linux (unless (featurep 'xemacs) (org-defkey org-mode-map [S-iso-lefttab] 'org-shifttab)) @@ -19072,6 +19804,8 @@ BEG and END default to the buffer boundaries." (org-defkey org-mode-map [(meta up)] 'org-metaup) (org-defkey org-mode-map [(meta down)] 'org-metadown) +(org-defkey org-mode-map [(control meta shift right)] 'org-increase-number-at-point) +(org-defkey org-mode-map [(control meta shift left)] 'org-decrease-number-at-point) (org-defkey org-mode-map [(meta shift left)] 'org-shiftmetaleft) (org-defkey org-mode-map [(meta shift right)] 'org-shiftmetaright) (org-defkey org-mode-map [(meta shift up)] 'org-shiftmetaup) @@ -19122,7 +19856,7 @@ BEG and END default to the buffer boundaries." (org-defkey org-mode-map [?\C-c (right)] 'org-shiftright) (org-defkey org-mode-map [?\C-c ?\C-x (right)] 'org-shiftcontrolright) (org-defkey org-mode-map [?\C-c ?\C-x (left)] 'org-shiftcontrolleft) - (org-defkey org-mode-map [?\e (tab)] 'pcomplete) + (org-defkey org-mode-map [?\e (tab)] #'pcomplete) (org-defkey org-mode-map [?\e (shift return)] 'org-insert-todo-heading) (org-defkey org-mode-map [?\e (shift left)] 'org-shiftmetaleft) (org-defkey org-mode-map [?\e (shift right)] 'org-shiftmetaright) @@ -19131,7 +19865,7 @@ BEG and END default to the buffer boundaries." ;; All the other keys -(org-defkey org-mode-map "\C-c\C-a" 'show-all) ; in case allout messed up. +(org-defkey org-mode-map "\C-c\C-a" 'outline-show-all) ; in case allout messed up. (org-defkey org-mode-map "\C-c\C-r" 'org-reveal) (if (boundp 'narrow-map) (org-defkey narrow-map "s" 'org-narrow-to-subtree) @@ -19152,7 +19886,7 @@ BEG and END default to the buffer boundaries." (org-defkey org-mode-map "\C-c\M-f" 'org-next-block) (org-defkey org-mode-map "\C-c\M-b" 'org-previous-block) (org-defkey org-mode-map "\C-c$" 'org-archive-subtree) -(org-defkey org-mode-map "\C-c\C-x\C-s" 'org-advertized-archive-subtree) +(org-defkey org-mode-map "\C-c\C-x\C-s" 'org-archive-subtree) (org-defkey org-mode-map "\C-c\C-x\C-a" 'org-archive-subtree-default) (org-defkey org-mode-map "\C-c\C-xd" 'org-insert-drawer) (org-defkey org-mode-map "\C-c\C-xa" 'org-toggle-archive-tag) @@ -19178,6 +19912,7 @@ BEG and END default to the buffer boundaries." (org-defkey org-mode-map "\C-c\C-x\C-n" 'org-next-link) (org-defkey org-mode-map "\C-c\C-x\C-p" 'org-previous-link) (org-defkey org-mode-map "\C-c\C-l" 'org-insert-link) +(org-defkey org-mode-map "\C-c\M-l" 'org-insert-last-stored-link) (org-defkey org-mode-map "\C-c\C-\M-l" 'org-insert-all-links) (org-defkey org-mode-map "\C-c\C-o" 'org-open-at-point) (org-defkey org-mode-map "\C-c%" 'org-mark-ring-push) @@ -19202,8 +19937,10 @@ BEG and END default to the buffer boundaries." (org-defkey org-mode-map "\C-c\C-k" 'org-kill-note-or-show-branches) (org-defkey org-mode-map "\C-c#" 'org-update-statistics-cookies) (org-defkey org-mode-map [remap open-line] 'org-open-line) +(org-defkey org-mode-map [remap comment-dwim] 'org-comment-dwim) (org-defkey org-mode-map [remap forward-paragraph] 'org-forward-paragraph) (org-defkey org-mode-map [remap backward-paragraph] 'org-backward-paragraph) +(org-defkey org-mode-map "\M-^" 'org-delete-indentation) (org-defkey org-mode-map "\C-m" 'org-return) (org-defkey org-mode-map "\C-j" 'org-return-indent) (org-defkey org-mode-map "\C-c?" 'org-table-field-info) @@ -19212,6 +19949,8 @@ BEG and END default to the buffer boundaries." (org-defkey org-mode-map "\C-c=" 'org-table-eval-formula) (org-defkey org-mode-map "\C-c'" 'org-edit-special) (org-defkey org-mode-map "\C-c`" 'org-table-edit-field) +(org-defkey org-mode-map "\C-c\"a" 'orgtbl-ascii-plot) +(org-defkey org-mode-map "\C-c\"g" 'org-plot/gnuplot) (org-defkey org-mode-map "\C-c|" 'org-table-create-or-convert-from-region) (org-defkey org-mode-map [(control ?#)] 'org-table-rotate-recalc-marks) (org-defkey org-mode-map "\C-c~" 'org-table-create-with-table.el) @@ -19219,7 +19958,7 @@ BEG and END default to the buffer boundaries." (org-defkey org-mode-map "\C-c}" 'org-table-toggle-coordinate-overlays) (org-defkey org-mode-map "\C-c{" 'org-table-toggle-formula-debugger) (org-defkey org-mode-map "\C-c\C-e" 'org-export-dispatch) -(org-defkey org-mode-map "\C-c:" 'org-toggle-fixed-width-section) +(org-defkey org-mode-map "\C-c:" 'org-toggle-fixed-width) (org-defkey org-mode-map "\C-c\C-x\C-f" 'org-emphasize) (org-defkey org-mode-map "\C-c\C-xf" 'org-footnote-action) (org-defkey org-mode-map "\C-c\C-x\C-mg" 'org-mobile-pull) @@ -19243,7 +19982,7 @@ BEG and END default to the buffer boundaries." (org-defkey org-mode-map "\C-c\C-x\C-d" 'org-clock-display) (org-defkey org-mode-map "\C-c\C-x\C-r" 'org-clock-report) (org-defkey org-mode-map "\C-c\C-x\C-u" 'org-dblock-update) -(org-defkey org-mode-map "\C-c\C-x\C-l" 'org-preview-latex-fragment) +(org-defkey org-mode-map "\C-c\C-x\C-l" 'org-toggle-latex-fragment) (org-defkey org-mode-map "\C-c\C-x\C-v" 'org-toggle-inline-images) (org-defkey org-mode-map "\C-c\C-x\C-\M-v" 'org-redisplay-inline-images) (org-defkey org-mode-map "\C-c\C-x\\" 'org-toggle-pretty-entities) @@ -19255,7 +19994,6 @@ BEG and END default to the buffer boundaries." (org-defkey org-mode-map "\C-c\C-xo" 'org-toggle-ordered-property) (org-defkey org-mode-map "\C-c\C-xi" 'org-insert-columns-dblock) (org-defkey org-mode-map [(control ?c) (control ?x) ?\;] 'org-timer-set-timer) -(org-defkey org-mode-map [(control ?c) (control ?x) ?\:] 'org-timer-cancel-timer) (org-defkey org-mode-map "\C-c\C-x." 'org-timer) (org-defkey org-mode-map "\C-c\C-x-" 'org-timer-item) @@ -19280,8 +20018,8 @@ BEG and END default to the buffer boundaries." (defconst org-speed-commands-default '( ("Outline Navigation") - ("n" . (org-speed-move-safe 'outline-next-visible-heading)) - ("p" . (org-speed-move-safe 'outline-previous-visible-heading)) + ("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) @@ -19296,8 +20034,8 @@ BEG and END default to the buffer boundaries." ("s" . org-narrow-to-subtree) ("=" . org-columns) ("Outline Structure Editing") - ("U" . org-shiftmetaup) - ("D" . org-shiftmetadown) + ("U" . org-metaup) + ("D" . org-metadown) ("r" . org-metaright) ("l" . org-metaleft) ("R" . org-shiftmetaright) @@ -19427,9 +20165,11 @@ overwritten, and the table is not marked as requiring realignment." (org-check-before-invisible-edit 'insert) (cond ((and org-use-speed-commands - (setq org-speed-command - (run-hook-with-args-until-success - 'org-speed-command-hook (this-command-keys)))) + (let ((kv (this-command-keys-vector))) + (setq org-speed-command + (run-hook-with-args-until-success + 'org-speed-command-hook + (make-string 1 (aref kv (1- (length kv)))))))) (cond ((commandp org-speed-command) (setq this-command org-speed-command) @@ -19443,23 +20183,23 @@ overwritten, and the table is not marked as requiring realignment." ((and (org-table-p) (progn - ;; check if we blank the field, and if that triggers align + ;; Check if we blank the field, and if that triggers align. (and (featurep 'org-table) org-table-auto-blank-field - (member last-command - '(org-cycle org-return org-shifttab org-ctrl-c-ctrl-c yas/expand)) - (if (or (equal (char-after) ?\ ) (looking-at "[^|\n]* |")) - ;; got extra space, this field does not determine column width + (memq last-command + '(org-cycle org-return org-shifttab org-ctrl-c-ctrl-c)) + (if (or (eq (char-after) ?\s) (looking-at "[^|\n]* |")) + ;; Got extra space, this field does not determine + ;; column width. (let (org-table-may-need-update) (org-table-blank-field)) - ;; no extra space, this field may determine column width + ;; No extra space, this field may determine column + ;; width. (org-table-blank-field))) t) (eq N 1) - (looking-at "[^|\n]* |")) - (let (org-table-may-need-update) - (goto-char (1- (match-end 0))) - (backward-delete-char 1) - (goto-char (match-beginning 0)) - (self-insert-command N))) + (looking-at "[^|\n]* \\( \\)|")) + ;; There is room for insertion without re-aligning the table. + (delete-region (match-beginning 1) (match-end 1)) + (self-insert-command N)) (t (setq org-table-may-need-update t) (self-insert-command N) @@ -19511,7 +20251,7 @@ The detailed reaction depends on the user option `org-catch-invisible-edits'." (if invisible-before-point (goto-char (previous-single-char-property-change (point) 'invisible))) - (show-subtree)) + (outline-show-subtree)) (cond ((eq org-catch-invisible-edits 'show) ;; That's it, we do the edit after showing @@ -19814,31 +20554,29 @@ individual commands for more information." (t (org-modifier-cursor-error)))) (defun org-shiftmetaup (&optional arg) - "Move subtree up or kill table row. -Calls `org-move-subtree-up' or `org-table-kill-row' or -`org-move-item-up' or `org-timestamp-up', depending on context. -See the individual commands for more information." + "Drag the line at point up. +In a table, kill the current row. +On a clock timestamp, update the value of the timestamp like `S-' +but also adjust the previous clocked item in the clock history. +Everywhere else, drag the line at point up." (interactive "P") (cond ((run-hook-with-args-until-success 'org-shiftmetaup-hook)) ((org-at-table-p) (call-interactively 'org-table-kill-row)) - ((org-at-heading-p) (call-interactively 'org-move-subtree-up)) - ((org-at-item-p) (call-interactively 'org-move-item-up)) ((org-at-clock-log-p) (let ((org-clock-adjust-closest t)) (call-interactively 'org-timestamp-up))) (t (call-interactively 'org-drag-line-backward)))) (defun org-shiftmetadown (&optional arg) - "Move subtree down or insert table row. -Calls `org-move-subtree-down' or `org-table-insert-row' or -`org-move-item-down' or `org-timestamp-up', depending on context. -See the individual commands for more information." + "Drag the line at point down. +In a table, insert an empty row at the current line. +On a clock timestamp, update the value of the timestamp like `S-' +but also adjust the previous clocked item in the clock history. +Everywhere else, drag the line at point down." (interactive "P") (cond ((run-hook-with-args-until-success 'org-shiftmetadown-hook)) ((org-at-table-p) (call-interactively 'org-table-insert-row)) - ((org-at-heading-p) (call-interactively 'org-move-subtree-down)) - ((org-at-item-p) (call-interactively 'org-move-item-down)) ((org-at-clock-log-p) (let ((org-clock-adjust-closest t)) (call-interactively 'org-timestamp-down))) (t (call-interactively 'org-drag-line-forward)))) @@ -19848,10 +20586,15 @@ See the individual commands for more information." "Hidden subtree, open with TAB or use subtree command M-S-/")) (defun org-metaleft (&optional arg) - "Promote heading or move table column to left. -Calls `org-do-promote' or `org-table-move-column', depending on context. -With no specific context, calls the Emacs default `backward-word'. -See the individual commands for more information." + "Promote heading, list item at point or move table column left. + +Calls `org-do-promote', `org-outdent-item' or `org-table-move-column', +depending on context. With no specific context, calls the Emacs +default `backward-word'. See the individual commands for more +information. + +This function runs the hook `org-metaleft-hook' as a first step, +and returns at first non-nil value." (interactive "P") (cond ((run-hook-with-args-until-success 'org-metaleft-hook)) @@ -19877,10 +20620,17 @@ See the individual commands for more information." (t (call-interactively 'backward-word)))) (defun org-metaright (&optional arg) - "Demote a subtree, a list item or move table column to right. + "Demote heading, list item at point or move table column right. + In front of a drawer or a block keyword, indent it correctly. + +Calls `org-do-demote', `org-indent-item', `org-table-move-column', +`org-indnet-drawer' or `org-indent-block' depending on context. With no specific context, calls the Emacs default `forward-word'. -See the individual commands for more information." +See the individual commands for more information. + +This function runs the hook `org-metaright-hook' as a first step, +and returns at first non-nil value." (interactive "P") (cond ((run-hook-with-args-until-success 'org-metaright-hook)) @@ -20142,6 +20892,32 @@ Optional argument N tells to change by that many units." (org-clock-timestamps-down n)) (user-error "Not at a clock log"))) +(defun org-increase-number-at-point (&optional inc) + "Increment the number at point. +With an optional prefix numeric argument INC, increment using +this numeric value." + (interactive "p") + (if (not (number-at-point)) + (user-error "Not on a number") + (unless inc (setq inc 1)) + (let ((pos (point)) + (beg (skip-chars-backward "-+^/*0-9eE.")) + (end (skip-chars-forward "-+^/*0-9eE^.")) nap) + (setq nap (buffer-substring-no-properties + (+ pos beg) (+ pos beg end))) + (delete-region (+ pos beg) (+ pos beg end)) + (insert (calc-eval (concat (number-to-string inc) "+" nap)))) + (when (org-at-table-p) + (org-table-align) + (org-table-end-of-field 1)))) + +(defun org-decrease-number-at-point (&optional inc) + "Decrement the number at point. +With an optional prefix numeric argument INC, decrement using +this numeric value." + (interactive "p") + (org-increase-number-at-point (- (or inc 1)))) + (defun org-ctrl-c-ret () "Call `org-table-hline-and-move' or `org-insert-heading' dep. on context." (interactive) @@ -20209,7 +20985,9 @@ See the individual commands for more information." When at a table, call the formula editor with `org-table-edit-formulas'. When in a source code block, call `org-edit-src-code'. When in a fixed-width region, call `org-edit-fixed-width-region'. +When in an export block, call `org-edit-export-block'. When at an #+INCLUDE keyword, visit the included file. +When at a footnote reference, call `org-edit-footnote-reference' On a link, call `ffap' to visit the link at point. Otherwise, return a user error." (interactive "P") @@ -20232,24 +21010,35 @@ Otherwise, return a user error." session params)))))) (keyword (if (member (org-element-property :key element) '("INCLUDE" "SETUPFILE")) - (find-file - (org-remove-double-quotes - (car (org-split-string (org-element-property :value element))))) + (org-open-link-from-string + (format "[[%s]]" + (expand-file-name + (let ((value (org-element-property :value element))) + (cond ((not (org-string-nw-p value)) + (user-error "No file to edit")) + ((string-match "\\`\"\\(.*?\\)\"" value) + (match-string 1 value)) + ((string-match "\\`[^ \t\"]\\S-*" value) + (match-string 0 value)) + (t (user-error "No valid file specified"))))))) (user-error "No special environment to edit here"))) (table (if (eq (org-element-property :type element) 'table.el) - (org-edit-src-code) + (org-edit-table.el) (call-interactively 'org-table-edit-formulas))) ;; Only Org tables contain `table-row' type elements. (table-row (call-interactively 'org-table-edit-formulas)) - ((example-block export-block) (org-edit-src-code)) + (example-block (org-edit-src-code)) + (export-block (org-edit-export-block)) (fixed-width (org-edit-fixed-width-region)) (otherwise - ;; No notable element at point. Though, we may be at a link, - ;; which is an object. Thus, scan deeper. - (if (eq (org-element-type (org-element-context element)) 'link) - (call-interactively 'ffap) - (user-error "No special environment to edit here")))))) + ;; No notable element at point. Though, we may be at a link or + ;; a footnote reference, which are objects. Thus, scan deeper. + (let ((context (org-element-context element))) + (case (org-element-type context) + (link (call-interactively #'ffap)) + (footnote-reference (org-edit-footnote-reference)) + (t (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) @@ -20299,22 +21088,20 @@ This command does many different things, depending on context: (interactive "P") (cond ((or (and (boundp 'org-clock-overlays) org-clock-overlays) - org-occur-highlights - org-latex-fragment-image-overlays) + org-occur-highlights) (and (boundp 'org-clock-overlays) (org-clock-remove-overlays)) (org-remove-occur-highlights) - (org-remove-latex-fragment-image-overlays) (message "Temporary highlights/overlays removed from current buffer")) ((and (local-variable-p 'org-finish-function (current-buffer)) (fboundp org-finish-function)) (funcall org-finish-function)) ((run-hook-with-args-until-success 'org-ctrl-c-ctrl-c-hook)) (t - (let* ((context (org-element-context)) (type (org-element-type context))) - ;; Test if point is within a blank line. - (if (save-excursion (beginning-of-line) (looking-at "[ \t]*$")) - (or (run-hook-with-args-until-success 'org-ctrl-c-ctrl-c-final-hook) - (user-error "C-c C-c can do nothing useful at this location")) + (if (save-excursion (beginning-of-line) (looking-at "[ \t]*$")) + (or (run-hook-with-args-until-success 'org-ctrl-c-ctrl-c-final-hook) + (user-error "C-c C-c can do nothing useful at this location")) + (let* ((context (org-element-context)) + (type (org-element-type context))) (case type ;; When at a link, act according to the parent instead. (link (setq context (org-element-property :parent context)) @@ -20324,16 +21111,16 @@ This command does many different things, depending on context: ((bold code entity export-snippet inline-babel-call inline-src-block italic latex-fragment line-break macro strike-through subscript superscript underline verbatim) - (while (and (setq context (org-element-property :parent context)) - (not (memq (setq type (org-element-type context)) - '(radio-target paragraph verse-block - table-cell))))))) + (setq context + (org-element-lineage + context '(radio-target paragraph verse-block table-cell))))) ;; For convenience: at the first line of a paragraph on the ;; same line as an item, apply function on that item instead. (when (eq type 'paragraph) (let ((parent (org-element-property :parent context))) (when (and (eq (org-element-type parent) 'item) - (= (point-at-bol) (org-element-property :begin parent))) + (= (line-beginning-position) + (org-element-property :begin parent))) (setq context parent type 'item)))) ;; Act according to type of element or object at point. (case type @@ -20352,7 +21139,7 @@ This command does many different things, depending on context: (item ;; At an item: a double C-u set checkbox to "[-]" ;; unconditionally, whereas a single one will toggle its - ;; presence. Without an universal argument, if the item + ;; presence. Without a universal argument, if the item ;; has a checkbox, toggle it. Otherwise repair the list. (let* ((box (org-element-property :checkbox context)) (struct (org-element-property :structure context)) @@ -20439,7 +21226,8 @@ This command does many different things, depending on context: ;; a `table.el' type, just give up. At a table row or ;; cell, maybe recalculate line but always align table. (if (eq (org-element-property :type context) 'table.el) - (message "Use C-c ' to edit table.el tables") + (message "%s" (substitute-command-keys "\\\ +Use \\[org-edit-special] to edit table.el tables")) (let ((org-enable-table-editor t)) (if (or (eq type 'table) ;; Check if point is at a TBLFM line. @@ -20476,11 +21264,44 @@ This command does many different things, depending on context: (interactive) (if (not org-finish-function) (progn - (hide-subtree) - (call-interactively 'show-branches)) + (outline-hide-subtree) + (call-interactively 'outline-show-branches)) (let ((org-note-abort t)) (funcall org-finish-function)))) +(defun org-delete-indentation (&optional ARG) + "Join current line to previous and fix whitespace at join. + +If previous line is a headline add to headline title. Otherwise +the function calls `delete-indentation'. + +With argument, join this line to following line." + (interactive "*P") + (if (save-excursion + (if ARG (beginning-of-line) + (forward-line -1)) + (looking-at org-complex-heading-regexp)) + ;; At headline. + (let ((tags-column (when (match-beginning 5) + (save-excursion (goto-char (match-beginning 5)) + (current-column)))) + (string (concat " " (progn (when ARG (forward-line 1)) + (org-trim (delete-and-extract-region + (line-beginning-position) + (line-end-position))))))) + (unless (bobp) (delete-region (point) (1- (point)))) + (goto-char (or (match-end 4) + (match-beginning 5) + (match-end 0))) + (skip-chars-backward " \t") + (save-excursion (insert string)) + ;; Adjust alignment of tags. + (when tags-column + (org-align-tags-here (if org-auto-align-tags + org-tags-column + tags-column)))) + (delete-indentation ARG))) + (defun org-open-line (n) "Insert a new row in tables, call `open-line' elsewhere. If `org-special-ctrl-o' is nil, just call `open-line' everywhere." @@ -20495,43 +21316,67 @@ If `org-special-ctrl-o' is nil, just call `open-line' everywhere." (defun org-return (&optional indent) "Goto next table row or insert a newline. + Calls `org-table-next-row' or `newline', depending on context. -See the individual commands for more information." + +When optional INDENT argument is non-nil, call +`newline-and-indent' instead of `newline'. + +When `org-return-follows-link' is non-nil and point is on +a timestamp or a link, call `org-open-at-point'. However, it +will not happen if point is in a table or on a \"dead\" +object (e.g., within a comment). In these case, you need to use +`org-open-at-point' directly." (interactive) - (let (org-ts-what) + (let ((context (if org-return-follows-link (org-element-context) + (org-element-at-point)))) (cond - ((or (bobp) (org-in-src-block-p)) - (if indent (newline-and-indent) (newline))) - ((org-at-table-p) + ;; In a table, call `org-table-next-row'. + ((or (and (eq (org-element-type context) 'table) + (>= (point) (org-element-property :contents-begin context)) + (< (point) (org-element-property :contents-end context))) + (org-element-lineage context '(table-row table-cell) t)) (org-table-justify-field-maybe) - (call-interactively 'org-table-next-row)) - ;; when `newline-and-indent' is called within a list, make sure - ;; text moved stays inside the item. - ((and (org-in-item-p) indent) - (if (and (org-at-item-p) (>= (point) (match-end 0))) - (progn - (save-match-data (newline)) - (org-indent-line-to (length (match-string 0)))) - (let ((ind (org-get-indentation))) - (newline) - (if (org-looking-back org-list-end-re) - (org-indent-line) - (org-indent-line-to ind))))) + (call-interactively #'org-table-next-row)) + ;; On a link or a timestamp, call `org-open-line' if + ;; `org-return-follows-link' allows it. Tolerate fuzzy + ;; locations, e.g., in a comment, as `org-open-line'. ((and org-return-follows-link - (org-at-timestamp-p t) - (not (eq org-ts-what 'after))) - (org-follow-timestamp-link)) - ((and org-return-follows-link - (let ((tprop (get-text-property (point) 'face))) - (or (eq tprop 'org-link) - (and (listp tprop) (memq 'org-link tprop))))) - (call-interactively 'org-open-at-point)) - ((and (org-at-heading-p) - (looking-at - (org-re "\\([ \t]+\\(:[[:alnum:]_@#%:]+:\\)\\)[ \t]*$"))) - (org-show-entry) - (end-of-line 1) - (newline)) + (or (org-at-timestamp-p t) + (org-at-date-range-p t) + (org-in-regexp org-any-link-re))) + (call-interactively #'org-open-at-point)) + ;; Insert newline in heading, but preserve tags. + ((and (not (bolp)) + (save-excursion (beginning-of-line) + (looking-at org-complex-heading-regexp))) + ;; At headline. Split line. However, if point is on keyword, + ;; priority cookie or tags, do not break any of them: add + ;; a newline after the headline instead. + (let ((tags-column (and (match-beginning 5) + (save-excursion (goto-char (match-beginning 5)) + (current-column)))) + (string + (when (and (match-end 4) + (>= (point) + (or (match-end 3) (match-end 2) (1+ (match-end 1)))) + (<= (point) (match-end 4))) + (delete-and-extract-region (point) (match-end 4))))) + (when (and tags-column string) ; Adjust tag alignment. + (org-align-tags-here + (if org-auto-align-tags org-tags-column tags-column))) + (end-of-line) + (org-show-entry) + (if indent (newline-and-indent) (newline)) + (when string (save-excursion (insert (org-trim string)))))) + ;; In a list, make sure indenting keeps trailing text within. + ((and indent + (not (eolp)) + (org-element-lineage context '(item))) + (let ((trailing-data + (delete-and-extract-region (point) (line-end-position)))) + (newline-and-indent) + (save-excursion (insert trailing-data)))) (t (if indent (newline-and-indent) (newline)))))) (defun org-return-indent () @@ -20645,6 +21490,8 @@ With a prefix argument ARG, change the region in a single item." ((org-at-heading-p) (let* ((bul (org-list-bullet-string "-")) (bul-len (length bul)) + (done (org-entry-is-done-p)) + (todo (org-entry-is-todo-p)) ;; Indentation of the first heading. It should be ;; relative to the indentation of its parent, if any. (start-ind (save-excursion @@ -20655,6 +21502,7 @@ With a prefix argument ARG, change the region in a single item." ;; Level of first heading. Further headings will be ;; compared to it to determine hierarchy in the list. (ref-level (org-reduced-level (org-outline-level)))) + (when (or done todo) (org-todo "")) (while (< (point) end) (let* ((level (org-reduced-level (org-outline-level))) (delta (max 0 (- level ref-level)))) @@ -20664,6 +21512,15 @@ With a prefix argument ARG, change the region in a single item." (when (< level ref-level) (setq ref-level level)) (replace-match bul t t) (org-indent-line-to (+ start-ind (* delta bul-len))) + (when (or done todo) + (let* ((struct (org-list-struct)) + (old (copy-tree struct))) + (org-list-set-checkbox (line-beginning-position) + struct + (if done "[X]" "[ ]")) + (org-list-write-struct struct + (org-list-parents-alist struct) + old))) ;; Ensure all text down to END (or SECTION-END) belongs ;; to the newly created item. (let ((section-end (save-excursion @@ -20676,19 +21533,19 @@ With a prefix argument ARG, change the region in a single item." ;; an item, and shift indentation of others lines to ;; set them as item's body. (arg (let* ((bul (org-list-bullet-string "-")) - (bul-len (length bul)) - (ref-ind (org-get-indentation))) - (skip-chars-forward " \t") - (insert bul) - (forward-line) - (while (< (point) end) - ;; Ensure that lines less indented than first one - ;; still get included in item body. - (funcall shift-text - (+ ref-ind bul-len) - (min end (save-excursion (or (outline-next-heading) - (point))))) - (forward-line)))) + (bul-len (length bul)) + (ref-ind (org-get-indentation))) + (skip-chars-forward " \t") + (insert bul) + (forward-line) + (while (< (point) end) + ;; Ensure that lines less indented than first one + ;; still get included in item body. + (funcall shift-text + (+ ref-ind bul-len) + (min end (save-excursion (or (outline-next-heading) + (point))))) + (forward-line)))) ;; Case 4. Normal line without ARG: turn each non-item line ;; into an item. (t @@ -20764,31 +21621,16 @@ number of stars to add." ;; Case 2. Started at an item: change items into headlines. ;; One star will be added by `org-list-to-subtree'. ((org-at-item-p) - (let* ((stars (make-string - ;; subtract the star that will be added again by - ;; `org-list-to-subtree' - (if (numberp nstars) (1- nstars) - (or (org-current-level) 0)) - ?*)) - (add-stars - (cond (nstars "") ; stars from prefix only - ((equal stars "") "") ; before first heading - (org-odd-levels-only "*") ; inside heading, odd - (t "")))) ; inside heading, oddeven - (while (< (point) end) - (when (org-at-item-p) - ;; Pay attention to cases when region ends before list. - (let* ((struct (org-list-struct)) - (list-end (min (org-list-get-bottom-point struct) (1+ end)))) - (save-restriction - (narrow-to-region (point) list-end) - (insert - (org-list-to-subtree - (org-list-parse-list t) - '(:istart (concat stars add-stars (funcall get-stars depth)) - :icount (concat stars add-stars (funcall get-stars depth))))))) - (setq toggled t)) - (forward-line)))) + (while (< (point) end) + (when (org-at-item-p) + ;; Pay attention to cases when region ends before list. + (let* ((struct (org-list-struct)) + (list-end (min (org-list-get-bottom-point struct) (1+ end)))) + (save-restriction + (narrow-to-region (point) list-end) + (insert (org-list-to-subtree (org-list-parse-list t))))) + (setq toggled t)) + (forward-line))) ;; Case 3. Started at normal text: make every line an heading, ;; skipping headlines and items. (t (let* ((stars @@ -20808,24 +21650,15 @@ number of stars to add." (forward-line))))))) (unless toggled (message "Cannot toggle heading from here")))) -(defun org-meta-return (&optional arg) +(defun org-meta-return (&optional _arg) "Insert a new heading or wrap a region in a table. Calls `org-insert-heading' or `org-table-wrap-region', depending on context. See the individual commands for more information." - (interactive "P") + (interactive) (org-check-before-invisible-edit 'insert) (or (run-hook-with-args-until-success 'org-metareturn-hook) - (let* ((element (org-element-at-point)) - (type (org-element-type element))) - (when (eq type 'table-row) - (setq element (org-element-property :parent element)) - (setq type 'table)) - (if (and (eq type 'table) - (eq (org-element-property :type element) 'org) - (>= (point) (org-element-property :contents-begin element)) - (< (point) (org-element-property :contents-end element))) - (call-interactively 'org-table-wrap-region) - (call-interactively 'org-insert-heading))))) + (call-interactively (if (org-at-table-p) #'org-table-wrap-region + #'org-insert-heading)))) ;;; Menu entries @@ -20893,7 +21726,11 @@ on context. See the individual commands for more information." ["Import from File" org-table-import (not (org-at-table-p))] ["Export to File" org-table-export (org-at-table-p)] "--" - ["Create/Convert from/to table.el" org-table-create-with-table.el t])) + ["Create/Convert from/to table.el" org-table-create-with-table.el t] + "--" + ("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"]))) (easy-menu-define org-org-menu org-mode-map "Org menu" '("Org" @@ -20902,7 +21739,7 @@ on context. See the individual commands for more information." ["Cycle Global Visibility" org-shifttab :active (not (org-at-table-p))] ["Sparse Tree..." org-sparse-tree t] ["Reveal Context" org-reveal t] - ["Show All" show-all t] + ["Show All" outline-show-all t] "--" ["Subtree to indirect buffer" org-tree-to-indirect-buffer t]) "--" @@ -20918,8 +21755,8 @@ on context. See the individual commands for more information." ("Edit Structure" ["Refile Subtree" org-refile (org-in-subtree-not-table-p)] "--" - ["Move Subtree Up" org-shiftmetaup (org-in-subtree-not-table-p)] - ["Move Subtree Down" org-shiftmetadown (org-in-subtree-not-table-p)] + ["Move Subtree Up" org-metaup (org-at-heading-p)] + ["Move Subtree Down" org-metadown (org-at-heading-p)] "--" ["Copy Subtree" org-copy-special (org-in-subtree-not-table-p)] ["Cut Subtree" org-cut-special (org-in-subtree-not-table-p)] @@ -20947,7 +21784,7 @@ on context. See the individual commands for more information." ("Archive" ["Archive (default method)" org-archive-subtree-default (org-in-subtree-not-table-p)] "--" - ["Move Subtree to Archive file" org-advertized-archive-subtree (org-in-subtree-not-table-p)] + ["Move Subtree to Archive file" org-archive-subtree (org-in-subtree-not-table-p)] ["Toggle ARCHIVE tag" org-toggle-archive-tag (org-in-subtree-not-table-p)] ["Move subtree to Archive sibling" org-archive-to-archive-sibling (org-in-subtree-not-table-p)] ) @@ -21110,6 +21947,7 @@ output buffer into your mail program, as it gives us important information about your Org-mode version and configuration." (interactive) (require 'reporter) + (defvar reporter-prompt-for-summary-p) (org-load-modules-maybe) (org-require-autoloaded-modules) (let ((reporter-prompt-for-summary-p "Bug report subject: ")) @@ -21273,9 +22111,9 @@ With prefix arg UNCOMPILED, load the uncompiled versions." ;;; Generally useful functions -(defun org-get-at-bol (property) - "Get text property PROPERTY at beginning of line." - (get-text-property (point-at-bol) property)) +(defsubst org-get-at-eol (property n) + "Get text property PROPERTY at the end of line less N characters." + (get-text-property (- (point-at-eol) n) property)) (defun org-find-text-property-in-string (prop s) "Return the first non-nil value of property PROP in string S." @@ -21314,17 +22152,6 @@ With prefix arg UNCOMPILED, load the uncompiled versions." (>= (match-end 0) pos) start)))) -(defun org-in-commented-line () - "Is point in a line starting with `#'?" - (equal (char-after (point-at-bol)) ?#)) - -(defun org-in-indented-comment-line () - "Is point in a line starting with `#' after some white space?" - (save-excursion - (save-match-data - (goto-char (point-at-bol)) - (looking-at "[ \t]*#")))) - (defun org-in-verbatim-emphasis () (save-match-data (and (org-in-regexp org-emph-re 2) @@ -21369,11 +22196,13 @@ upon the next fontification round." 'invisible 'org-link s)) (setq s (concat (substring s 0 b) (substring s (or (next-single-property-change - b 'invisible s) (length s))))))) + b 'invisible s) + (length s))))))) (while (setq b (text-property-any 0 (length s) 'org-cwidth t s)) (setq s (concat (substring s 0 b) (substring s (or (next-single-property-change - b 'org-cwidth s) (length s)))))) + b 'org-cwidth s) + (length s)))))) (setq l (string-width s) b -1) (while (setq b (text-property-any (1+ b) (length s) 'org-dwidth t s)) (setq l (- l (get-text-property b 'org-dwidth-n s)))) @@ -21470,11 +22299,9 @@ N may optionally be the number of spaces to remove." (defun org-fill-template (template alist) "Find each %key of ALIST in TEMPLATE and replace it." - (let ((case-fold-search nil) - entry key value) - (setq alist (sort (copy-sequence alist) - (lambda (a b) (< (length (car a)) (length (car b)))))) - (while (setq entry (pop alist)) + (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))) @@ -21488,12 +22315,6 @@ N may optionally be the number of spaces to remove." (or (buffer-base-buffer buffer) buffer))) -(defun org-trim (s) - "Remove whitespace at beginning and end of string." - (if (string-match "\\`[ \t\n\r]+" s) (setq s (replace-match "" t t s))) - (if (string-match "[ \t\n\r]+\\'" s) (setq s (replace-match "" t t s))) - s) - (defun org-wrap (string &optional width lines) "Wrap string to either a number of lines, or a width in characters. If WIDTH is non-nil, the string is wrapped to that width, however many lines @@ -21531,13 +22352,12 @@ The return value is a list of lines, without newlines at the end." (defun org-split-string (string &optional separators) "Splits STRING into substrings at SEPARATORS. +SEPARATORS is a regular expression. No empty strings are returned if there are matches at the beginning and end of string." - (let ((rexp (or separators "[ \f\t\n\r\v]+")) - (start 0) - notfirst - (list nil)) - (while (and (string-match rexp string + ;; FIXME: why not use (split-string STRING SEPARATORS t)? + (let ((start 0) notfirst list) + (while (and (string-match (or separators "[ \f\t\n\r\v]+") string (if (and notfirst (= start (match-beginning 0)) (< start (length string))) @@ -21547,14 +22367,10 @@ and end of string." (or (eq (match-beginning 0) 0) (and (eq (match-beginning 0) (match-end 0)) (eq (match-beginning 0) start)) - (setq list - (cons (substring string start (match-beginning 0)) - list))) + (push (substring string start (match-beginning 0)) list)) (setq start (match-end 0))) (or (eq start (length string)) - (setq list - (cons (substring string start) - list))) + (push (substring string start) list)) (nreverse list))) (defun org-quote-vert (s) @@ -21572,9 +22388,7 @@ and end of string." When INSIDE is non-nil, don't consider we are within a src block when point is at #+BEGIN_SRC or #+END_SRC." (let ((case-fold-search t) ov) - (or (and (setq ov (overlays-at (point))) - (memq 'org-block-background - (overlay-properties (car ov)))) + (or (and (eq (get-char-property (point) 'src-block) t)) (and (not inside) (save-match-data (save-excursion @@ -21602,7 +22416,7 @@ contexts are: :clocktable in a clocktable :src-block in a source block :link on a hyperlink -:keyword on a keyword: SCHEDULED, DEADLINE, CLOSE, COMMENT, QUOTE. +:keyword on a keyword: SCHEDULED, DEADLINE, CLOSE, COMMENT. :target on a <> :radio-target on a <<>> :latex-fragment on a LaTeX fragment @@ -21652,16 +22466,16 @@ and :keyword." ;; New the "medium" contexts: clocktables, source blocks (cond ((org-in-clocktable-p) (push (list :clocktable - (and (or (looking-at "#\\+BEGIN: clocktable") - (search-backward "#+BEGIN: clocktable" nil t)) - (match-beginning 0)) - (and (re-search-forward "#\\+END:?" nil t) + (and (or (looking-at "[ \t]*\\(#\\+BEGIN: clocktable\\)") + (re-search-backward "[ \t]*\\(#+BEGIN: clocktable\\)" nil t)) + (match-beginning 1)) + (and (re-search-forward "[ \t]*#\\+END:?" nil t) (match-end 0))) clist)) ((org-in-src-block-p) (push (list :src-block - (and (or (looking-at "#\\+BEGIN_SRC") - (search-backward "#+BEGIN_SRC" nil t)) - (match-beginning 0)) + (and (or (looking-at "[ \t]*\\(#\\+BEGIN_SRC\\)") + (re-search-backward "[ \t]*\\(#+BEGIN_SRC\\)" nil t)) + (match-beginning 1)) (and (search-forward "#+END_SRC" nil t) (match-beginning 0))) clist)))) (goto-char p) @@ -21684,11 +22498,12 @@ and :keyword." (if (looking-at org-radio-target-regexp) (push (org-point-in-group p 0 :radio-target) clist)) (goto-char p)) - ((setq o (car (delq nil - (mapcar - (lambda (x) - (if (memq x org-latex-fragment-image-overlays) x)) - (overlays-at (point)))))) + ((setq o (org-some + (lambda (o) + (and (eq (overlay-get o 'org-overlay-type) + 'org-latex-overlay) + o)) + (overlays-at (point)))) (push (list :latex-fragment (overlay-start o) (overlay-end o)) clist) (push (list :latex-preview @@ -21700,13 +22515,13 @@ and :keyword." (setq clist (nreverse (delq nil clist))) clist)) -;; FIXME: Compare with at-regexp-p Do we need both? (defun org-in-regexp (re &optional nlines visually) - "Check if point is inside a match of regexp. -Normally only the current line is checked, but you can include NLINES extra -lines both before and after point into the search. -If VISUALLY is set, require that the cursor is not after the match but -really on, so that the block visually is on the match." + "Check if point is inside a match of RE. + +Normally only the current line is checked, but you can include +NLINES extra lines after point into the search. If VISUALLY is +set, require that the cursor is not after the match but really +on, so that the block visually is on the match." (catch 'exit (let ((pos (point)) (eol (point-at-eol (+ 1 (or nlines 0)))) @@ -21717,18 +22532,8 @@ really on, so that the block visually is on the match." (if (and (<= (match-beginning 0) pos) (>= (+ inc (match-end 0)) pos)) (throw 'exit (cons (match-beginning 0) (match-end 0))))))))) - -(defun org-at-regexp-p (regexp) - "Is point inside a match of REGEXP in the current line?" - (catch 'exit - (save-excursion - (let ((pos (point)) (end (point-at-eol))) - (beginning-of-line 1) - (while (re-search-forward regexp end t) - (if (and (<= (match-beginning 0) pos) - (>= (match-end 0) pos)) - (throw 'exit t))) - nil)))) +(define-obsolete-function-alias 'org-at-regexp-p 'org-in-regexp + "Org mode 8.3") (defun org-between-regexps-p (start-re end-re &optional lim-up lim-down) "Non-nil when point is between matches of START-RE and END-RE. @@ -21749,7 +22554,7 @@ position before START-RE (resp. after END-RE)." (save-excursion ;; Point is on a block when on START-RE or if START-RE can be ;; found before it... - (and (or (org-at-regexp-p start-re) + (and (or (org-in-regexp start-re) (re-search-backward start-re limit-up t)) (setq beg (match-beginning 0)) ;; ... and END-RE after it... @@ -21785,34 +22590,24 @@ block from point." names)) nil))) -(defun org-in-drawer-p () - "Is point within a drawer?" - (save-match-data - (let ((case-fold-search t) - (lim-up (save-excursion (outline-previous-heading))) - (lim-down (save-excursion (outline-next-heading)))) - (org-between-regexps-p - (concat "^[ \t]*:" (regexp-opt org-drawers) ":") - "^[ \t]*:end:.*$" - lim-up lim-down)))) - -(defun org-occur-in-agenda-files (regexp &optional nlines) +(defun org-occur-in-agenda-files (regexp &optional _nlines) "Call `multi-occur' with buffers for all agenda files." - (interactive "sOrg-files matching: \np") + (interactive "sOrg-files matching: ") (let* ((files (org-agenda-files)) - (tnames (mapcar 'file-truename files)) - (extra org-agenda-text-search-extra-files) - f) + (tnames (mapcar #'file-truename files)) + (extra org-agenda-text-search-extra-files)) (when (eq (car extra) 'agenda-archives) (setq extra (cdr extra)) (setq files (org-add-archive-files files))) - (while (setq f (pop extra)) + (dolist (f extra) (unless (member (file-truename f) tnames) - (add-to-list 'files f 'append) - (add-to-list 'tnames (file-truename f) 'append))) + (unless (member f files) (setq files (append files (list f)))) + (setq tnames (append tnames (list (file-truename f)))))) (multi-occur (mapcar (lambda (x) (with-current-buffer + ;; FIXME: Why not just (find-file-noselect x)? + ;; Is it to avoid the "revert buffer" prompt? (or (get-file-buffer x) (find-file-noselect x)) (widen) (current-buffer))) @@ -21827,13 +22622,13 @@ block from point." (org-reveal)))) ;; Emacs 22 (defadvice occur-mode-goto-occurrence - (after org-occur-reveal activate) + (after org-occur-reveal activate) (and (derived-mode-p 'org-mode) (org-reveal))) (defadvice occur-mode-goto-occurrence-other-window - (after org-occur-reveal activate) + (after org-occur-reveal activate) (and (derived-mode-p 'org-mode) (org-reveal))) (defadvice occur-mode-display-occurrence - (after org-occur-reveal activate) + (after org-occur-reveal activate) (when (derived-mode-p 'org-mode) (let ((pos (occur-mode-find-occurrence))) (with-current-buffer (marker-buffer pos) @@ -21862,8 +22657,8 @@ for the search purpose." For example, in this alist: -\(org-uniquify-alist '((a 1) (b 2) (a 3))) - => '((a 1 3) (b 2)) +\(org-uniquify-alist \\='((a 1) (b 2) (a 3))) + => \\='((a 1 3) (b 2)) merge (a 1) and (a 3) into (a 1 3). @@ -21877,7 +22672,7 @@ The function returns the new ALIST." (setq n (cons (car e) (append (cdr (assoc (car e) rtn)) (cdr e)))) (setq rtn (assq-delete-all (car e) rtn)) (push n rtn)))) - alist) + alist) rtn)) (defun org-delete-all (elts list) @@ -21997,7 +22792,7 @@ so values can contain further %-escapes if they are define later in TABLE." (case-fold-search nil) (pchg 0) e re rpl) - (while (setq e (pop tbl)) + (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))) @@ -22060,14 +22855,15 @@ 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." - (let (date day defd tp tm hod mod) + (let (date day defd tp hod mod) (when with-time (setq tp (get-text-property (point) 'time)) (when (and tp (string-match "\\([0-9][0-9]\\):\\([0-9][0-9]\\)" tp)) (setq hod (string-to-number (match-string 1 tp)) mod (string-to-number (match-string 2 tp)))) - (or tp (setq hod (nth 2 (decode-time (current-time))) - mod (nth 1 (decode-time (current-time)))))) + (or tp (let ((now (decode-time))) + (setq hod (nth 2 now) + mod (nth 1 now))))) (cond ((eq major-mode 'calendar-mode) (setq date (calendar-cursor-to-date) @@ -22099,169 +22895,344 @@ hierarchy of headlines by UP levels before marking the subtree." ;;; Indentation +(defun org--get-expected-indentation (element contentsp) + "Expected indentation column for current line, according to ELEMENT. +ELEMENT is an element containing point. CONTENTSP is non-nil +when indentation is to be computed according to contents of +ELEMENT." + (let ((type (org-element-type element)) + (start (org-element-property :begin element)) + (post-affiliated (org-element-property :post-affiliated element))) + (org-with-wide-buffer + (cond + (contentsp + (case type + ((diary-sexp footnote-definition) 0) + ((headline inlinetask nil) + (if (not org-adapt-indentation) 0 + (let ((level (org-current-level))) + (if level (1+ level) 0)))) + ((item plain-list) (org-list-item-body-column post-affiliated)) + (t + (goto-char start) + (org-get-indentation)))) + ((memq type '(headline inlinetask nil)) + (if (save-excursion (beginning-of-line) (looking-at "[ \t]*$")) + (org--get-expected-indentation element t) + 0)) + ((memq type '(diary-sexp footnote-definition)) 0) + ;; First paragraph of a footnote definition or an item. + ;; Indent like parent. + ((< (line-beginning-position) start) + (org--get-expected-indentation + (org-element-property :parent element) t)) + ;; At first line: indent according to previous sibling, if any, + ;; ignoring footnote definitions and inline tasks, or parent's + ;; contents. + ((= (line-beginning-position) start) + (catch 'exit + (while t + (if (= (point-min) start) (throw 'exit 0) + (goto-char (1- start)) + (let* ((previous (org-element-at-point)) + (parent previous)) + (while (and parent (<= (org-element-property :end parent) start)) + (setq previous parent + parent (org-element-property :parent parent))) + (cond + ((not previous) (throw 'exit 0)) + ((> (org-element-property :end previous) start) + (throw 'exit (org--get-expected-indentation previous t))) + ((memq (org-element-type previous) + '(footnote-definition inlinetask)) + (setq start (org-element-property :begin previous))) + (t (goto-char (org-element-property :begin previous)) + (throw 'exit + (if (bolp) (org-get-indentation) + ;; At first paragraph in an item or + ;; a footnote definition. + (org--get-expected-indentation + (org-element-property :parent previous) t)))))))))) + ;; Otherwise, move to the first non-blank line above. + (t + (beginning-of-line) + (let ((pos (point))) + (skip-chars-backward " \r\t\n") + (cond + ;; Two blank lines end a footnote definition or a plain + ;; list. When we indent an empty line after them, the + ;; containing list or footnote definition is over, so it + ;; qualifies as a previous sibling. Therefore, we indent + ;; like its first line. + ((and (memq type '(footnote-definition plain-list)) + (> (count-lines (point) pos) 2)) + (goto-char start) + (org-get-indentation)) + ;; Line above is the first one of a paragraph at the + ;; beginning of an item or a footnote definition. Indent + ;; like parent. + ((< (line-beginning-position) start) + (org--get-expected-indentation + (org-element-property :parent element) t)) + ;; Line above is the beginning of an element, i.e., point + ;; was originally on the blank lines between element's start + ;; and contents. + ((= (line-beginning-position) post-affiliated) + (org--get-expected-indentation element t)) + ;; POS is after contents in a greater element. Indent like + ;; the beginning of the element. + ;; + ;; As a special case, if point is at the end of a footnote + ;; definition or an item, indent like the very last element + ;; within. + ((and (not (eq type 'paragraph)) + (let ((cend (org-element-property :contents-end element))) + (and cend (<= cend pos)))) + (if (memq type '(footnote-definition item plain-list)) + (let ((last (org-element-at-point))) + (org--get-expected-indentation + last + (memq (org-element-type last) + '(footnote-definition item plain-list)))) + (goto-char start) + (org-get-indentation))) + ;; In any other case, indent like the current line. + (t (org-get-indentation))))))))) + +(defun org--align-node-property () + "Align node property at point. +Alignment is done according to `org-property-format', which see." + (when (save-excursion + (beginning-of-line) + (looking-at org-property-re)) + (replace-match + (concat (match-string 4) + (org-trim + (format org-property-format (match-string 1) (match-string 3)))) + t t))) + (defun org-indent-line () - "Indent line depending on context." + "Indent line depending on context. + +Indentation is done according to the following rules: + + - Footnote definitions, diary sexps, headlines and inline tasks + have to start at column 0. + + - On the very first line of an element, consider, in order, the + next rules until one matches: + + 1. If there's a sibling element before, ignoring footnote + 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. + + 3. Otherwise, indent relatively to current level, if + `org-adapt-indentation' is non-nil, or to left margin. + + - On a blank line at the end of an element, indent according to + the type of the element. More precisely + + 1. If element is a plain list, an item, or a footnote + definition, indent like the very last element within. + + 2. If element is a paragraph, indent like its last non blank + line. + + 3. Otherwise, indent like its very first line. + + - In the code part of a source block, use language major mode + to indent current line if `org-src-tab-acts-natively' is + non-nil. If it is nil, do nothing. + + - Otherwise, indent like the first non-blank line above. + +The function doesn't indent an item as it could break the whole +list structure. Instead, use \\\\[org-shiftmetaleft] or \ +\\[org-shiftmetaright]. + +Also align node properties according to `org-property-format'." (interactive) - (let* ((pos (point)) - (itemp (org-at-item-p)) - (case-fold-search t) - (org-drawer-regexp (or org-drawer-regexp "\000")) - (inline-task-p (and (featurep 'org-inlinetask) - (org-inlinetask-in-task-p))) - (inline-re (and inline-task-p - (org-inlinetask-outline-regexp))) - column) - (if (and orgstruct-is-++ (eq pos (point))) - (let ((indent-line-function (cadadr (assoc 'indent-line-function org-fb-vars)))) - (indent-according-to-mode)) - (beginning-of-line 1) - (cond - ;; Headings - ((looking-at org-outline-regexp) (setq column 0)) - ;; Footnote definition - ((looking-at org-footnote-definition-re) (setq column 0)) - ;; Literal examples - ((looking-at "[ \t]*:\\( \\|$\\)") - (setq column (org-get-indentation))) ; do nothing - ;; Lists - ((ignore-errors (goto-char (org-in-item-p))) - (setq column (if itemp - (org-get-indentation) - (org-list-item-body-column (point)))) - (goto-char pos)) - ;; Drawers - ((and (looking-at "[ \t]*:END:") - (save-excursion (re-search-backward org-drawer-regexp nil t))) - (save-excursion - (goto-char (1- (match-beginning 1))) - (setq column (current-column)))) - ;; Special blocks - ((and (looking-at "[ \t]*#\\+end_\\([a-z]+\\)") - (save-excursion - (re-search-backward - (concat "^[ \t]*#\\+begin_" (downcase (match-string 1))) nil t))) - (setq column (org-get-indentation (match-string 0)))) - ((and (not (looking-at "[ \t]*#\\+begin_")) - (org-between-regexps-p "^[ \t]*#\\+begin_" "[ \t]*#\\+end_")) - (save-excursion - (re-search-backward "^[ \t]*#\\+begin_\\([a-z]+\\)" nil t)) - (setq column - (cond ((equal (downcase (match-string 1)) "src") - ;; src blocks: let `org-edit-src-exit' handle them - (org-get-indentation)) - ((equal (downcase (match-string 1)) "example") - (max (org-get-indentation) - (org-get-indentation (match-string 0)))) - (t - (org-get-indentation (match-string 0)))))) - ;; This line has nothing special, look at the previous relevant - ;; line to compute indentation - (t - (beginning-of-line 0) - (while (and (not (bobp)) - (not (looking-at org-table-line-regexp)) - (not (looking-at org-drawer-regexp)) - ;; When point started in an inline task, do not move - ;; above task starting line. - (not (and inline-task-p (looking-at inline-re))) - ;; Skip drawers, blocks, empty lines, verbatim, - ;; comments, tables, footnotes definitions, lists, - ;; inline tasks. - (or (and (looking-at "[ \t]*:END:") - (re-search-backward org-drawer-regexp nil t)) - (and (looking-at "[ \t]*#\\+end_") - (re-search-backward "[ \t]*#\\+begin_"nil t)) - (looking-at "[ \t]*[\n:#|]") - (looking-at org-footnote-definition-re) - (and (not inline-task-p) - (featurep 'org-inlinetask) - (org-inlinetask-in-task-p) - (or (org-inlinetask-goto-beginning) t)))) - (beginning-of-line 0)) - (cond - ;; There was a list item above. - ((ignore-errors (goto-char (org-in-item-p))) - (goto-char (org-list-get-top-point (org-list-struct))) - (setq column (org-get-indentation))) - ;; There was an heading above. - ((looking-at "\\*+[ \t]+") - (if (not org-adapt-indentation) - (setq column 0) - (goto-char (match-end 0)) - (setq column (current-column)))) - ;; A drawer had started and is unfinished - ((looking-at org-drawer-regexp) - (goto-char (1- (match-beginning 1))) - (setq column (current-column))) - ;; Else, nothing noticeable found: get indentation and go on. - (t (setq column (org-get-indentation)))))) - ;; Now apply indentation and move cursor accordingly - (goto-char pos) - (if (<= (current-column) (current-indentation)) - (org-indent-line-to column) - (save-excursion (org-indent-line-to column))) - ;; Special polishing for properties, see `org-property-format' - (setq column (current-column)) - (beginning-of-line 1) - (if (looking-at org-property-re) - (replace-match (concat (match-string 4) - (format org-property-format - (match-string 1) (match-string 3))) - t t)) - (org-move-to-column column)))) + (cond + (orgstruct-is-++ + (let ((indent-line-function + (cadadr (assq 'indent-line-function org-fb-vars)))) + (indent-according-to-mode))) + ((org-at-heading-p) 'noindent) + (t + (let* ((element (save-excursion (beginning-of-line) (org-element-at-point))) + (type (org-element-type element))) + (cond ((and (memq type '(plain-list item)) + (= (line-beginning-position) + (org-element-property :post-affiliated element))) + 'noindent) + ((and (eq type 'src-block) + org-src-tab-acts-natively + (> (line-beginning-position) + (org-element-property :post-affiliated element)) + (< (line-beginning-position) + (org-with-wide-buffer + (goto-char (org-element-property :end element)) + (skip-chars-backward " \r\t\n") + (line-beginning-position)))) + (org-babel-do-key-sequence-in-edit-buffer (kbd "TAB"))) + (t + (let ((column (org--get-expected-indentation element nil))) + ;; Preserve current column. + (if (<= (current-column) (current-indentation)) + (org-indent-line-to column) + (save-excursion (org-indent-line-to column)))) + ;; Align node property. Also preserve current column. + (when (eq type 'node-property) + (let ((column (current-column))) + (org--align-node-property) + (org-move-to-column column))))))))) + +(defun org-indent-region (start end) + "Indent each non-blank line in the region. +Called from a program, START and END specify the region to +indent. The function will not indent contents of example blocks, +verse blocks and export blocks as leading white spaces are +assumed to be significant there." + (interactive "r") + (save-excursion + (goto-char start) + (skip-chars-forward " \r\t\n") + (unless (eobp) (beginning-of-line)) + (let ((indent-to + (lambda (ind pos) + ;; Set IND as indentation for all lines between point and + ;; POS or END, whichever comes first. Blank lines are + ;; ignored. Leave point after POS once done. + (let ((limit (copy-marker (min end pos)))) + (while (< (point) limit) + (unless (org-looking-at-p "[ \t]*$") (org-indent-line-to ind)) + (forward-line)) + (set-marker limit nil)))) + (end (copy-marker end))) + (while (< (point) end) + (if (or (org-looking-at-p " \r\t\n") (org-at-heading-p)) (forward-line) + (let* ((element (org-element-at-point)) + (type (org-element-type element)) + (element-end (copy-marker (org-element-property :end element))) + (ind (org--get-expected-indentation element nil))) + (cond + ((or (memq type '(paragraph table table-row)) + (not (or (org-element-property :contents-begin element) + (memq type + '(example-block export-block src-block))))) + ;; Elements here are indented as a single block. Also + ;; align node properties. + (when (eq type 'node-property) + (org--align-node-property) + (beginning-of-line)) + (funcall indent-to ind element-end)) + (t + ;; Elements in this category consist of three parts: + ;; before the contents, the contents, and after the + ;; contents. The contents are treated specially, + ;; according to the element type, or not indented at + ;; all. Other parts are indented as a single block. + (let* ((post (copy-marker + (org-element-property :post-affiliated element))) + (cbeg + (copy-marker + (cond + ((not (org-element-property :contents-begin element)) + ;; Fake contents for source blocks. + (org-with-wide-buffer + (goto-char post) + (forward-line) + (point))) + ((memq type '(footnote-definition item plain-list)) + ;; Contents in these elements could start on + ;; the same line as the beginning of the + ;; element. Make sure we start indenting + ;; from the second line. + (org-with-wide-buffer + (goto-char post) + (end-of-line) + (skip-chars-forward " \r\t\n") + (if (eobp) (point) (line-beginning-position)))) + (t (org-element-property :contents-begin element))))) + (cend (copy-marker + (or (org-element-property :contents-end element) + ;; Fake contents for source blocks. + (org-with-wide-buffer + (goto-char element-end) + (skip-chars-backward " \r\t\n") + (line-beginning-position))) + t))) + ;; Do not change items indentation individually as it + ;; might break the list as a whole. On the other + ;; hand, when at a plain list, indent it as a whole. + (cond ((eq type 'plain-list) + (let ((offset (- ind (org-get-indentation)))) + (unless (zerop offset) + (indent-rigidly (org-element-property :begin element) + (org-element-property :end element) + offset)) + (goto-char cbeg))) + ((eq type 'item) (goto-char cbeg)) + (t (funcall indent-to ind cbeg))) + (when (< (point) end) + (case type + ((example-block export-block verse-block)) + (src-block + ;; In a source block, indent source code + ;; according to language major mode, but only if + ;; `org-src-tab-acts-natively' is non-nil. + (when (and (< (point) end) org-src-tab-acts-natively) + (ignore-errors + (org-babel-do-in-edit-buffer + (indent-region (point-min) (point-max)))))) + (t (org-indent-region (point) (min cend end)))) + (goto-char (min cend end)) + (when (< (point) end) (funcall indent-to ind element-end))) + (set-marker post nil) + (set-marker cbeg nil) + (set-marker cend nil)))) + (set-marker element-end nil)))) + (set-marker end nil)))) (defun org-indent-drawer () "Indent the drawer at point." (interactive) - (let ((p (point)) - (e (and (save-excursion (re-search-forward ":END:" nil t)) - (match-end 0))) - (folded - (save-excursion - (end-of-line) - (when (overlays-at (point)) - (member 'invisible (overlay-properties - (car (overlays-at (point))))))))) - (when folded (org-cycle)) - (indent-for-tab-command) - (while (and (move-beginning-of-line 2) (< (point) e)) - (indent-for-tab-command)) - (goto-char p) - (when folded (org-cycle))) + (unless (save-excursion + (beginning-of-line) + (org-looking-at-p org-drawer-regexp)) + (user-error "Not at a drawer")) + (let ((element (org-element-at-point))) + (unless (memq (org-element-type element) '(drawer property-drawer)) + (user-error "Not at a drawer")) + (org-with-wide-buffer + (org-indent-region (org-element-property :begin element) + (org-element-property :end element)))) (message "Drawer at point indented")) (defun org-indent-block () "Indent the block at point." (interactive) - (let ((p (point)) - (case-fold-search t) - (e (and (save-excursion (re-search-forward "#\\+end_?\\(?:[a-z]+\\)?" nil t)) - (match-end 0))) - (folded - (save-excursion - (end-of-line) - (when (overlays-at (point)) - (member 'invisible (overlay-properties - (car (overlays-at (point))))))))) - (when folded (org-cycle)) - (indent-for-tab-command) - (while (and (move-beginning-of-line 2) (< (point) e)) - (indent-for-tab-command)) - (goto-char p) - (when folded (org-cycle))) + (unless (save-excursion + (beginning-of-line) + (let ((case-fold-search t)) + (org-looking-at-p "[ \t]*#\\+\\(begin\\|end\\)_"))) + (user-error "Not at a block")) + (let ((element (org-element-at-point))) + (unless (memq (org-element-type element) + '(comment-block center-block dynamic-block example-block + export-block quote-block special-block + src-block verse-block)) + (user-error "Not at a block")) + (org-with-wide-buffer + (org-indent-region (org-element-property :begin element) + (org-element-property :end element)))) (message "Block at point indented")) -(defun org-indent-region (start end) - "Indent region." - (interactive "r") - (save-excursion - (let ((line-end (org-current-line end))) - (goto-char start) - (while (< (org-current-line) line-end) - (cond ((org-in-src-block-p t) (org-src-native-tab-command-maybe)) - (t (call-interactively 'org-indent-line))) - (move-beginning-of-line 2))))) - ;;; Filling @@ -22322,69 +23293,64 @@ matches in paragraphs or comments, use it." (when (derived-mode-p 'message-mode) (save-excursion (beginning-of-line) - (cond ((or (not (message-in-body-p)) - (looking-at orgtbl-line-start-regexp)) - (throw 'exit nil)) + (cond ((not (message-in-body-p)) (throw 'exit nil)) + ((org-looking-at-p org-table-line-regexp) (throw 'exit nil)) ((looking-at message-cite-prefix-regexp) (throw 'exit (match-string-no-properties 0))) ((looking-at org-outline-regexp) - (throw 'exit (make-string (length (match-string 0)) ? )))))) + (throw 'exit (make-string (length (match-string 0)) ?\s)))))) (org-with-wide-buffer - (let* ((p (line-beginning-position)) - (element (save-excursion - (beginning-of-line) - (or (ignore-errors (org-element-at-point)) - (user-error "An element cannot be parsed line %d" - (line-number-at-pos (point)))))) - (type (org-element-type element)) - (post-affiliated (org-element-property :post-affiliated element))) - (unless (and post-affiliated (< p post-affiliated)) - (case type - (comment - (save-excursion - (beginning-of-line) - (looking-at "[ \t]*") - (concat (match-string 0) "# "))) - (footnote-definition "") - ((item plain-list) - (make-string (org-list-item-body-column - (or post-affiliated - (org-element-property :begin element))) - ? )) - (paragraph - ;; Fill prefix is usually the same as the current line, - ;; unless the paragraph is at the beginning of an item. - (let ((parent (org-element-property :parent element))) + (unless (org-at-heading-p) + (let* ((p (line-beginning-position)) + (element (save-excursion + (beginning-of-line) + (org-element-at-point))) + (type (org-element-type element)) + (post-affiliated (org-element-property :post-affiliated element))) + (unless (< p post-affiliated) + (case type + (comment (save-excursion (beginning-of-line) - (cond ((eq (org-element-type parent) 'item) - (make-string (org-list-item-body-column - (org-element-property :begin parent)) - ? )) - ((and adaptive-fill-regexp - ;; Locally disable - ;; `adaptive-fill-function' to let - ;; `fill-context-prefix' handle - ;; `adaptive-fill-regexp' variable. - (let (adaptive-fill-function) - (fill-context-prefix - post-affiliated - (org-element-property :end element))))) - ((looking-at "[ \t]+") (match-string 0)) - (t ""))))) - (comment-block - ;; Only fill contents if P is within block boundaries. - (let* ((cbeg (save-excursion (goto-char post-affiliated) - (forward-line) - (point))) - (cend (save-excursion - (goto-char (org-element-property :end element)) - (skip-chars-backward " \r\t\n") - (line-beginning-position)))) - (when (and (>= p cbeg) (< p cend)) - (if (save-excursion (beginning-of-line) (looking-at "[ \t]+")) - (match-string 0) - "")))))))))) + (looking-at "[ \t]*") + (concat (match-string 0) "# "))) + (footnote-definition "") + ((item plain-list) + (make-string (org-list-item-body-column post-affiliated) ?\s)) + (paragraph + ;; Fill prefix is usually the same as the current line, + ;; unless the paragraph is at the beginning of an item. + (let ((parent (org-element-property :parent element))) + (save-excursion + (beginning-of-line) + (cond ((eq (org-element-type parent) 'item) + (make-string (org-list-item-body-column + (org-element-property :begin parent)) + ?\s)) + ((and adaptive-fill-regexp + ;; Locally disable + ;; `adaptive-fill-function' to let + ;; `fill-context-prefix' handle + ;; `adaptive-fill-regexp' variable. + (let (adaptive-fill-function) + (fill-context-prefix + post-affiliated + (org-element-property :end element))))) + ((looking-at "[ \t]+") (match-string 0)) + (t ""))))) + (comment-block + ;; Only fill contents if P is within block boundaries. + (let* ((cbeg (save-excursion (goto-char post-affiliated) + (forward-line) + (point))) + (cend (save-excursion + (goto-char (org-element-property :end element)) + (skip-chars-backward " \r\t\n") + (line-beginning-position)))) + (when (and (>= p cbeg) (< p cend)) + (if (save-excursion (beginning-of-line) (looking-at "[ \t]+")) + (match-string 0) + ""))))))))))) (declare-function message-goto-body "message" ()) (defvar message-cite-prefix-regexp) ; From message.el @@ -22455,25 +23421,18 @@ a footnote definition, try to fill the first paragraph within." (concat "^" message-cite-prefix-regexp) end t)) (setq end (match-beginning 0)))) ;; Fill paragraph, taking line breaks into account. - ;; For that, slice the paragraph using line breaks as - ;; separators, and fill the parts in reverse order to - ;; avoid messing with markers. (save-excursion - (goto-char end) - (mapc - (lambda (pos) - (fill-region-as-paragraph pos (point) justify) - (goto-char pos)) - ;; Find the list of ending positions for line breaks - ;; in the current paragraph. Add paragraph - ;; beginning to include first slice. - (nreverse - (cons beg - (org-element-map - (org-element--parse-objects - beg end nil (org-element-restriction 'paragraph)) - 'line-break - (lambda (lb) (org-element-property :end lb))))))) + (goto-char beg) + (let ((cuts (list beg))) + (while (re-search-forward "\\\\\\\\[ \t]*\n" end t) + (when (eq 'line-break + (org-element-type + (save-excursion (backward-char) + (org-element-context)))) + (push (point) cuts))) + (dolist (c (delq end cuts)) + (fill-region-as-paragraph c end justify) + (setq end c)))) t))) ;; Contents of `comment-block' type elements should be ;; filled as plain text, but only if point is within block @@ -22554,6 +23513,130 @@ non-nil." (insert-before-markers-and-inherit fill-prefix)) +;;; Fixed Width Areas + +(defun org-toggle-fixed-width () + "Toggle fixed-width markup. + +Add or remove fixed-width markup on current line, whenever it +makes sense. Return an error otherwise. + +If a region is active and if it contains only fixed-width areas +or blank lines, remove all fixed-width markup in it. If the +region contains anything else, convert all non-fixed-width lines +to fixed-width ones. + +Blank lines at the end of the region are ignored unless the +region only contains such lines." + (interactive) + (if (not (org-region-active-p)) + ;; No region: + ;; + ;; Remove fixed width marker only in a fixed-with element. + ;; + ;; Add fixed width maker in paragraphs, in blank lines after + ;; elements or at the beginning of a headline or an inlinetask, + ;; and before any one-line elements (e.g., a clock). + (progn + (beginning-of-line) + (let* ((element (org-element-at-point)) + (type (org-element-type element))) + (cond + ((and (eq type 'fixed-width) + (looking-at "[ \t]*\\(:\\(?: \\|$\\)\\)")) + (replace-match + "" nil nil nil (if (= (line-end-position) (match-end 0)) 0 1))) + ((and (memq type '(babel-call clock comment diary-sexp headline + horizontal-rule keyword paragraph + planning)) + (<= (org-element-property :post-affiliated element) (point))) + (skip-chars-forward " \t") + (insert ": ")) + ((and (org-looking-at-p "[ \t]*$") + (or (eq type 'inlinetask) + (save-excursion + (skip-chars-forward " \r\t\n") + (<= (org-element-property :end element) (point))))) + (delete-region (point) (line-end-position)) + (org-indent-line) + (insert ": ")) + (t (user-error "Cannot insert a fixed-width line here"))))) + ;; Region active. + (let* ((begin (save-excursion + (goto-char (region-beginning)) + (line-beginning-position))) + (end (copy-marker + (save-excursion + (goto-char (region-end)) + (unless (eolp) (beginning-of-line)) + (if (save-excursion (re-search-backward "\\S-" begin t)) + (progn (skip-chars-backward " \r\t\n") (point)) + (point))))) + (all-fixed-width-p + (catch 'not-all-p + (save-excursion + (goto-char begin) + (skip-chars-forward " \r\t\n") + (when (eobp) (throw 'not-all-p nil)) + (while (< (point) end) + (let ((element (org-element-at-point))) + (if (eq (org-element-type element) 'fixed-width) + (goto-char (org-element-property :end element)) + (throw 'not-all-p nil)))) + t)))) + (if all-fixed-width-p + (save-excursion + (goto-char begin) + (while (< (point) end) + (when (looking-at "[ \t]*\\(:\\(?: \\|$\\)\\)") + (replace-match + "" nil nil nil + (if (= (line-end-position) (match-end 0)) 0 1))) + (forward-line))) + (let ((min-ind (point-max))) + ;; Find minimum indentation across all lines. + (save-excursion + (goto-char begin) + (if (not (save-excursion (re-search-forward "\\S-" end t))) + (setq min-ind 0) + (catch 'zerop + (while (< (point) end) + (unless (org-looking-at-p "[ \t]*$") + (let ((ind (org-get-indentation))) + (setq min-ind (min min-ind ind)) + (when (zerop ind) (throw 'zerop t)))) + (forward-line))))) + ;; Loop over all lines and add fixed-width markup everywhere + ;; but in fixed-width lines. + (save-excursion + (goto-char begin) + (while (< (point) end) + (cond + ((org-at-heading-p) + (insert ": ") + (forward-line) + (while (and (< (point) end) (org-looking-at-p "[ \t]*$")) + (insert ":") + (forward-line))) + ((org-looking-at-p "[ \t]*:\\( \\|$\\)") + (let* ((element (org-element-at-point)) + (element-end (org-element-property :end element))) + (if (eq (org-element-type element) 'fixed-width) + (progn (goto-char element-end) + (skip-chars-backward " \r\t\n") + (forward-line)) + (let ((limit (min end element-end))) + (while (< (point) limit) + (org-move-to-column min-ind t) + (insert ": ") + (forward-line)))))) + (t + (org-move-to-column min-ind t) + (insert ": ") + (forward-line))))))) + (set-marker end nil)))) + + ;;; Comments ;; Org comments syntax is quite complex. It requires the entire line @@ -22583,78 +23666,124 @@ non-nil." (defun org-insert-comment () "Insert an empty comment above current line. -If the line is empty, insert comment at its beginning." - (beginning-of-line) - (if (looking-at "\\s-*$") (replace-match "") (open-line 1)) - (org-indent-line) - (insert "# ")) +If the line is empty, insert comment at its beginning. When +point is within a source block, comment according to the related +major mode." + (if (let ((element (org-element-at-point))) + (and (eq (org-element-type element) 'src-block) + (< (save-excursion + (goto-char (org-element-property :post-affiliated element)) + (line-end-position)) + (point)) + (> (save-excursion + (goto-char (org-element-property :end element)) + (skip-chars-backward " \r\t\n") + (line-beginning-position)) + (point)))) + (org-babel-do-in-edit-buffer (call-interactively 'comment-dwim)) + (beginning-of-line) + (if (looking-at "\\s-*$") (delete-region (point) (point-at-eol)) + (open-line 1)) + (org-indent-line) + (insert "# "))) (defvar comment-empty-lines) ; From newcomment.el. -(defun org-comment-or-uncomment-region (beg end &rest ignore) +(defun org-comment-or-uncomment-region (beg end &rest _) "Comment or uncomment each non-blank line in the region. Uncomment each non-blank line between BEG and END if it only -contains commented lines. Otherwise, comment them." - (save-restriction - ;; Restrict region - (narrow-to-region (save-excursion (goto-char beg) - (skip-chars-forward " \r\t\n" end) - (line-beginning-position)) - (save-excursion (goto-char end) - (skip-chars-backward " \r\t\n" beg) - (line-end-position))) - (let ((uncommentp - ;; UNCOMMENTP is non-nil when every non blank line between - ;; BEG and END is a comment. - (save-excursion - (goto-char (point-min)) - (while (and (not (eobp)) - (let ((element (org-element-at-point))) - (and (eq (org-element-type element) 'comment) - (goto-char (min (point-max) - (org-element-property - :end element))))))) - (eobp)))) - (if uncommentp - ;; Only blank lines and comments in region: uncomment it. - (save-excursion - (goto-char (point-min)) - (while (not (eobp)) - (when (looking-at "[ \t]*\\(#\\(?: \\|$\\)\\)") - (replace-match "" nil nil nil 1)) - (forward-line))) - ;; Comment each line in region. - (let ((min-indent (point-max))) - ;; First find the minimum indentation across all lines. - (save-excursion - (goto-char (point-min)) - (while (and (not (eobp)) (not (zerop min-indent))) - (unless (looking-at "[ \t]*$") - (setq min-indent (min min-indent (current-indentation)))) - (forward-line))) - ;; Then loop over all lines. - (save-excursion - (goto-char (point-min)) - (while (not (eobp)) - (unless (and (not comment-empty-lines) (looking-at "[ \t]*$")) - ;; Don't get fooled by invisible text (e.g. link path) - ;; when moving to column MIN-INDENT. - (let ((buffer-invisibility-spec nil)) - (org-move-to-column min-indent t)) - (insert comment-start)) - (forward-line)))))))) +contains commented lines. Otherwise, comment them. If region is +strictly within a source block, use appropriate comment syntax." + (if (let ((element (org-element-at-point))) + (and (eq (org-element-type element) 'src-block) + (< (save-excursion + (goto-char (org-element-property :post-affiliated element)) + (line-end-position)) + beg) + (>= (save-excursion + (goto-char (org-element-property :end element)) + (skip-chars-backward " \r\t\n") + (line-beginning-position)) + end))) + (org-babel-do-in-edit-buffer (call-interactively 'comment-dwim)) + (save-restriction + ;; Restrict region + (narrow-to-region (save-excursion (goto-char beg) + (skip-chars-forward " \r\t\n" end) + (line-beginning-position)) + (save-excursion (goto-char end) + (skip-chars-backward " \r\t\n" beg) + (line-end-position))) + (let ((uncommentp + ;; UNCOMMENTP is non-nil when every non blank line between + ;; BEG and END is a comment. + (save-excursion + (goto-char (point-min)) + (while (and (not (eobp)) + (let ((element (org-element-at-point))) + (and (eq (org-element-type element) 'comment) + (goto-char (min (point-max) + (org-element-property + :end element))))))) + (eobp)))) + (if uncommentp + ;; Only blank lines and comments in region: uncomment it. + (save-excursion + (goto-char (point-min)) + (while (not (eobp)) + (when (looking-at "[ \t]*\\(#\\(?: \\|$\\)\\)") + (replace-match "" nil nil nil 1)) + (forward-line))) + ;; Comment each line in region. + (let ((min-indent (point-max))) + ;; First find the minimum indentation across all lines. + (save-excursion + (goto-char (point-min)) + (while (and (not (eobp)) (not (zerop min-indent))) + (unless (looking-at "[ \t]*$") + (setq min-indent (min min-indent (current-indentation)))) + (forward-line))) + ;; Then loop over all lines. + (save-excursion + (goto-char (point-min)) + (while (not (eobp)) + (unless (and (not comment-empty-lines) (looking-at "[ \t]*$")) + ;; Don't get fooled by invisible text (e.g. link path) + ;; when moving to column MIN-INDENT. + (let ((buffer-invisibility-spec nil)) + (org-move-to-column min-indent t)) + (insert comment-start)) + (forward-line))))))))) + +(defun org-comment-dwim (arg) + "Call `comment-dwim' within a source edit buffer if needed." + (interactive "*P") + (if (org-in-src-block-p) + (org-babel-do-in-edit-buffer (call-interactively 'comment-dwim)) + (call-interactively 'comment-dwim))) -;;; Planning +;;; Timestamps API ;; This section contains tools to operate on timestamp objects, as ;; returned by, e.g. `org-element-context'. +(defun org-timestamp--to-internal-time (timestamp &optional end) + "Encode TIMESTAMP object into Emacs internal time. +Use end of date range or time range when END is non-nil." + (apply #'encode-time + (cons 0 + (mapcar + (lambda (prop) (or (org-element-property prop timestamp) 0)) + (if end '(:minute-end :hour-end :day-end :month-end :year-end) + '(:minute-start :hour-start :day-start :month-start + :year-start)))))) + (defun org-timestamp-has-time-p (timestamp) "Non-nil when TIMESTAMP has a time specified." (org-element-property :hour-start timestamp)) (defun org-timestamp-format (timestamp format &optional end utc) - "Format a TIMESTAMP element into a string. + "Format a TIMESTAMP object into a string. FORMAT is a format specifier to be passed to `format-time-string'. @@ -22665,27 +23794,18 @@ time-range, if possible. When optional argument UTC is non-nil, time will be expressed as Universal Time." (format-time-string - format - (apply 'encode-time - (cons 0 - (mapcar - (lambda (prop) (or (org-element-property prop timestamp) 0)) - (if end '(:minute-end :hour-end :day-end :month-end :year-end) - '(:minute-start :hour-start :day-start :month-start - :year-start))))) - utc)) + format (org-timestamp--to-internal-time timestamp end) utc)) (defun org-timestamp-split-range (timestamp &optional end) - "Extract a timestamp object from a date or time range. + "Extract a TIMESTAMP object from a date or time range. -TIMESTAMP is a timestamp object. END, when non-nil, means extract -the end of the range. Otherwise, extract its start. +END, when non-nil, means extract the end of the range. +Otherwise, extract its start. -Return a new timestamp object sharing the same parent as -TIMESTAMP." +Return a new timestamp object." (let ((type (org-element-property :type timestamp))) (if (memq type '(active inactive diary)) timestamp - (let ((split-ts (list 'timestamp (copy-sequence (nth 1 timestamp))))) + (let ((split-ts (org-element-copy timestamp))) ;; Set new type. (org-element-put-property split-ts :type (if (eq type 'active-range) 'active 'inactive)) @@ -22699,88 +23819,45 @@ TIMESTAMP." (dolist (p-cell p-alist) (org-element-put-property split-ts - (funcall (if end 'car 'cdr) p-cell) + (funcall (if end #'car #'cdr) p-cell) (org-element-property - (funcall (if end 'cdr 'car) p-cell) split-ts))) + (funcall (if end #'cdr #'car) p-cell) split-ts))) ;; Eventually refresh `:raw-value'. (org-element-put-property split-ts :raw-value nil) (org-element-put-property split-ts :raw-value (org-element-interpret-data split-ts))))))) (defun org-timestamp-translate (timestamp &optional boundary) - "Apply `org-translate-time' on a TIMESTAMP object. + "Translate TIMESTAMP object to custom format. + +Format string is defined in `org-time-stamp-custom-formats', +which see. + When optional argument BOUNDARY is non-nil, it is either the symbol `start' or `end'. In this case, only translate the starting or ending part of TIMESTAMP if it is a date or time -range. Otherwise, translate both parts." - (if (and (not boundary) - (memq (org-element-property :type timestamp) - '(active-range inactive-range))) - (concat - (org-translate-time - (org-element-property :raw-value - (org-timestamp-split-range timestamp))) - "--" - (org-translate-time - (org-element-property :raw-value - (org-timestamp-split-range timestamp t)))) - (org-translate-time - (org-element-property - :raw-value - (if (not boundary) timestamp - (org-timestamp-split-range timestamp (eq boundary 'end))))))) +range. Otherwise, translate both parts. + +Return timestamp as-is if `org-display-custom-times' is nil or if +it has a `diary' type." + (let ((type (org-element-property :type timestamp))) + (if (or (not org-display-custom-times) (eq type 'diary)) + (org-element-interpret-data timestamp) + (let ((fmt (funcall (if (org-timestamp-has-time-p timestamp) #'cdr #'car) + org-time-stamp-custom-formats))) + (if (and (not boundary) (memq type '(active-range inactive-range))) + (concat (org-timestamp-format timestamp fmt) + "--" + (org-timestamp-format timestamp fmt t)) + (org-timestamp-format timestamp fmt (eq boundary 'end))))))) ;;; Other stuff. -(defun org-toggle-fixed-width-section (arg) - "Toggle the fixed-width export. -If there is no active region, the QUOTE keyword at the current headline is -inserted or removed. When present, it causes the text between this headline -and the next to be exported as fixed-width text, and unmodified. -If there is an active region, this command adds or removes a colon as the -first character of this line. If the first character of a line is a colon, -this line is also exported in fixed-width font." - (interactive "P") - (let* ((cc 0) - (regionp (org-region-active-p)) - (beg (if regionp (region-beginning) (point))) - (end (if regionp (region-end))) - (nlines (or arg (if (and beg end) (count-lines beg end) 1))) - (case-fold-search nil) - (re "[ \t]*\\(:\\(?: \\|$\\)\\)") - off) - (if regionp - (save-excursion - (goto-char beg) - (setq cc (current-column)) - (beginning-of-line 1) - (setq off (looking-at re)) - (while (> nlines 0) - (setq nlines (1- nlines)) - (beginning-of-line 1) - (cond - (arg - (org-move-to-column cc t) - (insert ": \n") - (forward-line -1)) - ((and off (looking-at re)) - (replace-match "" t t nil 1)) - ((not off) (org-move-to-column cc t) (insert ": "))) - (forward-line 1))) - (save-excursion - (org-back-to-heading) - (cond - ((looking-at (format org-heading-keyword-regexp-format - org-quote-string)) - (goto-char (match-end 1)) - (looking-at (concat " +" org-quote-string)) - (replace-match "" t t) - (when (eolp) (insert " "))) - ((looking-at org-outline-regexp) - (goto-char (match-end 0)) - (insert org-quote-string " "))))))) +(defvar reftex-docstruct-symbol) +(defvar reftex-cite-format) +(defvar org--rds) (defun org-reftex-citation () "Use reftex-citation to insert a citation into the buffer. @@ -22796,20 +23873,20 @@ into the buffer. Export of such citations to both LaTeX and HTML is handled by the contributed package ox-bibtex by Taru Karttunen." (interactive) - (let ((reftex-docstruct-symbol 'rds) + (let ((reftex-docstruct-symbol 'org--rds) (reftex-cite-format "\\cite{%l}") - rds bib) + org--rds bib) (save-excursion (save-restriction (widen) (let ((case-fold-search t) - (re "^#\\+bibliography:[ \t]+\\([^ \t\n]+\\)")) + (re "^[ \t]*#\\+BIBLIOGRAPHY:[ \t]+\\([^ \t\n]+\\)")) (if (not (save-excursion (or (re-search-forward re nil t) (re-search-backward re nil t)))) - (error "No bibliography defined in file") + (user-error "No bibliography defined in file") (setq bib (concat (match-string 1) ".bib") - rds (list (list 'bib bib))))))) + org--rds (list (list 'bib bib))))))) (call-interactively 'reftex-citation))) ;;;; Functions extending outline functionality @@ -22842,7 +23919,7 @@ beyond the end of the headline." (when special (cond ((and (looking-at org-complex-heading-regexp) - (= (char-after (match-end 1)) ?\ )) + (eq (char-after (match-end 1)) ?\s)) (setq refpos (min (1+ (or (match-end 3) (match-end 2) (match-end 1))) (point-at-eol))) (goto-char @@ -22913,7 +23990,7 @@ the cursor is already beyond the end of the headline." (goto-char (match-end 0)) (goto-char (match-beginning 1)))) (call-interactively move-fun)))) - ((org-element-property :hiddenp element) + ((outline-invisible-p (line-end-position)) ;; If element is hidden, `move-end-of-line' would put point ;; after it. Use `end-of-line' to stay on current line. (call-interactively 'end-of-line)) @@ -22926,30 +24003,55 @@ the cursor is already beyond the end of the headline." (define-key org-mode-map "\C-a" 'org-beginning-of-line) (define-key org-mode-map "\C-e" 'org-end-of-line) -(defun org-backward-sentence (&optional arg) +(defun org-backward-sentence (&optional _arg) "Go to beginning of sentence, or beginning of table field. This will call `backward-sentence' or `org-table-beginning-of-field', depending on context." - (interactive "P") - (cond - ((org-at-table-p) (call-interactively 'org-table-beginning-of-field)) - (t (call-interactively 'backward-sentence)))) - -(defun org-forward-sentence (&optional arg) + (interactive) + (let* ((element (org-element-at-point)) + (contents-begin (org-element-property :contents-begin element)) + (table (org-element-lineage element '(table) t))) + (if (and table + (> (point) contents-begin) + (<= (point) (org-element-property :contents-end table))) + (call-interactively #'org-table-beginning-of-field) + (save-restriction + (when (and contents-begin + (< (point-min) contents-begin) + (> (point) contents-begin)) + (narrow-to-region contents-begin + (org-element-property :contents-end element))) + (call-interactively #'backward-sentence))))) + +(defun org-forward-sentence (&optional _arg) "Go to end of sentence, or end of table field. This will call `forward-sentence' or `org-table-end-of-field', depending on context." - (interactive "P") - (cond - ((org-at-table-p) (call-interactively 'org-table-end-of-field)) - (t (call-interactively 'forward-sentence)))) + (interactive) + (let* ((element (org-element-at-point)) + (contents-end (org-element-property :contents-end element)) + (table (org-element-lineage element '(table) t))) + (if (and table + (>= (point) (org-element-property :contents-begin table)) + (< (point) contents-end)) + (call-interactively #'org-table-end-of-field) + (save-restriction + (when (and contents-end + (> (point-max) contents-end) + ;; Skip blank lines between elements. + (< (org-element-property :end element) + (save-excursion (goto-char contents-end) + (skip-chars-forward " \r\t\n")))) + (narrow-to-region (org-element-property :contents-begin element) + contents-end)) + (call-interactively #'forward-sentence))))) (define-key org-mode-map "\M-a" 'org-backward-sentence) (define-key org-mode-map "\M-e" 'org-forward-sentence) -(defun org-kill-line (&optional arg) +(defun org-kill-line (&optional _arg) "Kill line, to tags or end of line." - (interactive "P") + (interactive) (cond ((or (not org-special-ctrl-k) (bolp) @@ -22976,15 +24078,15 @@ cursor is at the beginning of a line or after the stars of a currently empty headline, then the yank is handled specially. How exactly depends on the value of the following variables, both set by default. -org-yank-folded-subtrees +`org-yank-folded-subtrees' When set, the subtree(s) will be folded after insertion, but only if doing so would now swallow text after the yanked text. -org-yank-adjusted-subtrees +`org-yank-adjusted-subtrees' When set, the subtree will be promoted or demoted in order to - fit into the local outline tree structure, which means that the level - will be adjusted so that it becomes the smaller one of the two - *visible* surrounding headings. + fit into the local outline tree structure, which means that the + level will be adjusted so that it becomes the smaller one of the + two *visible* surrounding headings. Any prefix to this command will cause `yank' to be called directly with no special treatment. In particular, a simple \\[universal-argument] prefix \ @@ -23034,7 +24136,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)) - (hide-subtree) + (outline-hide-subtree) (org-cycle-show-empty-lines 'folded) (condition-case nil (outline-forward-same-level 1) @@ -23107,11 +24209,27 @@ This version does not only check the character property, but also ;; Compatibility alias with Org versions < 7.8.03 (defalias 'org-on-heading-p 'org-at-heading-p) +(defun org-in-commented-heading-p (&optional no-inheritance) + "Non-nil if point is under a commented heading. +This function also checks ancestors of the current headline, +unless optional argument NO-INHERITANCE is non-nil." + (cond + ((org-before-first-heading-p) nil) + ((let ((headline (nth 4 (org-heading-components)))) + (and headline + (let ((case-fold-search nil)) + (org-string-match-p (concat "^" org-comment-string "\\(?: \\|$\\)") + headline))))) + (no-inheritance nil) + (t + (save-excursion (and (org-up-heading-safe) (org-in-commented-heading-p)))))) + (defun org-at-comment-p nil - "Is cursor in a line starting with a # character?" + "Is cursor in a commented line?" (save-excursion - (beginning-of-line) - (looking-at "^#"))) + (save-match-data + (beginning-of-line) + (looking-at "^[ \t]*# ")))) (defun org-at-drawer-p nil "Is cursor at a drawer keyword?" @@ -23162,14 +24280,11 @@ headline found, or nil if no higher level is found. Also, this function will be a lot faster than `outline-up-heading', because it relies on stars being the outline starters. This can really make a significant difference in outlines with very many siblings." - (let (start-level re) - (org-back-to-heading t) - (setq start-level (funcall outline-level)) - (if (equal start-level 1) - nil - (setq re (concat "^\\*\\{1," (number-to-string (1- start-level)) "\\} ")) - (if (re-search-backward re nil t) - (funcall outline-level))))) + (when (ignore-errors (org-back-to-heading t)) + (let ((level-up (1- (funcall outline-level)))) + (and (> level-up 0) + (re-search-backward (format "^\\*\\{1,%d\\} " level-up) nil t) + (funcall outline-level))))) (defun org-first-sibling-p () "Is this heading the first child of its parents?" @@ -23194,7 +24309,7 @@ move point." (pos (point)) (re org-outline-regexp-bol) level l) - (when (condition-case nil (org-back-to-heading t) (error nil)) + (when (ignore-errors (org-back-to-heading t)) (setq level (funcall outline-level)) (catch 'exit (or previous (forward-char 1)) @@ -23218,7 +24333,7 @@ move point." Return t when a child was found. Otherwise don't move point and return nil." (let (level (pos (point)) (re org-outline-regexp-bol)) - (when (condition-case nil (org-back-to-heading t) (error nil)) + (when (ignore-errors (org-back-to-heading t)) (setq level (outline-level)) (forward-char 1) (if (and (re-search-forward re nil t) (> (outline-level) level)) @@ -23307,24 +24422,28 @@ If there is no such heading, return nil." (forward-char -1)))))) (point)) -(defun org-end-of-meta-data-and-drawers () - "Jump to the first text after meta data and drawers in the current entry. -This will move over empty lines, lines with planning time stamps, -clocking lines, and drawers." +(defun org-end-of-meta-data (&optional full) + "Skip planning line and properties drawer in current entry. +When optional argument FULL is non-nil, also skip empty lines, +clocking lines and regular drawers at the beginning of the +entry." (org-back-to-heading t) - (let ((end (save-excursion (outline-next-heading) (point))) - (re (concat "\\(" org-drawer-regexp "\\)" - "\\|" "[ \t]*" org-keyword-time-regexp))) - (forward-line 1) - (while (re-search-forward re end t) - (if (not (match-end 1)) - ;; empty or planning line - (forward-line 1) - ;; a drawer, find the end - (re-search-forward "^[ \t]*:END:" end 'move) - (forward-line 1))) - (and (re-search-forward "[^\n]" nil t) (backward-char 1)) - (point))) + (forward-line) + (when (org-looking-at-p org-planning-line-re) (forward-line)) + (when (looking-at org-property-drawer-re) + (goto-char (match-end 0)) + (forward-line)) + (when (and full (not (org-at-heading-p))) + (catch 'exit + (let ((end (save-excursion (outline-next-heading) (point))) + (re (concat "[ \t]*$" "\\|" org-clock-line-re))) + (while (not (eobp)) + (cond ((org-looking-at-p org-drawer-regexp) + (if (re-search-forward "^[ \t]*:END:[ \t]*$" end t) + (forward-line) + (throw 'exit t))) + ((org-looking-at-p re) (forward-line)) + (t (throw 'exit t)))))))) (defun org-forward-heading-same-level (arg &optional invisible-ok) "Move forward to the ARG'th subheading at same level as this one. @@ -23365,20 +24484,64 @@ Stop at the first and last subheadings of a superior heading." (interactive "p") (org-forward-heading-same-level (if arg (- arg) -1) invisible-ok)) +(defun org-next-visible-heading (arg) + "Move to the next visible heading. + +This function wraps `outline-next-visible-heading' with +`org-with-limited-levels' in order to skip over inline tasks and +respect customization of `org-odd-levels-only'." + (interactive "p") + (org-with-limited-levels + (outline-next-visible-heading arg))) + +(defun org-previous-visible-heading (arg) + "Move to the next visible heading. + +This function wraps `outline-previous-visible-heading' with +`org-with-limited-levels' in order to skip over inline tasks and +respect customization of `org-odd-levels-only'." + (interactive "p") + (org-with-limited-levels + (outline-previous-visible-heading arg))) + (defun org-next-block (arg &optional backward block-regexp) "Jump to the next block. -With a prefix argument ARG, jump forward ARG many source blocks. + +With a prefix argument ARG, jump forward ARG many blocks. + When BACKWARD is non-nil, jump to the previous block. -When BLOCK-REGEXP is non-nil, use this regexp to find blocks." + +When BLOCK-REGEXP is non-nil, use this regexp to find blocks. +Match data is set according to this regexp when the function +returns. + +Return point at beginning of the opening line of found block. +Throw an error if no block is found." (interactive "p") - (let ((re (or block-regexp org-block-regexp)) - (re-search-fn (or (and backward 're-search-backward) - 're-search-forward))) - (if (looking-at re) (forward-char 1)) - (condition-case nil - (funcall re-search-fn re nil nil arg) - (error (error "No %s code blocks" (if backward "previous" "further" )))) - (goto-char (match-beginning 0)) (org-show-context))) + (let ((re (or block-regexp "^[ \t]*#\\+BEGIN")) + (case-fold-search t) + (search-fn (if backward #'re-search-backward #'re-search-forward)) + (count (or arg 1)) + (origin (point)) + last-element) + (if backward (beginning-of-line) (end-of-line)) + (while (and (> count 0) (funcall search-fn re nil t)) + (let ((element (save-excursion + (goto-char (match-beginning 0)) + (save-match-data (org-element-at-point))))) + (when (and (memq (org-element-type element) + '(center-block comment-block dynamic-block + example-block export-block quote-block + special-block src-block verse-block)) + (<= (match-beginning 0) + (org-element-property :post-affiliated element))) + (setq last-element element) + (decf count)))) + (if (= count 0) + (prog1 (goto-char (org-element-property :post-affiliated last-element)) + (save-match-data (org-show-context))) + (goto-char origin) + (user-error "No %s code blocks" (if backward "previous" "further"))))) (defun org-previous-block (arg &optional block-regexp) "Jump to the previous block. @@ -23417,7 +24580,7 @@ item, etc. It also provides some special moves for convenience: (skip-chars-forward " \r\t\n") (or (eobp) (beginning-of-line))) ;; On affiliated keywords, move to element's beginning. - ((and post-affiliated (< (point) post-affiliated)) + ((< (point) post-affiliated) (goto-char post-affiliated)) ;; At a table row, move to the end of the table. Similarly, ;; at a node property, move to the end of the property @@ -23496,7 +24659,7 @@ convenience: ((= (point) begin) (backward-char) (org-backward-paragraph)) - ((and post-affiliated (<= (point) post-affiliated)) (goto-char begin)) + ((<= (point) post-affiliated) (goto-char begin)) ((memq type '(node-property table-row)) (goto-char (org-element-property :post-affiliated (org-element-property :parent element)))) @@ -23570,18 +24733,21 @@ Move to the previous element at the same level, when possible." (progn (goto-char origin) (user-error "Cannot move further up")))))) (t - (let* ((trail (org-element-at-point 'keep-trail)) - (elem (car trail)) - (prev-elem (nth 1 trail)) + (let* ((elem (org-element-at-point)) (beg (org-element-property :begin elem))) (cond ;; Move to beginning of current element if point isn't ;; there already. ((null beg) (message "No element at point")) ((/= (point) beg) (goto-char beg)) - (prev-elem (goto-char (org-element-property :begin prev-elem))) - ((org-before-first-heading-p) (goto-char (point-min))) - (t (org-back-to-heading))))))) + (t (goto-char beg) + (skip-chars-backward " \r\t\n") + (unless (bobp) + (let ((prev (org-element-at-point))) + (goto-char (org-element-property :begin prev)) + (while (and (setq prev (org-element-property :parent prev)) + (<= (org-element-property :end prev) beg)) + (goto-char (org-element-property :begin prev))))))))))) (defun org-up-element () "Move to upper element." @@ -23606,7 +24772,7 @@ Move to the previous element at the same level, when possible." (forward-char)) ((memq (org-element-type element) org-element-greater-elements) ;; If contents are hidden, first disclose them. - (when (org-element-property :hiddenp element) (org-cycle)) + (when (outline-invisible-p (line-end-position)) (org-cycle)) (goto-char (or (org-element-property :contents-begin element) (user-error "No content for this element")))) (t (user-error "No inner element"))))) @@ -23615,9 +24781,19 @@ Move to the previous element at the same level, when possible." "Move backward element at point." (interactive) (if (org-with-limited-levels (org-at-heading-p)) (org-move-subtree-up) - (let* ((trail (org-element-at-point 'keep-trail)) - (elem (car trail)) - (prev-elem (nth 1 trail))) + (let* ((elem (org-element-at-point)) + (prev-elem + (save-excursion + (goto-char (org-element-property :begin elem)) + (skip-chars-backward " \r\t\n") + (unless (bobp) + (let* ((beg (org-element-property :begin elem)) + (prev (org-element-at-point)) + (up prev)) + (while (and (setq up (org-element-property :parent up)) + (<= (org-element-property :end up) beg)) + (setq prev up)) + prev))))) ;; Error out if no previous element or previous element is ;; a parent of the current one. (if (or (not prev-elem) (org-element-nested-p elem prev-elem)) @@ -23766,27 +24942,26 @@ modified." Show the heading too, if it is currently invisible." (interactive) (save-excursion - (condition-case nil - (progn - (org-back-to-heading t) - (outline-flag-region - (max (point-min) (1- (point))) - (save-excursion - (if (re-search-forward - (concat "[\r\n]\\(" org-outline-regexp "\\)") nil t) - (match-beginning 1) - (point-max))) - nil) - (org-cycle-hide-drawers 'children)) - (error nil)))) + (ignore-errors + (org-back-to-heading t) + (outline-flag-region + (max (point-min) (1- (point))) + (save-excursion + (if (re-search-forward + (concat "[\r\n]\\(" org-outline-regexp "\\)") nil t) + (match-beginning 1) + (point-max))) + nil) + (org-cycle-hide-drawers 'children)))) (defun org-make-options-regexp (kwds &optional extra) - "Make a regular expression for keyword lines." - (concat - "^#\\+\\(" - (mapconcat 'regexp-quote kwds "\\|") - (if extra (concat "\\|" extra)) - "\\):[ \t]*\\(.*\\)")) + "Make a regular expression for keyword lines. +KWDS is a list of keywords, as strings. Optional argument EXTRA, +when non-nil, is a regexp matching keywords names." + (concat "^[ \t]*#\\+\\(" + (regexp-opt kwds) + (and extra (concat (and kwds "\\|") extra)) + "\\):[ \t]*\\(.*\\)")) ;; Make isearch reveal the necessary context (defun org-isearch-end () @@ -23942,34 +25117,97 @@ To get rid of the restriction, use \\[org-agenda-remove-restriction-lock]." ;;; Fixes and Hacks for problems with other packages -;; Make flyspell not check words in links, to not mess up our keymap -(defvar org-element-affiliated-keywords) ; From org-element.el -(defvar org-element-block-name-alist) ; From org-element.el +(defun org--flyspell-object-check-p (element) + "Non-nil when Flyspell can check object at point. +ELEMENT is the element at point." + (let ((object (save-excursion + (when (org-looking-at-p "\\>") (backward-char)) + (org-element-context element)))) + (case (org-element-type object) + ;; Prevent checks in links due to keybinding conflict with + ;; Flyspell. + ((code entity export-snippet inline-babel-call + inline-src-block line-break latex-fragment link macro + statistics-cookie target timestamp verbatim) + nil) + (footnote-reference + ;; Only in inline footnotes, within the definition. + (and (eq (org-element-property :type object) 'inline) + (< (save-excursion + (goto-char (org-element-property :begin object)) + (search-forward ":" nil t 2)) + (point)))) + (otherwise t)))) + (defun org-mode-flyspell-verify () - "Don't let flyspell put overlays at active buttons, or on - {todo,all-time,additional-option-like}-keywords." - (require 'org-element) ; For `org-element-affiliated-keywords' - (let ((pos (max (1- (point)) (point-min))) - (word (thing-at-point 'word))) - (and (not (get-text-property pos 'keymap)) - (not (get-text-property pos 'org-no-flyspell)) - (not (member word org-todo-keywords-1)) - (not (member word org-all-time-keywords)) - (not (member word org-options-keywords)) - (not (member word (mapcar 'car org-startup-options))) - (not (member-ignore-case word org-element-affiliated-keywords)) - (not (member-ignore-case word (org-get-export-keywords))) - (not (member-ignore-case - word (mapcar 'car org-element-block-name-alist))) - (not (member-ignore-case word '("BEGIN" "END" "ATTR"))) - (not (org-in-src-block-p))))) + "Function used for `flyspell-generic-check-word-predicate'." + (if (org-at-heading-p) + ;; At a headline or an inlinetask, check title only. This is + ;; faster than relying on `org-element-at-point'. + (and (save-excursion (beginning-of-line) + (and (let ((case-fold-search t)) + (not (looking-at "\\*+ END[ \t]*$"))) + (looking-at org-complex-heading-regexp))) + (match-beginning 4) + (>= (point) (match-beginning 4)) + (or (not (match-beginning 5)) + (< (point) (match-beginning 5)))) + (let* ((element (org-element-at-point)) + (post-affiliated (org-element-property :post-affiliated element))) + (cond + ;; Ignore checks in all affiliated keywords but captions. + ((< (point) post-affiliated) + (and (save-excursion + (beginning-of-line) + (let ((case-fold-search t)) (looking-at "[ \t]*#\\+CAPTION:"))) + (> (point) (match-end 0)) + (org--flyspell-object-check-p element))) + ;; Ignore checks in LOGBOOK (or equivalent) drawer. + ((let ((log (org-log-into-drawer))) + (and log + (let ((drawer (org-element-lineage element '(drawer)))) + (and drawer + (eq (compare-strings + log nil nil + (org-element-property :drawer-name drawer) nil nil t) + t))))) + nil) + (t + (case (org-element-type element) + ((comment quote-section) t) + (comment-block + ;; Allow checks between block markers, not on them. + (and (> (line-beginning-position) post-affiliated) + (save-excursion + (end-of-line) + (skip-chars-forward " \r\t\n") + (< (point) (org-element-property :end element))))) + ;; Arbitrary list of keywords where checks are meaningful. + ;; Make sure point is on the value part of the element. + (keyword + (and (member (org-element-property :key element) + '("DESCRIPTION" "TITLE")) + (save-excursion + (search-backward ":" (line-beginning-position) t)))) + ;; Check is globally allowed in paragraphs verse blocks and + ;; table rows (after affiliated keywords) but some objects + ;; must not be affected. + ((paragraph table-row verse-block) + (let ((cbeg (org-element-property :contents-begin element)) + (cend (org-element-property :contents-end element))) + (and cbeg (>= (point) cbeg) (< (point) cend) + (org--flyspell-object-check-p element)))))))))) +(put 'org-mode 'flyspell-mode-predicate 'org-mode-flyspell-verify) (defun org-remove-flyspell-overlays-in (beg end) "Remove flyspell overlays in region." (and (org-bound-and-true-p flyspell-mode) (fboundp 'flyspell-delete-region-overlays) - (flyspell-delete-region-overlays beg end)) - (add-text-properties beg end '(org-no-flyspell t))) + (flyspell-delete-region-overlays beg end))) + +(defvar flyspell-delayed-commands) +(eval-after-load "flyspell" + '(add-to-list 'flyspell-delayed-commands 'org-self-insert-command)) ;; Make `bookmark-jump' shows the jump location if it was hidden. (eval-after-load "bookmark" @@ -24002,6 +25240,27 @@ To get rid of the restriction, use \\[org-agenda-remove-restriction-lock]." (outline-invisible-p))) (org-show-context 'bookmark-jump))) +(defun org-mark-jump-unhide () + "Make the point visible with `org-show-context' after jumping to the mark." + (when (and (derived-mode-p 'org-mode) + (outline-invisible-p)) + (org-show-context 'mark-goto))) + +(eval-after-load "simple" + '(defadvice pop-to-mark-command (after org-make-visible activate) + "Make the point visible with `org-show-context'." + (org-mark-jump-unhide))) + +(eval-after-load "simple" + '(defadvice exchange-point-and-mark (after org-make-visible activate) + "Make the point visible with `org-show-context'." + (org-mark-jump-unhide))) + +(eval-after-load "simple" + '(defadvice pop-global-mark (after org-make-visible activate) + "Make the point visible with `org-show-context'." + (org-mark-jump-unhide))) + ;; Make session.el ignore our circular variable (defvar session-globals-exclude) (eval-after-load "session" diff --git a/elpa/org-20150629/orgcard.pdf b/elpa/org-20160215/orgcard.pdf similarity index 99% rename from elpa/org-20150629/orgcard.pdf rename to elpa/org-20160215/orgcard.pdf index 6879f6472fa97687755ad3c9004d2462fba853ee..7187a30914c1c0dd5222d10a9ad81a510aa008c1 100644 GIT binary patch delta 164 zcmX?bp8ddi_J%EtQjZPI42%p-4M4y|*T78Oz(8G-OW!v?#U-&MRYAkW%E$ms$#(C@ zjG`QsOj;@YoCXVJ7PA&!}CT1pvb_zBGmBcF8*>M$@Bo>ua W6s4wd85$W|n3-{@s=E5SaRC6&`zZ(j delta 164 zcmX?bp8ddi_J%EtQjZNy4a|%z4M4zH*T7WWz(8G-OW!v?#U-&MRYAkW%E$ms$#(C@ zjG`M$@Bo>ua W6s4wd85$W|n3-{@s=E5SaRC6_k|{O- diff --git a/elpa/org-20150629/ox-ascii.el b/elpa/org-20160215/ox-ascii.el similarity index 74% rename from elpa/org-20150629/ox-ascii.el rename to elpa/org-20160215/ox-ascii.el index 7e24f903..aa12d9eb 100644 --- a/elpa/org-20150629/ox-ascii.el +++ b/elpa/org-20160215/ox-ascii.el @@ -1,6 +1,6 @@ ;;; ox-ascii.el --- ASCII Back-End for Org Export Engine -;; Copyright (C) 2012-2014 Free Software Foundation, Inc. +;; Copyright (C) 2012-2016 Free Software Foundation, Inc. ;; Author: Nicolas Goaziou ;; Keywords: outlines, hypermedia, calendar, wp @@ -35,10 +35,10 @@ ;;; Define Back-End ;; -;; The following setting won't allow to modify preferred charset +;; The following setting won't allow modifying preferred charset ;; through a buffer keyword or an option item, but, since the property -;; will appear in communication channel nonetheless, it allows to -;; override `org-ascii-charset' variable on the fly by the ext-plist +;; will appear in communication channel nonetheless, it allows +;; overriding `org-ascii-charset' variable on the fly by the ext-plist ;; mechanism. ;; ;; We also install a filter for headlines and sections, in order to @@ -49,8 +49,6 @@ (center-block . org-ascii-center-block) (clock . org-ascii-clock) (code . org-ascii-code) - (comment . (lambda (&rest args) "")) - (comment-block . (lambda (&rest args) "")) (drawer . org-ascii-drawer) (dynamic-block . org-ascii-dynamic-block) (entity . org-ascii-entity) @@ -71,12 +69,13 @@ (latex-fragment . org-ascii-latex-fragment) (line-break . org-ascii-line-break) (link . org-ascii-link) + (node-property . org-ascii-node-property) (paragraph . org-ascii-paragraph) (plain-list . org-ascii-plain-list) (plain-text . org-ascii-plain-text) (planning . org-ascii-planning) + (property-drawer . org-ascii-property-drawer) (quote-block . org-ascii-quote-block) - (quote-section . org-ascii-quote-section) (radio-target . org-ascii-radio-target) (section . org-ascii-section) (special-block . org-ascii-special-block) @@ -119,7 +118,30 @@ (:filter-parse-tree org-ascii-filter-paragraph-spacing org-ascii-filter-comment-spacing) (:filter-section . org-ascii-filter-headline-blank-lines)) - :options-alist '((:ascii-charset nil nil org-ascii-charset))) + :options-alist + '((:subtitle "SUBTITLE" nil nil parse) + (:ascii-bullets nil nil org-ascii-bullets) + (:ascii-caption-above nil nil org-ascii-caption-above) + (:ascii-charset nil nil org-ascii-charset) + (:ascii-global-margin nil nil org-ascii-global-margin) + (:ascii-format-drawer-function nil nil org-ascii-format-drawer-function) + (:ascii-format-inlinetask-function + nil nil org-ascii-format-inlinetask-function) + (:ascii-headline-spacing nil nil org-ascii-headline-spacing) + (:ascii-indented-line-width nil nil org-ascii-indented-line-width) + (:ascii-inlinetask-width nil nil org-ascii-inlinetask-width) + (:ascii-inner-margin nil nil org-ascii-inner-margin) + (:ascii-links-to-notes nil nil org-ascii-links-to-notes) + (:ascii-list-margin nil nil org-ascii-list-margin) + (:ascii-paragraph-spacing nil nil org-ascii-paragraph-spacing) + (:ascii-quote-margin nil nil org-ascii-quote-margin) + (:ascii-table-keep-all-vertical-lines + nil nil org-ascii-table-keep-all-vertical-lines) + (:ascii-table-use-ascii-art nil nil org-ascii-table-use-ascii-art) + (:ascii-table-widen-columns nil nil org-ascii-table-widen-columns) + (:ascii-text-width nil nil org-ascii-text-width) + (:ascii-underline nil nil org-ascii-underline) + (:ascii-verbatim-format nil nil org-ascii-verbatim-format))) @@ -162,6 +184,15 @@ This margin is applied on both sides of the text." :package-version '(Org . "8.0") :type 'integer) +(defcustom org-ascii-list-margin 0 + "Width of margin used for plain lists, in characters. +This margin applies to top level list only, not to its +sub-lists." + :group 'org-export-ascii + :version "25.1" + :package-version '(Org . "8.3") + :type 'integer) + (defcustom org-ascii-inlinetask-width 30 "Width of inline tasks, in number of characters. This number ignores any margin." @@ -185,7 +216,7 @@ original Org buffer at the same place." :package-version '(Org . "8.0") :type '(choice (const :tag "Replicate original spacing" nil) - (cons :tag "Set an uniform spacing" + (cons :tag "Set a uniform spacing" (integer :tag "Number of blank lines before contents") (integer :tag "Number of blank lines after contents")))) @@ -384,14 +415,18 @@ nil to ignore the inline task." ;; Internal functions fall into three categories. -;; The first one is about text formatting. The core function is -;; `org-ascii--current-text-width', which determines the current -;; text width allowed to a given element. In other words, it helps -;; keeping each line width within maximum text width defined in -;; `org-ascii-text-width'. Once this information is known, -;; `org-ascii--fill-string', `org-ascii--justify-string', -;; `org-ascii--box-string' and `org-ascii--indent-string' can -;; operate on a given output string. +;; The first one is about text formatting. The core functions are +;; `org-ascii--current-text-width' and +;; `org-ascii--current-justification', which determine, respectively, +;; the current text width allowed to a given element and its expected +;; justification. Once this information is known, +;; `org-ascii--fill-string', `org-ascii--justify-lines', +;; `org-ascii--justify-element' `org-ascii--box-string' and +;; `org-ascii--indent-string' can operate on a given output string. +;; In particular, justification happens at the regular (i.e., +;; non-greater) element level, which means that when the exporting +;; process reaches a container (e.g., a center block) content are +;; already justified. ;; The second category contains functions handling elements listings, ;; triggered by "#+TOC:" keyword. As such, `org-ascii--build-toc' @@ -420,7 +455,8 @@ a communication channel. Optional argument JUSTIFY can specify any type of justification among `left', `center', `right' or `full'. A nil value is equivalent to `left'. For a justification that doesn't also fill -string, see `org-ascii--justify-string'. +string, see `org-ascii--justify-lines' and +`org-ascii--justify-block'. Return nil if S isn't a string." (when (stringp s) @@ -435,8 +471,8 @@ Return nil if S isn't a string." (fill-region (point-min) (point-max) justify)) (buffer-string))))) -(defun org-ascii--justify-string (s text-width how) - "Justify string S. +(defun org-ascii--justify-lines (s text-width how) + "Justify all lines in string S. TEXT-WIDTH is an integer specifying maximum length of a line. HOW determines the type of justification: it can be `left', `right', `full' or `center'." @@ -452,6 +488,48 @@ HOW determines the type of justification: it can be `left', (forward-line))) (buffer-string))) +(defun org-ascii--justify-element (contents element info) + "Justify CONTENTS of ELEMENT. +INFO is a plist used as a communication channel. Justification +is done according to the type of element. More accurately, +paragraphs are filled and other elements are justified as blocks, +that is according to the widest non blank line in CONTENTS." + (if (not (org-string-nw-p contents)) contents + (let ((text-width (org-ascii--current-text-width element info)) + (how (org-ascii--current-justification element))) + (cond + ((eq (org-element-type element) 'paragraph) + ;; Paragraphs are treated specially as they need to be filled. + (org-ascii--fill-string contents text-width info how)) + ((eq how 'left) contents) + (t (with-temp-buffer + (insert contents) + (goto-char (point-min)) + (catch 'exit + (let ((max-width 0)) + ;; Compute maximum width. Bail out if it is greater + ;; than page width, since no justification is + ;; possible. + (save-excursion + (while (not (eobp)) + (unless (org-looking-at-p "[ \t]*$") + (end-of-line) + (let ((column (current-column))) + (cond + ((>= column text-width) (throw 'exit contents)) + ((> column max-width) (setq max-width column))))) + (forward-line))) + ;; Justify every line according to TEXT-WIDTH and + ;; MAX-WIDTH. + (let ((offset (/ (- text-width max-width) + (if (eq how 'right) 1 2)))) + (if (zerop offset) (throw 'exit contents) + (while (not (eobp)) + (unless (org-looking-at-p "[ \t]*$") + (org-indent-to-column offset)) + (forward-line))))) + (buffer-string)))))))) + (defun org-ascii--indent-string (s width) "Indent string S by WIDTH white spaces. Empty lines are not indented." @@ -474,24 +552,25 @@ INFO is a plist used as a communication channel." INFO is a plist used as a communication channel." (case (org-element-type element) ;; Elements with an absolute width: `headline' and `inlinetask'. - (inlinetask org-ascii-inlinetask-width) + (inlinetask (plist-get info :ascii-inlinetask-width)) (headline - (- org-ascii-text-width + (- (plist-get info :ascii-text-width) (let ((low-level-rank (org-export-low-level-p element info))) - (if low-level-rank (* low-level-rank 2) org-ascii-global-margin)))) + (if low-level-rank (* low-level-rank 2) + (plist-get info :ascii-global-margin))))) ;; Elements with a relative width: store maximum text width in ;; TOTAL-WIDTH. (otherwise - (let* ((genealogy (cons element (org-export-get-genealogy element))) + (let* ((genealogy (org-element-lineage element nil t)) ;; Total width is determined by the presence, or not, of an ;; inline task among ELEMENT parents. (total-width (if (loop for parent in genealogy thereis (eq (org-element-type parent) 'inlinetask)) - org-ascii-inlinetask-width + (plist-get info :ascii-inlinetask-width) ;; No inlinetask: Remove global margin from text width. - (- org-ascii-text-width - org-ascii-global-margin + (- (plist-get info :ascii-text-width) + (plist-get info :ascii-global-margin) (let ((parent (org-export-get-parent-headline element))) ;; Inner margin doesn't apply to text before first ;; headline. @@ -502,41 +581,66 @@ INFO is a plist used as a communication channel." ;; low level headlines, since they've got their ;; own indentation mechanism. (if low-level-rank (* low-level-rank 2) - org-ascii-inner-margin)))))))) + (plist-get info :ascii-inner-margin))))))))) (- total-width - ;; Each `quote-block', `quote-section' and `verse-block' above - ;; narrows text width by twice the standard margin size. + ;; Each `quote-block' and `verse-block' above narrows text + ;; width by twice the standard margin size. (+ (* (loop for parent in genealogy when (memq (org-element-type parent) - '(quote-block quote-section verse-block)) + '(quote-block verse-block)) count parent) - 2 org-ascii-quote-margin) + 2 (plist-get info :ascii-quote-margin)) + ;; Apply list margin once per "top-level" plain-list + ;; containing current line + (* (let ((count 0)) + (dolist (e genealogy count) + (and (eq (org-element-type e) 'plain-list) + (not (eq (org-element-type (org-export-get-parent e)) + 'item)) + (incf count)))) + (plist-get info :ascii-list-margin)) ;; Text width within a plain-list is restricted by ;; indentation of current item. If that's the case, ;; compute it with the help of `:structure' property from ;; parent item, if any. - (let ((parent-item + (let ((item (if (eq (org-element-type element) 'item) element (loop for parent in genealogy when (eq (org-element-type parent) 'item) return parent)))) - (if (not parent-item) 0 + (if (not item) 0 ;; Compute indentation offset of the current item, ;; that is the sum of the difference between its ;; indentation and the indentation of the top item in ;; the list and current item bullet's length. Also ;; remove checkbox length, and tag length (for ;; description lists) or bullet length. - (let ((struct (org-element-property :structure parent-item)) - (beg-item (org-element-property :begin parent-item))) + (let ((struct (org-element-property :structure item)) + (beg-item (org-element-property :begin item))) (+ (- (org-list-get-ind beg-item struct) (org-list-get-ind (org-list-get-top-point struct) struct)) - (string-width (or (org-ascii--checkbox parent-item info) + (string-width (or (org-ascii--checkbox item info) "")) (string-width - (or (org-list-get-tag beg-item struct) - (org-list-get-bullet beg-item struct))))))))))))) + (let ((tag (org-element-property :tag item))) + (if tag (org-export-data tag info) + (org-element-property :bullet item)))))))))))))) + +(defun org-ascii--current-justification (element) + "Return expected justification for ELEMENT's contents. +Return value is a symbol among `left', `center', `right' and +`full'." + (let (justification) + (while (and (not justification) + (setq element (org-element-property :parent element))) + (case (org-element-type element) + (center-block (setq justification 'center)) + (special-block + (let ((name (org-element-property :type element))) + (cond ((string= name "JUSTIFYRIGHT") (setq justification 'right)) + ((string= name "JUSTIFYLEFT") (setq justification 'left))))))) + (or justification 'left))) (defun org-ascii--build-title (element info text-width &optional underline notags toc) @@ -601,7 +705,7 @@ possible. It doesn't apply to `inlinetask' elements." (let ((under-char (nth (1- (org-export-get-relative-level element info)) (cdr (assq (plist-get info :ascii-charset) - org-ascii-underline))))) + (plist-get info :ascii-underline)))))) (and under-char (concat "\n" (make-string (/ (string-width first-part) @@ -640,7 +744,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) +(defun org-ascii--build-toc (info &optional n keyword local) "Return a table of contents. INFO is a plist used as a communication channel. @@ -649,28 +753,34 @@ 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." - (let ((title (org-ascii--translate "Table of Contents" info))) - (concat - title "\n" - (make-string (string-width title) - (if (eq (plist-get info :ascii-charset) 'utf-8) ?─ ?_)) - "\n\n" - (let ((text-width - (if keyword (org-ascii--current-text-width keyword info) - (- org-ascii-text-width org-ascii-global-margin)))) - (mapconcat - (lambda (headline) - (let* ((level (org-export-get-relative-level headline info)) - (indent (* (1- level) 3))) - (concat - (unless (zerop indent) (concat (make-string (1- indent) ?.) " ")) - (org-ascii--build-title - headline info (- text-width indent) nil - (or (not (plist-get info :with-tags)) - (eq (plist-get info :with-tags) 'not-in-toc)) - 'toc)))) - (org-export-collect-headlines info n) "\n"))))) +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." + (concat + (unless local + (let ((title (org-ascii--translate "Table of Contents" info))) + (concat title "\n" + (make-string + (string-width title) + (if (eq (plist-get info :ascii-charset) 'utf-8) ?─ ?_)) + "\n\n"))) + (let ((text-width + (if keyword (org-ascii--current-text-width keyword info) + (- (plist-get info :ascii-text-width) + (plist-get info :ascii-global-margin))))) + (mapconcat + (lambda (headline) + (let* ((level (org-export-get-relative-level headline info)) + (indent (* (1- level) 3))) + (concat + (unless (zerop indent) (concat (make-string (1- indent) ?.) " ")) + (org-ascii--build-title + headline info (- text-width indent) nil + (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")))) (defun org-ascii--list-listings (keyword info) "Return a list of listings. @@ -685,7 +795,8 @@ generation. INFO is a plist used as a communication channel." "\n\n" (let ((text-width (if keyword (org-ascii--current-text-width keyword info) - (- org-ascii-text-width org-ascii-global-margin))) + (- (plist-get info :ascii-text-width) + (plist-get info :ascii-global-margin)))) ;; Use a counter instead of retrieving ordinal of each ;; src-block. (count 0)) @@ -724,7 +835,8 @@ generation. INFO is a plist used as a communication channel." "\n\n" (let ((text-width (if keyword (org-ascii--current-text-width keyword info) - (- org-ascii-text-width org-ascii-global-margin))) + (- (plist-get info :ascii-text-width) + (plist-get info :ascii-global-margin)))) ;; Use a counter instead of retrieving ordinal of each ;; src-block. (count 0)) @@ -809,16 +921,28 @@ channel." (format "[%s] %s" anchor - (if (not dest) (org-ascii--translate "Unknown reference" info) + (if (stringp dest) ; External file. + dest (format (org-ascii--translate "See section %s" info) - (mapconcat 'number-to-string - (org-export-get-headline-number dest info) ".")))) - width info) "\n\n"))) + (if (org-export-numbered-headline-p dest info) + (mapconcat #'number-to-string + (org-export-get-headline-number dest info) + ".") + (org-export-data (org-element-property :title dest) info))))) + width info) + "\n\n"))) ;; Do not add a link that cannot be resolved and doesn't have ;; any description: destination is already visible in the ;; paragraph. ((not (org-element-contents link)) nil) + ;; Do not add a link already handled by custom export + ;; functions. + ((let ((protocol (nth 2 (assoc type org-link-protocols))) + (path (org-element-property :path link))) + (and (functionp protocol) + (funcall protocol (org-link-unescape path) anchor 'ascii))) + nil) (t (concat (org-ascii--fill-string @@ -843,11 +967,15 @@ INFO is a plist used as a communication channel." (defun org-ascii-template--document-title (info) "Return document title, as a string. INFO is a plist used as a communication channel." - (let* ((text-width org-ascii-text-width) + (let* ((text-width (plist-get info :ascii-text-width)) ;; Links in the title will not be resolved later, so we make ;; sure their path is located right after them. - (org-ascii-links-to-notes nil) - (title (org-export-data (plist-get info :title) info)) + (info (org-combine-plists info '(:ascii-links-to-notes nil))) + (with-title (plist-get info :with-title)) + (title (org-export-data + (when with-title (plist-get info :title)) info)) + (subtitle (org-export-data + (when with-title (plist-get info :subtitle)) info)) (author (and (plist-get info :with-author) (let ((auth (plist-get info :author))) (and auth (org-export-data auth info))))) @@ -878,7 +1006,7 @@ INFO is a plist used as a communication channel." date "\n\n\n")) ((org-string-nw-p date) (concat - (org-ascii--justify-string date text-width 'right) + (org-ascii--justify-lines date text-width 'right) "\n\n\n")) ((and (org-string-nw-p author) (org-string-nw-p email)) (concat author "\n" email "\n\n\n")) @@ -890,8 +1018,14 @@ INFO is a plist used as a communication channel." (let* ((utf8p (eq (plist-get info :ascii-charset) 'utf-8)) ;; Format TITLE. It may be filled if it is too wide, ;; that is wider than the two thirds of the total width. - (title-len (min (length title) (/ (* 2 text-width) 3))) + (title-len (min (apply #'max + (mapcar #'length + (org-split-string + (concat title "\n" subtitle) "\n"))) + (/ (* 2 text-width) 3))) (formatted-title (org-ascii--fill-string title title-len info)) + (formatted-subtitle (when (org-string-nw-p subtitle) + (org-ascii--fill-string subtitle title-len info))) (line (make-string (min (+ (max title-len @@ -899,17 +1033,16 @@ INFO is a plist used as a communication channel." (string-width (or email ""))) 2) text-width) (if utf8p ?━ ?_)))) - (org-ascii--justify-string + (org-ascii--justify-lines (concat line "\n" (unless utf8p "\n") (upcase formatted-title) + (and formatted-subtitle (concat "\n" formatted-subtitle)) (cond ((and (org-string-nw-p author) (org-string-nw-p email)) - (concat (if utf8p "\n\n\n" "\n\n") author "\n" email)) - ((org-string-nw-p author) - (concat (if utf8p "\n\n\n" "\n\n") author)) - ((org-string-nw-p email) - (concat (if utf8p "\n\n\n" "\n\n") email))) + (concat "\n\n" author "\n" email)) + ((org-string-nw-p author) (concat "\n\n" author)) + ((org-string-nw-p email) (concat "\n\n" email))) "\n" line (when (org-string-nw-p date) (concat "\n\n\n" date)) "\n\n\n") text-width 'center))))) @@ -919,81 +1052,82 @@ INFO is a plist used as a communication channel." CONTENTS is the transcoded contents string. INFO is a plist holding export options." (org-element-normalize-string - (org-ascii--indent-string - (concat - ;; 1. Document's body. - contents - ;; 2. Footnote definitions. - (let ((definitions (org-export-collect-footnote-definitions - (plist-get info :parse-tree) info)) - ;; Insert full links right inside the footnote definition - ;; as they have no chance to be inserted later. - (org-ascii-links-to-notes nil)) - (when definitions - (concat - "\n\n\n" - (let ((title (org-ascii--translate "Footnotes" info))) - (concat - title "\n" - (make-string - (string-width title) - (if (eq (plist-get info :ascii-charset) 'utf-8) ?─ ?_)))) - "\n\n" - (let ((text-width (- org-ascii-text-width org-ascii-global-margin))) - (mapconcat - (lambda (ref) - (let ((id (format "[%s] " (car ref)))) - ;; Distinguish between inline definitions and - ;; full-fledged definitions. - (org-trim - (let ((def (nth 2 ref))) - (if (eq (org-element-type def) 'org-data) - ;; Full-fledged definition: footnote ID is - ;; inserted inside the first parsed paragraph - ;; (FIRST), if any, to be sure filling will - ;; take it into consideration. - (let ((first (car (org-element-contents def)))) - (if (not (eq (org-element-type first) 'paragraph)) - (concat id "\n" (org-export-data def info)) - (push id (nthcdr 2 first)) - (org-export-data def info))) - ;; Fill paragraph once footnote ID is inserted - ;; in order to have a correct length for first - ;; line. - (org-ascii--fill-string - (concat id (org-export-data def info)) - text-width info)))))) - definitions "\n\n")))))) - org-ascii-global-margin))) + (let ((global-margin (plist-get info :ascii-global-margin))) + (org-ascii--indent-string + (concat + ;; 1. Document's body. + contents + ;; 2. Footnote definitions. + (let ((definitions (org-export-collect-footnote-definitions info)) + ;; Insert full links right inside the footnote definition + ;; as they have no chance to be inserted later. + (info (org-combine-plists info '(:ascii-links-to-notes nil)))) + (when definitions + (concat + "\n\n\n" + (let ((title (org-ascii--translate "Footnotes" info))) + (concat + title "\n" + (make-string + (string-width title) + (if (eq (plist-get info :ascii-charset) 'utf-8) ?─ ?_)))) + "\n\n" + (let ((text-width (- (plist-get info :ascii-text-width) + global-margin))) + (mapconcat + (lambda (ref) + (let ((id (format "[%s] " (car ref)))) + ;; Distinguish between inline definitions and + ;; full-fledged definitions. + (org-trim + (let ((def (nth 2 ref))) + (if (eq (org-element-type def) 'org-data) + ;; Full-fledged definition: footnote ID is + ;; inserted inside the first parsed + ;; paragraph (FIRST), if any, to be sure + ;; filling will take it into consideration. + (let ((first (car (org-element-contents def)))) + (if (not (eq (org-element-type first) 'paragraph)) + (concat id "\n" (org-export-data def info)) + (push id (nthcdr 2 first)) + (org-export-data def info))) + ;; Fill paragraph once footnote ID is inserted + ;; in order to have a correct length for first + ;; line. + (org-ascii--fill-string + (concat id (org-export-data def info)) + text-width info)))))) + definitions "\n\n")))))) + global-margin)))) (defun org-ascii-template (contents info) "Return complete document string after ASCII conversion. CONTENTS is the transcoded contents string. INFO is a plist holding export options." - (concat - ;; 1. Build title block. - (org-ascii--indent-string - (concat (org-ascii-template--document-title info) - ;; 2. Table of contents. - (let ((depth (plist-get info :with-toc))) - (when depth - (concat - (org-ascii--build-toc info (and (wholenump depth) depth)) - "\n\n\n")))) - org-ascii-global-margin) - ;; 3. Document's body. - contents - ;; 4. Creator. Ignore `comment' value as there are no comments in - ;; ASCII. Justify it to the bottom right. - (org-ascii--indent-string - (let ((creator-info (plist-get info :with-creator)) - (text-width (- org-ascii-text-width org-ascii-global-margin))) - (unless (or (not creator-info) (eq creator-info 'comment)) - (concat - "\n\n\n" - (org-ascii--fill-string - (plist-get info :creator) text-width info 'right)))) - org-ascii-global-margin))) + (let ((global-margin (plist-get info :ascii-global-margin))) + (concat + ;; Build title block. + (org-ascii--indent-string + (concat (org-ascii-template--document-title info) + ;; 2. Table of contents. + (let ((depth (plist-get info :with-toc))) + (when depth + (concat + (org-ascii--build-toc info (and (wholenump depth) depth)) + "\n\n\n")))) + global-margin) + ;; Document's body. + contents + ;; Creator. Justify it to the bottom right. + (and (plist-get info :with-creator) + (org-ascii--indent-string + (let ((text-width + (- (plist-get info :ascii-text-width) global-margin))) + (concat + "\n\n\n" + (org-ascii--fill-string + (plist-get info :creator) text-width info 'right))) + global-margin))))) (defun org-ascii--translate (s info) "Translate string S according to specified language and charset. @@ -1020,8 +1154,9 @@ contextual information." "Transcode a CENTER-BLOCK element from Org to ASCII. CONTENTS holds the contents of the block. INFO is a plist holding contextual information." - (org-ascii--justify-string - contents (org-ascii--current-text-width center-block info) 'center)) + ;; Center has already been taken care of at a lower level, so + ;; there's nothing left to do. + contents) ;;;; Clock @@ -1030,16 +1165,16 @@ holding contextual information." "Transcode a CLOCK object from Org to ASCII. CONTENTS is nil. INFO is a plist holding contextual information." - (concat org-clock-string " " - (org-translate-time - (org-element-property :raw-value - (org-element-property :value clock))) - (let ((time (org-element-property :duration clock))) - (and time - (concat " => " - (apply 'format - "%2s:%02s" - (org-split-string time ":"))))))) + (org-ascii--justify-element + (concat org-clock-string " " + (org-timestamp-translate (org-element-property :value clock)) + (let ((time (org-element-property :duration clock))) + (and time + (concat " => " + (apply 'format + "%2s:%02s" + (org-split-string time ":")))))) + clock info)) ;;;; Code @@ -1048,7 +1183,8 @@ information." "Return a CODE object from Org to ASCII. CONTENTS is nil. INFO is a plist holding contextual information." - (format org-ascii-verbatim-format (org-element-property :value code))) + (format (plist-get info :ascii-verbatim-format) + (org-element-property :value code))) ;;;; Drawer @@ -1059,7 +1195,8 @@ CONTENTS holds the contents of the block. INFO is a plist holding contextual information." (let ((name (org-element-property :drawer-name drawer)) (width (org-ascii--current-text-width drawer info))) - (funcall org-ascii-format-drawer-function name contents width))) + (funcall (plist-get info :ascii-format-drawer-function) + name contents width))) ;;;; Dynamic Block @@ -1087,8 +1224,10 @@ contextual information." (defun org-ascii-example-block (example-block contents info) "Transcode a EXAMPLE-BLOCK element from Org to ASCII. CONTENTS is nil. INFO is a plist holding contextual information." - (org-ascii--box-string - (org-export-format-code-default example-block info) info)) + (org-ascii--justify-element + (org-ascii--box-string + (org-export-format-code-default example-block info) info) + example-block info)) ;;;; Export Snippet @@ -1106,7 +1245,8 @@ CONTENTS is nil. INFO is a plist holding contextual information." "Transcode a EXPORT-BLOCK element from Org to ASCII. CONTENTS is nil. INFO is a plist holding contextual information." (when (string= (org-element-property :type export-block) "ASCII") - (org-remove-indentation (org-element-property :value export-block)))) + (org-ascii--justify-element + (org-element-property :value export-block) export-block info))) ;;;; Fixed Width @@ -1114,9 +1254,11 @@ CONTENTS is nil. INFO is a plist holding contextual information." (defun org-ascii-fixed-width (fixed-width contents info) "Transcode a FIXED-WIDTH element from Org to ASCII. CONTENTS is nil. INFO is a plist holding contextual information." - (org-ascii--box-string - (org-remove-indentation - (org-element-property :value fixed-width)) info)) + (org-ascii--justify-element + (org-ascii--box-string + (org-remove-indentation + (org-element-property :value fixed-width)) info) + fixed-width info)) ;;;; Footnote Definition @@ -1149,8 +1291,9 @@ holding contextual information." ;; original buffer's spacing. (pre-blanks (make-string - (if org-ascii-headline-spacing (car org-ascii-headline-spacing) - (org-element-property :pre-blank headline)) ?\n)) + (or (car (plist-get info :ascii-headline-spacing)) + (org-element-property :pre-blank headline)) + ?\n)) ;; Even if HEADLINE has no section, there might be some ;; links in its title that we shouldn't forget to describe. (links @@ -1164,7 +1307,7 @@ holding contextual information." (concat ;; Bullet. (let ((bullets (cdr (assq (plist-get info :ascii-charset) - org-ascii-bullets)))) + (plist-get info :ascii-bullets))))) (char-to-string (nth (mod (1- low-level-rank) (length bullets)) bullets))) " " @@ -1192,7 +1335,7 @@ information." (let ((text-width (org-ascii--current-text-width horizontal-rule info)) (spec-width (org-export-read-attribute :attr_ascii horizontal-rule :width))) - (org-ascii--justify-string + (org-ascii--justify-lines (make-string (if (and spec-width (string-match "^[0-9]+$" spec-width)) (string-to-number spec-width) text-width) @@ -1206,7 +1349,7 @@ information." "Transcode an INLINE-SRC-BLOCK element from Org to ASCII. CONTENTS holds the contents of the item. INFO is a plist holding contextual information." - (format org-ascii-verbatim-format + (format (plist-get info :ascii-verbatim-format) (org-element-property :value inline-src-block))) @@ -1218,7 +1361,7 @@ contextual information." See `org-ascii-format-inlinetask-function' for a description of the parameters." (let* ((utf8p (eq (plist-get info :ascii-charset) 'utf-8)) - (width (or width org-ascii-inlinetask-width))) + (width (or width (plist-get info :ascii-inlinetask-width)))) (org-ascii--indent-string (concat ;; Top line, with an additional blank line if not in UTF-8. @@ -1236,9 +1379,9 @@ of the parameters." ;; Bottom line. (make-string width (if utf8p ?━ ?_))) ;; Flush the inlinetask to the right. - (- org-ascii-text-width org-ascii-global-margin + (- (plist-get info :ascii-text-width) (plist-get info :ascii-global-margin) (if (not (org-export-get-parent-headline inlinetask)) 0 - org-ascii-inner-margin) + (plist-get info :ascii-inner-margin)) (org-ascii--current-text-width inlinetask info))))) (defun org-ascii-inlinetask (inlinetask contents info) @@ -1246,7 +1389,7 @@ of the parameters." CONTENTS holds the contents of the block. INFO is a plist holding contextual information." (let ((width (org-ascii--current-text-width inlinetask info))) - (funcall org-ascii-format-inlinetask-function + (funcall (plist-get info :ascii-format-inlinetask-function) ;; todo. (and (plist-get info :with-todo-keywords) (let ((todo (org-element-property @@ -1334,20 +1477,21 @@ information." (let ((key (org-element-property :key keyword)) (value (org-element-property :value keyword))) (cond - ((string= key "ASCII") value) + ((string= key "ASCII") (org-ascii--justify-element value keyword info)) ((string= key "TOC") - (let ((value (downcase value))) - (cond - ((string-match "\\" value) - (let ((depth (or (and (string-match "[0-9]+" value) - (string-to-number (match-string 0 value))) - (plist-get info :with-toc)))) - (org-ascii--build-toc - info (and (wholenump depth) depth) keyword))) - ((string= "tables" value) - (org-ascii--list-tables keyword info)) - ((string= "listings" value) - (org-ascii--list-listings keyword info)))))))) + (org-ascii--justify-element + (let ((case-fold-search t)) + (cond + ((org-string-match-p "\\" value) + (let ((depth (and (string-match "\\<[0-9]+\\>" value) + (string-to-number (match-string 0 value)))) + (localp (org-string-match-p "\\" value))) + (org-ascii--build-toc info depth keyword localp))) + ((org-string-match-p "\\" value) + (org-ascii--list-tables keyword info)) + ((org-string-match-p "\\" value) + (org-ascii--list-listings keyword info)))) + keyword info))))) ;;;; Latex Environment @@ -1357,7 +1501,9 @@ information." CONTENTS is nil. INFO is a plist holding contextual information." (when (plist-get info :with-latex) - (org-remove-indentation (org-element-property :value latex-environment)))) + (org-ascii--justify-element + (org-remove-indentation (org-element-property :value latex-environment)) + latex-environment info))) ;;;; Latex Fragment @@ -1385,9 +1531,9 @@ CONTENTS is nil. INFO is a plist holding contextual DESC is the description part of the link, or the empty string. INFO is a plist holding contextual information." - (let ((raw-link (org-element-property :raw-link link)) - (type (org-element-property :type link))) + (let ((type (org-element-property :type link))) (cond + ((org-export-custom-protocol-maybe link desc 'ascii)) ((string= type "coderef") (let ((ref (org-element-property :path link))) (format (org-export-get-coderef-format ref desc) @@ -1404,14 +1550,33 @@ INFO is a plist holding contextual information." (let ((number (org-export-get-ordinal destination info nil 'org-ascii--has-caption-p))) - (when number - (if (atom number) (number-to-string number) - (mapconcat 'number-to-string number ".")))))))) + (if number + (if (atom number) (number-to-string number) + (mapconcat #'number-to-string number ".")) + ;; Unnumbered headline. + (when (eq 'headline (org-element-type destination)) + (format "[%s]" + (org-export-data + (org-element-property :title destination) + info))))))))) (t - (if (not (org-string-nw-p desc)) (format "[%s]" raw-link) - (concat - (format "[%s]" desc) - (unless org-ascii-links-to-notes (format " (%s)" raw-link)))))))) + (let ((raw-link (org-element-property :raw-link link))) + (if (not (org-string-nw-p desc)) (format "[%s]" raw-link) + (concat (format "[%s]" desc) + (and (not (plist-get info :ascii-links-to-notes)) + (format " (%s)" raw-link))))))))) + + +;;;; Node Properties + +(defun org-ascii-node-property (node-property contents info) + "Transcode a NODE-PROPERTY element from Org to ASCII. +CONTENTS is nil. INFO is a plist holding contextual +information." + (format "%s:%s" + (org-element-property :key node-property) + (let ((value (org-element-property :value node-property))) + (if value (concat " " value) "")))) ;;;; Paragraph @@ -1420,16 +1585,17 @@ INFO is a plist holding contextual information." "Transcode a PARAGRAPH element from Org to ASCII. CONTENTS is the contents of the paragraph, as a string. INFO is the plist used as a communication channel." - (org-ascii--fill-string - (if (not (wholenump org-ascii-indented-line-width)) contents - (concat - ;; Do not indent first paragraph in a section. - (unless (and (not (org-export-get-previous-element paragraph info)) - (eq (org-element-type (org-export-get-parent paragraph)) - 'section)) - (make-string org-ascii-indented-line-width ?\s)) - (replace-regexp-in-string "\\`[ \t]+" "" contents))) - (org-ascii--current-text-width paragraph info) info)) + (org-ascii--justify-element + (let ((indented-line-width (plist-get info :ascii-indented-line-width))) + (if (not (wholenump indented-line-width)) contents + (concat + ;; Do not indent first paragraph in a section. + (unless (and (not (org-export-get-previous-element paragraph info)) + (eq (org-element-type (org-export-get-parent paragraph)) + 'section)) + (make-string indented-line-width ?\s)) + (replace-regexp-in-string "\\`[ \t]+" "" contents)))) + paragraph info)) ;;;; Plain List @@ -1438,7 +1604,11 @@ the plist used as a communication channel." "Transcode a PLAIN-LIST element from Org to ASCII. CONTENTS is the contents of the list. INFO is a plist holding contextual information." - contents) + (let ((margin (plist-get info :ascii-list-margin))) + (if (or (< margin 1) + (eq (org-element-type (org-export-get-parent plain-list)) 'item)) + contents + (org-ascii--indent-string contents margin)))) ;;;; Plain Text @@ -1466,25 +1636,34 @@ INFO is a plist used as a communication channel." "Transcode a PLANNING element from Org to ASCII. CONTENTS is nil. INFO is a plist used as a communication channel." - (mapconcat - 'identity - (delq nil - (list (let ((closed (org-element-property :closed planning))) - (when closed - (concat org-closed-string " " - (org-translate-time - (org-element-property :raw-value closed))))) - (let ((deadline (org-element-property :deadline planning))) - (when deadline - (concat org-deadline-string " " - (org-translate-time - (org-element-property :raw-value deadline))))) - (let ((scheduled (org-element-property :scheduled planning))) - (when scheduled - (concat org-scheduled-string " " - (org-translate-time - (org-element-property :raw-value scheduled))))))) - " ")) + (org-ascii--justify-element + (mapconcat + #'identity + (delq nil + (list (let ((closed (org-element-property :closed planning))) + (when closed + (concat org-closed-string " " + (org-timestamp-translate closed)))) + (let ((deadline (org-element-property :deadline planning))) + (when deadline + (concat org-deadline-string " " + (org-timestamp-translate deadline)))) + (let ((scheduled (org-element-property :scheduled planning))) + (when scheduled + (concat org-scheduled-string " " + (org-timestamp-translate scheduled)))))) + " ") + planning info)) + + +;;;; Property Drawer + +(defun org-ascii-property-drawer (property-drawer contents info) + "Transcode a PROPERTY-DRAWER element from Org to ASCII. +CONTENTS holds the contents of the drawer. INFO is a plist +holding contextual information." + (and (org-string-nw-p contents) + (org-ascii--justify-element contents property-drawer info))) ;;;; Quote Block @@ -1493,26 +1672,7 @@ channel." "Transcode a QUOTE-BLOCK element from Org to ASCII. CONTENTS holds the contents of the block. INFO is a plist holding contextual information." - (org-ascii--indent-string contents org-ascii-quote-margin)) - - -;;;; Quote Section - -(defun org-ascii-quote-section (quote-section contents info) - "Transcode a QUOTE-SECTION element from Org to ASCII. -CONTENTS is nil. INFO is a plist holding contextual information." - (let ((width (org-ascii--current-text-width quote-section info)) - (value - (org-export-data - (org-remove-indentation (org-element-property :value quote-section)) - info))) - (org-ascii--indent-string - value - (+ org-ascii-quote-margin - ;; Don't apply inner margin if parent headline is low level. - (let ((headline (org-export-get-parent-headline quote-section))) - (if (org-export-low-level-p headline info) 0 - org-ascii-inner-margin)))))) + (org-ascii--indent-string contents (plist-get info :ascii-quote-margin))) ;;;; Radio Target @@ -1533,7 +1693,7 @@ contextual information." (org-ascii--indent-string (concat contents - (when org-ascii-links-to-notes + (when (plist-get info :ascii-links-to-notes) ;; Add list of links at the end of SECTION. (let ((links (org-ascii--describe-links (org-ascii--unique-links section info) @@ -1543,7 +1703,7 @@ contextual information." ;; Do not apply inner margin if parent headline is low level. (let ((headline (org-export-get-parent-headline section))) (if (or (not headline) (org-export-low-level-p headline info)) 0 - org-ascii-inner-margin)))) + (plist-get info :ascii-inner-margin))))) ;;;; Special Block @@ -1552,6 +1712,9 @@ contextual information." "Transcode a SPECIAL-BLOCK element from Org to ASCII. CONTENTS holds the contents of the block. INFO is a plist holding contextual information." + ;; "JUSTIFYLEFT" and "JUSTFYRIGHT" have already been taken care of + ;; at a lower level. There is no other special block type to + ;; handle. contents) @@ -1562,13 +1725,15 @@ holding contextual information." CONTENTS holds the contents of the item. INFO is a plist holding contextual information." (let ((caption (org-ascii--build-caption src-block info)) + (caption-above-p (plist-get info :ascii-caption-above)) (code (org-export-format-code-default src-block info))) (if (equal code "") "" - (concat - (when (and caption org-ascii-caption-above) (concat caption "\n")) - (org-ascii--box-string code info) - (when (and caption (not org-ascii-caption-above)) - (concat "\n" caption)))))) + (org-ascii--justify-element + (concat + (and caption caption-above-p (concat caption "\n")) + (org-ascii--box-string code info) + (and caption (not caption-above-p) (concat "\n" caption))) + src-block info)))) ;;;; Statistics Cookie @@ -1616,26 +1781,29 @@ holding contextual information." "Transcode a TABLE element from Org to ASCII. CONTENTS is the contents of the table. INFO is a plist holding contextual information." - (let ((caption (org-ascii--build-caption table info))) - (concat - ;; Possibly add a caption string above. - (when (and caption org-ascii-caption-above) (concat caption "\n")) - ;; Insert table. Note: "table.el" tables are left unmodified. - (cond ((eq (org-element-property :type table) 'org) contents) - ((and org-ascii-table-use-ascii-art - (eq (plist-get info :ascii-charset) 'utf-8) - (require 'ascii-art-to-unicode nil t)) - (with-temp-buffer - (insert (org-remove-indentation - (org-element-property :value table))) - (goto-char (point-min)) - (aa2u) - (goto-char (point-max)) - (skip-chars-backward " \r\t\n") - (buffer-substring (point-min) (point)))) - (t (org-remove-indentation (org-element-property :value table)))) - ;; Possible add a caption string below. - (and (not org-ascii-caption-above) caption)))) + (let ((caption (org-ascii--build-caption table info)) + (caption-above-p (plist-get info :ascii-caption-above))) + (org-ascii--justify-element + (concat + ;; Possibly add a caption string above. + (and caption caption-above-p (concat caption "\n")) + ;; Insert table. Note: "table.el" tables are left unmodified. + (cond ((eq (org-element-property :type table) 'org) contents) + ((and (plist-get info :ascii-table-use-ascii-art) + (eq (plist-get info :ascii-charset) 'utf-8) + (require 'ascii-art-to-unicode nil t)) + (with-temp-buffer + (insert (org-remove-indentation + (org-element-property :value table))) + (goto-char (point-min)) + (aa2u) + (goto-char (point-max)) + (skip-chars-backward " \r\t\n") + (buffer-substring (point-min) (point)))) + (t (org-remove-indentation (org-element-property :value table)))) + ;; Possible add a caption string below. + (and (not caption-above-p) caption)) + table info))) ;;;; Table Cell @@ -1661,12 +1829,13 @@ are ignored." (plist-put info :ascii-table-cell-width-cache (make-hash-table :test 'equal))) :ascii-table-cell-width-cache))) - (key (cons table col))) + (key (cons table col)) + (widenp (plist-get info :ascii-table-widen-columns))) (or (gethash key cache) (puthash key (let ((cookie-width (org-export-table-cell-width table-cell info))) - (or (and (not org-ascii-table-widen-columns) cookie-width) + (or (and (not widenp) cookie-width) (let ((contents-width (let ((max-width 0)) (org-element-map table 'table-row @@ -1681,8 +1850,7 @@ are ignored." info) max-width))) (cond ((not cookie-width) contents-width) - (org-ascii-table-widen-columns - (max cookie-width contents-width)) + (widenp (max cookie-width contents-width)) (t cookie-width))))) cache)))) @@ -1696,14 +1864,14 @@ a communication channel." ;; each cell in the column. (let ((width (org-ascii--table-cell-width table-cell info))) ;; When contents are too large, truncate them. - (unless (or org-ascii-table-widen-columns + (unless (or (plist-get info :ascii-table-widen-columns) (<= (string-width (or contents "")) width)) (setq contents (concat (substring contents 0 (- width 2)) "=>"))) ;; Align contents correctly within the cell. (let* ((indent-tabs-mode nil) (data (when contents - (org-ascii--justify-string + (org-ascii--justify-lines contents width (org-export-table-cell-alignment table-cell info))))) (setq contents @@ -1790,7 +1958,7 @@ holding contextual information." (defun org-ascii-verbatim (verbatim contents info) "Return a VERBATIM object from Org to ASCII. CONTENTS is nil. INFO is a plist holding contextual information." - (format org-ascii-verbatim-format + (format (plist-get info :ascii-verbatim-format) (org-element-property :value verbatim))) @@ -1802,8 +1970,8 @@ CONTENTS is verse block contents. INFO is a plist holding contextual information." (let ((verse-width (org-ascii--current-text-width verse-block info))) (org-ascii--indent-string - (org-ascii--justify-string contents verse-width 'left) - org-ascii-quote-margin))) + (org-ascii--justify-element contents verse-block info) + (plist-get info :ascii-quote-margin)))) @@ -1818,9 +1986,10 @@ plist containing the communication channel. This function only applies to `ascii' back-end. See `org-ascii-headline-spacing' for information." - (if (not org-ascii-headline-spacing) headline - (let ((blanks (make-string (1+ (cdr org-ascii-headline-spacing)) ?\n))) - (replace-regexp-in-string "\n\\(?:\n[ \t]*\\)*\\'" blanks headline)))) + (let ((headline-spacing (plist-get info :ascii-headline-spacing))) + (if (not headline-spacing) headline + (let ((blanks (make-string (1+ (cdr headline-spacing)) ?\n))) + (replace-regexp-in-string "\n\\(?:\n[ \t]*\\)*\\'" blanks headline))))) (defun org-ascii-filter-paragraph-spacing (tree back-end info) "Filter controlling number of blank lines between paragraphs. @@ -1830,13 +1999,13 @@ back-end used for export. INFO is a plist used as a communication channel. See `org-ascii-paragraph-spacing' for information." - (when (wholenump org-ascii-paragraph-spacing) - (org-element-map tree 'paragraph - (lambda (p) - (when (eq (org-element-type (org-export-get-next-element p info)) - 'paragraph) - (org-element-put-property - p :post-blank org-ascii-paragraph-spacing))))) + (let ((paragraph-spacing (plist-get info :ascii-paragraph-spacing))) + (when (wholenump paragraph-spacing) + (org-element-map tree 'paragraph + (lambda (p) + (when (eq (org-element-type (org-export-get-next-element p info)) + 'paragraph) + (org-element-put-property p :post-blank paragraph-spacing)))))) tree) (defun org-ascii-filter-comment-spacing (tree backend info) diff --git a/elpa/org-20150629/ox-beamer.el b/elpa/org-20160215/ox-beamer.el similarity index 86% rename from elpa/org-20150629/ox-beamer.el rename to elpa/org-20160215/ox-beamer.el index abfd181c..7afe3903 100644 --- a/elpa/org-20150629/ox-beamer.el +++ b/elpa/org-20160215/ox-beamer.el @@ -1,6 +1,6 @@ ;;; ox-beamer.el --- Beamer Back-End for Org Export Engine -;; Copyright (C) 2007-2014 Free Software Foundation, Inc. +;; Copyright (C) 2007-2016 Free Software Foundation, Inc. ;; Author: Carsten Dominik ;; Nicolas Goaziou @@ -105,7 +105,9 @@ key Selection key for `org-beamer-select-environment' open The opening template for the environment, with the following escapes %a the action/overlay specification %A the default action/overlay specification - %o the options argument of the template + %R the raw BEAMER_act value + %o the options argument, with square brackets + %O the raw BEAMER_opt value %h the headline text %r the raw headline text (i.e. without any processing) %H if there is headline text, that raw text in {} braces @@ -133,6 +135,15 @@ You might want to put e.g. \"allowframebreaks=0.9\" here." :type '(string :tag "Outline frame options")) +(defcustom org-beamer-subtitle-format "\\subtitle{%s}" + "Format string used for transcoded subtitle. +The format string should have at most one \"%s\"-expression, +which is replaced with the subtitle." + :group 'org-export-beamer + :version "25.1" + :package-version '(Org . "8.3") + :type '(string :tag "Format string")) + ;;; Internal Variables @@ -231,15 +242,20 @@ Return overlay specification, as a string, or nil." (if a (org-beamer-export-to-pdf t s v b) (org-open-file (org-beamer-export-to-pdf nil s v b))))))) :options-alist - '((:beamer-theme "BEAMER_THEME" nil org-beamer-theme) + '((:headline-levels nil "H" org-beamer-frame-level) + (:latex-class "LATEX_CLASS" nil "beamer" t) + (:beamer-subtitle-format nil nil org-beamer-subtitle-format) + (:beamer-column-view-format "COLUMNS" nil org-beamer-column-view-format) + (:beamer-theme "BEAMER_THEME" nil org-beamer-theme) (:beamer-color-theme "BEAMER_COLOR_THEME" nil nil t) (:beamer-font-theme "BEAMER_FONT_THEME" nil nil t) (:beamer-inner-theme "BEAMER_INNER_THEME" nil nil t) (:beamer-outer-theme "BEAMER_OUTER_THEME" nil nil t) - (:beamer-header-extra "BEAMER_HEADER" nil nil newline) - ;; Modify existing properties. - (:headline-levels nil "H" org-beamer-frame-level) - (:latex-class "LATEX_CLASS" nil "beamer" t)) + (:beamer-header "BEAMER_HEADER" nil nil newline) + (:beamer-environments-extra nil nil org-beamer-environments-extra) + (:beamer-frame-default-options nil nil org-beamer-frame-default-options) + (:beamer-outline-frame-options nil nil org-beamer-outline-frame-options) + (:beamer-outline-frame-title nil nil org-beamer-outline-frame-title)) :translate-alist '((bold . org-beamer-bold) (export-block . org-beamer-export-block) (export-snippet . org-beamer-export-snippet) @@ -315,16 +331,17 @@ channel." INFO is a plist used as a communication channel. The value is either the label specified in \"BEAMER_opt\" -property, or a fallback value built from headline's number. This -function assumes HEADLINE will be treated as a frame." +property, or a unique internal label. This function assumes +HEADLINE will be treated as a frame." (let ((opt (org-element-property :BEAMER_OPT headline))) - (if (and (org-string-nw-p opt) + (if (and (stringp opt) (string-match "\\(?:^\\|,\\)label=\\(.*?\\)\\(?:$\\|,\\)" opt)) - (match-string 1 opt) - (format "sec-%s" - (mapconcat 'number-to-string - (org-export-get-headline-number headline info) - "-"))))) + (let ((label (match-string 1 opt))) + ;; Strip protective braces, if any. + (if (org-string-match-p "\\`{.*}\\'" label) + (substring label 1 -1) + label)) + (format "sec:%s" (org-export-get-reference headline info))))) (defun org-beamer--frame-level (headline info) "Return frame level in subtree containing HEADLINE. @@ -333,12 +350,10 @@ INFO is a plist used as a communication channel." ;; 1. Look for "frame" environment in parents, starting from the ;; farthest. (catch 'exit - (mapc (lambda (parent) - (let ((env (org-element-property :BEAMER_ENV parent))) - (when (and env (member-ignore-case env '("frame" "fullframe"))) - (throw 'exit (org-export-get-relative-level parent info))))) - (nreverse (org-export-get-genealogy headline))) - nil) + (dolist (parent (nreverse (org-element-lineage headline))) + (let ((env (org-element-property :BEAMER_ENV parent))) + (when (and env (member-ignore-case env '("frame" "fullframe"))) + (throw 'exit (org-export-get-relative-level parent info)))))) ;; 2. Look for "frame" environment in HEADLINE. (let ((env (org-element-property :BEAMER_ENV headline))) (and env (member-ignore-case env '("frame" "fullframe")) @@ -413,7 +428,8 @@ used as a communication channel." ;; Collect options from default value and headline's ;; properties. Also add a label for links. (append - (org-split-string org-beamer-frame-default-options ",") + (org-split-string + (plist-get info :beamer-frame-default-options) ",") (and beamer-opt (org-split-string ;; Remove square brackets if user provided @@ -422,12 +438,20 @@ used as a communication channel." (match-string 1 beamer-opt)) ",")) ;; Provide an automatic label for the frame - ;; unless the user specified one. + ;; unless the user specified one. Also refrain + ;; from labeling `allowframebreaks' frames; this + ;; is not allowed by beamer. (unless (and beamer-opt - (string-match "\\(^\\|,\\)label=" beamer-opt)) + (or (string-match "\\(^\\|,\\)label=" beamer-opt) + (string-match "allowframebreaks" beamer-opt))) (list - (format "label=%s" - (org-beamer--get-label headline info))))))) + (let ((label (org-beamer--get-label headline info))) + ;; Labels containing colons need to be + ;; wrapped within braces. + (format (if (org-string-match-p ":" label) + "label={%s}" + "label=%s") + label))))))) ;; Change options list into a string. (org-beamer--normalize-argument (mapconcat @@ -475,14 +499,15 @@ used as a communication channel." (env-format (cond ((member environment '("column" "columns")) nil) ((assoc environment - (append org-beamer-environments-extra + (append (plist-get info :beamer-environments-extra) org-beamer-environments-default))) (t (user-error "Wrong block type at a headline named \"%s\"" raw-title)))) (title (org-export-data (org-element-property :title headline) info)) - (options (let ((options (org-element-property :BEAMER_OPT headline))) - (if (not options) "" - (org-beamer--normalize-argument options 'option)))) + (raw-options (org-element-property :BEAMER_OPT headline)) + (options (if raw-options + (org-beamer--normalize-argument raw-options 'option) + "")) ;; Start a "columns" environment when explicitly requested or ;; when there is no previous headline or the previous ;; headline do not have a BEAMER_column property. @@ -521,7 +546,7 @@ used as a communication channel." ;; One can specify placement for column only when ;; HEADLINE stands for a column on its own. (if (equal environment "column") options "") - (format "%s\\textwidth" column-width))) + (format "%s\\columnwidth" column-width))) ;; Block's opening string. (when (nth 2 env-format) (concat @@ -534,15 +559,18 @@ used as a communication channel." ;; overlay specification and the default one is nil. (let ((action (org-element-property :BEAMER_ACT headline))) (cond - ((not action) (list (cons "a" "") (cons "A" ""))) + ((not action) (list (cons "a" "") (cons "A" "") (cons "R" ""))) ((string-match "\\`\\[.*\\]\\'" action) (list (cons "A" (org-beamer--normalize-argument action 'defaction)) - (cons "a" ""))) + (cons "a" "") + (cons "R" action))) (t (list (cons "a" (org-beamer--normalize-argument action 'action)) - (cons "A" ""))))) + (cons "A" "") + (cons "R" action))))) (list (cons "o" options) + (cons "O" (or raw-options "")) (cons "h" title) (cons "r" raw-title) (cons "H" (if (equal raw-title "") "" @@ -578,28 +606,27 @@ as a communication channel." (when overlay (org-beamer--normalize-argument overlay - (if (string-match "^\\[.*\\]$" overlay) 'defaction + (if (string-match "\\`\\[.*\\]\\'" overlay) 'defaction 'action)))) ;; Options. (let ((options (org-element-property :BEAMER_OPT headline))) (when options (org-beamer--normalize-argument options 'option))) ;; Resolve reference provided by "BEAMER_ref" - ;; property. This is done by building a minimal fake - ;; link and calling the appropriate resolve function, - ;; depending on the reference syntax. - (let* ((type - (progn - (string-match "^\\(id:\\|#\\|\\*\\)?\\(.*\\)" ref) - (cond - ((or (not (match-string 1 ref)) - (equal (match-string 1 ref) "*")) 'fuzzy) - ((equal (match-string 1 ref) "id:") 'id) - (t 'custom-id)))) - (link (list 'link (list :path (match-string 2 ref)))) - (target (if (eq type 'fuzzy) - (org-export-resolve-fuzzy-link link info) - (org-export-resolve-id-link link info)))) + ;; property. This is done by building a minimal + ;; fake link and calling the appropriate resolve + ;; function, depending on the reference syntax. + (let ((target + (if (string-match "\\`\\(id:\\|#\\)" ref) + (org-export-resolve-id-link + `(link (:path ,(substring ref (match-end 0)))) + info) + (org-export-resolve-fuzzy-link + `(link (:path + ;; Look for headlines only. + ,(if (eq (string-to-char ref) ?*) ref + (concat "*" ref)))) + info)))) ;; Now use user-defined label provided in TARGET ;; headline, or fallback to standard one. (format "{%s}" (org-beamer--get-label target info))))))) @@ -640,15 +667,27 @@ as a communication channel." "Transcode an ITEM element into Beamer code. CONTENTS holds the contents of the item. INFO is a plist holding contextual information." - (let ((action (let ((first-element (car (org-element-contents item)))) - (and (eq (org-element-type first-element) 'paragraph) - (org-beamer--element-has-overlay-p first-element)))) - (output (org-export-with-backend 'latex item contents info))) - (if (or (not action) (not (string-match "\\\\item" output))) output - ;; If the item starts with a paragraph and that paragraph starts - ;; with an export snippet specifying an overlay, insert it after - ;; \item command. - (replace-match (concat "\\\\item" action) nil nil output)))) + (org-export-with-backend + ;; Delegate item export to `latex'. However, we use `beamer' + ;; transcoders for objects in the description tag. + (org-export-create-backend + :parent 'beamer + :transcoders + (list + (cons + 'item + (lambda (item c i) + (let ((action + (let ((first (car (org-element-contents item)))) + (and (eq (org-element-type first) 'paragraph) + (org-beamer--element-has-overlay-p first)))) + (output (org-latex-item item contents info))) + (if (not (and action (string-match "\\\\item" output))) output + ;; If the item starts with a paragraph and that paragraph + ;; starts with an export snippet specifying an overlay, + ;; append it to the \item command. + (replace-match (concat "\\\\item" action) nil nil output))))))) + item contents info)) ;;;; Keyword @@ -683,15 +722,16 @@ CONTENTS is the description part of the link. INFO is a plist used as a communication channel." (let ((type (org-element-property :type link)) (path (org-element-property :path link))) - ;; Use \hyperlink command for all internal links. (cond + ;; Link type is handled by a special function. + ((org-export-custom-protocol-maybe link contents 'beamer)) + ;; Use \hyperlink command for all internal links. ((equal type "radio") (let ((destination (org-export-resolve-radio-link link info))) (if (not destination) contents (format "\\hyperlink%s{%s}{%s}" (or (org-beamer--element-has-overlay-p link) "") - (org-export-solidify-link-text - (org-element-property :value destination)) + (org-export-get-reference destination info) contents)))) ((and (member type '("custom-id" "fuzzy" "id")) (let ((destination (if (string= type "fuzzy") @@ -713,11 +753,11 @@ used as a communication channel." label contents)))) (target - (let ((path (org-export-solidify-link-text path))) - (if (not contents) (format "\\ref{%s}" path) + (let ((ref (org-export-get-reference destination info))) + (if (not contents) (format "\\ref{%s}" ref) (format "\\hyperlink%s{%s}{%s}" (or (org-beamer--element-has-overlay-p link) "") - path + ref contents)))))))) ;; Otherwise, use `latex' back-end. (t (org-export-with-backend 'latex link contents info))))) @@ -755,7 +795,8 @@ contextual information." 'option) ;; Eventually insert contents and close environment. contents - latex-type)))) + latex-type) + info))) ;;;; Radio Target @@ -766,8 +807,7 @@ TEXT is the text of the target. INFO is a plist holding contextual information." (format "\\hypertarget%s{%s}{%s}" (or (org-beamer--element-has-overlay-p radio-target) "") - (org-export-solidify-link-text - (org-element-property :value radio-target)) + (org-export-get-reference radio-target info) text)) @@ -777,8 +817,7 @@ contextual information." "Transcode a TARGET object into Beamer code. CONTENTS is nil. INFO is a plist holding contextual information." - (format "\\label{%s}" - (org-export-solidify-link-text (org-element-property :value target)))) + (format "\\label{%s}" (org-export-get-reference target info))) ;;;; Template @@ -790,7 +829,8 @@ information." "Return complete document string after Beamer conversion. CONTENTS is the transcoded contents string. INFO is a plist holding export options." - (let ((title (org-export-data (plist-get info :title) info))) + (let ((title (org-export-data (plist-get info :title) info)) + (subtitle (org-export-data (plist-get info :subtitle) info))) (concat ;; 1. Time-stamp. (and (plist-get info :time-stamp-file) @@ -817,8 +857,7 @@ holding export options." (concat (org-element-normalize-string (plist-get info :latex-header)) (org-element-normalize-string - (plist-get info :latex-header-extra)) - (plist-get info :beamer-header-extra))))) + (plist-get info :latex-header-extra)))))) info))) ;; 3. Insert themes. (let ((format-theme @@ -852,52 +891,52 @@ holding export options." (org-export-data (plist-get info :email) info)))) (cond ((and author email (not (string= "" email))) (format "\\author{%s\\thanks{%s}}\n" author email)) - (author (format "\\author{%s}\n" author)) - (t "\\author{}\n"))) + ((or author email) (format "\\author{%s}\n" (or author email))))) ;; 6. Date. (let ((date (and (plist-get info :with-date) (org-export-get-date info)))) (format "\\date{%s}\n" (org-export-data date info))) ;; 7. Title (format "\\title{%s}\n" title) - ;; 8. Hyperref options. - (when (plist-get info :latex-hyperref-p) - (format "\\hypersetup{\n pdfkeywords={%s},\n pdfsubject={%s},\n pdfcreator={%s}}\n" - (or (plist-get info :keywords) "") - (or (plist-get info :description) "") - (if (not (plist-get info :with-creator)) "" - (plist-get info :creator)))) - ;; 9. Document start. + (when (org-string-nw-p subtitle) + (concat (format (plist-get info :beamer-subtitle-format) subtitle) "\n")) + ;; 8. Beamer-header + (let ((beamer-header (plist-get info :beamer-header))) + (when beamer-header + (format "%s\n" (plist-get info :beamer-header)))) + ;; 9. Hyperref options. + (let ((template (plist-get info :latex-hyperref-template))) + (and (stringp template) + (format-spec template (org-latex--format-spec info)))) + ;; 10. Document start. "\\begin{document}\n\n" - ;; 10. Title command. + ;; 11. Title command. (org-element-normalize-string - (cond ((string= "" title) nil) + (cond ((not (plist-get info :with-title)) nil) + ((string= "" title) nil) ((not (stringp org-latex-title-command)) nil) ((string-match "\\(?:[^%]\\|^\\)%s" org-latex-title-command) (format org-latex-title-command title)) (t org-latex-title-command))) - ;; 11. Table of contents. + ;; 12. Table of contents. (let ((depth (plist-get info :with-toc))) (when depth (concat (format "\\begin{frame}%s{%s}\n" (org-beamer--normalize-argument - org-beamer-outline-frame-options 'option) - org-beamer-outline-frame-title) + (plist-get info :beamer-outline-frame-options) 'option) + (plist-get info :beamer-outline-frame-title)) (when (wholenump depth) (format "\\setcounter{tocdepth}{%d}\n" depth)) "\\tableofcontents\n" "\\end{frame}\n\n"))) - ;; 12. Document's body. + ;; 13. Document's body. contents - ;; 13. Creator. - (let ((creator-info (plist-get info :with-creator))) - (cond - ((not creator-info) "") - ((eq creator-info 'comment) - (format "%% %s\n" (plist-get info :creator))) - (t (concat (plist-get info :creator) "\n")))) - ;; 14. Document end. + ;; 14. Creator. + (if (plist-get info :with-creator) + (concat (plist-get info :creator) "\n") + "") + ;; 15. Document end. "\\end{document}"))) @@ -1120,30 +1159,6 @@ aid, but the tag does not have any semantic meaning." (org-entry-put nil "BEAMER_env" (match-string 1 tags))) (t (org-entry-delete nil "BEAMER_env")))))) -;;;###autoload -(defun org-beamer-insert-options-template (&optional kind) - "Insert a settings template, to make sure users do this right." - (interactive (progn - (message "Current [s]ubtree or [g]lobal?") - (if (eq (read-char-exclusive) ?g) (list 'global) - (list 'subtree)))) - (if (eq kind 'subtree) - (progn - (org-back-to-heading t) - (org-reveal) - (org-entry-put nil "EXPORT_LaTeX_CLASS" "beamer") - (org-entry-put nil "EXPORT_LaTeX_CLASS_OPTIONS" "[presentation]") - (org-entry-put nil "EXPORT_FILE_NAME" "presentation.pdf") - (when org-beamer-column-view-format - (org-entry-put nil "COLUMNS" org-beamer-column-view-format)) - (org-entry-put nil "BEAMER_col_ALL" org-beamer-column-widths)) - (insert "#+LaTeX_CLASS: beamer\n") - (insert "#+LaTeX_CLASS_OPTIONS: [presentation]\n") - (when org-beamer-theme (insert "#+BEAMER_THEME: " org-beamer-theme "\n")) - (when org-beamer-column-view-format - (insert "#+COLUMNS: " org-beamer-column-view-format "\n")) - (insert "#+PROPERTY: BEAMER_col_ALL " org-beamer-column-widths "\n"))) - ;;;###autoload (defun org-beamer-publish-to-latex (plist filename pub-dir) "Publish an Org file to a Beamer presentation (LaTeX). diff --git a/elpa/org-20150629/ox-html.el b/elpa/org-20160215/ox-html.el similarity index 74% rename from elpa/org-20150629/ox-html.el rename to elpa/org-20160215/ox-html.el index 23498b26..32ec5205 100644 --- a/elpa/org-20150629/ox-html.el +++ b/elpa/org-20160215/ox-html.el @@ -1,6 +1,6 @@ ;;; ox-html.el --- HTML Back-End for Org Export Engine -;; Copyright (C) 2011-2014 Free Software Foundation, Inc. +;; Copyright (C) 2011-2016 Free Software Foundation, Inc. ;; Author: Carsten Dominik ;; Jambunathan K @@ -72,13 +72,13 @@ (latex-fragment . org-html-latex-fragment) (line-break . org-html-line-break) (link . org-html-link) + (node-property . org-html-node-property) (paragraph . org-html-paragraph) (plain-list . org-html-plain-list) (plain-text . org-html-plain-text) (planning . org-html-planning) (property-drawer . org-html-property-drawer) (quote-block . org-html-quote-block) - (quote-section . org-html-quote-section) (radio-target . org-html-radio-target) (section . org-html-section) (special-block . org-html-special-block) @@ -108,25 +108,65 @@ (if a (org-html-export-to-html t s v b) (org-open-file (org-html-export-to-html nil s v b))))))) :options-alist - '((:html-extension nil nil org-html-extension) - (:html-link-org-as-html nil nil org-html-link-org-files-as-html) - (:html-doctype "HTML_DOCTYPE" nil org-html-doctype) + '((:html-doctype "HTML_DOCTYPE" nil org-html-doctype) (:html-container "HTML_CONTAINER" nil org-html-container-element) + (:description "DESCRIPTION" nil nil newline) + (:keywords "KEYWORDS" nil nil space) (:html-html5-fancy nil "html5-fancy" org-html-html5-fancy) (:html-link-use-abs-url nil "html-link-use-abs-url" org-html-link-use-abs-url) (:html-link-home "HTML_LINK_HOME" nil org-html-link-home) (:html-link-up "HTML_LINK_UP" nil org-html-link-up) (:html-mathjax "HTML_MATHJAX" nil "" space) + (:html-link-use-abs-url nil "html-link-use-abs-url" org-html-link-use-abs-url) (:html-postamble nil "html-postamble" org-html-postamble) (:html-preamble nil "html-preamble" org-html-preamble) (:html-head "HTML_HEAD" nil org-html-head newline) (:html-head-extra "HTML_HEAD_EXTRA" nil org-html-head-extra newline) - (:html-head-include-default-style nil "html-style" org-html-head-include-default-style) + (:subtitle "SUBTITLE" nil nil parse) + (:html-head-include-default-style + nil "html-style" org-html-head-include-default-style) (:html-head-include-scripts nil "html-scripts" org-html-head-include-scripts) + (:html-allow-name-attribute-in-anchors + nil nil org-html-allow-name-attribute-in-anchors) + (:html-divs nil nil org-html-divs) + (:html-checkbox-type nil nil org-html-checkbox-type) + (:html-extension nil nil org-html-extension) + (:html-footnote-format nil nil org-html-footnote-format) + (:html-footnote-separator nil nil org-html-footnote-separator) + (:html-footnotes-section nil nil org-html-footnotes-section) + (:html-format-drawer-function nil nil org-html-format-drawer-function) + (:html-format-headline-function nil nil org-html-format-headline-function) + (:html-format-inlinetask-function + nil nil org-html-format-inlinetask-function) + (:html-home/up-format nil nil org-html-home/up-format) + (:html-indent nil nil org-html-indent) + (:html-infojs-options nil nil org-html-infojs-options) + (:html-infojs-template nil nil org-html-infojs-template) + (:html-inline-image-rules nil nil org-html-inline-image-rules) + (:html-link-org-files-as-html nil nil org-html-link-org-files-as-html) + (:html-mathjax-options nil nil org-html-mathjax-options) + (:html-mathjax-template nil nil org-html-mathjax-template) + (: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-table-align-individual-fields + nil nil org-html-table-align-individual-fields) + (:html-table-caption-above nil nil org-html-table-caption-above) + (:html-table-data-tags nil nil org-html-table-data-tags) + (:html-table-header-tags nil nil org-html-table-header-tags) + (:html-table-use-header-tags-for-first-column + nil nil org-html-table-use-header-tags-for-first-column) + (:html-tag-class-prefix nil nil org-html-tag-class-prefix) + (:html-text-markup-alist nil nil org-html-text-markup-alist) + (:html-todo-kwd-class-prefix nil nil org-html-todo-kwd-class-prefix) + (:html-toplevel-hlevel nil nil org-html-toplevel-hlevel) + (:html-use-infojs nil nil org-html-use-infojs) + (:html-validation-link nil nil org-html-validation-link) + (:html-viewport nil nil org-html-viewport) + (:html-inline-images nil nil org-html-inline-images) (:html-table-attributes nil nil org-html-table-default-attributes) (:html-table-row-tags nil nil org-html-table-row-tags) (:html-xml-declaration nil nil org-html-xml-declaration) - (:html-inline-images nil nil org-html-inline-images) (:infojs-opt "INFOJS_OPT" nil nil) ;; Redefine regular options. (:creator "CREATOR" nil org-html-creator-string) @@ -232,16 +272,22 @@ for the JavaScript code in this tag. (defconst org-html-style-default "