summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--Makefile1
-rw-r--r--README_maintainer1
-rw-r--r--contrib/README1
-rw-r--r--contrib/lisp/ob-stata.el313
-rw-r--r--contrib/lisp/org-annotate-file.el26
-rw-r--r--contrib/lisp/org-bibtex-extras.el22
-rw-r--r--contrib/lisp/org-contacts.el122
-rw-r--r--contrib/lisp/org-effectiveness.el41
-rw-r--r--contrib/lisp/org-expiry.el5
-rw-r--r--contrib/lisp/org-git-link.el27
-rw-r--r--contrib/lisp/org-index.el228
-rw-r--r--contrib/lisp/org-license.el41
-rw-r--r--contrib/lisp/org-mac-link.el582
-rw-r--r--contrib/lisp/org-mime.el17
-rw-r--r--contrib/lisp/org-mtags.el255
-rw-r--r--contrib/lisp/org-notmuch.el34
-rw-r--r--contrib/lisp/org-passwords.el342
-rw-r--r--contrib/lisp/ox-bibtex.el84
-rw-r--r--contrib/lisp/ox-deck.el2
-rw-r--r--contrib/lisp/ox-extra.el190
-rw-r--r--contrib/lisp/ox-gfm.el193
-rw-r--r--contrib/lisp/ox-groff.el12
-rw-r--r--contrib/lisp/ox-koma-letter.el14
-rw-r--r--contrib/lisp/ox-rss.el43
-rw-r--r--contrib/lisp/ox-s5.el2
-rw-r--r--contrib/lisp/ox-taskjuggler.el52
-rw-r--r--doc/htmlxref.cnf2
-rw-r--r--doc/org.texi1126
-rw-r--r--doc/orgguide.texi41
-rw-r--r--doc/texinfo.tex3161
-rw-r--r--etc/ORG-NEWS97
-rw-r--r--lisp/ob-C.el338
-rw-r--r--lisp/ob-J.el10
-rw-r--r--lisp/ob-R.el142
-rw-r--r--lisp/ob-awk.el18
-rw-r--r--lisp/ob-clojure.el31
-rw-r--r--lisp/ob-comint.el2
-rw-r--r--lisp/ob-core.el172
-rw-r--r--lisp/ob-ditaa.el18
-rw-r--r--lisp/ob-dot.el4
-rw-r--r--lisp/ob-eval.el7
-rw-r--r--lisp/ob-exp.el57
-rw-r--r--lisp/ob-forth.el86
-rw-r--r--lisp/ob-gnuplot.el18
-rw-r--r--lisp/ob-groovy.el10
-rw-r--r--lisp/ob-haskell.el1
-rw-r--r--lisp/ob-java.el22
-rw-r--r--lisp/ob-js.el7
-rw-r--r--lisp/ob-keys.el1
-rw-r--r--lisp/ob-latex.el15
-rw-r--r--lisp/ob-lilypond.el286
-rw-r--r--lisp/ob-lisp.el4
-rw-r--r--lisp/ob-maxima.el9
-rw-r--r--lisp/ob-ocaml.el3
-rw-r--r--lisp/ob-octave.el12
-rw-r--r--lisp/ob-python.el4
-rw-r--r--lisp/ob-ruby.el41
-rw-r--r--lisp/ob-scheme.el23
-rw-r--r--lisp/ob-screen.el4
-rw-r--r--lisp/ob-shell.el76
-rw-r--r--lisp/ob-sql.el18
-rw-r--r--lisp/ob-table.el22
-rw-r--r--lisp/ob-tangle.el42
-rw-r--r--lisp/org-agenda.el828
-rw-r--r--lisp/org-attach.el4
-rw-r--r--lisp/org-bbdb.el7
-rw-r--r--lisp/org-bibtex.el41
-rw-r--r--lisp/org-capture.el10
-rw-r--r--lisp/org-clock.el166
-rw-r--r--lisp/org-colview.el8
-rw-r--r--lisp/org-compat.el21
-rw-r--r--lisp/org-element.el1398
-rw-r--r--lisp/org-entities.el6
-rw-r--r--lisp/org-faces.el13
-rw-r--r--lisp/org-footnote.el70
-rw-r--r--lisp/org-gnus.el14
-rw-r--r--lisp/org-habit.el13
-rw-r--r--lisp/org-list.el4
-rw-r--r--lisp/org-macs.el21
-rw-r--r--lisp/org-mobile.el2
-rw-r--r--lisp/org-mouse.el13
-rw-r--r--lisp/org-rmail.el2
-rw-r--r--lisp/org-src.el58
-rw-r--r--lisp/org-table.el1288
-rw-r--r--lisp/org-timer.el13
-rwxr-xr-x[-rw-r--r--]lisp/org.el2711
-rw-r--r--lisp/ox-ascii.el660
-rw-r--r--lisp/ox-beamer.el50
-rw-r--r--lisp/ox-html.el754
-rw-r--r--lisp/ox-icalendar.el336
-rw-r--r--lisp/ox-latex.el689
-rw-r--r--lisp/ox-man.el84
-rw-r--r--lisp/ox-md.el170
-rw-r--r--lisp/ox-odt.el291
-rw-r--r--lisp/ox-org.el76
-rw-r--r--lisp/ox-publish.el17
-rw-r--r--lisp/ox-texinfo.el1478
-rw-r--r--lisp/ox.el354
-rw-r--r--mk/org-fixup.el16
-rw-r--r--mk/server.mk2
-rw-r--r--mk/targets.mk4
-rw-r--r--testing/README20
-rw-r--r--testing/examples/babel.org56
-rw-r--r--testing/examples/include.html1
-rw-r--r--testing/examples/ob-C-test.org88
-rw-r--r--testing/examples/ob-awk-test.org7
-rw-r--r--testing/examples/ob-shell-test.org88
-rw-r--r--testing/lisp/test-ob-C.el161
-rw-r--r--testing/lisp/test-ob-awk.el9
-rw-r--r--testing/lisp/test-ob-exp.el90
-rw-r--r--testing/lisp/test-ob-lilypond.el365
-rw-r--r--testing/lisp/test-ob-ruby.el35
-rw-r--r--testing/lisp/test-ob-shell.el39
-rw-r--r--testing/lisp/test-ob.el93
-rw-r--r--testing/lisp/test-org-element.el452
-rw-r--r--testing/lisp/test-org-list.el4
-rw-r--r--testing/lisp/test-org-table.el383
-rw-r--r--testing/lisp/test-org.el572
-rw-r--r--testing/lisp/test-ox.el214
-rw-r--r--testing/org-test.el13
121 files changed, 14346 insertions, 8617 deletions
diff --git a/.gitignore b/.gitignore
index a9d73ad..70980ce 100644
--- a/.gitignore
+++ b/.gitignore
@@ -43,6 +43,7 @@ ORGWEBPAGE/Changes.txt
local*.mk
.gitattributes
mk/x11idle
+ChangeLog
# texi2pdf --tidy
diff --git a/Makefile b/Makefile
index ce06116..f6312f2 100644
--- a/Makefile
+++ b/Makefile
@@ -17,7 +17,6 @@ help helpall::
$(info )
$(info Getting Help)
$(info ============)
- $(info )
$(info make help - show brief help)
$(info make targets - ditto)
$(info make helpall - show extended help)
diff --git a/README_maintainer b/README_maintainer
index 04dc2c0..6b162aa 100644
--- a/README_maintainer
+++ b/README_maintainer
@@ -2,6 +2,7 @@
#+TITLE: Org maintainer tasks
#+STARTUP: noindent
+#+OPTIONS: ^:nil
This document describes the tasks the Org-mode maintainer has to do
and how they are performed.
diff --git a/contrib/README b/contrib/README
index 2a67b65..e92da14 100644
--- a/contrib/README
+++ b/contrib/README
@@ -80,6 +80,7 @@ ob-fomus.el --- Org-babel functions for fomus evaluation
ob-julia.el --- Org-babel functions for julia evaluation
ob-mathomatic.el --- Org-babel functions for mathomatic evaluation
ob-oz.el --- Org-babel functions for Oz evaluation
+ob-stata.el --- Org-babel functions for Stata evaluation
ob-tcl.el --- Org-babel functions for tcl evaluation
External libraries
diff --git a/contrib/lisp/ob-stata.el b/contrib/lisp/ob-stata.el
new file mode 100644
index 0000000..29aa88d
--- a/dev/null
+++ b/contrib/lisp/ob-stata.el
@@ -0,0 +1,313 @@
+;;; ob-stata.el --- org-babel functions for stata code evaluation
+
+;; Copyright (C) 2014 Ista Zahn
+;; Author: Ista Zahn istazahn@gmail.com
+;; G. Jay Kerns
+;; Eric Schulte
+;; Dan Davison
+
+
+;; This file is not part of GNU Emacs.
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 3, 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:
+
+;; The file provides Org-Babel support for evaluating stata code.
+;; It is basically result of find-and-replace "stata" for "julia"
+;; in ob-julia.el by G. Jay Kerns. Only ":results output" works: the
+;; header args must include ":results output" (this is the default).
+;; Note that I'm not sure ':results value' makes sense or is useful
+;; but I have left all the value-processing stuff inherited from
+;; ob-julia and ob-R. ':results graphics' would be nice, but I have
+;; not tried to implement it.
+;; --Ista, 07/30/2014
+
+;;; Requirements:
+;; Stata: http://stata.com
+;; ESS: http://ess.r-project.org
+
+;;; Code:
+(require 'ob)
+(eval-when-compile (require 'cl))
+
+(declare-function orgtbl-to-csv "org-table" (table params))
+(declare-function stata "ext:ess-stata" (&optional start-args))
+(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 org-number-sequence "org-compat" (from &optional to inc))
+(declare-function org-remove-if-not "org" (predicate seq))
+
+(defconst org-babel-header-args:stata
+ '((width . :any)
+ (horizontal . :any)
+ (results . ((file list vector table scalar verbatim)
+ (raw org html latex code pp wrap)
+ (replace silent append prepend)
+ ;; NOTE: not sure 'value' makes sense in stata
+ ;; we may want to remove it from the list
+ (output value graphics))))
+ "stata-specific header arguments.")
+
+(add-to-list 'org-babel-tangle-lang-exts '("stata" . "do"))
+
+;; only ':results output' currently works, so make that the default
+(defvar org-babel-default-header-args:stata '((:results . "output")))
+
+(defcustom org-babel-stata-command inferior-STA-program-name
+ "Name of command to use for executing stata code."
+ :group 'org-babel
+ :version "24.4"
+ :package-version '(Org . "8.3")
+ :type 'string)
+
+(defvar ess-local-process-name) ; dynamically scoped
+(defun org-babel-edit-prep:stata (info)
+ (let ((session (cdr (assoc :session (nth 2 info)))))
+ (when (and session (string-match "^\\*\\(.+?\\)\\*$" session))
+ (save-match-data (org-babel-stata-initiate-session session nil)))))
+
+(defun org-babel-expand-body:stata (body params &optional graphics-file)
+ "Expand BODY according to PARAMS, return the expanded body."
+ (let ((graphics-file
+ (or graphics-file (org-babel-stata-graphical-output-file params))))
+ (mapconcat
+ #'identity
+ ((lambda (inside)
+ (if graphics-file
+ inside
+ inside))
+ (append (org-babel-variable-assignments:stata params)
+ (list body))) "\n")))
+
+(defun org-babel-execute:stata (body params)
+ "Execute a block of stata code.
+This function is called by `org-babel-execute-src-block'."
+ (save-excursion
+ (let* ((result-params (cdr (assoc :result-params params)))
+ (result-type (cdr (assoc :result-type params)))
+ (session (org-babel-stata-initiate-session
+ (cdr (assoc :session params)) params))
+ (colnames-p (cdr (assoc :colnames params)))
+ (rownames-p (cdr (assoc :rownames params)))
+ (graphics-file (org-babel-stata-graphical-output-file params))
+ (full-body (org-babel-expand-body:stata body params graphics-file))
+ (result
+ (org-babel-stata-evaluate
+ session full-body result-type result-params
+ (or (equal "yes" colnames-p)
+ (org-babel-pick-name
+ (cdr (assoc :colname-names params)) colnames-p))
+ (or (equal "yes" rownames-p)
+ (org-babel-pick-name
+ (cdr (assoc :rowname-names params)) rownames-p)))))
+ (if graphics-file nil result))))
+
+(defun org-babel-prep-session:stata (session params)
+ "Prepare SESSION according to the header arguments specified in PARAMS."
+ (let* ((session (org-babel-stata-initiate-session session params))
+ (var-lines (org-babel-variable-assignments:stata params)))
+ (org-babel-comint-in-buffer session
+ (mapc (lambda (var)
+ (end-of-line 1) (insert var) (comint-send-input nil t)
+ (org-babel-comint-wait-for-output session)) var-lines))
+ session))
+
+(defun org-babel-load-session:stata (session body params)
+ "Load BODY into SESSION."
+ (save-window-excursion
+ (let ((buffer (org-babel-prep-session:stata 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:stata (params)
+ "Return list of stata statements assigning the block's variables."
+ (let ((vars (mapcar #'cdr (org-babel-get-header params :var))))
+ (mapcar
+ (lambda (pair)
+ (org-babel-stata-assign-elisp
+ (car pair) (cdr pair)
+ (equal "yes" (cdr (assoc :colnames params)))
+ (equal "yes" (cdr (assoc :rownames params)))))
+ (mapcar
+ (lambda (i)
+ (cons (car (nth i vars))
+ (org-babel-reassemble-table
+ (cdr (nth i vars))
+ (cdr (nth i (cdr (assoc :colname-names params))))
+ (cdr (nth i (cdr (assoc :rowname-names params)))))))
+ (org-number-sequence 0 (1- (length vars)))))))
+
+(defun org-babel-stata-quote-csv-field (s)
+ "Quote field S for export to stata."
+ (if (stringp s)
+ (concat "\"" (mapconcat 'identity (split-string s "\"") "\"\"") "\"")
+ (format "%S" s)))
+
+(defun org-babel-stata-assign-elisp (name value colnames-p rownames-p)
+ "Construct stata code assigning the elisp VALUE to a variable named NAME."
+ (if (listp value)
+ (let ((max (apply #'max (mapcar #'length (org-remove-if-not
+ #'sequencep value))))
+ (min (apply #'min (mapcar #'length (org-remove-if-not
+ #'sequencep value))))
+ (transition-file (org-babel-temp-file "stata-import-")))
+ ;; 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-csv value '(:fmt org-babel-stata-quote-csv-field))
+ "\n"))
+ (let ((file (org-babel-process-file-name transition-file 'noquote))
+ (header (if (or (eq (nth 1 value) 'hline) colnames-p)
+ "TRUE" "FALSE"))
+ (row-names (if rownames-p "1" "NULL")))
+ (if (= max min)
+ (format "%s = insheet using \"%s\"" name file)
+ (format "%s = insheet using \"%s\""
+ name file))))
+ (format "%s = %s" name (org-babel-stata-quote-csv-field value))))
+
+(defvar ess-ask-for-ess-directory) ; dynamically scoped
+
+(defun org-babel-stata-initiate-session (session params)
+ "If there is not a current stata process then create one."
+ (unless (string= session "none")
+ (let ((session (or session "*stata*"))
+ (ess-ask-for-ess-directory
+ (and (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
+ (save-window-excursion
+ (require 'ess) (stata)
+ (rename-buffer
+ (if (bufferp session)
+ (buffer-name session)
+ (if (stringp session)
+ session
+ (buffer-name))))
+ (current-buffer))))))
+
+(defun org-babel-stata-associate-session (session)
+ "Associate stata code buffer with a stata session.
+Make SESSION be the inferior ESS process associated with the
+current code buffer."
+ (setq ess-local-process-name
+ (process-name (get-buffer-process session)))
+ (ess-make-buffer-current))
+
+(defun org-babel-stata-graphical-output-file (params)
+ "Name of file to which stata should send graphical output."
+ (and (member "graphics" (cdr (assq :result-params params)))
+ (cdr (assq :file params))))
+
+(defvar org-babel-stata-eoe-indicator "display \"org_babel_stata_eoe\"")
+(defvar org-babel-stata-eoe-output "org_babel_stata_eoe")
+
+(defvar org-babel-stata-write-object-command "outsheet using \"%s\"")
+
+(defun org-babel-stata-evaluate
+ (session body result-type result-params column-names-p row-names-p)
+ "Evaluate stata code in BODY."
+ (if session
+ (org-babel-stata-evaluate-session
+ session body result-type result-params column-names-p row-names-p)
+ (org-babel-stata-evaluate-external-process
+ body result-type result-params column-names-p row-names-p)))
+
+(defun org-babel-stata-evaluate-external-process
+ (body result-type result-params column-names-p row-names-p)
+ "Evaluate BODY in external stata 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."
+ (case result-type
+ (value
+ (let ((tmp-file (org-babel-temp-file "stata-")))
+ (org-babel-eval org-babel-stata-command
+ (format org-babel-stata-write-object-command
+ (org-babel-process-file-name tmp-file 'noquote)
+ (format "begin\n%s\nend" body)))
+ (org-babel-stata-process-value-result
+ (org-babel-result-cond result-params
+ (with-temp-buffer
+ (insert-file-contents tmp-file)
+ (buffer-string))
+ (org-babel-import-elisp-from-file tmp-file '(4)))
+ column-names-p)))
+ (output (org-babel-eval org-babel-stata-command body))))
+
+(defun org-babel-stata-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
+last statement in BODY, as elisp."
+ (case result-type
+ (value
+ (with-temp-buffer
+ (insert (org-babel-chomp body))
+ (let ((ess-local-process-name
+ (process-name (get-buffer-process session)))
+ (ess-eval-visibly-p nil))
+ (ess-eval-buffer nil)))
+ (let ((tmp-file (org-babel-temp-file "stata-")))
+ (org-babel-comint-eval-invisibly-and-wait-for-file
+ session tmp-file
+ (format org-babel-stata-write-object-command
+ (org-babel-process-file-name tmp-file 'noquote) "ans"))
+ (org-babel-stata-process-value-result
+ (org-babel-result-cond result-params
+ (with-temp-buffer
+ (insert-file-contents tmp-file)
+ (buffer-string))
+ (org-babel-import-elisp-from-file tmp-file '(4)))
+ column-names-p)))
+ (output
+ (mapconcat
+ #'org-babel-chomp
+ (butlast
+ (delq nil
+ (mapcar
+ (lambda (line) (when (> (length line) 0) line))
+ (mapcar
+ (lambda (line) ;; cleanup extra prompts left in output
+ (if (string-match
+ "^\\([ ]*[>+\\.][ ]?\\)+\\([[0-9]+\\|[ ]\\)" line)
+ (substring line (match-end 1))
+ line))
+ (org-babel-comint-with-output (session org-babel-stata-eoe-output)
+ (insert (mapconcat #'org-babel-chomp
+ (list body org-babel-stata-eoe-indicator)
+ "\n"))
+ (inferior-ess-send-input)))))) "\n"))))
+
+(defun org-babel-stata-process-value-result (result column-names-p)
+ "stata-specific processing of return value.
+Insert hline if column names in output have been requested."
+ (if column-names-p
+ (cons (car result) (cons 'hline (cdr result)))
+ result))
+
+(provide 'ob-stata)
+
+;;; ob-stata.el ends here
diff --git a/contrib/lisp/org-annotate-file.el b/contrib/lisp/org-annotate-file.el
index 8fbb590..b8e8bd9 100644
--- a/contrib/lisp/org-annotate-file.el
+++ b/contrib/lisp/org-annotate-file.el
@@ -59,14 +59,24 @@
(require 'org)
-(defvar org-annotate-file-storage-file "~/.org-annotate-file.org"
- "File in which to keep annotations.")
-
-(defvar org-annotate-file-add-search nil
- "If non-nil, add a link as a second level to the actual file location.")
-
-(defvar org-annotate-file-always-open t
- "If non-nil, always expand the full tree when visiting the annotation file.")
+(defgroup org-annotate-file nil
+ "Org Annotate"
+ :group 'org)
+
+(defcustom org-annotate-file-storage-file "~/.org-annotate-file.org"
+ "File in which to keep annotations."
+ :group 'org-annotate-file
+ :type 'file)
+
+(defcustom org-annotate-file-add-search nil
+ "If non-nil, add a link as a second level to the actual file location."
+ :group 'org-annotate-file
+ :type 'boolean)
+
+(defcustom org-annotate-file-always-open t
+ "If non-nil, always expand the full tree when visiting the annotation file."
+ :group 'org-annotate-file
+ :type 'boolean)
(defun org-annotate-file-ellipsify-desc (string &optional after)
"Return shortened STRING with appended ellipsis.
diff --git a/contrib/lisp/org-bibtex-extras.el b/contrib/lisp/org-bibtex-extras.el
index 8d5b2ac..5f05039 100644
--- a/contrib/lisp/org-bibtex-extras.el
+++ b/contrib/lisp/org-bibtex-extras.el
@@ -83,19 +83,6 @@ For example, to point to your `obe-bibtex-file' use the following.
obe-citations))
obe-citations)))
-(defun obe-goto-citation (&optional citation)
- "Visit a citation given its ID."
- (interactive)
- (let ((citation (or citation
- (org-icompleting-read "Citation: "
- (obe-citations)))))
- (find-file (or obe-bibtex-file
- (error "`obe-bibtex-file' has not been configured")))
- (goto-char (point-min))
- (when (re-search-forward (format " :CUSTOM_ID: %s" citation) nil t)
- (outline-previous-visible-heading 1)
- t)))
-
(defun obe-html-export-citations ()
"Convert all \\cite{...} citations in the current file into HTML links."
(save-excursion
@@ -107,15 +94,6 @@ For example, to point to your `obe-bibtex-file' use the following.
(mapcar #'org-babel-trim
(split-string (match-string 1) ",")) ", "))))))
-(defun obe-get-meta-data (citation)
- "Collect meta-data for CITATION."
- (save-excursion
- (when (obe-goto-citation citation)
- (let ((pt (point)))
- `((:authors . ,(split-string (org-entry-get pt "AUTHOR") " and " t))
- (:title . ,(org-no-properties (org-get-heading 1 1)))
- (:journal . ,(org-entry-get pt "JOURNAL")))))))
-
(defun obe-meta-to-json (meta &optional fields)
"Turn a list of META data from citations into a string of json."
(let ((counter 1) nodes links)
diff --git a/contrib/lisp/org-contacts.el b/contrib/lisp/org-contacts.el
index 7cc42fc..88aef9d 100644
--- a/contrib/lisp/org-contacts.el
+++ b/contrib/lisp/org-contacts.el
@@ -155,6 +155,11 @@ The following replacements are available:
:type 'string
:group 'org-contacts)
+(defcustom org-contacts-tags-props-prefix "#"
+ "Tags and properties prefix."
+ :type 'string
+ :group 'org-contacts)
+
(defcustom org-contacts-matcher
(mapconcat 'identity (list org-contacts-email-property
org-contacts-alias-property
@@ -183,6 +188,12 @@ This overrides `org-email-link-description-format' if set."
:group 'org-contacts
:type 'boolean)
+(defcustom org-contacts-complete-functions
+ '(org-contacts-complete-group org-contacts-complete-tags-props org-contacts-complete-name)
+ "List of functions used to complete contacts in `message-mode'."
+ :group 'org-contacts
+ :type 'hook)
+
;; Decalre external functions and variables
(declare-function org-reverse-string "org")
(declare-function diary-ordinal-suffix "ext:diary-lib")
@@ -244,7 +255,7 @@ to dead or no buffer."
(let* (todo-only
(contacts-matcher
(cdr (org-make-tags-matcher org-contacts-matcher)))
- markers result)
+ result)
(when (org-contacts-db-need-update-p)
(let ((progress-reporter
(make-progress-reporter "Updating Org Contacts Database..." 0 (length org-contacts-files)))
@@ -253,21 +264,26 @@ to dead or no buffer."
(org-check-agenda-file file)
(with-current-buffer (org-get-agenda-file-buffer file)
(unless (eq major-mode 'org-mode)
- (error "File %s is no in `org-mode'" file))
- (org-scan-tags
- '(add-to-list 'markers (set-marker (make-marker) (point)))
- contacts-matcher
- todo-only))
+ (error "File %s is not in `org-mode'" file))
+ (setf result
+ (append result
+ (org-scan-tags
+ 'org-contacts-at-point
+ contacts-matcher
+ todo-only))))
(progress-reporter-update progress-reporter (setq i (1+ i))))
- (dolist (marker markers result)
- (org-with-point-at marker
- (add-to-list 'result
- (list (org-get-heading t) marker (org-entry-properties marker 'all)))))
(setf org-contacts-db result
org-contacts-last-update (current-time))
- (progress-reporter-done progress-reporter)))
+ (progress-reporter-done progress-reporter)))
org-contacts-db))
+(defun org-contacts-at-point (&optional pom)
+ "Return the contacts at point-or-marker POM or current position
+if nil."
+ (setq pom (or pom (point)))
+ (org-with-point-at pom
+ (list (org-get-heading t) (set-marker (make-marker) pom) (org-entry-properties pom 'all))))
+
(defun org-contacts-filter (&optional name-match tags-match prop-match)
"Search for a contact matching any of NAME-MATCH, TAGS-MATCH, PROP-MATCH.
If all match values are nil, return all contacts.
@@ -500,11 +516,12 @@ A group FOO is composed of contacts with the tag FOO."
;; returned by `org-contacts-filter'.
for contact-name = (car contact)
;; Grab the first email of the contact
- for email = (org-contacts-strip-link (car (org-contacts-split-property
- (or
- (cdr (assoc-string org-contacts-email-property
- (caddr contact)))
- ""))))
+ for email = (org-contacts-strip-link
+ (or (car (org-contacts-split-property
+ (or
+ (cdr (assoc-string org-contacts-email-property
+ (caddr contact)))
+ ""))) ""))
;; If the user has an email address, append USER <EMAIL>.
if email collect (org-contacts-format-email contact-name email))
", ")))
@@ -512,6 +529,45 @@ A group FOO is composed of contacts with the tag FOO."
(completion-table-case-fold completion-list
(not org-contacts-completion-ignore-case))))))))
+(defun org-contacts-complete-tags-props (start end string)
+ "Insert emails that match the tags expression.
+
+For example: FOO-BAR will match entries tagged with FOO but not
+with BAR.
+
+See (org) Matching tags and properties for a complete
+description."
+ (let* ((completion-ignore-case org-contacts-completion-ignore-case)
+ (completion-p (org-string-match-p
+ (concat "^" org-contacts-tags-props-prefix) string)))
+ (when completion-p
+ (let ((result
+ (mapconcat
+ 'identity
+ (loop for contact in (org-contacts-db)
+ for contact-name = (car contact)
+ for email = (org-contacts-strip-link (or (car (org-contacts-split-property
+ (or
+ (cdr (assoc-string org-contacts-email-property
+ (caddr contact)))
+ ""))) ""))
+ for tags = (cdr (assoc "TAGS" (nth 2 contact)))
+ for tags-list = (if tags
+ (split-string (substring (cdr (assoc "TAGS" (nth 2 contact))) 1 -1) ":")
+ '())
+ for marker = (second contact)
+ if (with-current-buffer (marker-buffer marker)
+ (save-excursion
+ (goto-char marker)
+ (let (todo-only)
+ (eval (cdr (org-make-tags-matcher (subseq string 1)))))))
+ collect (org-contacts-format-email contact-name email))
+ ",")))
+ (when (not (string= "" result))
+ ;; return (start end function)
+ (lexical-let* ((to-return result))
+ (list start end
+ (lambda (string pred &optional to-ignore) to-return))))))))
(defun org-contacts-remove-ignored-property-values (ignore-list list)
"Remove all ignore-list's elements from list and you can use
@@ -570,8 +626,8 @@ A group FOO is composed of contacts with the tag FOO."
(goto-char (match-end 0))
(point))))
(string (buffer-substring start end)))
- (or (org-contacts-complete-group start end string)
- (org-contacts-complete-name start end string))))))
+ (run-hook-with-args-until-success
+ 'org-contacts-complete-functions start end string)))))
(defun org-contacts-gnus-get-name-email ()
"Get name and email address from Gnus message."
@@ -960,11 +1016,39 @@ to do our best."
"END:VCARD\n\n")))
(defun org-contacts-export-as-vcard (&optional name file to-buffer)
+ "Export org contacts to V-Card 3.0.
+
+By default, all contacts are exported to `org-contacts-vcard-file'.
+
+When NAME is \\[universal-argument], prompts for a contact name.
+
+When NAME is \\[universal-argument] \\[universal-argument],
+prompts for a contact name and a file name where to export.
+
+When NAME is \\[universal-argument] \\[universal-argument]
+\\[universal-argument], prompts for a contact name and a buffer where to export.
+
+If the function is not called interactively, all parameters are
+passed to `org-contacts-export-as-vcard-internal'."
+ (interactive "P")
+ (when (called-interactively-p 'any)
+ (cl-psetf name
+ (when name
+ (read-string "Contact name: "
+ (first (org-contacts-at-point))))
+ file
+ (when (equal name '(16))
+ (read-file-name "File: " nil org-contacts-vcard-file))
+ to-buffer
+ (when (equal name '(64))
+ (read-buffer "Buffer: "))))
+ (org-contacts-export-as-vcard-internal name file to-buffer))
+
+(defun org-contacts-export-as-vcard-internal (&optional name file to-buffer)
"Export all contacts matching NAME as VCard 3.0.
If TO-BUFFER is nil, the content is written to FILE or
`org-contacts-vcard-file'. If TO-BUFFER is non-nil, the buffer
is created and the VCard is written into that buffer."
- (interactive) ; TODO ask for name?
(let* ((filename (or file org-contacts-vcard-file))
(buffer (if to-buffer
(get-buffer-create to-buffer)
diff --git a/contrib/lisp/org-effectiveness.el b/contrib/lisp/org-effectiveness.el
index 9981712..1e80d1f 100644
--- a/contrib/lisp/org-effectiveness.el
+++ b/contrib/lisp/org-effectiveness.el
@@ -156,7 +156,7 @@ many TODO pending"
(let ((month startmonth)
(year startyear)
(str ""))
- (while (and (>= endyear year) (>= endmonth month))
+ (while (or (> endyear year) (and (= endyear year) (>= endmonth month)))
(setq str (concat str (number-to-string year) "-" (org-effectiveness-month-to-string month) " " (org-effectiveness-in-date (concat (number-to-string year) "-" (org-effectiveness-month-to-string month)) 1) "\n"))
(if (= month 12)
(progn
@@ -196,6 +196,18 @@ many TODO pending"
(setq z (+ z 1)))
(insert "+"))))
+(defun org-effectiveness-html-bar(n &optional label)
+ "Print a bar with the percentage from 0 to 100 printed in html"
+ (interactive "nPercentage: \nsLabel: ")
+ (if (or (< n 0) (> n 100))
+ (message "The percentage must be between 0 to 100")
+ (let ((x 0)
+ (y 0)
+ (z 0))
+ (insert (format "\n<div class='percentage-%d'>%d</div>" n n))
+)))
+
+
(defun org-effectiveness-check-dates (startdate enddate)
"Generate a list with ((startyear startmonth) (endyear endmonth))"
(setq str nil)
@@ -244,6 +256,33 @@ many TODO pending"
(setq month (+ 1 month)))))
(switch-to-buffer "*org-effectiveness*"))
+(defun org-effectiveness-plot-html (startdate enddate)
+ "Print html bars about the effectiveness in a buffer"
+ (interactive "sGive me the start date: \nsGive me the end date: " startdate enddate)
+ (setq dates (org-effectiveness-check-dates startdate enddate))
+ (let ((syear (cadr (assoc 'startyear dates)))
+ (smonth (cadr (assoc 'startmonth dates)))
+ (year (cadr (assoc 'startyear dates)))
+ (month (cadr (assoc 'startmonth dates)))
+ (emonth (cadr (assoc 'endmonth dates)))
+ (eyear (cadr (assoc 'endyear dates)))
+ (buffer (current-buffer))
+ (str ""))
+ (switch-to-buffer "*org-effectiveness-html*")
+ (insert "<html><head><title>Graphbar</title><meta http-equiv='Content-type' content='text/html; charset=utf-8'><link rel='stylesheet' type='text/css' href='graphbar.css' title='graphbar'></head><body>")
+ (while (or (> eyear year) (and (= eyear year) (>= emonth month)))
+ (setq str (org-effectiveness-in-date (concat (number-to-string year) "-" (org-effectiveness-month-to-string month)) 1))
+ (switch-to-buffer "*org-effectiveness-html*")
+ (org-effectiveness-html-bar (string-to-number str) (format "%s-%s" year month))
+ (switch-to-buffer buffer)
+ (format "%s-%s" year month)
+ (if (eq month 12)
+ (progn
+ (setq year (+ 1 year))
+ (setq month 1))
+ (setq month (+ 1 month))))
+ (switch-to-buffer "*org-effectiveness-html*")
+ (insert "</body></html>")))
(provide 'org-effectiveness)
diff --git a/contrib/lisp/org-expiry.el b/contrib/lisp/org-expiry.el
index d58043f..1506c3b 100644
--- a/contrib/lisp/org-expiry.el
+++ b/contrib/lisp/org-expiry.el
@@ -218,11 +218,12 @@ Return nil if the entry is not expired. Otherwise return the
amount of time between today and the expiry date.
If there is no creation date, use `org-expiry-created-date'.
-If there is no expiry date, use `org-expiry-expiry-date'."
+If there is no expiry date, use `org-expiry-wait'."
(let* ((ex-prop org-expiry-expiry-property-name)
(cr-prop org-expiry-created-property-name)
(ct (current-time))
- (cr (org-read-date nil t (or (org-entry-get (point) cr-prop t) "+0d")))
+ (cr (org-read-date nil t (or (org-entry-get (point) cr-prop t)
+ org-expiry-created-date)))
(ex-field (or (org-entry-get (point) ex-prop t) org-expiry-wait))
(ex (if (string-match "^[ \t]?[+-]" ex-field)
(time-add cr (time-subtract (org-read-date nil t ex-field) ct))
diff --git a/contrib/lisp/org-git-link.el b/contrib/lisp/org-git-link.el
index 7d95bbb..ad0ce71 100644
--- a/contrib/lisp/org-git-link.el
+++ b/contrib/lisp/org-git-link.el
@@ -98,10 +98,12 @@
(let* ((strlist (org-git-split-string str))
(filepath (first strlist))
(commit (second strlist))
+ (line (third strlist))
(dirlist (org-git-find-gitdir (file-truename filepath)))
(gitdir (first dirlist))
(relpath (second dirlist)))
- (org-git-open-file-internal gitdir (concat commit ":" relpath))))
+ (org-git-open-file-internal gitdir (concat commit ":" relpath))
+ (when line (goto-line (string-to-int line)))))
;; Utility functions (file names etc)
@@ -141,16 +143,19 @@
;; splitting the link string
;; Both link open functions are called with a string of
-;; consisting of two parts separated by a double colon (::).
+;; consisting of three parts separated by a double colon (::).
(defun org-git-split-string (str)
- "Given a string of the form \"str1::str2\", return a list of
- two substrings \'(\"str1\" \"str2\"). If the double colon is mising, take str2 to be the empty string."
+ "Given a string of the form \"str1::str2::str3\", return a list of
+ three substrings \'(\"str1\" \"str2\" \"str3\"). If there are less
+than two double colons, str2 and/or str3 may be set the empty string."
(let ((strlist (split-string str "::")))
(cond ((= 1 (length strlist))
- (list (car strlist) ""))
+ (list (car strlist) "" ""))
((= 2 (length strlist))
+ (append strlist (list "")))
+ ((= 3 (length strlist))
strlist)
- (t (error "org-git-split-string: only one :: allowed: %s" str)))))
+ (t (error "org-git-split-string: only one or two :: allowed: %s" str)))))
;; finding the file name part of a commit
(defun org-git-link-filename (str)
@@ -168,22 +173,24 @@
(concat branch "@{" timestring "}"))
-(defun org-git-create-git-link (file)
+(defun org-git-create-git-link (file &optional line)
"Create git link part to file at specific time"
(interactive "FFile: ")
(let* ((gitdir (first (org-git-find-gitdir (file-truename file))))
(branchname (org-git-get-current-branch gitdir))
(timestring (format-time-string "%Y-%m-%d" (current-time))))
- (concat "git:" file "::" (org-git-create-searchstring branchname timestring))))
+ (concat "git:" file "::" (org-git-create-searchstring branchname timestring)
+ (if line (format "::%s" line) ""))))
(defun org-git-store-link ()
"Store git link to current file."
(when (buffer-file-name)
- (let ((file (abbreviate-file-name (buffer-file-name))))
+ (let ((file (abbreviate-file-name (buffer-file-name)))
+ (line (line-number-at-pos)))
(when (org-git-gitrepos-p file)
(org-store-link-props
:type "git"
- :link (org-git-create-git-link file))))))
+ :link (org-git-create-git-link file line))))))
(add-hook 'org-store-link-functions 'org-git-store-link)
diff --git a/contrib/lisp/org-index.el b/contrib/lisp/org-index.el
index ce53947..64974eb 100644
--- a/contrib/lisp/org-index.el
+++ b/contrib/lisp/org-index.el
@@ -5,7 +5,7 @@
;; Author: Marc Ihm <org-index@2484.de>
;; Keywords: outlines, hypermedia, matching
;; Requires: org
-;; Version: 2.4.2
+;; Version: 2.4.3
;; This file is not part of GNU Emacs.
@@ -72,6 +72,10 @@
;;; Change Log:
+;; [2014-04-26 Sa] Version 2.4.3:
+;; - Some Bugfixes and enhancements for occur-command
+;; - Fixes for assistant to create index table
+;;
;; [2014-02-01 Sa] Version 2.4.2:
;; - Follow mode in occur-buffer
;; - Reorder for x-columns
@@ -164,6 +168,7 @@
(defvar org-index--text-to-yank nil) ; Text, that can be yanked after call (mostly a reference)
(defvar org-index--last-ref) ; Last reference created or visited
(defvar org-index--point-before nil) ; Point in buffer with index table
+(defvar org-index--point-saved nil) ; Saved point if we want to return
(defvar org-index--silent nil) ; t, if user should not be queried
(defvar org-index--preferred-command) ; command, that is presented first
(defvar org-index--active-region) ; Active region, initially. I.e. what has been marked
@@ -172,7 +177,8 @@
(defvar org-index--active-window-index nil) ; Active window with index table (if any)
(defvar org-index--occur-follow-mode nil) ; True, if follow mode in occur-buffer is on
-(setq org-index--commands '(occur head ref link leave put enter goto help + reorder fill sort update highlight unhighlight missing statistics)) ; list of commands available
+
+(setq org-index--commands '(occur head ref link leave put enter goto help + reorder fill sort update multi-occur highlight unhighlight missing statistics)) ; list of commands available
(defun org-index (&optional ARG)
"Mark and find your favorite things and org-locations easily:
@@ -185,7 +191,7 @@ References are essentially small numbers (e.g. \"R237\" or \"-455-\"),
which are created by this package; they are well suited to be used
outside of org. Links are normal org-mode links.
-This is version 2.4.0 of org-index.
+This is version 2.4.3 of org-index.
The function `org-index' operates on a dedicated table, the index
table, which lives within its own Org-mode node. The table and
@@ -224,10 +230,6 @@ Commands known:
list of words seperated by space or comma (\",\"), to select
lines that contain all of the given words.
- If you supply a number (e.g. \"237\"): Apply emacs standard
- multi-occur operation on all org-mode buffers to search for
- this specific reference.
-
You may also read the note at the end of this help on saving
the keystroke RET with this frequent default command.
@@ -278,6 +280,9 @@ Commands known:
update: For the given reference, update the line in the
index table, i.e. increment its count.
+ multi-occur: Apply emacs standard multi-occur operation on all
+ org-mode buffers to search for the given reference.
+
highlight: Highlight references in active region or buffer.
unhighlight: Remove those highlights.
@@ -393,10 +398,6 @@ command \"head\" for reference \"237\".
(setq what 'enter)
(setq what-adjusted t))
- ;; For a proper reference as input, we do multi-occur
- (if (and (eq what 'occur) search-ref)
- (setq what 'multi-occur))
-
;; Check for invalid combinations of arguments; try to be helpful
(when (and (memq what '(head goto))
(not search-ref)
@@ -443,9 +444,13 @@ command \"head\" for reference \"237\".
;; Sort and align
(org-index--sort reorder-once)
- (org-index--align))
+ (org-index--align)
+
+ ;; Remember position for leave
+ (if org-index--point-before
+ (setq org-index--point-saved org-index--point-before)))
- ;; Return to initial position
+ ;; prepare to return to initial position in index table
(when initial-ref-or-link
(while (and (org-at-table-p)
(not (or
@@ -526,15 +531,15 @@ command \"head\" for reference \"237\".
(org-mark-ring-goto))
;; Return to saved position in index buffer
- (when org-index--point-before
+ (when org-index--point-saved
;; buffer displayed in window need to set point there first
(if (eq (window-buffer org-index--active-window-index)
org-index--buffer)
- (set-window-point org-index--active-window-index org-index--point-before))
+ (set-window-point org-index--active-window-index (marker-position org-index--point-saved)))
;; set position in buffer in any case and second
(with-current-buffer org-index--buffer
- (goto-char org-index--point-before)))
- (setq org-index--point-before nil))
+ (goto-char org-index--point-saved)))
+ (setq org-index--point-saved nil))
((eq what 'goto)
@@ -1026,7 +1031,8 @@ retrieves the value of the count-column for reference 12.
(unless search
;; Search string can come from several sources:
;; From link or ref columns of table
- (when org-index--within-node
+ (when (and org-index--within-node
+ (org-at-table-p))
(setq search-from-table (or (org-index--get-field :link)
(org-index--get-field :ref))))
@@ -1085,16 +1091,16 @@ retrieves the value of the count-column for reference 12.
;; Check id
(unless org-index-id
- (setq org-index-id (org-index--create-new-index
- t
- (format "No index table has been created yet." org-index-id))))
+ (org-index--create-new-index
+ t
+ (format "No index table has been created yet." org-index-id)))
;; Find node
(let (marker)
(setq marker (org-id-find org-index-id 'marker))
- (unless marker (setq org-index-id (org-index--create-new-index
- t
- (format "Cannot find node with id \"%s\"" org-index-id))))
+ (unless marker (org-index--create-new-index
+ t
+ (format "Cannot find node with id \"%s\"" org-index-id)))
; Try again with new node
(setq marker (org-id-find org-index-id 'marker))
(unless marker (error "Could not create node"))
@@ -1121,9 +1127,10 @@ retrieves the value of the count-column for reference 12.
;; get current position in index-buffer
(with-current-buffer org-index--buffer
- (unless (string= (org-id-get) org-index-id)
- (unless org-index--point-before
- (setq org-index--point-before (point))))))
+ (setq org-index--point-before
+ (if (string= (org-id-get) org-index-id)
+ nil
+ (point-marker)))))
(defun org-index--parse-table ()
@@ -1555,7 +1562,6 @@ retrieves the value of the count-column for reference 12.
You can add further columns or even remove the last column. All
other columns are required.
-
Finally: This node needs not be a top level node; its name is
completely at you choice; it is found through its ID only.
@@ -1576,15 +1582,15 @@ retrieves the value of the count-column for reference 12.
(org-show-context)
(show-subtree)
(recenter 1)
- (if (y-or-n-p "This is your new index table; Do you want to save its id to make it permanent ? ")
+ (setq org-index-id id)
+ (if (y-or-n-p "This is your new index table. It is already set for this emacs session. Do you want to save its id to make it available for future emacs sessions too ? ")
(progn
(customize-save-variable 'org-index-id id)
- (message "Saved org-index-id '%s' to %s" org-index-id custom-file))
+ (error "Saved org-index-id '%s' to %s" id custom-file))
(let (sq)
- (setq sq (format "(setq org-index-id \"%s\")" org-index-id))
+ (setq sq (format "(setq org-index-id \"%s\")" id))
(kill-new sq)
- (message "Did not make the id of the new index permamanent; you may want to put\n\n %s\n\ninto your own initialization; it is copied already, just yank it." sq))
- id))
+ (error "Did not make the id of the new index permamanent; you may want to put\n\n %s\n\ninto your own initialization; it is copied already, just yank it." sq))))
;; we had an error with the existing index table, so present old
;; and new one together
;; show existing index
@@ -1606,9 +1612,8 @@ retrieves the value of the count-column for reference 12.
(defun org-index--update-line (ref-or-link)
- (let (initial
- found
- count-field)
+ (let ((newcount 0)
+ initial)
(with-current-buffer org-index--buffer
(unless buffer-read-only
@@ -1624,33 +1629,34 @@ retrieves the value of the count-column for reference 12.
(if (not (org-at-table-p))
(error "Did not find reference or link '%s'" ref-or-link)
- (setq count-field (org-index--get-field :count))
-
- ;; update count field only if number or empty; leave :missing: and :reuse: as is
- (if (or (not count-field)
- (string-match "^[0-9]+$" count-field))
- (org-index--get-field :count
- (number-to-string
- (+ 1 (string-to-number (or count-field "0"))))))
-
- ;; update timestamp
- (org-table-goto-column (org-index--column-num :last))
- (org-table-blank-field)
- (org-insert-time-stamp nil t t)
-
- (setq found t))
+ (org-index--update-current-line))
- (if initial (goto-char initial))
-
- found))))
+ (if initial (goto-char initial))))))
+
+
+(defun org-index--update-current-line ()
+ (let (newcount (count-field (org-index--get-field :count)))
+
+ ;; update count field only if number or empty; leave :missing: and :reuse: as is
+ (when (or (not count-field)
+ (string-match "^[0-9]+$" count-field))
+ (setq newcount (+ 1 (string-to-number (or count-field "0"))))
+ (org-index--get-field :count
+ (number-to-string newcount)))
+
+ ;; update timestamp
+ (org-table-goto-column (org-index--column-num :last))
+ (org-table-blank-field)
+ (org-insert-time-stamp nil t t)))
(defun org-index--get-field (key &optional value)
(let (field)
- (setq field (org-trim (org-table-get-field (cdr (assoc key org-index--columns)) value)))
- (if (string= field "") (setq field nil))
+ (save-excursion
+ (setq field (org-trim (org-table-get-field (cdr (assoc key org-index--columns)) value)))
+ (if (string= field "") (setq field nil))
- (org-no-properties field)))
+ (org-no-properties field))))
(defun org-index--column-num (key)
@@ -1741,8 +1747,6 @@ retrieves the value of the count-column for reference 12.
(org-index--update-line link)
(org-id-goto link)
(org-reveal)
- (if (eq (current-buffer) org-index--buffer)
- (setq org-index--point-before nil))
(setq message-text "Followed link"))
(message (format "Scanning headlines for '%s' ..." ref))
@@ -1768,8 +1772,6 @@ retrieves the value of the count-column for reference 12.
nil))
(progn
- (if (eq buffer org-index--buffer)
- (setq org-index--point-before nil))
(setq message-text (format "Found '%s'" (or ref link)))
(if other
(progn
@@ -1791,7 +1793,8 @@ retrieves the value of the count-column for reference 12.
(word "") ; last word to search for growing and shrinking on keystrokes
(prompt "Search for: ")
(hint "")
- words ; list of other words that must match too
+ (key-help "<up>, <down> move. <return> finds node, <S-return> goes to table, <M-return> updates count. TAB finds in other window.\n")
+ words ; list of other words that must match too
occur-buffer
lines-to-show ; number of lines to show in window
start-of-lines ; position, where lines begin
@@ -1805,6 +1808,8 @@ retrieves the value of the count-column for reference 12.
in-c-backspace ; true while processing C-backspace
show-headings ; true, if headings should be shown
fun-on-ret ; function to be executed, if return is pressed
+ fun-on-s-ret ; shift
+ fun-on-m-ret ; shift
fun-on-tab ; function to be executed, if letter TAB is pressed
ret from to key)
@@ -1819,16 +1824,29 @@ retrieves the value of the count-column for reference 12.
(set-keymap-parent keymap org-mode-map)
(setq fun-on-ret (lambda () (interactive) (org-index--occur-find-heading nil)))
- (define-key keymap (kbd "RET") fun-on-ret)
+ (define-key keymap [return] fun-on-ret)
+ (setq fun-on-s-ret (lambda () (interactive)
+ (when (org-at-table-p)
+ (org-table-goto-column (org-index--column-num :ref))
+ (org-index 'goto))))
+ (define-key keymap [S-return] fun-on-s-ret)
+ (setq fun-on-m-ret (lambda () (interactive)
+ (when (org-at-table-p)
+ (org-index--update-current-line)
+ (org-table-align)
+ (org-table-goto-column (org-index--column-num :count))
+ (message (format "New count is %s" (org-trim (org-table-get-field))))
+ (org-index--update-line (org-index--get-field :ref)))))
+ (define-key keymap [M-return] fun-on-m-ret)
(setq fun-on-tab (lambda () (interactive)
(org-index--occur-find-heading t)
(setq org-index--occur-follow-mode (not org-index--occur-follow-mode))))
- (define-key keymap (kbd "<tab>") fun-on-tab)
+ (define-key keymap [tab] fun-on-tab)
(define-key keymap [(control ?i)] fun-on-tab)
- (define-key keymap (kbd "<up>") (lambda () (interactive)
+ (define-key keymap [up] (lambda () (interactive)
(forward-line -1)
(if org-index--occur-follow-mode (org-index--occur-find-heading t))))
- (define-key keymap (kbd "<down>") (lambda () (interactive)
+ (define-key keymap [down] (lambda () (interactive)
(forward-line 1)
(if org-index--occur-follow-mode (org-index--occur-find-heading t))))
(use-local-map keymap)))
@@ -1849,13 +1867,12 @@ retrieves the value of the count-column for reference 12.
;; fill in header
(erase-buffer)
(insert (concat "Incremental search, showing one window of matches. '?' toggles help.\n\n"))
- (setq start-of-lines (point))
+ (setq start-of-lines (point-marker))
(setq start-of-help start-of-lines)
(setq cursor-type 'hollow)
;; get window size of occur-buffer as number of lines to be searched
(setq lines-to-show (+ (- (window-body-height) (line-number-at-pos)) 1))
-
;; fill initially
(setq ret (org-index--get-matching-lines nil lines-to-show below-hline-bol))
@@ -1887,7 +1904,7 @@ retrieves the value of the count-column for reference 12.
(if (string= search-text "") "" " ")
hint))))
(setq hint "")
- (setq exit-gracefully (member key (list 'up 'down 'left 'right 'RET ?\C-g ?\C-m 'C-return ?\C-i 'TAB)))))
+ (setq exit-gracefully (member key (list 'up 'down 'left 'right 'RET ?\C-g ?\C-m 'C-return 'S-return ?\C-i 'TAB)))))
(not exit-gracefully))
@@ -1960,21 +1977,23 @@ retrieves the value of the count-column for reference 12.
(setq word ""))
- ((eq key ??) ; tab: toggle display of headlines and help
+ ((eq key ??) ; question mark: toggle display of headlines and help
(setq show-headings (not show-headings))
(goto-char start-of-lines)
(if show-headings
(progn
(forward-line -1)
- (kill-line)
- (setq start-of-help (point))
- (if (display-graphic-p)
- (insert "<backspace> and <c-backspace> erase, cursor keys move. RET finds node, C-RET all matches.\nTAB finds in other window. Comma seperates words, any other key adds to search word.\n\n")
- (insert "BACKSPACE to erase, to finish. Then cursor keys and RET to find node.\n\n"))
+; (kill-line)
+ (setq start-of-help (point-marker))
+ (insert "Normal keys add to search word, SPACE or COMMA start new word, BACKSPACE and C-BACKSPACE erase char or word. Every other key ends search: <C-return> completes list of matches. ")
+ (insert key-help)
+ (goto-char start-of-help)
+ (fill-paragraph)
+ (goto-char start-of-lines)
(insert org-index--headings))
(delete-region start-of-help start-of-lines)
- (insert "\n"))
- (setq start-of-lines (point)))
+ (insert "\n\n"))
+ (setq start-of-lines (point-marker)))
((and (integerp key)
@@ -2038,7 +2057,7 @@ retrieves the value of the count-column for reference 12.
(forward-line 1)))
;; get all the rest
- (when (eq key (kbd "<c-return>"))
+ (when (eq key 'C-return)
(message "Getting all matches ...")
(setq ret (org-index--get-matching-lines (cons word words) 0 (car left-off-at)))
(message "done.")
@@ -2052,15 +2071,18 @@ retrieves the value of the count-column for reference 12.
(delete-region (point-min) (point))
(insert (format (concat (if exit-gracefully "Search is done;" "Search aborted;")
(if (or at-end (eq key 'C-return))
- " showing all %d matches."
- " showing only some matches.")
- " Use cursor keys to move, press RET or TAB to find node.\n\n")
+ " showing all %d matches. "
+ " showing only some matches. ")
+ key-help)
numlines))
+ (insert "\n")
+ (setq start-of-lines (point-marker))
+ (goto-char (point-min))
+ (fill-paragraph)
+ (goto-char start-of-lines)
(if show-headings (insert "\n\n" org-index--headings)))
(forward-line))
- (setq buffer-read-only t)
-
;; perform action according to last char
(forward-line -1)
(cond
@@ -2077,11 +2099,12 @@ retrieves the value of the count-column for reference 12.
((eq key 'down)
(forward-line 1))
- ((eq key 'left)
- (forward-char -1))
+ ((eq key 'M-return)
+ (funcall fun-on-m-ret))
+
+ ((eq key 'S-return)
+ (funcall fun-on-s-ret)))))
- ((eq key 'right)
- (forward-char 1)))))
(defun org-index--occur-find-heading (x)
"helper for keymap of occur"
@@ -2168,34 +2191,11 @@ retrieves the value of the count-column for reference 12.
(let ((found-all t))
(setq line (downcase line))
(catch 'not-found
- (dolist (w words)
- (or (search w line)
- (throw 'not-found nil)))
- t)))
-
+ (dolist (w words)
+ (or (search w line)
+ (throw 'not-found nil)))
+ t)))
-(defun org-index--dump-variables ()
- "Dump variables of org-index; mostly for debugging"
- (interactive)
- "Dump all variables of org-index for debugging"
- (let ((buff (get-buffer-create "*org-index-dump-variables*"))
- (maxlen 0)
- vars name value)
-
- (with-current-buffer buff
- (erase-buffer)
- (mapatoms (lambda (s) (when (and (boundp s)
- (string-prefix-p "org-index-" (symbol-name s)))
-
- (setq name (symbol-name s))
- (setq value (symbol-value s))
- (setq vars (cons (cons name value) vars))
- (if (> (length name) maxlen)
- (setq maxlen (length name))))))
- (setq vars (sort vars (lambda (x y) (string< (car x) (car y)))))
- (mapc (lambda (x) (insert (format (format "%%-%ds: %%s\n" (+ maxlen 1)) (car x) (cdr x))))
- vars)
- (pop-to-buffer buff))))
(defadvice org-mark-ring-goto (after org-index--advice-text-to-yank activate)
diff --git a/contrib/lisp/org-license.el b/contrib/lisp/org-license.el
index 44a1ea7..426b148 100644
--- a/contrib/lisp/org-license.el
+++ b/contrib/lisp/org-license.el
@@ -45,15 +45,15 @@
(defun org-license-cc-by (language)
(interactive "MLanguage ( br | ca | de | en | es | eo | eu | fi | fr | gl | it | jp | nl | pt ): " language)
(cond ((equal language "br")
- (setq org-license-cc-url "https://creativecommons.org/licenses/by-sa/3.0/br/deed.pt_BR")
+ (setq org-license-cc-url "https://creativecommons.org/licenses/by/3.0/br/deed.pt_BR")
(insert (concat "* Licença
Este texto é disponibilizado nos termos da licença [[" org-license-cc-url "][Atribuição 3.0 Brasil]]\n")))
((equal language "ca")
- (setq org-license-cc-url "https://creativecommons.org/licenses/by-sa/3.0/es/deed.ca")
+ (setq org-license-cc-url "https://creativecommons.org/licenses/by/3.0/es/deed.ca")
(insert (concat "* Licència
El text està disponible sota la [[" org-license-cc-url "][Reconeixement 3.0 Espanya]]\n")))
((equal language "de")
- (setq org-license-cc-url "https://creativecommons.org/licenses/by-sa/3.0/de/deed.de")
+ (setq org-license-cc-url "https://creativecommons.org/licenses/by/3.0/de/deed.de")
(insert (concat "* Lizenz
Dieses Werk bzw. Inhalt steht unter einer [[" org-license-cc-url "][Lizenz Creative Commons Namensnennung 3.0 Deutschland]]\n")))
((equal language "eo")
@@ -96,8 +96,10 @@ Dit werk is valt onder een [[" org-license-cc-url "][Creative Commons Naamsverme
(setq org-license-cc-url "http://creativecommons.org/licenses/by/3.0/pt/deed.pt")
(insert (concat "* Licença
Este texto é disponibilizado nos termos da licença [[" org-license-cc-url "][Atribuição 3.0 Portugal]]\n")))
- (t (concat (insert "* License
-This document is under a [[" org-license-cc-url "][Creative Commons Attribution 3.0]]\n"))))
+ (t
+ (setq org-license-cc-url "http://creativecommons.org/licenses/by/4.0/deed")
+ (concat (insert "* License
+This document is under a [[" org-license-cc-url "][Creative Commons Attribution 4.0 International]]\n"))))
(if (string= "" org-license-images-directory)
(insert (concat "\n[[" org-license-cc-url "][file:http://i.creativecommons.org/l/by/3.0/80x15.png]]\n"))
(insert (concat "\n[[" org-license-cc-url "][file:" org-license-images-directory "/by/3.0/80x15.png]]\n"))))
@@ -153,9 +155,9 @@ Dit werk is valt onder een [[" org-license-cc-url "][Creative Commons Naamsverme
(insert (concat "* Licença
Este texto é disponibilizado nos termos da licença [[" org-license-cc-url "][Atribuição-CompartilhaIgual 3.0 Portugal]]\n")))
(t
- (setq org-license-cc-url "http://creativecommons.org/licenses/by-sa/3.0/deed")
+ (setq org-license-cc-url "http://creativecommons.org/licenses/by-sa/4.0/deed")
(insert (concat "* License
-This document is under a [[" org-license-cc-url "][Creative Commons Attribution-ShareAlike Unported 3.0]]\n"))))
+This document is under a [[" org-license-cc-url "][Creative Commons Attribution-ShareAlike 4.0 International]]\n"))))
(if (string= "" org-license-images-directory)
(insert (concat "\n[[" org-license-cc-url "][file:http://i.creativecommons.org/l/by-sa/3.0/80x15.png]]\n"))
(insert (concat "\n[[" org-license-cc-url "][file:" org-license-images-directory "/by-sa/3.0/80x15.png]]\n"))))
@@ -179,11 +181,11 @@ Dieses Werk bzw. Inhalt steht unter einer [[" org-license-cc-url "][Namensnennun
(insert (concat "* Licencia
Este documento está bajo una [[" org-license-cc-url "][Licencia Creative Commons Atribución-SinDerivadas 3.0]]\n")))
((equal language "eu")
- (setq org-license-cc-url "http://creativecommons.org/licenses/by-sa/3.0/es/deed.eu")
+ (setq org-license-cc-url "http://creativecommons.org/licenses/by-nd/3.0/es/deed.eu")
(insert (concat "* Licenzua
Testua [[" org-license-cc-url "][Aitortu-LanEratorririkGabe 3.0 Espainia]] lizentziari jarraituz erabil daiteke\n")))
((equal language "fi")
- (setq org-license-cc-url "http://creativecommons.org/licenses/by-sa/1.0/fi/deed.fi")
+ (setq org-license-cc-url "http://creativecommons.org/licenses/by-nd/1.0/fi/deed.fi")
(insert (concat "* Lisenssi
Teksti on saatavilla [[" org-license-cc-url "][Nimeä-JaaSamoin 1.0 Suomi]] lisenssillä\n")))
((equal language "fr")
@@ -211,9 +213,9 @@ Dit werk is valt onder een [[" org-license-cc-url "][Creative Commons Naamsverme
(insert (concat "* Licença
Este texto é disponibilizado nos termos da licença [[" org-license-cc-url "][Atribuição Sem Derivados 3.0 Portugal]]\n")))
(t
- (setq org-license-cc-url "http://creativecommons.org/licenses/by-nd/3.0/deed")
+ (setq org-license-cc-url "http://creativecommons.org/licenses/by-nd/4.0/deed")
(insert (concat "* License
-This document is under a [[" org-license-cc-url "][Creative Commons No Derivatives Unported 3.0]]\n"))))
+This document is under a [[" org-license-cc-url "][Creative Commons No Derivatives 4.0 International]]\n"))))
(if (string= "" org-license-images-directory)
(insert (concat "\n[[" org-license-cc-url "][file:http://i.creativecommons.org/l/by-nd/3.0/80x15.png]]\n"))
(insert (concat "\n[[" org-license-cc-url "][file:" org-license-images-directory "/by-nd/3.0/80x15.png]]\n"))))
@@ -270,9 +272,9 @@ Dit werk is valt onder een [[" org-license-cc-url "][Creative Commons Naamsverme
(insert (concat "* Licença
Este texto é disponibilizado nos termos da licença [[" org-license-cc-url "][Atribuição Não Comercial 3.0 Portugal]]\n")))
(t
- (setq org-license-cc-url "http://creativecommons.org/licenses/by-nc/3.0/deed")
+ (setq org-license-cc-url "http://creativecommons.org/licenses/by-nc/4.0/deed")
(insert (concat "* License
-This document is under a [[" org-license-cc-url "][Creative Commons Attribution-NonCommercial 3.0 Unported]]\n"))))
+This document is under a [[" org-license-cc-url "][Creative Commons Attribution-NonCommercial 4.0 International]]\n"))))
(if (string= "" org-license-images-directory)
(insert (concat "\n[[" org-license-cc-url "][file:http://i.creativecommons.org/l/by-nc/3.0/80x15.png]]\n"))
(insert (concat "\n[[" org-license-cc-url "][file:" org-license-images-directory "/by-nc/3.0/80x15.png]]\n"))))
@@ -328,9 +330,9 @@ Dit werk is valt onder een [[" org-license-cc-url "][Creative Commons Naamsverme
(insert (concat "* Licença
Este texto é disponibilizado nos termos da licença [[" org-license-cc-url "][Atribuição NãoComercial Compartil ha Igual 3.0 Portugal]]\n")))
(t
- (setq org-license-cc-url "http://creativecommons.org/licenses/by-nc-sa/3.0/deed")
+ (setq org-license-cc-url "http://creativecommons.org/licenses/by-nc-sa/4.0/deed")
(insert (concat "* License
-This document is under a [[" org-license-cc-url "][License Creative Commons Attribution Non Commercial Share Alike 3.0 Unported]]\n"))))
+This document is under a [[" org-license-cc-url "][License Creative Commons Attribution Non Commercial Share Alike 4.0 International]]\n"))))
(if (string= "" org-license-images-directory)
(insert (concat "\n[[" org-license-cc-url "][file:http://i.creativecommons.org/l/by-nc-sa/3.0/80x15.png]]\n"))
(insert (concat "\n[[" org-license-cc-url "][file:" org-license-images-directory "/by-nc-sa/3.0/80x15.png]]\n"))))
@@ -386,10 +388,9 @@ Dit werk is valt onder een [[" org-license-cc-url "][Creative Commons Naamsverme
(insert (concat "* Licença
Este texto é disponibilizado nos termos da licença [[" org-license-cc-url "][Atribuição Não Comercial Sem Derivados 3.0 Portugal]]\n")))
(t
- (setq org-license-cc-url "http://creativecommons.org/licenses/by-nc-nd/3.0/deed")
+ (setq org-license-cc-url "http://creativecommons.org/licenses/by-nc-nd/4.0/deed")
(insert (concat "* License
-This document is under a [[" org-license-cc-url "][License Creative Commons
-Reconocimiento-NoComercial-SinObraDerivada 3.0 Unported]]\n"))))
+This document is under a [[" org-license-cc-url "][License Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International]]\n"))))
(if (string= "" org-license-images-directory)
(insert (concat "\n[[" org-license-cc-url "][file:http://i.creativecommons.org/l/by-nc-nd/3.0/80x15.png]]\n"))
(insert (concat "\n[[" org-license-cc-url "][file:" org-license-images-directory "/by-nc-nd/3.0/80x15.png]]\n"))))
@@ -398,14 +399,14 @@ Reconocimiento-NoComercial-SinObraDerivada 3.0 Unported]]\n"))))
(interactive "MLanguage (es | en): " language)
(cond ((equal language "es")
(insert "* Licencia
-Copyright (C) 2013 " user-full-name
+Copyright (C) " (format-time-string "%Y") " " user-full-name
"\n Se permite copiar, distribuir y/o modificar este documento
bajo los términos de la GNU Free Documentation License, Version 1.3
o cualquier versión publicada por la Free Software Foundation;
sin Secciones Invariantes y sin Textos de Portada o Contraportada.
Una copia de la licencia está incluida en [[https://www.gnu.org/copyleft/fdl.html][GNU Free Documentation License]].\n"))
(t (insert (concat "* License
-Copyright (C) 2013 " user-full-name
+Copyright (C) " (format-time-string "%Y") " " user-full-name
"\n Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3
or any later version published by the Free Software Foundation;
diff --git a/contrib/lisp/org-mac-link.el b/contrib/lisp/org-mac-link.el
index d1687e0..3b58d04 100644
--- a/contrib/lisp/org-mac-link.el
+++ b/contrib/lisp/org-mac-link.el
@@ -3,11 +3,12 @@
;;
;; Copyright (c) 2010-2014 Free Software Foundation, Inc.
;;
-;; Authors:
-;; Anthony Lander <anthony.lander@gmail.com>
-;; John Wiegley <johnw@gnu.org>
-;; Christopher Suckling <suckling at gmail dot com>
-;; Daniil Frumin <difrumin@gmail.com>
+;; Author: Anthony Lander <anthony.lander@gmail.com>
+;; John Wiegley <johnw@gnu.org>
+;; Christopher Suckling <suckling at gmail dot com>
+;; Daniil Frumin <difrumin@gmail.com>
+;; Alan Schmitt <alan.schmitt@polytechnique.org>
+;; Mike McLean <mike.mclean@pobox.com>
;;
;;
;; Version: 1.1
@@ -57,6 +58,7 @@
;; Together.app - Grab links to the selected items in the library list
;; Skim.app - Grab a link to the selected page in the topmost pdf document
;; Microsoft Outlook.app - Grab a link to the selected message in the message list
+;; DEVONthink Pro Office.app - Grab a link to the selected DEVONthink item(s); open DEVONthink item by reference
;;
;;
;; Installation:
@@ -86,61 +88,66 @@
(require 'org)
(defgroup org-mac-link nil
- "Options concerning grabbing links from external Mac
-applications and inserting them in org documents"
+ "Options for grabbing links from Mac applications."
:tag "Org Mac link"
:group 'org-link)
(defcustom org-mac-grab-Finder-app-p t
- "Enable menu option [F]inder to grab links from the Finder"
+ "Add menu option [F]inder to grab links from the Finder."
:tag "Grab Finder.app links"
:group 'org-mac-link
:type 'boolean)
(defcustom org-mac-grab-Mail-app-p t
- "Enable menu option [m]ail to grab links from Mail.app"
+ "Add menu option [m]ail to grab links from Mail.app."
:tag "Grab Mail.app links"
:group 'org-mac-link
:type 'boolean)
(defcustom org-mac-grab-Outlook-app-p t
- "Enable menu option [o]utlook to grab links from Microsoft Outlook.app"
+ "Add menu option [o]utlook to grab links from Microsoft Outlook.app."
:tag "Grab Microsoft Outlook.app links"
:group 'org-mac-link
:type 'boolean)
+(defcustom org-mac-grab-devonthink-app-p t
+ "Add menu option [d]EVONthink to grab links from DEVONthink Pro Office.app."
+ :tag "Grab DEVONthink Pro Office.app links"
+ :group 'org-mac-link
+ :type 'boolean)
+
(defcustom org-mac-grab-Addressbook-app-p t
- "Enable menu option [a]ddressbook to grab links from AddressBook.app"
+ "Add menu option [a]ddressbook to grab links from AddressBook.app."
:tag "Grab AddressBook.app links"
:group 'org-mac-link
:type 'boolean)
(defcustom org-mac-grab-Safari-app-p t
- "Enable menu option [s]afari to grab links from Safari.app"
+ "Add menu option [s]afari to grab links from Safari.app."
:tag "Grab Safari.app links"
:group 'org-mac-link
:type 'boolean)
(defcustom org-mac-grab-Firefox-app-p t
- "Enable menu option [f]irefox to grab links from Firefox.app"
+ "Add menu option [f]irefox to grab links from Firefox.app."
:tag "Grab Firefox.app links"
:group 'org-mac-link
:type 'boolean)
(defcustom org-mac-grab-Firefox+Vimperator-p nil
- "Enable menu option [v]imperator to grab links from Firefox.app running the Vimperator plugin"
+ "Add menu option [v]imperator to grab links from Firefox.app running the Vimperator plugin."
:tag "Grab Vimperator/Firefox.app links"
:group 'org-mac-link
:type 'boolean)
(defcustom org-mac-grab-Chrome-app-p t
- "Enable menu option [c]hrome to grab links from Google Chrome.app"
+ "Add menu option [c]hrome to grab links from Google Chrome.app."
:tag "Grab Google Chrome.app links"
:group 'org-mac-link
:type 'boolean)
(defcustom org-mac-grab-Together-app-p nil
- "Enable menu option [t]ogether to grab links from Together.app"
+ "Add menu option [t]ogether to grab links from Together.app."
:tag "Grab Together.app links"
:group 'org-mac-link
:type 'boolean)
@@ -148,19 +155,19 @@ applications and inserting them in org documents"
(defcustom org-mac-grab-Skim-app-p
(< 0 (length (shell-command-to-string
"mdfind kMDItemCFBundleIdentifier == 'net.sourceforge.skim-app.skim'")))
- "Enable menu option [S]kim to grab page links from Skim.app"
+ "Add menu option [S]kim to grab page links from Skim.app."
:tag "Grab Skim.app page links"
:group 'org-mac-link
:type 'boolean)
(defcustom org-mac-Skim-highlight-selection-p nil
- "Highlight (using notes) the selection (if present) when grabbing the a link from Skim.app"
+ "Highlight the active selection when grabbing a link from Skim.app."
:tag "Highlight selection in Skim.app"
:group 'org-mac-link
:type 'boolean)
(defgroup org-mac-flagged-mail nil
- "Options concerning linking to flagged Mail.app messages."
+ "Options foring linking to flagged Mail.app messages."
:tag "Org Mail.app"
:group 'org-link)
@@ -185,27 +192,32 @@ applications and inserting them in org documents"
(setq return (shell-command-to-string cmd))
(concat "\"" (org-trim return) "\""))))
-
(defun org-mac-grab-link ()
- "Prompt the user for an application to grab a link from, then go grab the link, and insert it at point"
+ "Prompt for an application to grab a link from.
+When done, go grab the link, and insert it at point."
(interactive)
- (let* ((descriptors `(("F" "inder" org-mac-finder-insert-selected ,org-mac-grab-Finder-app-p)
- ("m" "ail" org-mac-message-insert-selected ,org-mac-grab-Mail-app-p)
- ("o" "utlook" org-mac-outlook-message-insert-selected ,org-mac-grab-Outlook-app-p)
- ("a" "ddressbook" org-mac-addressbook-insert-selected ,org-mac-grab-Addressbook-app-p)
- ("s" "afari" org-mac-safari-insert-frontmost-url ,org-mac-grab-Safari-app-p)
- ("f" "irefox" org-mac-firefox-insert-frontmost-url ,org-mac-grab-Firefox-app-p)
- ("v" "imperator" org-mac-vimperator-insert-frontmost-url ,org-mac-grab-Firefox+Vimperator-p)
- ("c" "hrome" org-mac-chrome-insert-frontmost-url ,org-mac-grab-Chrome-app-p)
- ("t" "ogether" org-mac-together-insert-selected ,org-mac-grab-Together-app-p)
- ("S" "kim" org-mac-skim-insert-page ,org-mac-grab-Skim-app-p)))
+ (let* ((descriptors
+ `(("F" "inder" org-mac-finder-insert-selected ,org-mac-grab-Finder-app-p)
+ ("m" "ail" org-mac-message-insert-selected ,org-mac-grab-Mail-app-p)
+ ("d" "EVONthink Pro Office" org-mac-devonthink-item-insert-selected
+ ,org-mac-grab-devonthink-app-p)
+ ("o" "utlook" org-mac-outlook-message-insert-selected ,org-mac-grab-Outlook-app-p)
+ ("a" "ddressbook" org-mac-addressbook-insert-selected ,org-mac-grab-Addressbook-app-p)
+ ("s" "afari" org-mac-safari-insert-frontmost-url ,org-mac-grab-Safari-app-p)
+ ("f" "irefox" org-mac-firefox-insert-frontmost-url ,org-mac-grab-Firefox-app-p)
+ ("v" "imperator" org-mac-vimperator-insert-frontmost-url ,org-mac-grab-Firefox+Vimperator-p)
+ ("c" "hrome" org-mac-chrome-insert-frontmost-url ,org-mac-grab-Chrome-app-p)
+ ("t" "ogether" org-mac-together-insert-selected ,org-mac-grab-Together-app-p)
+ ("S" "kim" org-mac-skim-insert-page ,org-mac-grab-Skim-app-p)))
(menu-string (make-string 0 ?x))
input)
;; Create the menu string for the keymap
(mapc '(lambda (descriptor)
(when (elt descriptor 3)
- (setf menu-string (concat menu-string "[" (elt descriptor 0) "]" (elt descriptor 1) " "))))
+ (setf menu-string (concat menu-string
+ "[" (elt descriptor 0) "]"
+ (elt descriptor 1) " "))))
descriptors)
(setf (elt menu-string (- (length menu-string) 1)) ?:)
@@ -221,12 +233,13 @@ applications and inserting them in org documents"
descriptors)))
(defun org-mac-paste-applescript-links (as-link-list)
- "Paste in a list of links from an applescript handler. The
- links are of the form <link>::split::<name>"
+ "Paste in a list of links from an applescript handler.
+The links are of the form <link>::split::<name>."
(let* ((link-list
- (mapcar
- (lambda (x) (if (string-match "\\`\"\\(.*\\)\"\\'" x) (setq x (match-string 1 x))) x)
- (split-string as-link-list "[\r\n]+")))
+ (mapcar (lambda (x) (if (string-match "\\`\"\\(.*\\)\"\\'" x)
+ (setq x (match-string 1 x)))
+ x)
+ (split-string as-link-list "[\r\n]+")))
split-link URL description orglink orglink-insert rtn orglink-list)
(while link-list
(setq split-link (split-string (pop link-list) "::split::"))
@@ -240,7 +253,6 @@ applications and inserting them in org documents"
rtn))
-
;; Handle links from Firefox.app
;;
;; This code allows you to grab the current active url from the main
@@ -257,27 +269,28 @@ applications and inserting them in org documents"
;; seems that it is always the last active window).
(defun org-as-mac-firefox-get-frontmost-url ()
- (let ((result (do-applescript
- (concat
- "set oldClipboard to the clipboard\n"
- "set frontmostApplication to path to frontmost application\n"
- "tell application \"Firefox\"\n"
- " activate\n"
- " delay 0.15\n"
- " tell application \"System Events\"\n"
- " keystroke \"l\" using {command down}\n"
- " keystroke \"a\" using {command down}\n"
- " keystroke \"c\" using {command down}\n"
- " end tell\n"
- " delay 0.15\n"
- " set theUrl to the clipboard\n"
- " set the clipboard to oldClipboard\n"
- " set theResult to (get theUrl) & \"::split::\" & (get name of window 1)\n"
- "end tell\n"
- "activate application (frontmostApplication as text)\n"
- "set links to {}\n"
- "copy theResult to the end of links\n"
- "return links as string\n"))))
+ (let ((result
+ (do-applescript
+ (concat
+ "set oldClipboard to the clipboard\n"
+ "set frontmostApplication to path to frontmost application\n"
+ "tell application \"Firefox\"\n"
+ " activate\n"
+ " delay 0.15\n"
+ " tell application \"System Events\"\n"
+ " keystroke \"l\" using {command down}\n"
+ " keystroke \"a\" using {command down}\n"
+ " keystroke \"c\" using {command down}\n"
+ " end tell\n"
+ " delay 0.15\n"
+ " set theUrl to the clipboard\n"
+ " set the clipboard to oldClipboard\n"
+ " set theResult to (get theUrl) & \"::split::\" & (get name of window 1)\n"
+ "end tell\n"
+ "activate application (frontmostApplication as text)\n"
+ "set links to {}\n"
+ "copy theResult to the end of links\n"
+ "return links as string\n"))))
(car (split-string result "[\r\n]+" t))))
(defun org-mac-firefox-get-frontmost-url ()
@@ -303,27 +316,28 @@ applications and inserting them in org documents"
;; Firefox
(defun org-as-mac-vimperator-get-frontmost-url ()
- (let ((result (do-applescript
- (concat
- "set oldClipboard to the clipboard\n"
- "set frontmostApplication to path to frontmost application\n"
- "tell application \"Firefox\"\n"
- " activate\n"
- " delay 0.15\n"
- " tell application \"System Events\"\n"
- " keystroke \"y\"\n"
- " end tell\n"
- " delay 0.15\n"
- " set theUrl to the clipboard\n"
- " set the clipboard to oldClipboard\n"
- " set theResult to (get theUrl) & \"::split::\" & (get name of window 1)\n"
- "end tell\n"
- "activate application (frontmostApplication as text)\n"
- "set links to {}\n"
- "copy theResult to the end of links\n"
- "return links as string\n"))))
- (replace-regexp-in-string "\s+-\s+Vimperator" "" (car (split-string result "[\r\n]+" t)))))
-
+ (let ((result
+ (do-applescript
+ (concat
+ "set oldClipboard to the clipboard\n"
+ "set frontmostApplication to path to frontmost application\n"
+ "tell application \"Firefox\"\n"
+ " activate\n"
+ " delay 0.15\n"
+ " tell application \"System Events\"\n"
+ " keystroke \"y\"\n"
+ " end tell\n"
+ " delay 0.15\n"
+ " set theUrl to the clipboard\n"
+ " set the clipboard to oldClipboard\n"
+ " set theResult to (get theUrl) & \"::split::\" & (get name of window 1)\n"
+ "end tell\n"
+ "activate application (frontmostApplication as text)\n"
+ "set links to {}\n"
+ "copy theResult to the end of links\n"
+ "return links as string\n"))))
+ (replace-regexp-in-string
+ "\s+-\s+Vimperator" "" (car (split-string result "[\r\n]+" t)))))
(defun org-mac-vimperator-get-frontmost-url ()
(interactive)
@@ -348,19 +362,20 @@ applications and inserting them in org documents"
;; Firefox because Chrome doesn't publish an Applescript dictionary
(defun org-as-mac-chrome-get-frontmost-url ()
- (let ((result (do-applescript
- (concat
- "set frontmostApplication to path to frontmost application\n"
- "tell application \"Google Chrome\"\n"
- " set theUrl to get URL of active tab of first window\n"
- " set theResult to (get theUrl) & \"::split::\" & (get name of window 1)\n"
- "end tell\n"
- "activate application (frontmostApplication as text)\n"
- "set links to {}\n"
- "copy theResult to the end of links\n"
- "return links as string\n"))))
- (replace-regexp-in-string "^\"\\|\"$" ""
- (car (split-string result "[\r\n]+" t)))))
+ (let ((result
+ (do-applescript
+ (concat
+ "set frontmostApplication to path to frontmost application\n"
+ "tell application \"Google Chrome\"\n"
+ " set theUrl to get URL of active tab of first window\n"
+ " set theResult to (get theUrl) & \"::split::\" & (get name of window 1)\n"
+ "end tell\n"
+ "activate application (frontmostApplication as text)\n"
+ "set links to {}\n"
+ "copy theResult to the end of links\n"
+ "return links as string\n"))))
+ (replace-regexp-in-string
+ "^\"\\|\"$" "" (car (split-string result "[\r\n]+" t)))))
(defun org-mac-chrome-get-frontmost-url ()
(interactive)
@@ -384,13 +399,14 @@ applications and inserting them in org documents"
;; Grab the frontmost url from Safari.
(defun org-as-mac-safari-get-frontmost-url ()
- (let ((result (do-applescript
- (concat
- "tell application \"Safari\"\n"
- " set theUrl to URL of document 1\n"
- " set theName to the name of the document 1\n"
- " return theUrl & \"::split::\" & theName & \"\n\"\n"
- "end tell\n"))))
+ (let ((result
+ (do-applescript
+ (concat
+ "tell application \"Safari\"\n"
+ " set theUrl to URL of document 1\n"
+ " set theName to the name of the document 1\n"
+ " return theUrl & \"::split::\" & theName & \"\n\"\n"
+ "end tell\n"))))
(car (split-string result "[\r\n]+" t))))
(defun org-mac-safari-get-frontmost-url ()
@@ -411,30 +427,26 @@ applications and inserting them in org documents"
(insert (org-mac-safari-get-frontmost-url)))
-;;
-;;
;; Handle links from together.app
-;;
-;;
(org-add-link-type "x-together-item" 'org-mac-together-item-open)
(defun org-mac-together-item-open (uid)
- "Open the given uid, which is a reference to an item in Together"
+ "Open UID, which is a reference to an item in Together."
(shell-command (concat "open -a Together \"x-together-item:" uid "\"")))
(defun as-get-selected-together-items ()
(do-applescript
- (concat
- "tell application \"Together\"\n"
- " set theLinkList to {}\n"
- " set theSelection to selected items\n"
- " repeat with theItem in theSelection\n"
- " set theLink to (get item link of theItem) & \"::split::\" & (get name of theItem) & \"\n\"\n"
- " copy theLink to end of theLinkList\n"
- " end repeat\n"
- " return theLinkList as string\n"
- "end tell")))
+ (concat
+ "tell application \"Together\"\n"
+ " set theLinkList to {}\n"
+ " set theSelection to selected items\n"
+ " repeat with theItem in theSelection\n"
+ " set theLink to (get item link of theItem) & \"::split::\" & (get name of theItem) & \"\n\"\n"
+ " copy theLink to end of theLinkList\n"
+ " end repeat\n"
+ " return theLinkList as string\n"
+ "end tell")))
(defun org-mac-together-get-selected ()
(interactive)
@@ -444,26 +456,22 @@ applications and inserting them in org documents"
(defun org-mac-together-insert-selected ()
(interactive)
(insert (org-mac-together-get-selected)))
-
-;;
-;;
+
;; Handle links from Finder.app
-;;
-;;
(defun as-get-selected-finder-items ()
(do-applescript
- (concat
- "tell application \"Finder\"\n"
- " set theSelection to the selection\n"
- " set links to {}\n"
- " repeat with theItem in theSelection\n"
- " set theLink to \"file://\" & (POSIX path of (theItem as string)) & \"::split::\" & (get the name of theItem) & \"\n\"\n"
- " copy theLink to the end of links\n"
- " end repeat\n"
- " return links as string\n"
- "end tell\n")))
+ (concat
+ "tell application \"Finder\"\n"
+ " set theSelection to the selection\n"
+ " set links to {}\n"
+ " repeat with theItem in theSelection\n"
+ " set theLink to \"file://\" & (POSIX path of (theItem as string)) & \"::split::\" & (get the name of theItem) & \"\n\"\n"
+ " copy theLink to the end of links\n"
+ " end repeat\n"
+ " return links as string\n"
+ "end tell\n")))
(defun org-mac-finder-item-get-selected ()
(interactive)
@@ -475,30 +483,26 @@ applications and inserting them in org documents"
(insert (org-mac-finder-item-get-selected)))
-;;
-;;
;; Handle links from AddressBook.app
-;;
-;;
(org-add-link-type "addressbook" 'org-mac-addressbook-item-open)
(defun org-mac-addressbook-item-open (uid)
- "Open the given uid, which is a reference to an item in Together"
+ "Open UID, which is a reference to an item in the addressbook."
(shell-command (concat "open \"addressbook:" uid "\"")))
(defun as-get-selected-addressbook-items ()
(do-applescript
- (concat
- "tell application \"Address Book\"\n"
- " set theSelection to the selection\n"
- " set links to {}\n"
- " repeat with theItem in theSelection\n"
- " set theLink to \"addressbook://\" & (the id of theItem) & \"::split::\" & (the name of theItem) & \"\n\"\n"
- " copy theLink to the end of links\n"
- " end repeat\n"
- " return links as string\n"
- "end tell\n")))
+ (concat
+ "tell application \"Address Book\"\n"
+ " set theSelection to the selection\n"
+ " set links to {}\n"
+ " repeat with theItem in theSelection\n"
+ " set theLink to \"addressbook://\" & (the id of theItem) & \"::split::\" & (the name of theItem) & \"\n\"\n"
+ " copy theLink to the end of links\n"
+ " end repeat\n"
+ " return links as string\n"
+ "end tell\n")))
(defun org-mac-addressbook-item-get-selected ()
(interactive)
@@ -509,8 +513,7 @@ applications and inserting them in org documents"
(interactive)
(insert (org-mac-addressbook-item-get-selected)))
-;;
-;;
+
;; Handle links from Skim.app
;;
;; Original code & idea by Christopher Suckling (org-mac-protocol)
@@ -523,40 +526,39 @@ applications and inserting them in org documents"
(match-string 1 uri)))
(document (substring uri 0 (match-beginning 0))))
(do-applescript
- (concat
- "tell application \"Skim\"\n"
- "activate\n"
- "set theDoc to \"" document "\"\n"
- "set thePage to " page "\n"
- "open theDoc\n"
- "go document 1 to page thePage of document 1\n"
- "end tell"))))
-
+ (concat
+ "tell application \"Skim\"\n"
+ "activate\n"
+ "set theDoc to \"" document "\"\n"
+ "set thePage to " page "\n"
+ "open theDoc\n"
+ "go document 1 to page thePage of document 1\n"
+ "end tell"))))
(defun as-get-skim-page-link ()
(do-applescript
+ (concat
+ "tell application \"Skim\"\n"
+ "set theDoc to front document\n"
+ "set theTitle to (name of theDoc)\n"
+ "set thePath to (path of theDoc)\n"
+ "set thePage to (get index for current page of theDoc)\n"
+ "set theSelection to selection of theDoc\n"
+ "set theContent to contents of (get text for theSelection)\n"
+ "if theContent is missing value then\n"
+ " set theContent to theTitle & \", p. \" & thePage\n"
+ (when org-mac-Skim-highlight-selection-p
(concat
- "tell application \"Skim\"\n"
- "set theDoc to front document\n"
- "set theTitle to (name of theDoc)\n"
- "set thePath to (path of theDoc)\n"
- "set thePage to (get index for current page of theDoc)\n"
- "set theSelection to selection of theDoc\n"
- "set theContent to contents of (get text for theSelection)\n"
- "if theContent is missing value then\n"
- " set theContent to theTitle & \", p. \" & thePage\n"
- (when org-mac-Skim-highlight-selection-p
- (concat
- "else\n"
- " tell theDoc\n"
- " set theNote to make note with properties {type:highlight note, selection:theSelection}\n"
- " set text of theNote to (get text for theSelection)\n"
- " end tell\n"))
- "end if\n"
- "set theLink to \"skim://\" & thePath & \"::\" & thePage & "
- "\"::split::\" & theContent\n"
- "end tell\n"
- "return theLink as string\n")))
+ "else\n"
+ " tell theDoc\n"
+ " set theNote to make note with properties {type:highlight note, selection:theSelection}\n"
+ " set text of theNote to (get text for theSelection)\n"
+ " end tell\n"))
+ "end if\n"
+ "set theLink to \"skim://\" & thePath & \"::\" & thePage & "
+ "\"::split::\" & theContent\n"
+ "end tell\n"
+ "return theLink as string\n")))
(defun org-mac-skim-get-page ()
(interactive)
@@ -575,12 +577,8 @@ applications and inserting them in org documents"
(interactive)
(insert (org-mac-skim-get-page)))
-
-;;
-;;
;; Handle links from Microsoft Outlook.app
-;;
(org-add-link-type "mac-outlook" 'org-mac-outlook-message-open)
@@ -589,9 +587,9 @@ applications and inserting them in org documents"
(do-applescript
(concat
"tell application \"Microsoft Outlook\"\n"
- (format "open message id %s\n" (substring-no-properties msgid))
- "activate\n"
- "end tell")))
+ (format "open message id %s\n" (substring-no-properties msgid))
+ "activate\n"
+ "end tell")))
(defun org-as-get-selected-outlook-mail ()
"AppleScript to create links to selected messages in Microsoft Outlook.app."
@@ -672,16 +670,18 @@ The Org-syntax text will be pushed to the kill ring, and also returned."
(defun org-mac-outlook-message-insert-selected ()
"Insert a link to the messages currently selected in Microsoft Outlook.app.
-This will use AppleScript to get the message-id and the subject of the
-active mail in Microsoft Outlook.app and make a link out of it."
+This will use AppleScript to get the message-id and the subject
+of the active mail in Microsoft Outlook.app and make a link out
+of it."
(interactive)
(insert (org-mac-outlook-message-get-links "s")))
(defun org-mac-outlook-message-insert-flagged (org-buffer org-heading)
"Asks for an org buffer and a heading within it, and replace message links.
-If heading exists, delete all mac-outlook:// links within heading's first
-level. If heading doesn't exist, create it at point-max. Insert
-list of mac-outlook:// links to flagged mail after heading."
+If heading exists, delete all mac-outlook:// links within
+heading's first level. If heading doesn't exist, create it at
+point-max. Insert list of mac-outlook:// links to flagged mail
+after heading."
(interactive "bBuffer in which to insert links: \nsHeading after which to insert links: ")
(with-current-buffer org-buffer
(goto-char (point-min))
@@ -702,17 +702,78 @@ list of mac-outlook:// links to flagged mail after heading."
(org-insert-heading nil t)
(insert org-heading "\n" (org-mac-outlook-message-get-links "f"))))))
+
+;; Handle links from DEVONthink Pro Office.app
+
+(org-add-link-type "x-devonthink-item" 'org-devonthink-item-open)
+
+(defun org-devonthink-item-open (uid)
+ "Open UID, which is a reference to an item in DEVONthink Pro Office."
+ (shell-command (concat "open \"x-devonthink-item:" uid "\"")))
+
+(defun org-as-get-selected-devonthink-item ()
+ "AppleScript to create links to selected items in DEVONthink Pro Office.app."
+ (do-applescript
+ (concat
+ "set theLinkList to {}\n"
+ "tell application \"DEVONthink Pro\"\n"
+ "set selectedRecords to selection\n"
+ "set selectionCount to count of selectedRecords\n"
+ "if (selectionCount < 1) then\n"
+ "return\n"
+ "end if\n"
+ "repeat with theRecord in selectedRecords\n"
+ "set theID to uuid of theRecord\n"
+ "set theURL to \"x-devonthink-item:\" & theID\n"
+ "set theSubject to name of theRecord\n"
+ "set theLink to theURL & \"::split::\" & theSubject & \"\n\"\n"
+ "copy theLink to end of theLinkList\n"
+ "end repeat\n"
+ "end tell\n"
+ "return theLinkList as string"
+ )))
+
+(defun org-mac-devonthink-get-links ()
+ "Create links to the item(s) currently selected in DEVONthink Pro Office.
+This will use AppleScript to get the `uuid' and the `name' of the
+selected items in DEVONthink Pro Office.app and make links out of
+it/them. This function will push the Org-syntax text to the kill
+ring, and also return it."
+ (message "Org Mac DEVONthink: looking for selected items...")
+ (let* ((as-link-list (org-as-get-selected-devonthink-item))
+ (link-list (if as-link-list
+ (mapcar
+ (lambda (x) (if (string-match "\\`\"\\(.*\\)\"\\'" x)
+ (setq x (match-string 1 x)))
+ x)
+ (split-string as-link-list "[\r\n]+"))
+ nil))
+ orglink-list)
+ (while link-list
+ (let* ((current-item (pop link-list)))
+ (message "current item: %s" current-item)
+ (when (and current-item (not (string= current-item "")))
+ (let* ((split-link (split-string current-item "::split::"))
+ (orglink (org-make-link-string
+ (url-encode-url (car split-link))
+ (cadr split-link))))
+ (push orglink orglink-list)))))
+ (kill-new (mapconcat 'identity orglink-list "\n"))))
+
+(defun org-mac-devonthink-item-insert-selected ()
+ "Insert a link to the item(s) currently selected in DEVONthink Pro Office.
+This will use AppleScript to get the `uuid'(s) and the name(s) of the
+selected items in DEVONthink Pro Office and make link(s) out of it/them."
+ (interactive)
+ (insert (org-mac-devonthink-get-links)))
-;;
-;;
;; Handle links from Mail.app
-;;
(org-add-link-type "message" 'org-mac-message-open)
(defun org-mac-message-open (message-id)
- "Visit the message with the given MESSAGE-ID.
+ "Visit the message with MESSAGE-ID.
This will use the command `open' with the message URL."
(start-process (concat "open message:" message-id) nil
"open" (concat "message://<" (substring message-id 2) ">")))
@@ -720,67 +781,70 @@ This will use the command `open' with the message URL."
(defun org-as-get-selected-mail ()
"AppleScript to create links to selected messages in Mail.app."
(do-applescript
- (concat
- "tell application \"Mail\"\n"
- "set theLinkList to {}\n"
- "set theSelection to selection\n"
- "repeat with theMessage in theSelection\n"
- "set theID to message id of theMessage\n"
- "set theSubject to subject of theMessage\n"
- "set theLink to \"message://\" & theID & \"::split::\" & theSubject & \"\n\"\n"
- "copy theLink to end of theLinkList\n"
- "end repeat\n"
- "return theLinkList as string\n"
- "end tell")))
+ (concat
+ "tell application \"Mail\"\n"
+ "set theLinkList to {}\n"
+ "set theSelection to selection\n"
+ "repeat with theMessage in theSelection\n"
+ "set theID to message id of theMessage\n"
+ "set theSubject to subject of theMessage\n"
+ "set theLink to \"message://\" & theID & \"::split::\" & theSubject\n"
+ "if (theLinkList is not equal to {}) then\n"
+ "set theLink to \"\n\" & theLink\n"
+ "end if\n"
+ "copy theLink to end of theLinkList\n"
+ "end repeat\n"
+ "return theLinkList as string\n"
+ "end tell")))
(defun org-as-get-flagged-mail ()
"AppleScript to create links to flagged messages in Mail.app."
(do-applescript
- (concat
- ;; Is Growl installed?
- "tell application \"System Events\"\n"
- "set growlHelpers to the name of every process whose creator type contains \"GRRR\"\n"
- "if (count of growlHelpers) > 0 then\n"
- "set growlHelperApp to item 1 of growlHelpers\n"
- "else\n"
- "set growlHelperApp to \"\"\n"
- "end if\n"
- "end tell\n"
-
- ;; Get links
- "tell application \"Mail\"\n"
- "set theMailboxes to every mailbox of account \"" org-mac-mail-account "\"\n"
- "set theLinkList to {}\n"
- "repeat with aMailbox in theMailboxes\n"
- "set theSelection to (every message in aMailbox whose flagged status = true)\n"
- "repeat with theMessage in theSelection\n"
- "set theID to message id of theMessage\n"
- "set theSubject to subject of theMessage\n"
- "set theLink to \"message://\" & theID & \"::split::\" & theSubject & \"\n\"\n"
- "copy theLink to end of theLinkList\n"
-
- ;; Report progress through Growl
- ;; This "double tell" idiom is described in detail at
- ;; http://macscripter.net/viewtopic.php?id=24570 The
- ;; script compiler needs static knowledge of the
- ;; growlHelperApp. Hmm, since we're compiling
- ;; on-the-fly here, this is likely to be way less
- ;; portable than I'd hoped. It'll work when the name
- ;; is still "GrowlHelperApp", though.
- "if growlHelperApp is not \"\" then\n"
- "tell application \"GrowlHelperApp\"\n"
- "tell application growlHelperApp\n"
- "set the allNotificationsList to {\"FlaggedMail\"}\n"
- "set the enabledNotificationsList to allNotificationsList\n"
- "register as application \"FlaggedMail\" all notifications allNotificationsList default notifications enabledNotificationsList icon of application \"Mail\"\n"
- "notify with name \"FlaggedMail\" title \"Importing flagged message\" description theSubject application name \"FlaggedMail\"\n"
- "end tell\n"
- "end tell\n"
- "end if\n"
- "end repeat\n"
- "end repeat\n"
- "return theLinkList as string\n"
- "end tell")))
+ (concat
+ ;; Is Growl installed?
+ "tell application \"System Events\"\n"
+ "set growlHelpers to the name of every process whose creator type contains \"GRRR\"\n"
+ "if (count of growlHelpers) > 0 then\n"
+ "set growlHelperApp to item 1 of growlHelpers\n"
+ "else\n"
+ "set growlHelperApp to \"\"\n"
+ "end if\n"
+ "end tell\n"
+
+ ;; Get links
+ "tell application \"Mail\"\n"
+ "set theMailboxes to every mailbox of account \"" org-mac-mail-account "\"\n"
+ "set theLinkList to {}\n"
+ "repeat with aMailbox in theMailboxes\n"
+ "set theSelection to (every message in aMailbox whose flagged status = true)\n"
+ "repeat with theMessage in theSelection\n"
+ "set theID to message id of theMessage\n"
+ "set theSubject to subject of theMessage\n"
+ "set theLink to \"message://\" & theID & \"::split::\" & theSubject & \"\n\"\n"
+ "copy theLink to end of theLinkList\n"
+
+ ;; Report progress through Growl
+ ;; This "double tell" idiom is described in detail at
+ ;; http://macscripter.net/viewtopic.php?id=24570 The
+ ;; script compiler needs static knowledge of the
+ ;; growlHelperApp. Hmm, since we're compiling
+ ;; on-the-fly here, this is likely to be way less
+ ;; portable than I'd hoped. It'll work when the name
+ ;; is still "GrowlHelperApp", though.
+ "if growlHelperApp is not \"\" then\n"
+ "tell application \"GrowlHelperApp\"\n"
+ "tell application growlHelperApp\n"
+ "set the allNotificationsList to {\"FlaggedMail\"}\n"
+ "set the enabledNotificationsList to allNotificationsList\n"
+ "register as application \"FlaggedMail\" all notifications allNotificationsList default notifications enabledNotificationsList icon of application \"Mail\"\n"
+ "notify with name \"FlaggedMail\" title \"Importing flagged message\" description theSubject application name \"FlaggedMail\"\n"
+ "end tell\n"
+ "end tell\n"
+ "end if\n"
+ "end repeat\n"
+ "end repeat\n"
+ "return theLinkList as string\n"
+ "end tell")))
(defun org-mac-message-get-links (&optional select-or-flag)
"Create links to the messages currently selected or flagged in Mail.app.
@@ -795,13 +859,13 @@ The Org-syntax text will be pushed to the kill ring, and also returned."
(let* ((as-link-list
(if (string= select-or-flag "s")
(org-as-get-selected-mail)
- (if (string= select-or-flag "f")
- (org-as-get-flagged-mail)
- (error "Please select \"s\" or \"f\""))))
+ (if (string= select-or-flag "f")
+ (org-as-get-flagged-mail)
+ (error "Please select \"s\" or \"f\""))))
(link-list
(mapcar
(lambda (x) (if (string-match "\\`\"\\(.*\\)\"\\'" x) (setq x (match-string 1 x))) x)
- (split-string as-link-list "[\r\n]+")))
+ (split-string (substring as-link-list 1 -1) "[\r\n]+")))
split-link URL description orglink orglink-insert rtn orglink-list)
(while link-list
(setq split-link (split-string (pop link-list) "::split::"))
@@ -843,11 +907,11 @@ list of message:// links to flagged mail after heading."
(delete-region (match-beginning 0) (match-end 0)))
(insert "\n" (org-mac-message-get-links "f")))
(flush-lines "^$" (point) (outline-next-heading)))
- (insert "\n" (org-mac-message-get-links "f")))
- (goto-char (point-max))
- (insert "\n")
- (org-insert-heading nil t)
- (insert org-heading "\n" (org-mac-message-get-links "f"))))))
+ (insert "\n" (org-mac-message-get-links "f")))
+ (goto-char (point-max))
+ (insert "\n")
+ (org-insert-heading nil t)
+ (insert org-heading "\n" (org-mac-message-get-links "f"))))))
(provide 'org-mac-link)
diff --git a/contrib/lisp/org-mime.el b/contrib/lisp/org-mime.el
index b0007ac..44bf91b 100644
--- a/contrib/lisp/org-mime.el
+++ b/contrib/lisp/org-mime.el
@@ -163,10 +163,13 @@ and images in a multipart/related part."
('semi (concat
"--" "<<alternative>>-{\n"
"--" "[[text/plain]]\n" plain
- (when images (concat "--" "<<alternative>>-{\n"))
- "--" "[[text/html]]\n" html
- images
- (when images (concat "--" "}-<<alternative>>\n"))
+ (if (and images (> (length images) 0))
+ (concat "--" "<<related>>-{\n"
+ "--" "[[text/html]]\n" html
+ images
+ "--" "}-<<related>>\n")
+ (concat "--" "[[text/html]]\n" html
+ images))
"--" "}-<<alternative>>\n"))
('vm "?")))
@@ -269,8 +272,10 @@ export that region, otherwise export the entire body."
(defun org-mime-send-buffer (&optional fmt)
(run-hooks 'org-mime-send-buffer-hook)
(let* ((region-p (org-region-active-p))
- (subject (org-export-grab-title-from-buffer))
- (file (buffer-file-name (current-buffer)))
+ (file (buffer-file-name (current-buffer)))
+ (subject (if (not file) (buffer-name (buffer-base-buffer))
+ (file-name-sans-extension
+ (file-name-nondirectory file))))
(body-start (or (and region-p (region-beginning))
(save-excursion (goto-char (point-min)))))
(body-end (or (and region-p (region-end)) (point-max)))
diff --git a/contrib/lisp/org-mtags.el b/contrib/lisp/org-mtags.el
deleted file mode 100644
index 5342184..0000000
--- a/contrib/lisp/org-mtags.el
+++ b/dev/null
@@ -1,255 +0,0 @@
-;;; org-mtags.el --- Muse-like tags in Org-mode
-
-;; Copyright (C) 2008-2014 Free Software Foundation, Inc.
-;;
-;; Author: Carsten Dominik <carsten at orgmode dot org>
-;; Keywords: outlines, hypermedia, calendar, wp
-;; Homepage: http://orgmode.org
-;; Version: 0.01
-;;
-;; This file is not yet part of GNU Emacs.
-;;
-;; This program is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 3, 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 <http://www.gnu.org/licenses/>.
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;
-;;; Commentary:
-;;
-;; This modules implements some of the formatting tags available in
-;; Emacs Muse. This is not a way if adding new functionality, but just
-;; a different way to write some formatting directives. The advantage is
-;; that files written in this way can be read by Muse reasonably well,
-;; and that this provides an alternative way of writing formatting
-;; directives in Org, a way that some might find more pleasant to type
-;; and look at that the Org's #+BEGIN..#+END notation.
-
-;; The goal of this development is to make it easier for people to
-;; move between both worlds as they see fit for different tasks.
-
-;; The following muse tags will be translated during export into their
-;; native Org equivalents:
-;;
-;; <br>
-;; Needs to be at the end of a line. Will be translated to "\\".
-;;
-;; <example switches="-n -r">
-;; Needs to be on a line by itself, similarly the </example> tag.
-;; Will be translated into Org's #+BEGIN_EXAMPLE construct.
-;;
-;; <quote>
-;; Needs to be on a line by itself, similarly the </quote> tag.
-;; Will be translated into Org's #+BEGIN_QUOTE construct.
-;;
-;; <comment>
-;; Needs to be on a line by itself, similarly the </comment> tag.
-;; Will be translated into Org's #+BEGIN_COMMENT construct.
-;;
-;; <verse>
-;; Needs to be on a line by itself, similarly the </verse> tag.
-;; Will be translated into Org's #+BEGIN_VERSE construct.
-;;
-;; <contents>
-;; This gets translated into "[TABLE-OF-CONTENTS]". It will not
-;; trigger the production of a table of contents - that is done
-;; in Org with the "#+OPTIONS: toc:t" setting. But it will define
-;; the location where the TOC will be placed.
-;;
-;; <literal style="STYLE"> ;; only latex, html, and docbook supported
-;; in Org.
-;; Needs to be on a line by itself, similarly the </literal> tag.
-;;
-;; <src lang="LANG" switches="-n -r">
-;; Needs to be on a line by itself, similarly the </src> tag.
-;; Will be translated into Org's BEGIN_SRC construct.
-;;
-;; <include file="FILE" markup="MARKUP" lang="LANG"
-;; prefix="str" prefix1="str" switches="-n -r">
-;; Needs to be on a line by itself.
-;; Will be translated into Org's #+INCLUDE construct.
-;;
-;; The lisp/perl/ruby/python tags can be implemented using the
-;; `org-eval.el' module, which see.
-
-(require 'org)
-
-;;; Customization
-
-(defgroup org-mtags nil
- "Options concerning Muse tags in Org mode."
- :tag "Org Muse Tags"
- :group 'org)
-
-(defface org-mtags ; similar to shadow
- (org-compatible-face 'shadow
- '((((class color grayscale) (min-colors 88) (background light))
- (:foreground "grey50"))
- (((class color grayscale) (min-colors 88) (background dark))
- (:foreground "grey70"))
- (((class color) (min-colors 8) (background light))
- (:foreground "green"))
- (((class color) (min-colors 8) (background dark))
- (:foreground "yellow"))))
- "Face for Muse-like tags in Org."
- :group 'org-mtags
- :group 'org-faces)
-
-(defcustom org-mtags-prefer-muse-templates t
- "Non-nil means prefere Muse tags for structure elements.
-This is relevane when expanding the templates defined in the variable
-`org-structure-templates'."
- :group 'org-mtags
- :type 'boolean)
-
-(defconst org-mtags-supported-tags
- '("example" "quote" "comment" "verse" "contents" "literal" "src" "include")
- "The tags that are supported by org-mtags.el for conversion.
-In addition to this list, the <br> tag is supported as well.")
-
-(defconst org-mtags-fontification-re
- (concat
- "^[ \t]*</?\\("
- (mapconcat 'identity org-mtags-supported-tags "\\|")
- "\\)\\>[^>]*>\\|<br>[ \t]*$")
- "Regular expression used for fontifying muse tags.")
-
-(defun org-mtags-replace ()
- "Replace Muse-like tags with the appropriate Org constructs.
-The is done in the entire buffer."
- (interactive) ;; FIXME
- (let ((re (concat "^[ \t]*\\(</?\\("
- (mapconcat 'identity org-mtags-supported-tags "\\|")
- "\\)\\>\\)"))
- info tag rpl style markup lang file prefix prefix1 switches)
- ;; First, do the <br> tag
- (goto-char (point-min))
- (while (re-search-forward "<br>[ \t]*$" nil t)
- (replace-match "\\\\" t t))
- ;; Now, all the other tags
- (goto-char (point-min))
- (while (re-search-forward re nil t)
- (goto-char (match-beginning 1))
- (setq info (org-mtags-get-tag-and-attributes))
- (if (not info)
- (end-of-line 1)
- (setq tag (plist-get info :tag))
- (cond
- ((equal tag "contents")
- (setq rpl "[TABLE-OF-CONTENTS]")
- ;; FIXME: also trigger TOC in options-plist?????
- )
- ((member tag '("quote" "comment" "verse"))
- (if (plist-get info :closing)
- (setq rpl (format "#+END_%s" (upcase tag)))
- (setq rpl (format "#+BEGIN_%s" (upcase tag)))))
- ((equal tag "literal")
- (setq style (plist-get info :style))
- (and style (setq style (downcase style)))
- (if (plist-get info :closing)
- (setq rpl (cond
- ((member style '("latex"))
- "#+END_LaTeX")
- ((member style '("html"))
- "#+END_HTML")
- ((member style '("docbook"))
- "#+END_DOCBOOK")
- ((member style '("ascii"))
- "#+END_ASCII")))
- (setq rpl (cond
- ((member style '("latex"))
- "#+BEGIN_LaTeX")
- ((member style '("html"))
- "#+BEGIN_HTML")
- ((member style '("ascii"))
- "#+BEGIN_ASCII")))))
- ((equal tag "example")
- (if (plist-get info :closing)
- (setq rpl "#+END_EXAMPLE")
- (setq rpl "#+BEGIN_EXAMPLE")
- (when (setq switches (plist-get info :switches))
- (setq rpl (concat rpl " " switches)))))
- ((equal tag "src")
- (if (plist-get info :closing)
- (setq rpl "#+END_SRC")
- (setq rpl "#+BEGIN_SRC")
- (when (setq lang (plist-get info :lang))
- (setq rpl (concat rpl " " lang))
- (when (setq switches (plist-get info :switches))
- (setq rpl (concat rpl " " switches))))))
- ((equal tag "include")
- (setq file (plist-get info :file)
- markup (downcase (plist-get info :markup))
- lang (plist-get info :lang)
- prefix (plist-get info :prefix)
- prefix1 (plist-get info :prefix1)
- switches (plist-get info :switches))
- (setq rpl "#+INCLUDE")
- (setq rpl (concat rpl " " (prin1-to-string file)))
- (when markup
- (setq rpl (concat rpl " " markup))
- (when (and (equal markup "src") lang)
- (setq rpl (concat rpl " " lang))))
- (when prefix
- (setq rpl (concat rpl " :prefix " (prin1-to-string prefix))))
- (when prefix1
- (setq rpl (concat rpl " :prefix1 " (prin1-to-string prefix1))))
- (when switches
- (setq rpl (concat rpl " " switches)))))
- (when rpl
- (goto-char (plist-get info :match-beginning))
- (delete-region (point-at-bol) (plist-get info :match-end))
- (insert rpl))))))
-
-(defun org-mtags-get-tag-and-attributes ()
- "Parse a Muse-like tag at point ant rturn the information about it.
-The return value is a property list which contains all the attributes
-with string values. In addition, it reutnrs the following properties:
-
-:tag The tag as a string.
-:match-beginning The beginning of the match, just before \"<\".
-:match-end The end of the match, just after \">\".
-:closing t when the tag starts with \"</\"."
- (when (looking-at "<\\(/\\)?\\([a-zA-Z]+\\>\\)\\([^>]*\\)>")
- (let ((start 0)
- tag rest prop attributes endp val)
- (setq tag (org-match-string-no-properties 2)
- endp (match-end 1)
- rest (and (match-end 3)
- (org-match-string-no-properties 3))
- attributes (list :tag tag
- :match-beginning (match-beginning 0)
- :match-end (match-end 0)
- :closing endp))
- (when rest
- (while (string-match "\\([a-zA-Z]+\\)=\\([^ \t\n>]+\\|\"[^>]+\"\\)"
- rest start)
- (setq start (match-end 0)
- prop (org-match-string-no-properties 1 rest)
- val (org-remove-double-quotes
- (org-match-string-no-properties 2 rest)))
- (setq attributes (plist-put attributes
- (intern (concat ":" prop)) val))))
- attributes)))
-
-(defun org-mtags-fontify-tags (limit)
- "Fontify the muse-like tags."
- (while (re-search-forward org-mtags-fontification-re limit t)
- (add-text-properties (match-beginning 0) (match-end 0)
- '(face org-mtags font-lock-multiline t
- font-lock-fontified t))))
-
-(add-hook 'org-export-preprocess-hook 'org-mtags-replace)
-(add-hook 'org-font-lock-hook 'org-mtags-fontify-tags)
-
-(provide 'org-mtags)
-
-;;; org-mtags.el ends here
diff --git a/contrib/lisp/org-notmuch.el b/contrib/lisp/org-notmuch.el
index 2ab5c17..ae9b50b 100644
--- a/contrib/lisp/org-notmuch.el
+++ b/contrib/lisp/org-notmuch.el
@@ -41,6 +41,29 @@
(require 'org)
+;; customisable notmuch open functions
+(defcustom org-notmuch-open-function
+ 'org-notmuch-follow-link
+ "Function used to follow notmuch links.
+
+Should accept a notmuch search string as the sole argument."
+ :group 'org-notmuch
+ :version "24.4"
+ :package-version '(Org . "8.0")
+ :type 'function)
+
+(defcustom org-notmuch-search-open-function
+ 'org-notmuch-search-follow-link
+ "Function used to follow notmuch-search links.
+
+Should accept a notmuch search string as the sole argument."
+ :group 'org-notmuch
+ :version "24.4"
+ :package-version '(Org . "8.0")
+ :type 'function)
+
+
+
;; Install the link type
(org-add-link-type "notmuch" 'org-notmuch-open)
(add-hook 'org-store-link-functions 'org-notmuch-store-link)
@@ -62,7 +85,7 @@
(defun org-notmuch-open (path)
"Follow a notmuch message link specified by PATH."
- (org-notmuch-follow-link path))
+ (funcall org-notmuch-open-function path))
(defun org-notmuch-follow-link (search)
"Follow a notmuch link to SEARCH.
@@ -91,13 +114,20 @@ Can link to more than one message, if so all matching messages are shown."
(defun org-notmuch-search-open (path)
"Follow a notmuch message link specified by PATH."
(message path)
- (org-notmuch-search-follow-link path))
+ (funcall org-notmuch-search-open-function path))
(defun org-notmuch-search-follow-link (search)
"Follow a notmuch link by displaying SEARCH in notmuch-search mode."
(require 'notmuch)
(notmuch-search (org-link-unescape search)))
+
+
+(defun org-notmuch-tree-follow-link (search)
+ "Follow a notmuch link by displaying SEARCH in notmuch-tree mode."
+ (require 'notmuch)
+ (notmuch-tree (org-link-unescape search)))
+
(provide 'org-notmuch)
;;; org-notmuch.el ends here
diff --git a/contrib/lisp/org-passwords.el b/contrib/lisp/org-passwords.el
new file mode 100644
index 0000000..7ed8c80
--- a/dev/null
+++ b/contrib/lisp/org-passwords.el
@@ -0,0 +1,342 @@
+;;; org-passwords.el --- org derived mode for managing passwords
+
+;; Author: Jorge A. Alfaro-Murillo <jorge.alfaro-murillo@yale.edu>
+;; Created: December 26, 2012
+;; Keywords: passwords, password
+
+;; This file is NOT part of GNU Emacs.
+;;
+;; This program is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Commentary:
+
+;; This file contains the code for managing your passwords with
+;; Org-mode.
+
+;; A basic setup needs to indicate a passwords file, and a dictionary
+;; for the random words:
+
+;; (require org-passwords)
+;; (setq org-passwords-file "~/documents/passwords.gpg")
+;; (setq org-passwords-random-words-dictionary "/etc/dictionaries-common/words")
+
+;; Basic usage:
+
+;; `M-x org-passwords' opens the passwords file in
+;; `org-passwords-mode'.
+
+;; `M-x org-passwords-generate-password' generates a random string
+;; of numbers, lowercase letters and uppercase letters.
+
+;; `C-u M-x org-passwords-generate-password' generates a random
+;; string of numbers, lowercase letters, uppercase letters and
+;; symbols.
+
+;; `M-x org-passwords-random-words' concatenates random words from
+;; the dictionary defined by `org-passwords-random-words-dictionary'
+;; into a string, each word separated by the string defined in
+;; `org-passwords-random-words-separator'.
+
+;; `C-u M-x org-passwords-random-words' does the same as above, and
+;; also makes substitutions according to
+;; `org-passwords-random-words-substitutions'.
+
+;; It is also useful to set up keybindings for the functions
+;; `org-passwords-copy-username' and
+;; `org-passwords-copy-password' in the
+;; `org-passwords-mode', to easily make the passwords and usernames
+;; available to the facility for pasting text of the window system
+;; (clipboard on X and MS-Windows, pasteboard on Nextstep/Mac OS,
+;; etc.), without inserting them in the kill-ring. You can set for
+;; example:
+
+;; (eval-after-load "org-passwords"
+;; '(progn
+;; (define-key org-passwords-mode-map
+;; (kbd "C-c u")
+;; 'org-passwords-copy-username)
+;; (define-key org-passwords-mode-map
+;; (kbd "C-c p")
+;; 'org-passwords-copy-password)))
+
+;; Finally, to enter new passwords, you can use `org-capture' and a minimal template like:
+
+;; ("p" "password" entry (file "~/documents/passwords.gpg")
+;; "* %^{Title}\n %^{PASSWORD}p %^{USERNAME}p")
+
+;; When asked for the password you can then call either
+;; `org-passwords-generate-password' or `org-passwords-random-words'.
+;; Be sure to enable recursive minibuffers to call those functions
+;; from the minibuffer:
+
+;; (setq enable-recursive-minibuffers t)
+
+;;; Code:
+
+(require 'org)
+
+(define-derived-mode org-passwords-mode org-mode
+ "org-passwords-mode"
+ "Mode for storing passwords"
+ nil)
+
+(defgroup org-passwords nil
+ "Options for password management."
+ :group 'org)
+
+(defcustom org-passwords-password-property "PASSWORD"
+ "Name of the property for password entry password."
+ :type 'string
+ :group 'org-passwords)
+
+(defcustom org-passwords-username-property "USERNAME"
+ "Name of the property for password entry user name."
+ :type 'string
+ :group 'org-passwords)
+
+(defcustom org-passwords-file nil
+ "Default file name for the file that contains the passwords."
+ :type 'file
+ :group 'org-passwords)
+
+(defcustom org-passwords-time-opened "1 min"
+ "Time that the password file will remain open. It has to be a
+string, a number followed by units."
+ :type 'str
+ :group 'org-passwords)
+
+(defcustom org-passwords-random-words-dictionary nil
+ "Default file name for the file that contains a dictionary of
+words for `org-passwords-random-words'. Each non-empty line in
+the file is considered a word."
+ :type 'file
+ :group 'org-passwords)
+
+(defvar org-passwords-random-words-separator "-"
+ "A string to separate words in `org-passwords-random-words'.")
+
+(defvar org-passwords-random-words-substitutions
+ '(("a" . "@")
+ ("e" . "3")
+ ("o" . "0"))
+"A list of substitutions to be made with
+`org-passwords-random-words' if it is called with
+`universal-argument'. Each element is pair of
+strings (SUBSTITUTE-THIS . BY-THIS).")
+
+(defun org-passwords-copy-password ()
+ "Makes the password available to other programs. Puts the
+password of the entry at the location of the cursor in the
+facility for pasting text of the window system (clipboard on X
+and MS-Windows, pasteboard on Nextstep/Mac OS, etc.), without
+putting it in the kill ring."
+ (interactive)
+ (save-excursion
+ (search-backward-regexp "^\\*")
+ (search-forward-regexp (concat "^[[:space:]]*:"
+ org-passwords-password-property
+ ":[[:space:]]*"))
+ (funcall interprogram-cut-function
+ (buffer-substring-no-properties (point)
+ (funcall (lambda ()
+ (end-of-line)
+ (point)))))))
+
+(defun org-passwords-copy-username ()
+ "Makes the password available to other programs. Puts the
+username of the entry at the location of the cursor in the
+facility for pasting text of the window system (clipboard on X
+and MS-Windows, pasteboard on Nextstep/Mac OS, etc.), without
+putting it in the kill ring."
+ (interactive)
+ (save-excursion
+ (search-backward-regexp "^\\*")
+ (search-forward-regexp (concat "^[[:space:]]*:"
+ org-passwords-username-property
+ ":[[:space:]]*"))
+ (funcall interprogram-cut-function
+ (buffer-substring-no-properties (point)
+ (funcall (lambda ()
+ (end-of-line)
+ (point)))))))
+
+(defun org-passwords ()
+ "Open the password file. Open the password file defined by the
+variable `org-password-file' in read-only mode and kill that
+buffer later according to the value of the variable
+`org-passwords-time-opened'. It also adds the `org-password-file'
+to the auto-mode-alist so that it is opened with its mode being
+`org-passwords-mode'."
+ (interactive)
+ (if org-passwords-file
+ (progn
+ (add-to-list 'auto-mode-alist
+ (cons
+ (regexp-quote
+ (expand-file-name org-passwords-file))
+ 'org-passwords-mode))
+ (find-file-read-only org-passwords-file)
+ (org-passwords-set-up-kill-password-buffer))
+ (minibuffer-message "No default password file defined. Set the variable `org-password-file'.")))
+
+(defun org-passwords-set-up-kill-password-buffer ()
+ (run-at-time org-passwords-time-opened
+ nil
+ '(lambda ()
+ (if (get-file-buffer org-passwords-file)
+ (kill-buffer
+ (get-file-buffer org-passwords-file))))))
+
+;;; Password generator
+
+;; Set random number seed from current time and pid. Otherwise
+;; `random' gives the same results every time emacs restarts.
+(random t)
+
+(defun org-passwords-generate-password (arg)
+ "Ask a number of characters and insert a password of that size.
+Password has a random string of numbers, lowercase letters, and
+uppercase letters. Argument ARG include symbols."
+ (interactive "P")
+ (let ((number-of-chars
+ (string-to-number
+ (read-from-minibuffer "Number of Characters: "))))
+ (if arg
+ (insert (org-passwords-generate-password-with-symbols "" number-of-chars))
+ (insert (org-passwords-generate-password-without-symbols "" number-of-chars)))))
+
+(defun org-passwords-generate-password-with-symbols (previous-string nums-of-chars)
+ "Return a string consisting of PREVIOUS-STRING and
+NUMS-OF-CHARS random characters."
+ (if (eq nums-of-chars 0) previous-string
+ (insert (org-passwords-generate-password-with-symbols
+ (concat previous-string
+ (char-to-string
+ ;; symbols, letters, numbers are from 33 to 126
+ (+ (random (- 127 33)) 33)))
+ (1- nums-of-chars)))))
+
+(defun org-passwords-generate-password-without-symbols (previous-string nums-of-chars)
+ "Return string consisting of PREVIOUS-STRING and NUMS-OF-CHARS
+random numbers, lowercase letters, and numbers."
+ (if (eq nums-of-chars 0)
+ previous-string
+ ; There are 10 numbers, 26 lowercase letters and 26 uppercase
+ ; letters. 10 + 26 + 26 = 62. The number characters go from 48
+ ; to 57, the uppercase letters from 65 to 90, and the lowercase
+ ; from 97 to 122. The following makes each equally likely.
+ (let ((temp-value (random 62)))
+ (cond ((< temp-value 10)
+ ; If temp-value<10, then add a number
+ (org-passwords-generate-password-without-symbols
+ (concat previous-string
+ (char-to-string (+ 48 temp-value)))
+ (1- nums-of-chars)))
+ ((and (> temp-value 9) (< temp-value 36))
+ ; If 9<temp-value<36, then add an uppercase letter
+ (org-passwords-generate-password-without-symbols
+ (concat previous-string
+ (char-to-string (+ 65 (- temp-value 10))))
+ (1- nums-of-chars)))
+ ((> temp-value 35)
+ ; If temp-value>35, then add a lowecase letter
+ (org-passwords-generate-password-without-symbols
+ (concat previous-string
+ (char-to-string (+ 97 (- temp-value 36))))
+ (1- nums-of-chars)))))))
+
+;;; Random words
+
+(defun org-passwords-random-words (arg)
+ "Ask for a number of words and inserts a sequence of that many
+random words from the list in the file
+`org-passwords-random-words-dictionary' separated by
+`org-passwords-random-words-separator'. ARG make substitutions in
+the words as defined by
+`org-passwords-random-words-substitutions'."
+ (interactive "P")
+ (if org-passwords-random-words-dictionary
+ (let ((number-of-words
+ (string-to-number
+ (read-from-minibuffer "Number of words: ")))
+ (list-of-words
+ (with-temp-buffer
+ (insert-file-contents
+ org-passwords-random-words-dictionary)
+ (split-string (buffer-string) "\n" t))))
+ (insert
+ (org-passwords-substitute
+ (org-passwords-random-words-attach-number-of-words
+ (nth (random (length list-of-words))
+ list-of-words)
+ (1- number-of-words)
+ list-of-words
+ org-passwords-random-words-separator)
+ (if arg
+ org-passwords-random-words-substitutions
+ nil))))
+ (minibuffer-message
+ "No default dictionary file defined. Set the variable `org-passwords-random-words-dictionary'.")))
+
+(defun org-passwords-random-words-attach-number-of-words
+ (previous-string number-of-words list-of-words separator)
+ "Returns a string consisting of PREVIOUS-STRING followed by a
+succession of NUMBER-OF-WORDS random words from the list LIST-OF-WORDS
+separated SEPARATOR."
+ (if (eq number-of-words 0)
+ previous-string
+ (org-passwords-random-words-attach-number-of-words
+ (concat previous-string
+ separator
+ (nth (random (length list-of-words)) list-of-words))
+ (1- number-of-words)
+ list-of-words
+ separator)))
+
+(defun org-passwords-substitute (string-to-change list-of-substitutions)
+ "Substitutes each appearence in STRING-TO-CHANGE of the `car' of
+each element of LIST-OF-SUBSTITUTIONS by the `cdr' of that
+element. For example:
+ (org-passwords-substitute \"ab\" \'((\"a\" . \"b\") (\"b\" . \"c\")))
+ => \"bc\"
+Substitutions are made in order of the list, so for example:
+ (org-passwords-substitute \"ab\" \'((\"ab\" . \"c\") (\"b\" . \"d\")))
+ => \"c\""
+ (if list-of-substitutions
+ (concat (org-passwords-concat-this-with-string
+ (cdar list-of-substitutions)
+ (mapcar (lambda (x)
+ (org-passwords-substitute
+ x
+ (cdr list-of-substitutions)))
+ (split-string string-to-change
+ (caar list-of-substitutions)))))
+ string-to-change))
+
+(defun org-passwords-concat-this-with-string (this list-of-strings)
+ "Put the string THIS in between every string in LIST-OF-STRINGS. For example:
+ (org-passwords-concat-this-with-string \"Here\" \'(\"First\" \"Second\" \"Third\"))
+ => \"FirstHereSencondHereThird\""
+ (if (cdr list-of-strings)
+ (concat (car list-of-strings)
+ this
+ (org-passwords-concat-this-with-string
+ (cdr list-of-strings)
+ this))
+ (car list-of-strings)))
+
+(provide 'org-passwords)
+
+;;; org-passwords.el ends here
diff --git a/contrib/lisp/ox-bibtex.el b/contrib/lisp/ox-bibtex.el
index d92a1e4..7cb8972 100644
--- a/contrib/lisp/ox-bibtex.el
+++ b/contrib/lisp/ox-bibtex.el
@@ -36,7 +36,7 @@
;;
;; The usage is as follows:
;;
-;; #+BIBLIOGRAPHY: bibfilebasename stylename optional-options
+;; #+BIBLIOGRAPHY: bibfilename stylename optional-options
;;
;; e.g. given foo.bib and using style plain:
;;
@@ -44,6 +44,10 @@
;;
;; "stylename" can also be "nil", in which case no style will be used.
;;
+;; Full filepaths are also possible:
+;;
+;; #+BIBLIOGRAPHY: /home/user/Literature/foo.bib plain option:-d
+;;
;; Optional options are of the form:
;;
;; option:-foobar pass '-foobar' to bibtex2html
@@ -89,8 +93,6 @@
;; Initialization
(eval-when-compile (require 'cl))
-(let ((jump-fn (car (org-remove-if-not #'fboundp '(ebib obe-goto-citation)))))
- (org-add-link-type "cite" jump-fn))
;;; Internal Functions
@@ -149,6 +151,27 @@ to `org-bibtex-citation-p' predicate."
(and (string-match "\\`\\\\cite{" value)
(substring value (match-end 0) -1)))))
+
+;;; Follow cite: links
+
+(defun org-bibtex-file nil "Org-mode file of bibtex entries.")
+
+(defun org-bibtex-goto-citation (&optional citation)
+ "Visit a citation given its ID."
+ (interactive)
+ (let ((citation (or citation
+ (org-icompleting-read "Citation: "
+ (obe-citations)))))
+ (find-file (or org-bibtex-file
+ (error "`org-bibtex-file' has not been configured")))
+ (goto-char (point-min))
+ (when (re-search-forward (format " :CUSTOM_ID: %s" citation) nil t)
+ (outline-previous-visible-heading 1)
+ t)))
+
+(let ((jump-fn (car (org-remove-if-not #'fboundp '(ebib org-bibtex-goto-citation)))))
+ (org-add-link-type "cite" jump-fn))
+
;;; Filters
@@ -168,7 +191,16 @@ Return new parse tree."
(when (equal (org-element-property :key keyword) "BIBLIOGRAPHY")
(let ((arguments (org-bibtex-get-arguments keyword))
(file (org-bibtex-get-file keyword))
- temp-file)
+ temp-file
+ out-file)
+ ;; Test if filename is given with .bib-extension and strip
+ ;; it off. Filenames with another extensions will be
+ ;; untouched and will finally rise an error in bibtex2html.
+ (setq file (if (equal (file-name-extension file) "bib")
+ (file-name-sans-extension file) file))
+ ;; Outpufiles of bibtex2html will be put into current working directory
+ ;; so define a variable for this.
+ (setq out-file (file-name-base file))
;; limit is set: collect citations throughout the document
;; in TEMP-FILE and pass it to "bibtex2html" as "-citefile"
;; argument.
@@ -200,7 +232,7 @@ Return new parse tree."
(and temp-file (delete-file temp-file))
;; Open produced HTML file, and collect Bibtex key names
(with-temp-buffer
- (insert-file-contents (concat file ".html"))
+ (insert-file-contents (concat out-file ".html"))
;; Update `org-bibtex-html-entries-alist'.
(goto-char (point-min))
(while (re-search-forward
@@ -212,18 +244,25 @@ Return new parse tree."
(with-temp-buffer
(cond
((org-export-derived-backend-p backend 'html)
- (insert "<div id=\"bibliography\">\n<h2>References</h2>\n")
- (insert-file-contents (concat file ".html"))
+ (insert (format "<div id=\"bibliography\">\n<h2>%s</h2>\n"
+ (org-export-translate "References" :html info)))
+ (insert-file-contents (concat out-file ".html"))
(insert "\n</div>"))
((org-export-derived-backend-p backend 'ascii)
;; convert HTML references to text w/pandoc
(unless (eq 0 (call-process "pandoc" nil nil nil
- (concat file ".html")
+ (concat out-file ".html")
"-o"
- (concat file ".txt")))
+ (concat out-file ".txt")))
(error "Executing pandoc failed"))
- (insert "References\n==========\n\n")
- (insert-file-contents (concat file ".txt"))
+ (insert
+ (format
+ "%s\n==========\n\n"
+ (org-export-translate
+ "References"
+ (intern (format ":%s" (plist-get info :ascii-charset)))
+ info)))
+ (insert-file-contents (concat out-file ".txt"))
(goto-char (point-min))
(while (re-search-forward
"\\[ \\[bib\\][^ ]+ \\(\\]\\||[\n\r]\\)" nil t)
@@ -243,7 +282,10 @@ Return new parse tree."
(defun org-bibtex-merge-contiguous-citations (tree backend info)
"Merge all contiguous citation in parse tree.
As a side effect, this filter will also turn all \"cite\" links
-into \"\\cite{...}\" LaTeX fragments."
+into \"\\cite{...}\" LaTeX fragments and will extract options.
+Cite options are placed into square brackets at the beginning of
+the \"\\cite\" command for the LaTeX backend, and are removed for
+the HTML and ASCII backends."
(when (org-export-derived-backend-p backend 'html 'latex 'ascii)
(org-element-map tree '(link latex-fragment)
(lambda (object)
@@ -251,7 +293,8 @@ into \"\\cite{...}\" LaTeX fragments."
(let ((new-citation (list 'latex-fragment
(list :value ""
:post-blank (org-element-property
- :post-blank object)))))
+ :post-blank object))))
+ option)
;; Insert NEW-CITATION right before OBJECT.
(org-element-insert-before new-citation object)
;; Remove all subsequent contiguous citations from parse
@@ -266,6 +309,18 @@ into \"\\cite{...}\" LaTeX fragments."
(push (org-bibtex-get-citation-key next) keys))
(org-element-extract-element object)
(setq object next))
+ ;; Find any options in keys, e.g., "(Chapter 2)key" has
+ ;; the option "Chapter 2".
+ (setq keys
+ (mapcar
+ (lambda (k)
+ (if (string-match "^(\\([^)]\+\\))\\(.*\\)" k)
+ (progn
+ (when (org-export-derived-backend-p backend 'latex)
+ (setq option (format "[%s]" (match-string 1 k))))
+ (match-string 2 k))
+ k))
+ keys))
(org-element-extract-element object)
;; Eventually merge all keys within NEW-CITATION. Also
;; ensure NEW-CITATION has the same :post-blank property
@@ -275,7 +330,8 @@ into \"\\cite{...}\" LaTeX fragments."
:post-blank (org-element-property :post-blank object))
(org-element-put-property
new-citation
- :value (format "\\cite{%s}"
+ :value (format "\\cite%s{%s}"
+ (or option "")
(mapconcat 'identity (nreverse keys) ",")))))))))
tree)
diff --git a/contrib/lisp/ox-deck.el b/contrib/lisp/ox-deck.el
index ea2d8fe..0ebde41 100644
--- a/contrib/lisp/ox-deck.el
+++ b/contrib/lisp/ox-deck.el
@@ -378,7 +378,7 @@ the \"slide\" class will be added to the to the list element,
(defun org-deck-link (link desc info)
(replace-regexp-in-string "href=\"#" "href=\"#outline-container-"
- (org-html-link link desc info)))
+ (org-export-with-backend 'html link desc info)))
(defun org-deck-template (contents info)
"Return complete document string after HTML conversion.
diff --git a/contrib/lisp/ox-extra.el b/contrib/lisp/ox-extra.el
new file mode 100644
index 0000000..e6d45cc
--- a/dev/null
+++ b/contrib/lisp/ox-extra.el
@@ -0,0 +1,190 @@
+;;; ox-extra.el --- Convenience functions for org export
+
+;; Copyright (C) 2014 Aaron Ecay
+
+;; Author: Aaron Ecay <aaronecay@gmail.com>
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This file contains some convenience functions for org export, which
+;; are not part of org's core. Call `ox-extras-activate' passing a
+;; list of symbols naming extras, which will be installed globally in
+;; your org session.
+;;
+;; For example, you could include the following in your .emacs file:
+;;
+;; (require 'ox-extra)
+;; (ox-extras-activate '(latex-header-blocks ignore-headlines))
+;;
+
+;; Currently available extras:
+
+;; - `latex-header-blocks' -- allow the use of latex blocks, the
+;; contents of which which will be interpreted as #+latex_header lines
+;; for export. These blocks should be tagged with #+header: :header
+;; yes. For example:
+;; #+header: :header yes
+;; #+begin_latex
+;; ...
+;; #+end_latex
+
+;; - `ignore-headlines' -- allow a headline (but not its children) to
+;; be ignored. Any headline tagged with the 'ignore' tag will be
+;; ignored (i.e. will not be included in the export), but any child
+;; headlines will not be ignored (unless explicitly tagged to be
+;; ignored), and will instead have their levels promoted by one.
+
+;; TODO:
+;; - add a function to org-mode-hook that looks for a ox-extras local
+;; variable and activates the specified extras buffer-locally
+;; - allow specification of desired extras to be activated via
+;; customize
+
+;;; Code:
+
+(require 'ox)
+(eval-when-compile (require 'cl))
+
+(defun org-latex-header-blocks-filter (backend)
+ (when (org-export-derived-backend-p backend 'latex)
+ (let ((positions
+ (org-element-map (org-element-parse-buffer 'greater-element nil) 'export-block
+ (lambda (block)
+ (when (and (string= (org-element-property :type block) "LATEX")
+ (string= (org-export-read-attribute
+ :header block :header)
+ "yes"))
+ (list (org-element-property :begin block)
+ (org-element-property :end block)
+ (org-element-property :post-affiliated block)))))))
+ (mapc (lambda (pos)
+ (goto-char (nth 2 pos))
+ (destructuring-bind
+ (beg end &rest ignore)
+ (org-edit-src-find-region-and-lang)
+ (let ((contents-lines (split-string
+ (buffer-substring-no-properties beg end)
+ "\n")))
+ (delete-region (nth 0 pos) (nth 1 pos))
+ (dolist (line contents-lines)
+ (insert (concat "#+latex_header: "
+ (replace-regexp-in-string "\\` *" "" line)
+ "\n"))))))
+ ;; go in reverse, to avoid wrecking the numeric positions
+ ;; earlier in the file
+ (reverse positions)))))
+
+
+;; During export headlines which have the "ignore" tag are removed
+;; from the parse tree. Their contents are retained (leading to a
+;; possibly invalid parse tree, which nevertheless appears to function
+;; correctly with most export backends) all children headlines are
+;; retained and are promoted to the level of the ignored parent
+;; headline.
+;;
+;; This makes it possible to add structure to the original Org-mode
+;; document which does not effect the exported version, such as in the
+;; following examples.
+;;
+;; Wrapping an abstract in a headline
+;;
+;; * Abstract :ignore:
+;; #+LaTeX: \begin{abstract}
+;; #+HTML: <div id="abstract">
+;;
+;; ...
+;;
+;; #+HTML: </div>
+;; #+LaTeX: \end{abstract}
+;;
+;; Placing References under a headline (using ox-bibtex in contrib)
+;;
+;; * References :ignore:
+;; #+BIBLIOGRAPHY: dissertation plain
+;;
+;; Inserting an appendix for LaTeX using the appendix package.
+;;
+;; * Appendix :ignore:
+;; #+LaTeX: \begin{appendices}
+;; ** Reproduction
+;; ...
+;; ** Definitions
+;; #+LaTeX: \end{appendices}
+;;
+(defun org-export-ignore-headlines (data backend info)
+ "Remove headlines tagged \"ignore\" retaining contents and promoting children.
+Each headline tagged \"ignore\" will be removed retaining its
+contents and promoting any children headlines to the level of the
+parent."
+ (org-element-map data 'headline
+ (lambda (object)
+ (when (member "ignore" (org-element-property :tags object))
+ (let ((level-top (org-element-property :level object))
+ level-diff)
+ (mapc (lambda (el)
+ ;; recursively promote all nested headlines
+ (org-element-map el 'headline
+ (lambda (el)
+ (when (equal 'headline (org-element-type el))
+ (unless level-diff
+ (setq level-diff (- (org-element-property :level el)
+ level-top)))
+ (org-element-put-property el
+ :level (- (org-element-property :level el)
+ level-diff)))))
+ ;; insert back into parse tree
+ (org-element-insert-before el object))
+ (org-element-contents object)))
+ (org-element-extract-element object)))
+ info nil)
+ data)
+
+(defconst ox-extras
+ '((latex-header-blocks org-latex-header-blocks-filter org-export-before-parsing-hook)
+ (ignore-headlines org-export-ignore-headlines org-export-filter-parse-tree-functions))
+ "A list of org export extras that can be enabled.
+
+Should be a list of items of the form (NAME FN HOOK). NAME is a
+symbol, which can be passed to `ox-extras-activate'. FN is a
+function which will be added to HOOK.")
+
+(defun ox-extras-activate (extras)
+ "Activate certain org export extras.
+
+EXTRAS should be a list of extras (defined in `ox-extras') which
+should be activated."
+ (dolist (extra extras)
+ (let* ((lst (assq extra ox-extras))
+ (fn (nth 1 lst))
+ (hook (nth 2 lst)))
+ (when (and fn hook)
+ (add-hook hook fn)))))
+
+(defun ox-extras-deactivate (extras)
+ "Deactivate certain org export extras.
+
+This function is the opposite of `ox-extras-activate'. EXTRAS
+should be a list of extras (defined in `ox-extras') which should
+be activated."
+ (dolist (extra extras)
+ (let* ((lst (assq extra ox-extras))
+ (fn (nth 1 lst))
+ (hook (nth 2 lst)))
+ (when (and fn hook)
+ (remove-hook hook fn)))))
+
+(provide 'ox-extra)
+;;; ox-extra.el ends here
diff --git a/contrib/lisp/ox-gfm.el b/contrib/lisp/ox-gfm.el
new file mode 100644
index 0000000..f7acc94
--- a/dev/null
+++ b/contrib/lisp/ox-gfm.el
@@ -0,0 +1,193 @@
+;;; ox-gfm.el --- Github Flavored Markdown Back-End for Org Export Engine
+
+;; Copyright (C) 2014 Lars Tveito
+
+;; Author: Lars Tveito
+;; Keywords: org, wp, markdown, github
+
+;; This file is not 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 <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This library implements a Markdown back-end (github flavor) for Org
+;; exporter, based on the `md' back-end.
+
+;;; Code:
+
+(require 'ox-md)
+
+
+
+;;; User-Configurable Variables
+
+(defgroup org-export-gfm nil
+ "Options specific to Markdown export back-end."
+ :tag "Org Github Flavored Markdown"
+ :group 'org-export
+ :version "24.4"
+ :package-version '(Org . "8.0"))
+
+(defcustom org-gfm-lang '(("emacs-lisp" . "lisp") ("elisp" . "lisp"))
+ "Alist of languages that are not recognized by Github, to
+ languages that are. Emacs lisp is a good example of this, where
+ we can use lisp as a nice replacement."
+ :group 'org-export-gfm)
+
+
+
+;;; Define Back-End
+
+(org-export-define-derived-backend 'gfm 'md
+ :export-block '("GFM" "GITHUB FLAVORED MARKDOWN")
+ :filters-alist '((:filter-parse-tree . org-md-separate-elements))
+ :menu-entry
+ '(?g "Export to Github Flavored Markdown"
+ ((?G "To temporary buffer"
+ (lambda (a s v b) (org-gfm-export-as-markdown a s v)))
+ (?g "To file" (lambda (a s v b) (org-gfm-export-to-markdown a s v)))
+ (?o "To file and open"
+ (lambda (a s v b)
+ (if a (org-gfm-export-to-markdown t s v)
+ (org-open-file (org-gfm-export-to-markdown nil s v)))))))
+ :translate-alist '((inner-template . org-gfm-inner-template)
+ (strike-through . org-gfm-strike-through)
+ (src-block . org-gfm-src-block)))
+
+
+
+;;; Transcode Functions
+
+;;;; Src Block
+
+(defun org-gfm-src-block (src-block contents info)
+ "Transcode SRC-BLOCK element into Github Flavored Markdown
+format. CONTENTS is nil. INFO is a plist used as a communication
+channel."
+ (let* ((lang (org-element-property :language src-block))
+ (lang (or (assoc-default lang org-gfm-lang) lang))
+ (code (org-export-format-code-default src-block info))
+ (prefix (concat "```" lang "\n"))
+ (suffix "```"))
+ (concat prefix code suffix)))
+
+
+;;;; Strike-Through
+
+(defun org-html-strike-through (strike-through contents info)
+ "Transcode STRIKE-THROUGH from Org to Markdown (GFM).
+CONTENTS is the text with strike-through markup. INFO is a plist
+holding contextual information."
+ (format "~~%s~~" contents))
+
+;;;; Table of contents
+
+(defun org-gfm-format-toc (headline)
+ "Return an appropriate table of contents entry for HEADLINE. INFO is a
+plist used as a communication channel."
+ (let* ((title (org-export-data
+ (org-export-get-alt-title headline info) info))
+ (level (1- (org-element-property :level headline)))
+ (indent (concat (make-string (* level 2) ? )))
+ (ref-str (replace-regexp-in-string " " "-" (downcase title))))
+ (concat indent "- [" title "]" "(#" ref-str ")")))
+
+
+;;;; Template
+
+(defun org-gfm-inner-template (contents info)
+ "Return body of document after converting it to Markdown syntax.
+CONTENTS is the transcoded contents string. INFO is a plist
+holding export options."
+ (let* ((depth (plist-get info :with-toc))
+ (headlines (and depth (org-export-collect-headlines info depth)))
+ (toc-string (or (mapconcat 'org-gfm-format-toc headlines "\n") ""))
+ (toc-tail (if headlines "\n\n" "")))
+ (concat toc-string toc-tail contents)))
+
+
+
+;;; Interactive function
+
+;;;###autoload
+(defun org-gfm-export-as-markdown (&optional async subtreep visible-only)
+ "Export current buffer to a Github Flavored Markdown buffer.
+
+If narrowing is active in the current buffer, only export its
+narrowed part.
+
+If a region is active, export that region.
+
+A non-nil optional argument ASYNC means the process should happen
+asynchronously. The resulting buffer should be accessible
+through the `org-export-stack' interface.
+
+When optional argument SUBTREEP is non-nil, export the sub-tree
+at point, extracting information from the headline properties
+first.
+
+When optional argument VISIBLE-ONLY is non-nil, don't export
+contents of hidden elements.
+
+Export is done in a buffer named \"*Org GFM Export*\", which will
+be displayed when `org-export-show-temporary-export-buffer' is
+non-nil."
+ (interactive)
+ (org-export-to-buffer 'gfm "*Org GFM Export*"
+ async subtreep visible-only nil nil (lambda () (text-mode))))
+
+
+;;;###autoload
+(defun org-gfm-convert-region-to-md ()
+ "Assume the current region has org-mode syntax, and convert it
+to Github Flavored Markdown. This can be used in any buffer.
+For example, you can write an itemized list in org-mode syntax in
+a Markdown buffer and use this command to convert it."
+ (interactive)
+ (org-export-replace-region-by 'gfm))
+
+
+;;;###autoload
+(defun org-gfm-export-to-markdown (&optional async subtreep visible-only)
+ "Export current buffer to a Github Flavored Markdown file.
+
+If narrowing is active in the current buffer, only export its
+narrowed part.
+
+If a region is active, export that region.
+
+A non-nil optional argument ASYNC means the process should happen
+asynchronously. The resulting file should be accessible through
+the `org-export-stack' interface.
+
+When optional argument SUBTREEP is non-nil, export the sub-tree
+at point, extracting information from the headline properties
+first.
+
+When optional argument VISIBLE-ONLY is non-nil, don't export
+contents of hidden elements.
+
+Return output file's name."
+ (interactive)
+ (let ((outfile (org-export-output-file-name ".md" subtreep)))
+ (org-export-to-file 'gfm outfile async subtreep visible-only)))
+
+(provide 'ox-gfm)
+
+;; Local variables:
+;; generated-autoload-file: "org-loaddefs.el"
+;; End:
+
+;;; ox-gfm.el ends here
diff --git a/contrib/lisp/ox-groff.el b/contrib/lisp/ox-groff.el
index f1f0dd1..d8baf39 100644
--- a/contrib/lisp/ox-groff.el
+++ b/contrib/lisp/ox-groff.el
@@ -1253,12 +1253,8 @@ INFO is a plist holding contextual information. See
(path (cond
((member type '("http" "https" "ftp" "mailto"))
(concat type ":" raw-path))
- ((string= type "file")
- (when (string-match "\\(.+\\)::.+" raw-path)
- (setq raw-path (match-string 1 raw-path)))
- (if (file-name-absolute-p raw-path)
- (concat "file://" (expand-file-name raw-path))
- (concat "file://" raw-path)))
+ ((and (string= type "file") (file-name-absolute-p raw-path))
+ (concat "file://" raw-path))
(t raw-path)))
protocol)
(cond
@@ -1272,7 +1268,7 @@ INFO is a plist holding contextual information. See
;; description.
((string= type "radio")
(let ((destination (org-export-resolve-radio-link link info)))
- (when destination
+ (if (not destination) desc
(format "\\fI [%s] \\fP"
(org-export-solidify-link-text
(org-element-property :value destination))))))
@@ -1482,7 +1478,7 @@ holding contextual information."
"Transcode a SPECIAL-BLOCK element from Org to Groff.
CONTENTS holds the contents of the block. INFO is a plist
holding contextual information."
- (let ((type (downcase (org-element-property :type special-block))))
+ (let ((type (org-element-property :type special-block)))
(org-groff--wrap-label
special-block
(format "%s\n" contents))))
diff --git a/contrib/lisp/ox-koma-letter.el b/contrib/lisp/ox-koma-letter.el
index aa75ab8..597aeb8 100644
--- a/contrib/lisp/ox-koma-letter.el
+++ b/contrib/lisp/ox-koma-letter.el
@@ -390,7 +390,8 @@ was not present."
'((:latex-class "LATEX_CLASS" nil org-koma-letter-default-class t)
(:lco "LCO" nil org-koma-letter-class-option-file)
(:author "AUTHOR" nil (org-koma-letter--get-value org-koma-letter-author) t)
- (:from-address "FROM_ADDRESS" nil nil newline)
+ (:author-changed-in-buffer-p "AUTHOR" nil nil t)
+ (:from-address "FROM_ADDRESS" nil org-koma-letter-from-address newline)
(:phone-number "PHONE_NUMBER" nil org-koma-letter-phone-number)
(:email "EMAIL" nil (org-koma-letter--get-value org-koma-letter-email) t)
(:to-address "TO_ADDRESS" nil nil newline)
@@ -503,15 +504,14 @@ KEY should be `to' or `from'.
`ox-koma-letter' allows two ways to specify TO and FROM. If both
are present return the preferred one as determined by
`org-koma-letter-prefer-special-headings'."
- (let ((option (plist-get info (if (eq key 'to) :to-address :from-address)))
+ (let ((option (org-string-nw-p
+ (plist-get info (if (eq key 'to) :to-address :from-address))))
(headline (org-koma-letter--get-tagged-contents key)))
(replace-regexp-in-string
"\n" "\\\\\\\\\n"
(org-trim
- (or (if (plist-get info :special-headings) (or headline option)
- (or option headline))
- ;; Fallback values.
- (if (eq key 'to) "\\mbox{}" org-koma-letter-from-address))))))
+ (if (plist-get info :special-headings) (or headline option "")
+ (or option headline ""))))))
@@ -617,7 +617,7 @@ holding export options."
(org-koma-letter--build-settings 'buffer info)
;; From address.
(let ((from-address (org-koma-letter--determine-to-and-from info 'from)))
- (when (org-string-nw-p from-address)
+ (when (org-string-nw-p from-address)
(format "\\setkomavar{fromaddress}{%s}\n" from-address)))
;; Date.
(format "\\date{%s}\n" (org-export-data (org-export-get-date info) info))
diff --git a/contrib/lisp/ox-rss.el b/contrib/lisp/ox-rss.el
index c69a37b..fddaa1d 100644
--- a/contrib/lisp/ox-rss.el
+++ b/contrib/lisp/ox-rss.el
@@ -204,11 +204,10 @@ publishing directory.
Return output file name."
(let ((bf (get-file-buffer filename)))
(if bf
- (progn
- (org-icalendar-create-uid filename 'warn-user)
(with-current-buffer bf
+ (org-icalendar-create-uid filename 'warn-user)
(org-rss-add-pubdate-property)
- (write-file filename)))
+ (write-file filename))
(find-file filename)
(org-icalendar-create-uid filename 'warn-user)
(org-rss-add-pubdate-property)
@@ -239,13 +238,12 @@ communication channel."
(concat "sec-" (mapconcat 'number-to-string hl-number "-")))))
(category (org-rss-plain-text
(or (org-element-property :CATEGORY headline) "") info))
- (pubdate
- (let ((system-time-locale "C"))
- (format-time-string
- "%a, %d %b %Y %H:%M:%S %z"
- (org-time-string-to-time
- (or (org-element-property :PUBDATE headline)
- (error "Missing PUBDATE property"))))))
+ (pubdate0 (org-element-property :PUBDATE headline))
+ (pubdate (let ((system-time-locale "C"))
+ (if pubdate0
+ (format-time-string
+ "%a, %d %b %Y %H:%M:%S %z"
+ (org-time-string-to-time pubdate0)))))
(title (replace-regexp-in-string
org-bracket-link-regexp
(lambda (m) (or (match-string 3 m)
@@ -265,18 +263,19 @@ communication channel."
(org-element-property :CUSTOM_ID headline)
publink)
info))))
- (format
- (concat
- "<item>\n"
- "<title>%s</title>\n"
- "<link>%s</link>\n"
- "<author>%s</author>\n"
- "<guid isPermaLink=\"false\">%s</guid>\n"
- "<pubDate>%s</pubDate>\n"
- (org-rss-build-categories headline info) "\n"
- "<description><![CDATA[%s]]></description>\n"
- "</item>\n")
- title publink author guid pubdate contents))))
+ (if (not pubdate0) "" ;; Skip entries with no PUBDATE prop
+ (format
+ (concat
+ "<item>\n"
+ "<title>%s</title>\n"
+ "<link>%s</link>\n"
+ "<author>%s</author>\n"
+ "<guid isPermaLink=\"false\">%s</guid>\n"
+ "<pubDate>%s</pubDate>\n"
+ (org-rss-build-categories headline info) "\n"
+ "<description><![CDATA[%s]]></description>\n"
+ "</item>\n")
+ title publink author guid pubdate contents)))))
(defun org-rss-build-categories (headline info)
"Build categories for the RSS item."
diff --git a/contrib/lisp/ox-s5.el b/contrib/lisp/ox-s5.el
index 26e83a3..b94c38c 100644
--- a/contrib/lisp/ox-s5.el
+++ b/contrib/lisp/ox-s5.el
@@ -201,7 +201,7 @@ INFO is a plist used as a communication channel."
(concat section-number
(org-export-data
(org-export-get-alt-title headline info) info)
- (and tags "&nbsp;&nbsp;&nbsp;") (org-html--tags tags))))
+ (and tags "&nbsp;&nbsp;&nbsp;") (org-html--tags tags info))))
(defun org-s5-toc (depth info)
(let* ((headlines (org-export-collect-headlines info depth))
diff --git a/contrib/lisp/ox-taskjuggler.el b/contrib/lisp/ox-taskjuggler.el
index 761e180..807d702 100644
--- a/contrib/lisp/ox-taskjuggler.el
+++ b/contrib/lisp/ox-taskjuggler.el
@@ -310,6 +310,19 @@ If one of these appears as a property for a headline, it will be
exported with the corresponding task."
:group 'org-export-taskjuggler)
+(defcustom org-taskjuggler-valid-project-attributes
+ '(timingresolution timezone alertlevels currency currencyformat
+ dailyworkinghours extend includejournalentry now numberformat
+ outputdir scenario shorttimeformat timeformat trackingscenario
+ weekstartsmonday weekstartssunday workinghours
+ yearlyworkingdays)
+ "Valid attributes for Taskjuggler project.
+If one of these appears as a property for a headline that is a
+project definition, it will be exported with the corresponding
+task. Attribute 'timingresolution' should be the first in the
+list."
+ :group 'org-export-taskjuggler)
+
(defcustom org-taskjuggler-valid-resource-attributes
'(limits vacation shift booking efficiency journalentry rate
workinghours flags)
@@ -483,9 +496,9 @@ Return new string. If S is the empty string, return it."
(if (equal "" s) s (replace-regexp-in-string "^ *\\S-" " \\&" s)))
(defun org-taskjuggler--build-attributes (item attributes)
- "Return attributes string for task, resource or report ITEM.
-ITEM is a headline. ATTRIBUTES is a list of symbols
-representing valid attributes for ITEM."
+ "Return attributes string for ITEM.
+ITEM is a project, task, resource or report headline. ATTRIBUTES
+is a list of symbols representing valid attributes for ITEM."
(mapconcat
(lambda (attribute)
(let ((value (org-element-property
@@ -715,18 +728,27 @@ PROJECT is a headline. INFO is a plist used as a communication
channel. If no start date is specified, start today. If no end
date is specified, end `org-taskjuggler-default-project-duration'
days from now."
- (format "project %s \"%s\" \"%s\" %s %s {\n}\n"
- (org-taskjuggler-get-id project info)
- (org-taskjuggler-get-name project)
- ;; Version is obtained through :TASKJUGGLER_VERSION:
- ;; property or `org-taskjuggler-default-project-version'.
- (or (org-element-property :VERSION project)
- org-taskjuggler-default-project-version)
- (or (org-taskjuggler-get-start project)
- (format-time-string "%Y-%m-%d"))
- (let ((end (org-taskjuggler-get-end project)))
- (or (and end (format "- %s" end))
- (format "+%sd" org-taskjuggler-default-project-duration)))))
+ (concat
+ ;; Opening project.
+ (format "project %s \"%s\" \"%s\" %s %s {\n"
+ (org-taskjuggler-get-id project info)
+ (org-taskjuggler-get-name project)
+ ;; Version is obtained through :TASKJUGGLER_VERSION:
+ ;; property or `org-taskjuggler-default-project-version'.
+ (or (org-element-property :VERSION project)
+ org-taskjuggler-default-project-version)
+ (or (org-taskjuggler-get-start project)
+ (format-time-string "%Y-%m-%d"))
+ (let ((end (org-taskjuggler-get-end project)))
+ (or (and end (format "- %s" end))
+ (format "+%sd"
+ org-taskjuggler-default-project-duration))))
+ ;; Add attributes.
+ (org-taskjuggler--indent-string
+ (org-taskjuggler--build-attributes
+ project org-taskjuggler-valid-project-attributes))
+ ;; Closing project.
+ "}\n"))
(defun org-taskjuggler--build-resource (resource info)
"Return a resource declaration.
diff --git a/doc/htmlxref.cnf b/doc/htmlxref.cnf
new file mode 100644
index 0000000..13aa8ce
--- a/dev/null
+++ b/doc/htmlxref.cnf
@@ -0,0 +1,2 @@
+calc mono http://www.gnu.org/software/emacs/manual/html_mono/calc.html
+calc node http://www.gnu.org/software/emacs/manual/html_node/calc/
diff --git a/doc/org.texi b/doc/org.texi
index 9205abb..7d98d51 100644
--- a/doc/org.texi
+++ b/doc/org.texi
@@ -1,6 +1,6 @@
\input texinfo
@c %**start of header
-@setfilename ../../info/org
+@setfilename ../../info/org.info
@settitle The Org Manual
@include org-version.inc
@@ -581,10 +581,11 @@ Exporting
* HTML export:: Exporting to HTML
* @LaTeX{} and PDF export:: Exporting to @LaTeX{}, and processing to PDF
* Markdown export:: Exporting to Markdown
-* OpenDocument text export:: Exporting to OpenDocument Text
+* OpenDocument Text export:: Exporting to OpenDocument Text
* Org export:: Exporting to Org
+* Texinfo export:: Exporting to Texinfo
* iCalendar export:: Exporting to iCalendar
-* Other built-in back-ends:: Exporting to @code{Texinfo} or a man page
+* Other built-in back-ends:: Exporting to a man page
* Export in foreign buffers:: Author tables and lists in Org syntax
* Advanced configuration:: Fine-tuning the export output
@@ -636,6 +637,16 @@ Advanced topics in ODT export
* Customizing tables in ODT export:: How to define and use Table templates
* Validating OpenDocument XML:: How to debug corrupt OpenDocument files
+Texinfo export
+
+* Texinfo export commands:: How to invoke Texinfo export
+* Document preamble:: File header, title and copyright page
+* Headings and sectioning structure:: Building document structure
+* Indices:: Creating indices
+* Quoting Texinfo code:: Incorporating literal Texinfo code
+* Texinfo specific attributes:: Controlling Texinfo output
+* An example::
+
Publishing
* Configuration:: Defining projects
@@ -863,7 +874,11 @@ We @b{strongly recommend} to stick to a single installation method.
Recent Emacs distributions include a packaging system which lets you install
Elisp libraries. You can install Org with @kbd{M-x package-install RET org}.
-You need to do this in a session where no @code{.org} file has been visited.
+
+@noindent @b{Important}: you need to do this in a session where no @code{.org} file has
+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, initialize
the package system with @code{(package-initialize)} in your @file{.emacs}
before setting any Org option. If you want to use Org's package repository,
@@ -987,6 +1002,8 @@ active region by using the mouse to select a region, or pressing
If you find problems with Org, or if you have questions, remarks, or ideas
about it, please mail to the Org mailing list @email{emacs-orgmode@@gnu.org}.
+You can subscribe to the list
+@uref{https://lists.gnu.org/mailman/listinfo/emacs-orgmode, on this web page}.
If you are not a member of the mailing list, your mail will be passed to the
list after a moderator has approved it@footnote{Please consider subscribing
to the mailing list, in order to minimize the work the mailing list
@@ -1287,20 +1304,13 @@ Expose all the headings of the subtree, CONTENT view for just one subtree.
Expose all direct children of the subtree. With a numeric prefix argument N,
expose all children down to level N@.
@orgcmd{C-c C-x b,org-tree-to-indirect-buffer}
-Show the current subtree in an indirect buffer@footnote{The indirect
-buffer
-@ifinfo
-(@pxref{Indirect Buffers,,,emacs,GNU Emacs Manual})
-@end ifinfo
-@ifnotinfo
-(see the Emacs manual for more information about indirect buffers)
-@end ifnotinfo
-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.}. With a numeric
-prefix argument N, go up to level N and then take that tree. If N is
-negative then go up that many levels. With a @kbd{C-u} prefix, do not remove
-the previously used indirect buffer.
+Show the current subtree in an indirect buffer@footnote{The indirect buffer
+(@pxref{Indirect Buffers,,,emacs,GNU Emacs Manual}) 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.}. With a numeric prefix argument N, go up to level N and
+then take that tree. If N is negative then go up that many levels. With a
+@kbd{C-u} prefix, do not remove the previously used indirect buffer.
@orgcmd{C-c C-x v,org-copy-visible}
Copy the @i{visible} text in the region into the kill ring.
@end table
@@ -1417,19 +1427,23 @@ See also the option @code{org-goto-interface}.
@orgcmd{M-@key{RET},org-insert-heading}
@vindex org-M-RET-may-split-line
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
-(@pxref{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@footnote{If you do not want the line to be
-split, customize the variable @code{org-M-RET-may-split-line}.}. If
-the command is used at the @emph{beginning} of a headline, the new
-headline is created before the current line. If the command is used
-at the @emph{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
-@kbd{C-u C-u} will unconditionally respect the headline's content and
-create a new item at the end of the parent subtree.
+
+If the cursor is in a plain list item, a new item is created (@pxref{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 @code{org-M-RET-may-split-line}.
+
+If the command is used at the @emph{beginning} of a line, and if there is a
+heading or an item at point, the new heading/item is created @emph{before}
+the current line. If the command is used at the @emph{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 @kbd{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.
@orgcmd{C-@key{RET},org-insert-heading-respect-content}
Just like @kbd{M-@key{RET}}, except when adding a new heading below the
current heading, the new heading is placed after the body instead of before
@@ -2715,9 +2729,11 @@ Operations, , Logical Operations, calc, GNU Emacs Calc Manual}). For example
@item if($1 < 20, teen, string(""))
"teen" if age $1 is less than 20, else the Org table result field is set to
empty with the empty string.
-@item if("$1" == "nan" || "$2" == "nan", string(""), $1 + $2); E
+@item if("$1" == "nan" || "$2" == "nan", string(""), $1 + $2); E f-1
Sum of the first two columns. When at least one of the input fields is empty
-the Org table result field is set to empty.
+the Org table result field is set to empty. @samp{E} is required to not
+convert empty fields to 0. @samp{f-1} is an optional Calc format string
+similar to @samp{%.1f} but leaves empty results empty.
@item if(typeof(vmean($1..$7)) == 12, string(""), vmean($1..$7); E
Mean value of a range unless there is any empty field. Every field in the
range that is empty is replaced by @samp{nan} which lets @samp{vmean} result
@@ -5163,7 +5179,7 @@ first, and the value after it. Here is an example:
@end example
Depending on the value of @code{org-use-property-inheritance}, a property set
-this way will either be associated with a single entry, or the sub-tree
+this way will either be associated with a single entry, or the subtree
defined by the entry, see @ref{Property inheritance}.
You may define the allowed values for a particular property @samp{:Xyz:}
@@ -6533,6 +6549,8 @@ but you can specify your own function using the @code{:formatter} parameter.
:tcolumns @r{Number of columns to be used for times. If this is smaller}
@r{than @code{:maxlevel}, lower levels will be lumped into one column.}
:level @r{Should a level number column be included?}
+:sort @r{A cons cell like containing the column to sort and a sorting type.}
+ @r{E.g., @code{:sort (1 . ?a)} sorts the first column alphabetically.}
:compact @r{Abbreviation for @code{:level nil :indent t :narrow 40! :tcolumns 1}}
@r{All are overwritten except if there is an explicit @code{:narrow}}
:timestamp @r{A timestamp for the entry, when available. Look for SCHEDULED,}
@@ -7737,15 +7755,17 @@ current region/subtree.}. After pressing @kbd{< <}, you still need to press the
character selecting the command.
@item *
+@cindex agenda, sticky
@vindex org-agenda-sticky
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 @code{org-agenda-sticky}). With sticky agendas, the
-dispatcher only switches to the selected view, you need to update it by hand
-with @kbd{r} or @kbd{g}. You can toggle sticky agenda view any time with
-@code{org-toggle-sticky-agenda}.
+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 @code{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 @kbd{r} or @kbd{g} when needed. You can toggle sticky agenda view
+any time with @code{org-toggle-sticky-agenda}.
@end table
You can also define custom commands that will be accessible through the
@@ -8429,24 +8449,6 @@ will be narrowed by requiring or forbidding the selected additional tag.
Instead of pressing @kbd{+} or @kbd{-} after @kbd{/}, you can also
immediately use the @kbd{\} command.
-@vindex org-sort-agenda-noeffort-is-high
-In order to filter for effort estimates, you should set up allowed
-efforts globally, for example
-@lisp
-(setq org-global-properties
- '(("Effort_ALL". "0 0:10 0:30 1:00 2:00 3:00 4:00")))
-@end lisp
-You can then filter for an effort by first typing an operator, one of
-@kbd{<}, @kbd{>}, and @kbd{=}, and then the one-digit index of an effort
-estimate in your array of allowed values, where @kbd{0} means the 10th value.
-The filter 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, @kbd{<} will be assumed. For
-application of the operator, entries without a defined effort will be treated
-according to the value of @code{org-sort-agenda-noeffort-is-high}. To filter
-for tasks without effort definition, press @kbd{?} as the operator.
-
Org also supports automatic, context-aware tag filtering. If the variable
@code{org-agenda-auto-exclude-function} is set to a user-defined function,
that function can decide which tags should be excluded from the agenda
@@ -8517,6 +8519,23 @@ universal prefix arguments, it will remove all the regexp filters, which can
be accumulated. You can add a filter preset through the option
@code{org-agenda-category-filter-preset} (see below.)
+@orgcmd{_,org-agenda-filter-by-effort}
+@vindex org-agenda-effort-filter-preset
+@vindex org-sort-agenda-noeffort-is-high
+Filter the agenda view with respect to effort estimates.
+You first need to set up allowed efforts globally, for example
+@lisp
+(setq org-global-properties
+ '(("Effort_ALL". "0 0:10 0:30 1:00 2:00 3:00 4:00")))
+@end lisp
+You can then filter for an effort by first typing an operator, one of
+@kbd{<}, @kbd{>}, and @kbd{=}, and then the one-digit index of an effort
+estimate in your array of allowed values, where @kbd{0} means the 10th value.
+The filter 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
+@code{org-sort-agenda-noeffort-is-high}.
+
@orgcmd{|,org-agenda-filter-remove-all}
Remove all filters in the current agenda view.
@end table
@@ -8562,8 +8581,8 @@ Once you mark one of these five entry as @code{DONE}, rebuilding the agenda
will again the next five entries again, including the first entry that was
excluded so far.
-You can also dynamically set temporary limits@footnote{Those temporary limits
-are lost when rebuilding the agenda.}:
+You can also dynamically set temporary limits, which will be lost when
+rebuilding the agenda:
@table @kbd
@orgcmd{~,org-agenda-limit-interactively}
@@ -8591,6 +8610,10 @@ the other commands, the cursor needs to be in the desired line.
Next line (same as @key{down} and @kbd{C-n}).
@orgcmd{p,org-agenda-previous-line}
Previous line (same as @key{up} and @kbd{C-p}).
+@orgcmd{N,org-agenda-next-item}
+Next item: same as next line, but only consider items.
+@orgcmd{P,org-agenda-previous-item}
+Previous item: same as previous line, but only consider items.
@tsubheading{View/Go to Org file}
@orgcmdkkc{@key{SPC},mouse-3,org-agenda-show-and-scroll-up}
Display the original location of the item in another window.
@@ -9583,10 +9606,6 @@ The title of the exported document is taken from the special line
#+TITLE: This is the title of the document
@end example
-@noindent
-If this line does not exist, the title will be the name of the file
-associated with the buffer, without extension, or the buffer name.
-
@cindex property, EXPORT_TITLE
If you are exporting only a subtree, its heading will become the title of the
document. If the subtree has a property @code{EXPORT_TITLE}, that will take
@@ -9751,13 +9770,16 @@ a horizontal line.
@cindex #+BEGIN_COMMENT
Lines starting with zero or more whitespace characters followed by one
-@samp{#} and a whitespace are treated as comments and will never be exported.
+@samp{#} and a whitespace are treated as comments and, as such, are not
+exported.
-Also entire subtrees starting with the keyword @samp{COMMENT} will never be
-exported (and included code blocks will not be executed on export).
+Likewise, regions surrounded by @samp{#+BEGIN_COMMENT}
+... @samp{#+END_COMMENT} are not exported.
-Finally, regions surrounded by @samp{#+BEGIN_COMMENT}
-... @samp{#+END_COMMENT} will not be exported.
+Finally, a @samp{COMMENT} keyword at the beginning of an entry, but after any
+other keyword or priority cookie, comments out the entire subtree. In this
+case, the subtree is not exported and no code block within it is executed
+either. The command below helps changing the comment status of a headline.
@table @kbd
@kindex C-c ;
@@ -9948,28 +9970,37 @@ include your @file{.emacs} file, you could use:
@end example
@noindent
-The optional second and third parameter are the markup (e.g., @samp{quote},
-@samp{example}, or @samp{src}), and, if the markup is @samp{src}, the
-language for formatting the contents. The markup is optional; if it is not
-given, the text will be assumed to be in Org mode format and will be
-processed normally.
-
-Contents of the included file will belong to the same structure (headline,
-item) containing the @code{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 parameter, @code{:minlevel}. In
-that case, all headlines in the included file will be shifted so the one with
-the lowest level reaches that specified level. For example, to make a file
-become a sibling of the current top-level headline, use
+The first parameter names the the file to include. The optional second and
+third parameter specify the markup (i.e., @samp{example} or @samp{src}), and,
+if the markup is @samp{src}, the language for formatting the contents.
+
+If markup is requested, the included content will be placed within an
+appropriate block@footnote{While you can request paragraphs (@samp{verse},
+@samp{quote}, @samp{center}), but this places severe restrictions on the type
+of content that is permissible}. 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 @samp{example} and @samp{src}, which is requesting a
+literal example, the content will be code-escaped before inclusion.
+
+If no markup is requested, the text will be assumed to be in Org mode format
+and will be processed normally. However, footnote labels (@pxref{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
+@code{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 parameter, @code{:minlevel}. In that case, all
+headlines in the included file will be shifted so the one with the lowest
+level reaches that specified level. For example, to make a file become a
+sibling of the current top-level headline, use
@example
#+INCLUDE: "~/my-book/chapter2.org" :minlevel 1
@end example
You can also include a portion of a file by specifying a lines range using
-the @code{: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.
+the @code{: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.
@example
#+INCLUDE: "~/.emacs" :lines "5-10" @r{Include lines 5 to 10, 10 excluded}
@@ -10019,10 +10050,10 @@ Conversely, backslash characters before a comma, and only them, need to be
escaped with another backslash character.}.
These references, called macros, can be inserted anywhere Org markup is
-recognized: paragraphs, headlines, verse and example blocks, tables cells,
-lists and comments. They cannot be used within ordinary keywords (starting
-with @code{#+:}) but are allowed in @code{#+CAPTION}, @code{#+TITLE},
-@code{#+AUTHOR} and @code{#+EMAIL}.
+recognized: paragraphs, headlines, verse blocks, tables cells and lists.
+They cannot be used within ordinary keywords (starting with @code{#+}) but
+are allowed in @code{#+CAPTION}, @code{#+TITLE}, @code{#+AUTHOR} and
+@code{#+EMAIL}.
In addition to user-defined macros, a set of already defined macros can be
used: @code{@{@{@{title@}@}@}}, @code{@{@{@{author@}@}@}}, etc., will
@@ -10036,7 +10067,7 @@ and to the modification time of the file being exported, respectively.
The surrounding brackets can be made invisible by setting
@code{org-hide-macro-markers} to @code{t}.
-Macro expansion takes place during export.
+Macro expansion takes place during the very beginning of the export process.
@node Embedded @LaTeX{}
@@ -10324,16 +10355,16 @@ Org syntax includes pre-defined blocks (@pxref{Paragraphs} and @ref{Literal
examples}). It is also possible to create blocks containing raw code
targeted at a specific back-end (e.g., @samp{#+BEGIN_LATEX}).
-Any other block is a @emph{special block}.
+Any other block is a @emph{special block}. Its name is case-sensitive.
-For example, @samp{#+BEGIN_ABSTRACT} and @samp{#+BEGIN_VIDEO} are special
+For example, @samp{#+BEGIN_abstract} and @samp{#+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
-@samp{#+BEGIN_TEST} block, HTML back-end wraps its contents within a
+@samp{#+BEGIN_test} block, HTML back-end wraps its contents within a
@samp{<div name="test">} tag.
Refer to back-end specific documentation for more information.
@@ -10367,10 +10398,11 @@ in the iCalendar format.
* HTML export:: Exporting to HTML
* @LaTeX{} and PDF export:: Exporting to @LaTeX{}, and processing to PDF
* Markdown export:: Exporting to Markdown
-* OpenDocument text export:: Exporting to OpenDocument Text
+* OpenDocument Text export:: Exporting to OpenDocument Text
* Org export:: Exporting to Org
+* Texinfo export:: Exporting to Texinfo
* iCalendar export:: Exporting to iCalendar
-* Other built-in back-ends:: Exporting to @code{Texinfo} or a man page
+* Other built-in back-ends:: Exporting to a man page
* Export in foreign buffers:: Author tables and lists in Org syntax
* Advanced configuration:: Fine-tuning the export output
@end menu
@@ -10412,10 +10444,10 @@ export dispatcher with the following key combinations:
Toggle asynchronous export. Asynchronous export uses an external Emacs
process that is configured with a specified initialization file.
-While exporting asynchronously, the output is not displayed. It is stored in
-a list called ``the export stack'', and can be viewed from there. The stack
-can be reached by calling the dispatcher with a double @kbd{C-u} prefix
-argument, or with @kbd{&} key from the dispatcher.
+While exporting asynchronously, the output is not displayed, but stored in
+a place called ``the export stack''. This stack can be displayed by calling
+the dispatcher with a double @kbd{C-u} prefix argument, or with @kbd{&} key
+from the dispatcher menu.
@vindex org-export-in-background
To make this behavior the default, customize the variable
@@ -10436,14 +10468,8 @@ You can change the default state of this option by setting
@item C-v
Toggle visible-only export. Only export the text that is currently
visible, i.e. not hidden by outline visibility in the buffer.
-
@end table
-@vindex org-export-copy-to-kill-ring
-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 @code{org-export-copy-to-kill-ring}.
-
@node Export back-ends
@section Export back-ends
@cindex Export, back-ends
@@ -10562,8 +10588,7 @@ be executed during export even though the subtree is not exported.
@item TITLE
@cindex #+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.
@end table
The @code{#+OPTIONS} keyword is a compact@footnote{If you want to configure
@@ -10713,16 +10738,12 @@ Toggle inclusion of TODO keywords into exported text
Toggle inclusion of tables (@code{org-export-with-tables}).
@end table
-@cindex property, EXPORT_FILE_NAME
When exporting only a subtree, each of the previous keywords@footnote{With
the exception of @samp{SETUPFILE}.} can be overridden locally by special node
properties. These begin with @samp{EXPORT_}, followed by the name of the
keyword they supplant. For example, @samp{DATE} and @samp{OPTIONS} keywords
become, respectively, @samp{EXPORT_DATE} and @samp{EXPORT_OPTIONS}
-properties. Subtree export also supports the self-explicit
-@samp{EXPORT_FILE_NAME} property@footnote{There is no buffer-wide equivalent
-for this property. The file name in this case is derived from the file
-associated to the buffer, if possible, or asked to the user otherwise.}.
+properties.
@cindex #+BIND
@vindex org-export-allow-bind-keywords
@@ -10731,6 +10752,13 @@ can become buffer-local during export by using the BIND keyword. Its syntax
is @samp{#+BIND: variable value}. This is particularly useful for in-buffer
settings that cannot be changed using specific keywords.
+@cindex property, EXPORT_FILE_NAME
+The name of the output file to be generated is taken from the file associated
+to the buffer, when possible, or asked to you otherwise. For subtree export,
+you can also set @samp{EXPORT_FILE_NAME} property. In all cases, only the
+base name of the file is retained, and a back-end specific extension is
+added.
+
@node ASCII/Latin-1/UTF-8 export
@section ASCII/Latin-1/UTF-8 export
@cindex ASCII export
@@ -10741,6 +10769,10 @@ ASCII export produces a simple and very readable version of an Org mode
file, containing only plain ASCII@. Latin-1 and UTF-8 export augment the file
with special characters and symbols available in these encodings.
+@vindex org-ascii-text-width
+Upon exporting, text is filled and justified, when appropriate, according the
+text width set in @code{org-ascii-text-width}.
+
@vindex org-ascii-links-to-notes
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
@@ -10795,6 +10827,25 @@ specified using an @code{ATTR_ASCII} line, directly preceding the rule.
-----
@end example
+@subheading ASCII special blocks
+@cindex special blocks, in ASCII export
+@cindex #+BEGIN_JUSTIFYLEFT
+@cindex #+BEGIN_JUSTIFYRIGHT
+
+In addition to @code{#+BEGIN_CENTER} blocks (@pxref{Paragraphs}), it is
+possible to justify contents to the left or the right of the page with the
+following dedicated blocks.
+
+@example
+#+BEGIN_JUSTIFYLEFT
+It's just a jump to the left...
+#+END_JUSTIFYLEFT
+
+#+BEGIN_JUSTIFYRIGHT
+...and then a step to the right.
+#+END_JUSTIFYRIGHT
+@end example
+
@node Beamer export
@section Beamer export
@cindex Beamer export
@@ -10968,11 +11019,6 @@ In @code{org-beamer-mode}, this key offers fast selection of a Beamer
environment or the @code{BEAMER_COL} property.
@end table
-Also, a template for useful in-buffer settings or properties can be inserted
-into the buffer with @kbd{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.
-
@subheading An example
Here is a simple example Org document that is intended for Beamer export.
@@ -10980,7 +11026,7 @@ Here is a simple example Org document that is intended for Beamer export.
@smallexample
#+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
@@ -10989,20 +11035,20 @@ Here is a simple example Org document that is intended for Beamer 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:
@@ -11146,7 +11192,7 @@ Becomes:
Special blocks that do not correspond to HTML5 elements (see
@code{org-html-html5-elements}) will revert to the usual behavior, i.e.,
-@code{#+BEGIN_LEDERHOSEN} will still export to @samp{<div class="lederhosen">}.
+@code{#+BEGIN_lederhosen} will still export to @samp{<div class="lederhosen">}.
Headlines cannot appear within special blocks. To wrap a headline and its
contents in e.g., @samp{<section>} or @samp{<article>} tags, set the
@@ -11696,10 +11742,13 @@ task, you can use @code{:caption} attribute instead. Its value should be raw
@LaTeX{} code. It has precedence over @code{#+CAPTION}.
@item :float
@itemx :placement
-Float environment for the table. Possible values are @code{sidewaystable},
+The @code{:float} specifies the float environment for the table. Possible
+values are @code{sideways}@footnote{Formerly, the value was
+@code{sidewaystable}. This is deprecated since Org 8.3.},
@code{multicolumn}, @code{t} and @code{nil}. When unspecified, a table with
-a caption will have a @code{table} environment. Moreover, @code{:placement}
-attribute can specify the positioning of the float.
+a caption will have a @code{table} environment. Moreover, the
+@code{:placement} attribute can specify the positioning of the float. Note:
+@code{:placement} is ignored for @code{:float sideways} tables.
@item :align
@itemx :font
@itemx :width
@@ -11802,6 +11851,11 @@ environment.
@code{wrap}: if you would like to let text flow around the image. It will
make the figure occupy the left half of the page.
@item
+@code{sideways}: if you would like the image to appear alone on a separate
+page rotated ninety degrees using the @code{sidewaysfigure}
+environment. Setting this @code{:float} option will ignore the
+@code{:placement} setting.
+@item
@code{nil}: if you need to avoid any floating environment, even when
a caption is provided.
@end itemize
@@ -11882,15 +11936,15 @@ Value of @code{:options} attribute will be appended as-is to that
environment's opening string. For example:
@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
@end example
@noindent
@@ -11913,9 +11967,9 @@ example:
@example
#+ATTR_LATEX: :caption \MyCaption@{HeadingA@}
-#+BEGIN_PROOF
+#+BEGIN_proof
...
-#+END_PROOF
+#+END_proof
@end example
@subsubheading Horizontal rules
@@ -11965,8 +12019,8 @@ that one (@pxref{Export settings}).
@c begin opendocument
-@node OpenDocument text export
-@section OpenDocument text export
+@node OpenDocument Text export
+@section OpenDocument Text export
@cindex ODT
@cindex OpenDocument
@cindex export, OpenDocument
@@ -12297,7 +12351,7 @@ height:width ratio, do the following
@cindex #+ATTR_ODT
You can control the manner in which an image is anchored by setting the
@code{:anchor} property of it's @code{#+ATTR_ODT} line. You can specify one
-of the the following three values for the @code{:anchor} property:
+of the following three values for the @code{:anchor} property:
@samp{"as-char"}, @samp{"paragraph"} and @samp{"page"}.
To create an image that is anchored to a page, do the following:
@@ -12900,6 +12954,323 @@ Export to a temporary buffer. Do not create a file.
Export to an Org file, then open it.
@end table
+@node Texinfo export
+@section Texinfo export
+@cindex Texinfo export
+
+@samp{texinfo} export back-end generates Texinfo code and can compile it into
+an Info file.
+
+@menu
+* Texinfo export commands:: How to invoke Texinfo export
+* Document preamble:: File header, title and copyright page
+* Headings and sectioning structure:: Building document structure
+* Indices:: Creating indices
+* Quoting Texinfo code:: Incorporating literal Texinfo code
+* Texinfo specific attributes:: Controlling Texinfo output
+* An example::
+@end menu
+
+@node Texinfo export commands
+@subsection Texinfo export commands
+
+@vindex org-texinfo-info-process
+@table @kbd
+@orgcmd{C-c C-e i t,org-texinfo-export-to-texinfo}
+Export as a Texinfo file. For an Org file, @file{myfile.org}, the resulting
+file will be @file{myfile.texi}. The file will be overwritten without
+warning.
+@orgcmd{C-c C-e i i,org-texinfo-export-to-info}
+Export to Texinfo and then process to an Info file@footnote{By setting
+@code{org-texinfo-info-process}, it is possible to generate other formats,
+including DocBook.}.
+@end table
+
+@node Document preamble
+@subsection Document preamble
+
+When processing a document, @samp{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 (@pxref{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 @samp{Top}
+node.
+
+@subsubheading File header
+
+@cindex #+TEXINFO_FILENAME
+Upon creating the header of a Texinfo file, the back-end guesses a name for
+the Info file to be compiled. This may not be a sensible choice, e.g., if
+you want to produce the final document in a different directory. Specify an
+alternate path with @code{#+TEXINFO_FILENAME} keyword to override the default
+destination.
+
+@vindex org-texinfo-coding-system
+@vindex org-texinfo-classes
+@cindex #+TEXINFO_HEADER
+@cindex #+TEXINFO_CLASS
+Along with the output file name, the header contains information about the
+language (@pxref{Export settings}) and current encoding used@footnote{See
+@code{org-texinfo-coding-system} for more information.}. Insert
+a @code{#+TEXINFO_HEADER} keyword for each additional command needed, e.g.,
+@@code@{@@synindex@}.
+
+If you happen to regularly install the same set of commands, it may be easier
+to define your own class in @code{org-texinfo-classes}, which see. Set
+@code{#+TEXINFO_CLASS} keyword accordingly in your document to activate it.
+
+@subsubheading Title and copyright page
+
+@cindex #+TEXINFO_PRINTED_TITLE
+@cindex #+SUBTITLE
+The default template includes a title page for hard copy output. The title
+and author displayed on this page are extracted from, respectively,
+@code{#+TITLE} and @code{#+AUTHOR} keywords (@pxref{Export settings}). It is
+also possible to print a different, more specific, title with
+@code{#+TEXINFO_PRINTED_TITLE} keyword, and add subtitles with
+@code{#+SUBTITLE} keyword. Both expect raw Texinfo code in their value.
+
+@cindex #+SUBAUTHOR
+Likewise, information brought by @code{#+AUTHOR} may not be enough. You can
+include other authors with several @code{#+SUBAUTHOR} keywords. Values are
+also expected to be written in Texinfo code.
+
+@example
+#+AUTHOR: Jane Smith
+#+SUBAUTHOR: John Doe
+#+TEXINFO_PRINTED_TITLE: This Long Title@@inlinefmt@{tex,@@*@} Is Broken in @@TeX@{@}
+@end example
+
+@cindex property, COPYING
+Copying material is defined in a dedicated headline with a non-nil
+@code{:COPYING:} property. The contents are inserted within
+a @code{@@copying} command at the beginning of the document whereas the
+heading itself does not appear in the structure of the document.
+
+Copyright information is printed on the back of the title page.
+
+@example
+* Copying
+ :PROPERTIES:
+ :COPYING: t
+ :END:
+
+ This is a short example of a complete Texinfo file, version 1.0.
+
+ Copyright \copy 2014 Free Software Foundation, Inc.
+@end example
+
+@subsubheading The Top node
+
+@cindex #+TEXINFO_DIR_CATEGORY
+@cindex #+TEXINFO_DIR_TITLE
+@cindex #+TEXINFO_DIR_DESC
+You may ultimately want to install your new Info file to your system. You
+can write an appropriate entry in the top level directory specifying its
+category and title with, respectively, @code{#+TEXINFO_DIR_CATEGORY} and
+@code{#+TEXINFO_DIR_TITLE}. Optionally, you can add a short description
+using @code{#+TEXINFO_DIR_DESC}. The following example would write an entry
+similar to Org's in the @samp{Top} node.
+
+@example
+#+TEXINFO_DIR_CATEGORY: Emacs
+#+TEXINFO_DIR_TITLE: Org Mode: (org)
+#+TEXINFO_DIR_DESC: Outline-based notes management and organizer
+@end example
+
+@node Headings and sectioning structure
+@subsection Headings and sectioning structure
+
+@vindex org-texinfo-classes
+@vindex org-texinfo-default-class
+@cindex #+TEXINFO_CLASS
+@samp{texinfo} uses a pre-defined scheme, or class, to convert headlines into
+Texinfo structuring commands. For example, a top level headline appears as
+@code{@@chapter} if it should be numbered or as @code{@@unnumbered}
+otherwise. If you need to use a different set of commands, e.g., to start
+with @code{@@part} instead of @code{@@chapter}, install a new class in
+@code{org-texinfo-classes}, then activate it with @code{#+TEXINFO_CLASS}
+keyword. Export process defaults to @code{org-texinfo-default-class} when
+there is no such keyword in the document.
+
+If a headline's level has no associated structuring command, or is below
+a certain threshold @pxref{Export settings}, that headline becomes a list in
+Texinfo output.
+
+@cindex property, APPENDIX
+As an exception, a headline with a non-nil @code{:APPENDIX:} property becomes
+an appendix, independently on its level and the class used.
+
+@cindex property, DESCRIPTION
+Each regular sectioning structure creates a menu entry, named after the
+heading. You can provide a different, e.g., shorter, title in
+@code{:ALT_TITLE:} property (@pxref{Table of contents}). Optionally, you can
+specify a description for the item in @code{:DESCRIPTION:} property. E.g.,
+
+@example
+* Controlling Screen Display
+ :PROPERTIES:
+ :ALT_TITLE: Display
+ :DESCRIPTION: Controlling Screen Display
+ :END:
+@end example
+
+@node Indices
+@subsection Indices
+
+@cindex #+CINDEX
+@cindex #+FINDEX
+@cindex #+KINDEX
+@cindex #+PINDEX
+@cindex #+TINDEX
+@cindex #+VINDEX
+Index entries are created using dedicated keywords. @samp{texinfo} back-end
+provides one for each predefined type: @code{#+CINDEX}, @code{#+FINDEX},
+@code{#+KINDEX}, @code{#+PINDEX}, @code{#+TINDEX} and @code{#+VINDEX}. For
+custom indices, you can write raw Texinfo code (@pxref{Quoting Texinfo
+code}).
+
+@example
+#+CINDEX: Defining indexing entries
+@end example
+
+@cindex property, INDEX
+To generate an index, you need to set the @code{:INDEX:} property of
+a headline to an appropriate abbreviation (e.g., @samp{cp} or @samp{vr}).
+The headline is then exported as an unnumbered chapter or section command and
+the index is inserted after its contents.
+
+@example
+* Concept Index
+ :PROPERTIES:
+ :INDEX: cp
+ :END:
+@end example
+
+@node Quoting Texinfo code
+@subsection Quoting Texinfo code
+
+It is possible to insert raw Texinfo code using any of the following
+constructs
+
+@cindex #+TEXINFO
+@cindex #+BEGIN_TEXINFO
+@example
+Richard @@@@texinfo:@@sc@{@@@@Stallman@@@@texinfo:@}@@@@ commence' GNU.
+
+#+TEXINFO: @@need800
+This paragraph is preceded by...
+
+#+BEGIN_TEXINFO
+@@auindex Johnson, Mark
+@@auindex Lakoff, George
+#+END_TEXINFO
+@end example
+
+@node Texinfo specific attributes
+@subsection Texinfo specific attributes
+
+@cindex #+ATTR_TEXINFO
+@samp{texinfo} back-end understands several attributes in plain lists and
+tables. They must be specified using an @code{#+ATTR_TEXINFO} keyword,
+written just above the list or table.
+
+@subsubheading Plain lists
+
+In Texinfo output, description lists appear as two-column tables, using the
+default command @code{@@table}. You can use @code{@@ftable} or
+@code{@@vtable}@footnote{For more information, @inforef{Two-column
+Tables,,texinfo}.} instead with @code{:table-type} attribute.
+
+@vindex org-texinfo-def-table-markup
+In any case, these constructs require a highlighting command for entries in
+the list. You can provide one with @code{:indic} attribute. If you do not,
+it defaults to the value stored in @code{org-texinfo-def-table-markup}, which
+see.
+
+@example
+#+ATTR_TEXINFO: :indic @@asis
+- foo :: This is the text for /foo/, with no highlighting.
+@end example
+
+@subsubheading Tables
+
+When exporting a table, column widths are deduced from the longest cell in
+each column. You can also define them explicitly as fractions of the line
+length, using @code{:columns} attribute.
+
+@example
+#+ATTR_TEXINFO: :columns .5 .5
+| a cell | another cell |
+@end example
+
+@node An example
+@subsection An example
+
+Here is a thorough example, taken from @inforef{GNU Sample Texts,,texinfo}.
+
+@smallexample
+#+MACRO: version 2.0
+#+MACRO: updated last updated 4 March 2014
+
+#+OPTIONS: ':t toc:t author:t email:t
+#+TITLE: GNU Sample @{@{@{version@}@}@}
+#+AUTHOR: A.U. Thor
+#+EMAIL: bug-sample@@gnu.org
+#+LANGUAGE: en
+
+#+TEXINFO_FILENAME: sample.info
+#+TEXINFO_HEADER: @@syncodeindex pg cp
+
+#+TEXINFO_DIR_CATEGORY: Texinfo documentation system
+#+TEXINFO_DIR_TITLE: sample: (sample)
+#+TEXINFO_DIR_DESC: Invoking sample
+
+#+TEXINFO_PRINTED_TITLE: GNU Sample
+#+SUBTITLE: for version 2.0, last updated 4 March 2014
+
+* Copying
+ :PROPERTIES:
+ :COPYING: t
+ :END:
+
+ This manual is for GNU Sample (version @{@{@{version@}@}@},
+ @{@{@{updated@}@}@}), which is an example in the Texinfo documentation.
+
+ Copyright @@@@texinfo:@@copyright@{@}@@@@ 2013 Free Software Foundation,
+ Inc.
+
+ #+BEGIN_QUOTE
+ Permission is granted to copy, distribute and/or modify this
+ document under the terms of the GNU Free Documentation License,
+ Version 1.3 or any later version published by the Free Software
+ Foundation; with no Invariant Sections, with no Front-Cover Texts,
+ and with no Back-Cover Texts. A copy of the license is included in
+ the section entitled "GNU Free Documentation License".
+ #+END_QUOTE
+
+* Invoking sample
+
+ #+PINDEX: sample
+ #+CINDEX: invoking @@command@{sample@}
+
+ This is a sample manual. There is no sample program to invoke, but
+ if there were, you could see its basic usage and command line
+ options here.
+
+* GNU Free Documentation License
+ :PROPERTIES:
+ :APPENDIX: t
+ :END:
+
+ #+TEXINFO: @@include fdl.texi
+
+* Index
+ :PROPERTIES:
+ :INDEX: cp
+ :END:
+@end smallexample
+
@node iCalendar export
@section iCalendar export
@cindex iCalendar export
@@ -12978,12 +13349,11 @@ On top of the aforementioned back-ends, Org comes with other built-in ones:
@itemize
@item @file{ox-man.el}: export to a man page.
-@item @file{ox-texinfo.el}: export to @code{Texinfo} format.
@end itemize
-To activate these export back-ends, customize @code{org-export-backends} or
-load them directly with e.g., @code{(require 'ox-texinfo)}. This will add
-new keys in the export dispatcher (@pxref{The export dispatcher}).
+To activate these export back-end, customize @code{org-export-backends} or
+load them directly with e.g., @code{(require 'ox-man)}. This will add new
+keys in the export dispatcher (@pxref{The export dispatcher}).
See the comment section of these files for more information on how to use
them.
@@ -13057,63 +13427,63 @@ are all named after the same scheme: @code{org-export-filter-TYPE-functions},
where @code{TYPE} is the type targeted by the filter. Valid types are:
@multitable @columnfractions .33 .33 .33
-@item bold
+@item body
+@tab bold
@tab babel-call
-@tab center-block
-@item clock
+@item center-block
+@tab clock
@tab code
-@tab comment
-@item comment-block
+@item comment
+@tab comment-block
@tab diary-sexp
-@tab drawer
-@item dynamic-block
+@item drawer
+@tab dynamic-block
@tab entity
-@tab example-block
-@item export-block
+@item example-block
+@tab export-block
@tab export-snippet
-@tab final-output
-@item fixed-width
+@item final-output
+@tab fixed-width
@tab footnote-definition
-@tab footnote-reference
-@item headline
+@item footnote-reference
+@tab headline
@tab horizontal-rule
-@tab inline-babel-call
-@item inline-src-block
+@item inline-babel-call
+@tab inline-src-block
@tab inlinetask
-@tab italic
-@item item
+@item italic
+@tab item
@tab keyword
-@tab latex-environment
-@item latex-fragment
+@item latex-environment
+@tab latex-fragment
@tab line-break
-@tab link
-@item node-property
+@item link
+@tab node-property
@tab options
-@tab paragraph
-@item parse-tree
+@item paragraph
+@tab parse-tree
@tab plain-list
-@tab plain-text
-@item planning
+@item plain-text
+@tab planning
@tab property-drawer
-@tab quote-block
-@item quote-section
+@item quote-block
+@tab quote-section
@tab radio-target
-@tab section
-@item special-block
+@item section
+@tab special-block
@tab src-block
-@tab statistics-cookie
-@item strike-through
+@item statistics-cookie
+@tab strike-through
@tab subscript
-@tab superscript
-@item table
+@item superscript
+@tab table
@tab table-cell
-@tab table-row
-@item target
+@item table-row
+@tab target
@tab timestamp
-@tab underline
-@item verbatim
+@item underline
+@tab verbatim
@tab verse-block
-@tab
@end multitable
For example, the following snippet allows me to use non-breaking spaces in
@@ -13379,48 +13749,27 @@ result into the destination folder.
@subsection Options for the exporters
@cindex options, for publishing
-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.
+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.
-@vindex org-display-custom-times
-@vindex org-export-default-language
-@vindex org-export-exclude-tags
-@vindex org-export-headline-levels
-@vindex org-export-preserve-breaks
-@vindex org-export-publishing-directory
-@vindex org-export-select-tags
-@vindex org-export-with-archived-trees
-@vindex org-export-with-author
-@vindex org-export-with-creator
-@vindex org-export-with-drawers
-@vindex org-export-with-email
-@vindex org-export-with-emphasize
-@vindex org-export-with-fixed-width
-@vindex org-export-with-footnotes
-@vindex org-export-with-latex
-@vindex org-export-with-planning
-@vindex org-export-with-priority
-@vindex org-export-with-properties
-@vindex org-export-with-section-numbers
-@vindex org-export-with-special-strings
-@vindex org-export-with-sub-superscripts
-@vindex org-export-with-tables
-@vindex org-export-with-tags
-@vindex org-export-with-tasks
-@vindex org-export-with-timestamps
-@vindex org-export-with-toc
-@vindex org-export-with-todo-keywords
-@vindex user-mail-address
-@multitable @columnfractions 0.32 0.68
+@vindex org-publish-project-alist
+When a property is given a value in @code{org-publish-project-alist}, its
+setting overrides the value of the corresponding user variable (if any)
+during publishing. Options set within a file (@pxref{Export settings}),
+however, override everything.
+
+@subsubheading Generic properties
+
+@multitable {@code{:with-sub-superscript}} {@code{org-export-with-sub-superscripts}}
@item @code{:archived-trees} @tab @code{org-export-with-archived-trees}
@item @code{:exclude-tags} @tab @code{org-export-exclude-tags}
@item @code{:headline-levels} @tab @code{org-export-headline-levels}
@item @code{:language} @tab @code{org-export-default-language}
@item @code{:preserve-breaks} @tab @code{org-export-preserve-breaks}
-@item @code{:publishing-directory} @tab @code{org-export-publishing-directory}
@item @code{:section-numbers} @tab @code{org-export-with-section-numbers}
@item @code{:select-tags} @tab @code{org-export-select-tags}
@item @code{:with-author} @tab @code{org-export-with-author}
@@ -13444,53 +13793,174 @@ string of these options for details.
@item @code{:with-todo-keywords} @tab @code{org-export-with-todo-keywords}
@end multitable
-@vindex org-html-doctype
-@vindex org-html-container-element
-@vindex org-html-html5-fancy
-@vindex org-html-xml-declaration
-@vindex org-html-link-up
-@vindex org-html-link-home
-@vindex org-html-link-org-files-as-html
-@vindex org-html-link-use-abs-url
-@vindex org-html-head
-@vindex org-html-head-extra
-@vindex org-html-inline-images
-@vindex org-html-extension
-@vindex org-html-preamble
-@vindex org-html-postamble
-@vindex org-html-table-default-attributes
-@vindex org-html-table-row-tags
-@vindex org-html-head-include-default-style
-@vindex org-html-head-include-scripts
-@multitable @columnfractions 0.32 0.68
-@item @code{:html-doctype} @tab @code{org-html-doctype}
-@item @code{:html-container} @tab @code{org-html-container-element}
-@item @code{:html-html5-fancy} @tab @code{org-html-html5-fancy}
-@item @code{:html-xml-declaration} @tab @code{org-html-xml-declaration}
-@item @code{:html-link-up} @tab @code{org-html-link-up}
-@item @code{:html-link-home} @tab @code{org-html-link-home}
-@item @code{:html-link-org-as-html} @tab @code{org-html-link-org-files-as-html}
-@item @code{:html-link-use-abs-url} @tab @code{org-html-link-use-abs-url}
-@item @code{:html-head} @tab @code{org-html-head}
-@item @code{:html-head-extra} @tab @code{org-html-head-extra}
-@item @code{:html-inline-images} @tab @code{org-html-inline-images}
-@item @code{:html-extension} @tab @code{org-html-extension}
-@item @code{:html-preamble} @tab @code{org-html-preamble}
-@item @code{:html-postamble} @tab @code{org-html-postamble}
-@item @code{:html-table-attributes} @tab @code{org-html-table-default-attributes}
-@item @code{:html-table-row-tags} @tab @code{org-html-table-row-tags}
+@subsubheading ASCII specific properties
+
+@multitable {@code{:ascii-table-keep-all-vertical-lines}} {@code{org-ascii-table-keep-all-vertical-lines}}
+@item @code{:ascii-bullets} @tab @code{org-ascii-bullets}
+@item @code{:ascii-caption-above} @tab @code{org-ascii-caption-above}
+@item @code{:ascii-charset} @tab @code{org-ascii-charset}
+@item @code{:ascii-global-margin} @tab @code{org-ascii-global-margin}
+@item @code{:ascii-format-drawer-function} @tab @code{org-ascii-format-drawer-function}
+@item @code{:ascii-format-inlinetask-function} @tab @code{org-ascii-format-inlinetask-function}
+@item @code{:ascii-headline-spacing} @tab @code{org-ascii-headline-spacing}
+@item @code{:ascii-indented-line-width} @tab @code{org-ascii-indented-line-width}
+@item @code{:ascii-inlinetask-width} @tab @code{org-ascii-inlinetask-width}
+@item @code{:ascii-inner-margin} @tab @code{org-ascii-inner-margin}
+@item @code{:ascii-links-to-notes} @tab @code{org-ascii-links-to-notes}
+@item @code{:ascii-list-margin} @tab @code{org-ascii-list-margin}
+@item @code{:ascii-paragraph-spacing} @tab @code{org-ascii-paragraph-spacing}
+@item @code{:ascii-quote-margin} @tab @code{org-ascii-quote-margin}
+@item @code{:ascii-table-keep-all-vertical-lines} @tab @code{org-ascii-table-keep-all-vertical-lines}
+@item @code{:ascii-table-use-ascii-art} @tab @code{org-ascii-table-use-ascii-art}
+@item @code{:ascii-table-widen-columns} @tab @code{org-ascii-table-widen-columns}
+@item @code{:ascii-text-width} @tab @code{org-ascii-text-width}
+@item @code{:ascii-underline} @tab @code{org-ascii-underline}
+@item @code{:ascii-verbatim-format} @tab @code{org-ascii-verbatim-format}
+@end multitable
+
+@subsubheading Beamer specific properties
+
+@multitable {@code{:beamer-frame-default-options}} {@code{org-beamer-frame-default-options}}
+@item @code{:beamer-theme} @tab @code{org-beamer-theme}
+@item @code{:beamer-column-view-format} @tab @code{org-beamer-column-view-format}
+@item @code{:beamer-environments-extra} @tab @code{org-beamer-environments-extra}
+@item @code{:beamer-frame-default-options} @tab @code{org-beamer-frame-default-options}
+@item @code{:beamer-outline-frame-options} @tab @code{org-beamer-outline-frame-options}
+@item @code{:beamer-outline-frame-title} @tab @code{org-beamer-outline-frame-title}
+@end multitable
+
+@subsubheading HTML specific properties
+
+@multitable {@code{:html-table-use-header-tags-for-first-column}} {@code{org-html-table-use-header-tags-for-first-column}}
+@item @code{:html-allow-name-attribute-in-anchors} @tab @code{org-html-allow-name-attribute-in-anchors}
+@item @code{:html-checkbox-type} @tab @code{org-html-checkbox-type}
+@item @code{:html-container} @tab @code{org-html-container-element}
+@item @code{:html-divs} @tab @code{org-html-divs}
+@item @code{:html-doctype} @tab @code{org-html-doctype}
+@item @code{:html-extension} @tab @code{org-html-extension}
+@item @code{:html-footnote-format} @tab @code{org-html-footnote-format}
+@item @code{:html-footnote-separator} @tab @code{org-html-footnote-separator}
+@item @code{:html-footnotes-section} @tab @code{org-html-footnotes-section}
+@item @code{:html-format-drawer-function} @tab @code{org-html-format-drawer-function}
+@item @code{:html-format-headline-function} @tab @code{org-html-format-headline-function}
+@item @code{:html-format-inlinetask-function} @tab @code{org-html-format-inlinetask-function}
+@item @code{:html-head-extra} @tab @code{org-html-head-extra}
@item @code{:html-head-include-default-style} @tab @code{org-html-head-include-default-style}
-@item @code{:html-head-include-scripts} @tab @code{org-html-head-include-scripts}
+@item @code{:html-head-include-scripts} @tab @code{org-html-head-include-scripts}
+@item @code{:html-head} @tab @code{org-html-head}
+@item @code{:html-home/up-format} @tab @code{org-html-home/up-format}
+@item @code{:html-html5-fancy} @tab @code{org-html-html5-fancy}
+@item @code{:html-indent} @tab @code{org-html-indent}
+@item @code{:html-infojs-options} @tab @code{org-html-infojs-options}
+@item @code{:html-infojs-template} @tab @code{org-html-infojs-template}
+@item @code{:html-inline-image-rules} @tab @code{org-html-inline-image-rules}
+@item @code{:html-inline-images} @tab @code{org-html-inline-images}
+@item @code{:html-link-home} @tab @code{org-html-link-home}
+@item @code{:html-link-org-files-as-html} @tab @code{org-html-link-org-files-as-html}
+@item @code{:html-link-up} @tab @code{org-html-link-up}
+@item @code{:html-link-use-abs-url} @tab @code{org-html-link-use-abs-url}
+@item @code{:html-mathjax-options} @tab @code{org-html-mathjax-options}
+@item @code{:html-mathjax-template} @tab @code{org-html-mathjax-template}
+@item @code{:html-metadata-timestamp-format} @tab @code{org-html-metadata-timestamp-format}
+@item @code{:html-postamble-format} @tab @code{org-html-postamble-format}
+@item @code{:html-postamble} @tab @code{org-html-postamble}
+@item @code{:html-preamble-format} @tab @code{org-html-preamble-format}
+@item @code{:html-preamble} @tab @code{org-html-preamble}
+@item @code{:html-table-align-individual-fields} @tab @code{org-html-table-align-individual-fields}
+@item @code{:html-table-attributes} @tab @code{org-html-table-default-attributes}
+@item @code{:html-table-caption-above} @tab @code{org-html-table-caption-above}
+@item @code{:html-table-data-tags} @tab @code{org-html-table-data-tags}
+@item @code{:html-table-header-tags} @tab @code{org-html-table-header-tags}
+@item @code{:html-table-row-tags} @tab @code{org-html-table-row-tags}
+@item @code{:html-table-use-header-tags-for-first-column} @tab @code{org-html-table-use-header-tags-for-first-column}
+@item @code{:html-tag-class-prefix} @tab @code{org-html-tag-class-prefix}
+@item @code{:html-text-markup-alist} @tab @code{org-html-text-markup-alist}
+@item @code{:html-todo-kwd-class-prefix} @tab @code{org-html-todo-kwd-class-prefix}
+@item @code{:html-toplevel-hlevel} @tab @code{org-html-toplevel-hlevel}
+@item @code{:html-use-infojs} @tab @code{org-html-use-infojs}
+@item @code{:html-use-unicode-chars} @tab @code{org-html-use-unicode-chars}
+@item @code{:html-validation-link} @tab @code{org-html-validation-link}
+@item @code{:html-xml-declaration} @tab @code{org-html-xml-declaration}
@end multitable
-Most of the @code{org-export-with-*} variables have the same effect in each
-exporter.
+@subsubheading @LaTeX{} specific properties
+
+@multitable {@code{:latex-link-with-unknown-path-format}} {@code{org-latex-link-with-unknown-path-format}}
+@item @code{:latex-active-timestamp-format} @tab @code{org-latex-active-timestamp-format}
+@item @code{:latex-classes} @tab @code{org-latex-classes}
+@item @code{:latex-class} @tab @code{org-latex-default-class}
+@item @code{:latex-custom-id-labels} @tab @code{org-latex-custom-id-as-label}
+@item @code{:latex-default-figure-position} @tab @code{org-latex-default-figure-position}
+@item @code{:latex-default-table-environment} @tab @code{org-latex-default-table-environment}
+@item @code{:latex-default-table-mode} @tab @code{org-latex-default-table-mode}
+@item @code{:latex-diary-timestamp-format} @tab @code{org-latex-diary-timestamp-format}
+@item @code{:latex-footnote-separator} @tab @code{org-latex-footnote-separator}
+@item @code{:latex-format-drawer-function} @tab @code{org-latex-format-drawer-function}
+@item @code{:latex-format-headline-function} @tab @code{org-latex-format-headline-function}
+@item @code{:latex-format-inlinetask-function} @tab @code{org-latex-format-inlinetask-function}
+@item @code{:latex-hyperref-template} @tab @code{org-latex-hyperref-template}
+@item @code{:latex-image-default-height} @tab @code{org-latex-image-default-height}
+@item @code{:latex-image-default-option} @tab @code{org-latex-image-default-option}
+@item @code{:latex-image-default-width} @tab @code{org-latex-image-default-width}
+@item @code{:latex-inactive-timestamp-format} @tab @code{org-latex-inactive-timestamp-format}
+@item @code{:latex-inline-image-rules} @tab @code{org-latex-inline-image-rules}
+@item @code{:latex-link-with-unknown-path-format} @tab @code{org-latex-link-with-unknown-path-format}
+@item @code{:latex-listings-langs} @tab @code{org-latex-listings-langs}
+@item @code{:latex-listings-options} @tab @code{org-latex-listings-options}
+@item @code{:latex-listings} @tab @code{org-latex-listings}
+@item @code{:latex-minted-langs} @tab @code{org-latex-minted-langs}
+@item @code{:latex-minted-options} @tab @code{org-latex-minted-options}
+@item @code{:latex-table-caption-above} @tab @code{org-latex-table-caption-above}
+@item @code{:latex-table-scientific-notation} @tab @code{org-latex-table-scientific-notation}
+@item @code{:latex-tables-booktabs} @tab @code{org-latex-tables-booktabs}
+@item @code{:latex-tables-centered} @tab @code{org-latex-tables-centered}
+@item @code{:latex-text-markup-alist} @tab @code{org-latex-text-markup-alist}
+@item @code{:latex-title-command} @tab @code{org-latex-title-command}
+@item @code{:latex-toc-command} @tab @code{org-latex-toc-command}
+@end multitable
-@vindex org-publish-project-alist
-When a property is given a value in @code{org-publish-project-alist}, its
-setting overrides the value of the corresponding user variable (if any)
-during publishing. Options set within a file (@pxref{Export settings}),
-however, override everything.
+@subsubheading Markdown specific properties
+
+@multitable {@code{:md-headline-style}} {@code{org-md-headline-style}}
+@item @code{:md-headline-style} @tab @code{org-md-headline-style}
+@end multitable
+
+@subsubheading ODT specific properties
+
+@multitable {@code{:odt-format-inlinetask-function}} {@code{org-odt-format-inlinetask-function}}
+@item @code{:odt-content-template-file} @tab @code{org-odt-content-template-file}
+@item @code{:odt-display-outline-level} @tab @code{org-odt-display-outline-level}
+@item @code{:odt-fontify-srcblocks} @tab @code{org-odt-fontify-srcblocks}
+@item @code{:odt-format-drawer-function} @tab @code{org-odt-format-drawer-function}
+@item @code{:odt-format-headline-function} @tab @code{org-odt-format-headline-function}
+@item @code{:odt-format-inlinetask-function} @tab @code{org-odt-format-inlinetask-function}
+@item @code{:odt-inline-formula-rules} @tab @code{org-odt-inline-formula-rules}
+@item @code{:odt-inline-image-rules} @tab @code{org-odt-inline-image-rules}
+@item @code{:odt-pixels-per-inch} @tab @code{org-odt-pixels-per-inch}
+@item @code{:odt-styles-file} @tab @code{org-odt-styles-file}
+@item @code{:odt-table-styles} @tab @code{org-odt-table-styles}
+@item @code{:odt-use-date-fields} @tab @code{org-odt-use-date-fields}
+@end multitable
+
+@subsubheading Texinfo specific properties
+
+@multitable {@code{:texinfo-link-with-unknown-path-format}} {@code{org-texinfo-link-with-unknown-path-format}}
+@item @code{:texinfo-active-timestamp-format} @tab @code{org-texinfo-active-timestamp-format}
+@item @code{:texinfo-classes} @tab @code{org-texinfo-classes}
+@item @code{:texinfo-class} @tab @code{org-texinfo-default-class}
+@item @code{:texinfo-def-table-markup} @tab @code{org-texinfo-def-table-markup}
+@item @code{:texinfo-diary-timestamp-format} @tab @code{org-texinfo-diary-timestamp-format}
+@item @code{:texinfo-filename} @tab @code{org-texinfo-filename}
+@item @code{:texinfo-format-drawer-function} @tab @code{org-texinfo-format-drawer-function}
+@item @code{:texinfo-format-headline-function} @tab @code{org-texinfo-format-headline-function}
+@item @code{:texinfo-format-inlinetask-function} @tab @code{org-texinfo-format-inlinetask-function}
+@item @code{:texinfo-inactive-timestamp-format} @tab @code{org-texinfo-inactive-timestamp-format}
+@item @code{:texinfo-link-with-unknown-path-format} @tab @code{org-texinfo-link-with-unknown-path-format}
+@item @code{:texinfo-node-description-column} @tab @code{org-texinfo-node-description-column}
+@item @code{:texinfo-table-scientific-notation} @tab @code{org-texinfo-table-scientific-notation}
+@item @code{:texinfo-tables-verbatim} @tab @code{org-texinfo-tables-verbatim}
+@item @code{:texinfo-text-markup-alist} @tab @code{org-texinfo-text-markup-alist}
+@end multitable
@node Publishing links
@subsection Links between published files
@@ -14020,16 +14490,15 @@ option @code{org-babel-no-eval-on-ctrl-c-ctrl-c} can be used to remove code
evaluation from the @kbd{C-c C-c} key binding.}. This will call the
@code{org-babel-execute-src-block} function to evaluate the block and insert
its results into the Org mode buffer.
-@cindex #+CALL
+@cindex #+CALL
It is also possible to evaluate named code blocks from anywhere in 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'' (see @ref{Library
-of Babel}). Named code blocks can be evaluated with a separate
-@code{#+CALL:} line or inline within a block of text. In both cases
-the result is wrapped according to the value of
-@var{org-babel-inline-result-wrap}, which by default is @code{"=%s="} for
-markup that produces verbatim text.
+the current Org mode buffer or in the ``Library of Babel'' (@pxref{Library of
+Babel}). Named code blocks can be evaluated with a separate @code{#+CALL:}
+line or inline within a block of text. In both cases the result is wrapped
+according to the value of @code{org-babel-inline-result-wrap}, which by
+default is @code{"=%s="} for markup that produces verbatim text.
The syntax of the @code{#+CALL:} line is
@@ -14389,6 +14858,8 @@ argument in lowercase letters. The following header arguments are 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
@@ -14823,6 +15294,29 @@ description for file code block results which are inserted as Org mode links
with no value the link path will be placed in both the ``link'' and the
``description'' portion of the Org mode link.
+@node file-ext
+@subsubsection @code{:file-ext}
+@cindex @code{:file-ext}, src header argument
+
+The value of the @code{:file-ext} header argument is used to provide an
+extension to write the file output to. It is combined with the
+@code{#+NAME:} of the source block and the value of the @ref{output-dir}
+header argument to generate a complete file name.
+
+This header arg will be overridden by @code{:file}, and thus has no effect
+when the latter is specified.
+
+@node output-dir
+@subsubsection @code{:output-dir}
+@cindex @code{:output-dir}, src header argument
+
+The value of the @code{:output-dir} header argument is used to provide a
+directory to write the file output to. It may specify an absolute directory
+(beginning with @code{/}) or a relative directory (without @code{/}). It can
+be combined with the @code{#+NAME:} of the source block and the value of the
+@ref{file-ext} header argument to generate a complete file name, or used
+along with a @ref{file} header arg.
+
@node dir
@subsubsection @code{:dir} and remote execution
@cindex @code{:dir}, src header argument
@@ -14994,6 +15488,9 @@ during tangling. This has the effect of assigning values to variables
specified with @code{:var} (see @ref{var}), and of replacing ``noweb''
references (see @ref{Noweb reference syntax}) with their targets. The
@code{:no-expand} header argument can be used to turn off this behavior.
+Note: The @code{:no-expand} header argument has no impact on export,
+i.e. code blocks will irrespective of this header argument expanded for
+execution.
@node session
@subsubsection @code{:session}
@@ -15069,12 +15566,12 @@ references.
@node noweb-ref
@subsubsection @code{:noweb-ref}
@cindex @code{:noweb-ref}, src header argument
-When expanding ``noweb'' style references the bodies of all code block with
+When expanding ``noweb'' style references, the bodies of all code block with
@emph{either} a block name matching the reference name @emph{or} a
@code{: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
+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@footnote{(The example needs property inheritance
@@ -15596,10 +16093,10 @@ are active:
@item @kbd{C-c C-c} @tab @code{org-babel-execute-src-block}
@kindex C-c C-o
@item @kbd{C-c C-o} @tab @code{org-babel-open-src-block-result}
-@kindex C-up
-@item @kbd{C-@key{up}} @tab @code{org-babel-load-in-session}
+@kindex M-up
+@item @kbd{M-@key{up}} @tab @code{org-babel-load-in-session}
@kindex M-down
-@item @kbd{M-@key{down}} @tab @code{org-babel-pop-to-session}
+@item @kbd{M-@key{down}} @tab @code{org-babel-switch-to-session}
@end multitable
In an Org mode buffer, the following key bindings are active:
@@ -17015,10 +17512,6 @@ calculation marks, that column is automatically discarded as well.
Please note that the translator function sees the table @emph{after} the
removal of these columns, the function never knows that there have been
additional columns.
-
-@item :no-escape t
-When non-@code{nil}, do not escape special characters @code{&%#_^} when exporting
-the table. The default value is @code{nil}.
@end table
@noindent
@@ -17126,14 +17619,15 @@ Month & \multicolumn@{1@}@{c@}@{Days@} & Nr.\ sold & per day\\
@end example
The @LaTeX{} translator function @code{orgtbl-to-latex} is already part of
-Orgtbl mode. It uses a @code{tabular} environment to typeset the table
-and marks horizontal lines with @code{\hline}. Furthermore, it
-interprets the following parameters (see also @pxref{Translator functions}):
+Orgtbl mode. By default, it uses a @code{tabular} environment to typeset the
+table and marks horizontal lines with @code{\hline}. You can control the
+output through several parameters (see also @pxref{Translator functions}),
+including the following ones :
@table @code
@item :splice nil/t
-When set to t, return only table body lines, don't wrap them into a
-tabular environment. Default is @code{nil}.
+When non-nil, return only table body lines, don't wrap them into a tabular
+environment. Default is @code{nil}.
@item :fmt fmt
A format to be used to wrap each field, it should contain @code{%s} for the
@@ -17144,14 +17638,14 @@ A function of one argument can be used in place of the strings; the
function must return a formatted string.
@item :efmt efmt
-Use this format to print numbers with exponentials. The format should
-have @code{%s} twice for inserting mantissa and exponent, for example
-@code{"%s\\times10^@{%s@}"}. The default is @code{"%s\\,(%s)"}. This
-may also be a property list with column numbers and formats, for example
-@code{:efmt (2 "$%s\\times10^@{%s@}$" 4 "$%s\\cdot10^@{%s@}$")}. After
-@code{efmt} has been applied to a value, @code{fmt} will also be
-applied. Similar to @code{fmt}, functions of two arguments can be
-supplied instead of strings.
+Use this format to print numbers with exponentials. The format should have
+@code{%s} twice for inserting mantissa and exponent, for example
+@code{"%s\\times10^@{%s@}"}. This may also be a property list with column
+numbers and formats, for example @code{:efmt (2 "$%s\\times10^@{%s@}$"
+4 "$%s\\cdot10^@{%s@}$")}. After @code{efmt} has been applied to a value,
+@code{fmt} will also be applied. Similar to @code{fmt}, functions of two
+arguments can be supplied instead of strings. By default, no special
+formatting is applied.
@end table
@node Translator functions
@@ -17161,54 +17655,36 @@ supplied instead of strings.
Orgtbl mode has several translator functions built-in: @code{orgtbl-to-csv}
(comma-separated values), @code{orgtbl-to-tsv} (TAB-separated values)
-@code{orgtbl-to-latex}, @code{orgtbl-to-html}, and @code{orgtbl-to-texinfo}.
-Except for @code{orgtbl-to-html}@footnote{The HTML translator uses the same
-code that produces tables during HTML export.}, these all use a generic
-translator, @code{orgtbl-to-generic}. For example, @code{orgtbl-to-latex}
-itself is a very short function that computes the column definitions for the
-@code{tabular} environment, defines a few field and line separators and then
-hands processing over to the generic translator. Here is the entire code:
-
-@lisp
-@group
-(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))))
-@end group
-@end lisp
+@code{orgtbl-to-latex}, @code{orgtbl-to-html}, @code{orgtbl-to-texinfo},
+@code{orgtbl-to-unicode} and @code{orgtbl-to-orgtbl}. These all use
+a generic translator, @code{orgtbl-to-generic}, which, in turn, can delegate
+translations to various export back-ends (@pxref{Export back-ends}).
-As you can see, the properties passed into the function (variable
-@var{PARAMS}) are combined with the ones newly defined in the function
-(variable @var{PARAMS2}). The ones passed into the function (i.e., the
-ones set by the @samp{ORGTBL SEND} line) take precedence. So if you
-would like to use the @LaTeX{} translator, but wanted the line endings to
-be @samp{\\[2mm]} instead of the default @samp{\\}, you could just
-overrule the default with
+In particular, properties passed into the function (i.e., the ones set by the
+@samp{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 @samp{\\[2mm]} instead of the default @samp{\\}, you
+could just overrule the default with
@example
#+ORGTBL: SEND test orgtbl-to-latex :lend " \\\\[2mm]"
@end example
-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 @samp{!BTBL!}, ended with @samp{!ETBL!}, and where table lines are
-started with @samp{!BL!}, ended with @samp{!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 @samp{!BTBL!}, ended with @samp{!ETBL!}, and where table lines
+are started with @samp{!BL!}, ended with @samp{!EL!}, and where the field
+separator is a TAB, you could define your generic translator like this:
-@example
-#+ORGTBL: SEND test orgtbl-to-generic :tstart "!BTBL!" :tend "!ETBL!"
- :lstart "!BL! " :lend " !EL!" :sep "\t"
-@end example
+@lisp
+(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)))
+@end lisp
@noindent
Please check the documentation string of the function
diff --git a/doc/orgguide.texi b/doc/orgguide.texi
index cacca3c..ca8e052 100644
--- a/doc/orgguide.texi
+++ b/doc/orgguide.texi
@@ -211,7 +211,7 @@ Exporting
* ASCII/Latin-1/UTF-8 export:: Exporting to flat files with encoding
* HTML export:: Exporting to HTML
* @LaTeX{} and PDF export:: Exporting to @LaTeX{}, and processing to PDF
-* iCalendar export:: Exporting to iCalendar
+* iCalendar export:: Exporting to iCalendar
Miscellaneous
@@ -1498,7 +1498,7 @@ the resulting time in inserts it after the time range as @samp{=>
HH:MM}.
@item C-c C-x C-e
Update the effort estimate for the current clock task.
-@item C-c C-x C-x
+@item C-c C-x C-q
Cancel the current clock. This is useful if a clock was started by
mistake, or if you ended up working on something else.
@item C-c C-x C-j
@@ -2169,10 +2169,14 @@ consisting of only dashes, and at least 5 of them.
@subheading Comment lines
Lines starting with zero or more whitespace characters followed by @samp{#}
-and a whitespace are treated as comments and will never be exported. Also
-entire subtrees starting with the word @samp{COMMENT} will never be exported.
-Finally, regions surrounded by @samp{#+BEGIN_COMMENT}
-... @samp{#+END_COMMENT} will not be exported.
+and a whitespace are treated as comments and, as such, are not exported.
+
+Likewise, regions surrounded by @samp{#+BEGIN_COMMENT}
+... @samp{#+END_COMMENT} are not exported.
+
+Finally, a @samp{COMMENT} keyword at the beginning of an entry, but after any
+other keyword or priority cookie, comments out the entire subtree. The
+command below helps changing the comment status of a headline.
@table @kbd
@item C-c ;
@@ -2257,11 +2261,11 @@ include your @file{.emacs} file, you could use:
#+INCLUDE: "~/.emacs" src emacs-lisp
@end smallexample
@noindent
-The optional second and third parameter are the markup (e.g.@: @samp{quote},
-@samp{example}, or @samp{src}), and, if the markup is @samp{src}, the
-language for formatting the contents. The markup is optional, if it is not
-given, the text will be assumed to be in Org mode format and will be
-processed normally. @kbd{C-c '} will visit the included file.
+The optional second and third parameter are the markup (i.e., @samp{example}
+or @samp{src}), and, if the markup is @samp{src}, the language for formatting
+the contents. The markup is optional, if it is not given, the text will be
+assumed to be in Org mode format and will be processed normally. @kbd{C-c '}
+will visit the included file.
@node Embedded @LaTeX{}, , Include files, Markup
@section Embedded @LaTeX{}
@@ -2303,30 +2307,29 @@ that planning information can be incorporated into desktop calendars.
* ASCII/Latin-1/UTF-8 export:: Exporting to flat files with encoding
* HTML export:: Exporting to HTML
* @LaTeX{} and PDF export:: Exporting to @LaTeX{}, and processing to PDF
-* iCalendar export:: Exporting to iCalendar
+* iCalendar export:: Exporting to iCalendar
@end menu
@node Export options, The export dispatcher, Exporting, Exporting
@section Export options
-The exporter recognizes special lines in the buffer which provide
-additional information. These lines may be put anywhere in the file.
-The whole set of lines can be inserted into the buffer with @kbd{C-c
-C-e t}.
+The exporter recognizes special lines in the buffer which provide additional
+information. These lines may be put anywhere in the file. The whole set of
+lines can be inserted into the buffer with @kbd{C-c C-e #}.
@table @kbd
-@item C-c C-e t
+@item C-c C-e #
Insert template with export options, see example below.
@end table
@smallexample
-#+TITLE: the title to be shown (default is the buffer name)
+#+TITLE: the title to be shown
#+AUTHOR: the author (default taken from @code{user-full-name})
#+DATE: a date, fixed, or an Org timestamp
#+EMAIL: his/her email address (default from @code{user-mail-address})
#+DESCRIPTION: the page description, e.g.@: for the XHTML meta tag
#+KEYWORDS: the page keywords, e.g.@: for the XHTML meta tag
-#+LANGUAGE: language for HTML, e.g.@: @samp{en} (@code{org-export-default-language})
+#+LANGUAGE: language, e.g.@: @samp{en} (@code{org-export-default-language})
#+OPTIONS: H:2 num:t toc:t \n:nil ::t |:t ^:t f:t tex:t ...
@end smallexample
diff --git a/doc/texinfo.tex b/doc/texinfo.tex
index 0b958d3..5f5818d 100644
--- a/doc/texinfo.tex
+++ b/doc/texinfo.tex
@@ -3,11 +3,11 @@
% Load plain if necessary, i.e., if running under initex.
\expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi
%
-\def\texinfoversion{2012-01-03.18}
+\def\texinfoversion{2013-09-11.11}
%
-% Copyright (C) 1985, 1986, 1988, 1990, 1991, 1992, 1993, 1994, 1995,
+% Copyright 1985, 1986, 1988, 1990, 1991, 1992, 1993, 1994, 1995,
% 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
-% 2007, 2008-2013 Free Software Foundation, Inc.
+% 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
%
% This texinfo.tex file is free software: you can redistribute it and/or
% modify it under the terms of the GNU General Public License as
@@ -24,13 +24,14 @@
%
% As a special exception, when this file is read by TeX when processing
% a Texinfo source document, you may use the result without
-% restriction. (This has been our intent since Texinfo was invented.)
+% restriction. This Exception is an additional permission under section 7
+% of the GNU General Public License, version 3 ("GPLv3").
%
% Please try the latest version of texinfo.tex before submitting bug
% reports; you can get the latest version from:
-% http://www.gnu.org/software/texinfo/ (the Texinfo home page), or
-% ftp://tug.org/tex/texinfo.tex
-% (and all CTAN mirrors, see http://www.ctan.org).
+% http://ftp.gnu.org/gnu/texinfo/ (the Texinfo release area), or
+% http://ftpmirror.gnu.org/texinfo/ (same, via a mirror), or
+% http://www.gnu.org/software/texinfo/ (the Texinfo home page)
% The texinfo.tex in any given distribution could well be out
% of date, so if that's what you're using, please check.
%
@@ -65,7 +66,6 @@
\everyjob{\message{[Texinfo version \texinfoversion]}%
\catcode`+=\active \catcode`\_=\active}
-
\chardef\other=12
% We never want plain's \outer definition of \+ in Texinfo.
@@ -93,11 +93,13 @@
\let\ptexnewwrite\newwrite
\let\ptexnoindent=\noindent
\let\ptexplus=+
+\let\ptexraggedright=\raggedright
\let\ptexrbrace=\}
\let\ptexslash=\/
\let\ptexstar=\*
\let\ptext=\t
\let\ptextop=\top
+{\catcode`\'=\active \global\let\ptexquoteright'}% active in plain's math mode
% If this character appears in an error message or help string, it
% starts a new line in the output.
@@ -115,10 +117,11 @@
% Set up fixed words for English if not already set.
\ifx\putwordAppendix\undefined \gdef\putwordAppendix{Appendix}\fi
\ifx\putwordChapter\undefined \gdef\putwordChapter{Chapter}\fi
+\ifx\putworderror\undefined \gdef\putworderror{error}\fi
\ifx\putwordfile\undefined \gdef\putwordfile{file}\fi
\ifx\putwordin\undefined \gdef\putwordin{in}\fi
-\ifx\putwordIndexIsEmpty\undefined \gdef\putwordIndexIsEmpty{(Index is empty)}\fi
-\ifx\putwordIndexNonexistent\undefined \gdef\putwordIndexNonexistent{(Index is nonexistent)}\fi
+\ifx\putwordIndexIsEmpty\undefined \gdef\putwordIndexIsEmpty{(Index is empty)}\fi
+\ifx\putwordIndexNonexistent\undefined \gdef\putwordIndexNonexistent{(Index is nonexistent)}\fi
\ifx\putwordInfo\undefined \gdef\putwordInfo{Info}\fi
\ifx\putwordInstanceVariableof\undefined \gdef\putwordInstanceVariableof{Instance Variable of}\fi
\ifx\putwordMethodon\undefined \gdef\putwordMethodon{Method on}\fi
@@ -157,15 +160,18 @@
\def\spaceisspace{\catcode`\ =\spacecat}
% sometimes characters are active, so we need control sequences.
+\chardef\ampChar = `\&
\chardef\colonChar = `\:
\chardef\commaChar = `\,
\chardef\dashChar = `\-
\chardef\dotChar = `\.
\chardef\exclamChar= `\!
+\chardef\hashChar = `\#
\chardef\lquoteChar= `\`
\chardef\questChar = `\?
\chardef\rquoteChar= `\'
\chardef\semiChar = `\;
+\chardef\slashChar = `\/
\chardef\underChar = `\_
% Ignore a token.
@@ -196,36 +202,7 @@
% that mark overfull boxes (in case you have decided
% that the text looks ok even though it passes the margin).
%
-\def\finalout{\overfullrule=0pt}
-
-% @| inserts a changebar to the left of the current line. It should
-% surround any changed text. This approach does *not* work if the
-% change spans more than two lines of output. To handle that, we would
-% have adopt a much more difficult approach (putting marks into the main
-% vertical list for the beginning and end of each change).
-%
-\def\|{%
- % \vadjust can only be used in horizontal mode.
- \leavevmode
- %
- % Append this vertical mode material after the current line in the output.
- \vadjust{%
- % We want to insert a rule with the height and depth of the current
- % leading; that is exactly what \strutbox is supposed to record.
- \vskip-\baselineskip
- %
- % \vadjust-items are inserted at the left edge of the type. So
- % the \llap here moves out into the left-hand margin.
- \llap{%
- %
- % For a thicker or thinner bar, change the `1pt'.
- \vrule height\baselineskip width1pt
- %
- % This is the space between the bar and the text.
- \hskip 12pt
- }%
- }%
-}
+\def\finalout{\overfullrule=0pt }
% Sometimes it is convenient to have everything in the transcript file
% and nothing on the terminal. We don't just call \tracingall here,
@@ -243,7 +220,7 @@
\tracingmacros2
\tracingrestores1
\showboxbreadth\maxdimen \showboxdepth\maxdimen
- \ifx\eTeXversion\undefined\else % etex gives us more logging
+ \ifx\eTeXversion\thisisundefined\else % etex gives us more logging
\tracingscantokens1
\tracingifs1
\tracinggroups1
@@ -254,6 +231,13 @@
\errorcontextlines16
}%
+% @errormsg{MSG}. Do the index-like expansions on MSG, but if things
+% aren't perfect, it's not the end of the world, being an error message,
+% after all.
+%
+\def\errormsg{\begingroup \indexnofonts \doerrormsg}
+\def\doerrormsg#1{\errmessage{#1}}
+
% add check for \lastpenalty to plain's definitions. If the last thing
% we did was a \nobreak, we don't want to insert more space.
%
@@ -264,7 +248,6 @@
\def\bigbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\bigskipamount
\removelastskip\penalty-200\bigskip\fi\fi}
-% For @cropmarks command.
% Do @cropmarks to get crop marks.
%
\newif\ifcropmarks
@@ -298,9 +281,9 @@
\toks6=\expandafter{\prevsectiondefs}%
\toks8=\expandafter{\lastcolordefs}%
\mark{%
- \the\toks0 \the\toks2
- \noexpand\or \the\toks4 \the\toks6
- \noexpand\else \the\toks8
+ \the\toks0 \the\toks2 % 0: top marks (\last...)
+ \noexpand\or \the\toks4 \the\toks6 % 1: bottom marks (default, \prev...)
+ \noexpand\else \the\toks8 % 2: color marks
}%
}
% \topmark doesn't work for the very first chapter (after the title
@@ -339,10 +322,13 @@
%
% Do this outside of the \shipout so @code etc. will be expanded in
% the headline as they should be, not taken literally (outputting ''code).
+ \def\commmonheadfootline{\let\hsize=\pagewidth \texinfochars}
+ %
\ifodd\pageno \getoddheadingmarks \else \getevenheadingmarks \fi
- \setbox\headlinebox = \vbox{\let\hsize=\pagewidth \makeheadline}%
+ \global\setbox\headlinebox = \vbox{\commmonheadfootline \makeheadline}%
+ %
\ifodd\pageno \getoddfootingmarks \else \getevenfootingmarks \fi
- \setbox\footlinebox = \vbox{\let\hsize=\pagewidth \makefootline}%
+ \global\setbox\footlinebox = \vbox{\commmonheadfootline \makefootline}%
%
{%
% Have to do this stuff outside the \shipout because we want it to
@@ -355,7 +341,7 @@
% We don't want .vr (or whatever) entries like this:
% \entry{{\tt \indexbackslash }acronym}{32}{\code {\acronym}}
% "\acronym" won't work when it's read back in;
- % it needs to be
+ % it needs to be
% {\code {{\tt \backslashcurfont }acronym}
\shipout\vbox{%
% Do this early so pdf references go to the beginning of the page.
@@ -574,7 +560,7 @@
}
\def\inenvironment#1{%
\ifx#1\empty
- out of any environment%
+ outside of any environment%
\else
in environment \expandafter\string#1%
\fi
@@ -586,7 +572,7 @@
\parseargdef\end{%
\if 1\csname iscond.#1\endcsname
\else
- % The general wording of \badenverr may not be ideal, but... --kasal, 06nov03
+ % The general wording of \badenverr may not be ideal.
\expandafter\checkenv\csname#1\endcsname
\csname E#1\endcsname
\endgroup
@@ -596,85 +582,6 @@
\newhelp\EMsimple{Press RETURN to continue.}
-%% Simple single-character @ commands
-
-% @@ prints an @
-% Kludge this until the fonts are right (grr).
-\def\@{{\tt\char64}}
-
-% This is turned off because it was never documented
-% and you can use @w{...} around a quote to suppress ligatures.
-%% Define @` and @' to be the same as ` and '
-%% but suppressing ligatures.
-%\def\`{{`}}
-%\def\'{{'}}
-
-% Used to generate quoted braces.
-\def\mylbrace {{\tt\char123}}
-\def\myrbrace {{\tt\char125}}
-\let\{=\mylbrace
-\let\}=\myrbrace
-\begingroup
- % Definitions to produce \{ and \} commands for indices,
- % and @{ and @} for the aux/toc files.
- \catcode`\{ = \other \catcode`\} = \other
- \catcode`\[ = 1 \catcode`\] = 2
- \catcode`\! = 0 \catcode`\\ = \other
- !gdef!lbracecmd[\{]%
- !gdef!rbracecmd[\}]%
- !gdef!lbraceatcmd[@{]%
- !gdef!rbraceatcmd[@}]%
-!endgroup
-
-% @comma{} to avoid , parsing problems.
-\let\comma = ,
-
-% Accents: @, @dotaccent @ringaccent @ubaraccent @udotaccent
-% Others are defined by plain TeX: @` @' @" @^ @~ @= @u @v @H.
-\let\, = \c
-\let\dotaccent = \.
-\def\ringaccent#1{{\accent23 #1}}
-\let\tieaccent = \t
-\let\ubaraccent = \b
-\let\udotaccent = \d
-
-% Other special characters: @questiondown @exclamdown @ordf @ordm
-% Plain TeX defines: @AA @AE @O @OE @L (plus lowercase versions) @ss.
-\def\questiondown{?`}
-\def\exclamdown{!`}
-\def\ordf{\leavevmode\raise1ex\hbox{\selectfonts\lllsize \underbar{a}}}
-\def\ordm{\leavevmode\raise1ex\hbox{\selectfonts\lllsize \underbar{o}}}
-
-% Dotless i and dotless j, used for accents.
-\def\imacro{i}
-\def\jmacro{j}
-\def\dotless#1{%
- \def\temp{#1}%
- \ifx\temp\imacro \ifmmode\imath \else\ptexi \fi
- \else\ifx\temp\jmacro \ifmmode\jmath \else\j \fi
- \else \errmessage{@dotless can be used only with i or j}%
- \fi\fi
-}
-
-% The \TeX{} logo, as in plain, but resetting the spacing so that a
-% period following counts as ending a sentence. (Idea found in latex.)
-%
-\edef\TeX{\TeX \spacefactor=1000 }
-
-% @LaTeX{} logo. Not quite the same results as the definition in
-% latex.ltx, since we use a different font for the raised A; it's most
-% convenient for us to use an explicitly smaller font, rather than using
-% the \scriptstyle font (since we don't reset \scriptstyle and
-% \scriptscriptstyle).
-%
-\def\LaTeX{%
- L\kern-.36em
- {\setbox0=\hbox{T}%
- \vbox to \ht0{\hbox{\selectfonts\lllsize A}\vss}}%
- \kern-.15em
- \TeX
-}
-
% Be sure we're in horizontal mode when doing a tie, since we make space
% equivalent to this in @example-like environments. Otherwise, a space
% at the beginning of a line will start with \penalty -- and
@@ -691,7 +598,7 @@
\def\:{\spacefactor=1000 }
% @* forces a line break.
-\def\*{\hfil\break\hbox{}\ignorespaces}
+\def\*{\unskip\hfil\break\hbox{}\ignorespaces}
% @/ allows a line break.
\let\/=\allowbreak
@@ -706,7 +613,7 @@
\def\?{?\spacefactor=\endofsentencespacefactor\space}
% @frenchspacing on|off says whether to put extra space after punctuation.
-%
+%
\def\onword{on}
\def\offword{off}
%
@@ -716,7 +623,7 @@
\else\ifx\temp\offword \plainnonfrenchspacing
\else
\errhelp = \EMsimple
- \errmessage{Unknown @frenchspacing option `\temp', must be on/off}%
+ \errmessage{Unknown @frenchspacing option `\temp', must be on|off}%
\fi\fi
}
@@ -798,15 +705,6 @@ where each line of input produces a line of output.}
\newdimen\mil \mil=0.001in
-% Old definition--didn't work.
-%\parseargdef\need{\par %
-%% This method tries to make TeX break the page naturally
-%% if the depth of the box does not fit.
-%{\baselineskip=0pt%
-%\vtop to #1\mil{\vfil}\kern -#1\mil\nobreak
-%\prevdepth=-1000pt
-%}}
-
\parseargdef\need{%
% Ensure vertical mode, so we don't make a big box in the middle of a
% paragraph.
@@ -870,7 +768,7 @@ where each line of input produces a line of output.}
% @inmargin{WHICH}{TEXT} puts TEXT in the WHICH margin next to the current
% paragraph. For more general purposes, use the \margin insertion
-% class. WHICH is `l' or `r'.
+% class. WHICH is `l' or `r'. Not documented, written for gawk manual.
%
\newskip\inmarginspacing \inmarginspacing=1cm
\def\strutdepth{\dp\strutbox}
@@ -917,6 +815,36 @@ where each line of input produces a line of output.}
\temp
}
+% @| inserts a changebar to the left of the current line. It should
+% surround any changed text. This approach does *not* work if the
+% change spans more than two lines of output. To handle that, we would
+% have adopt a much more difficult approach (putting marks into the main
+% vertical list for the beginning and end of each change). This command
+% is not documented, not supported, and doesn't work.
+%
+\def\|{%
+ % \vadjust can only be used in horizontal mode.
+ \leavevmode
+ %
+ % Append this vertical mode material after the current line in the output.
+ \vadjust{%
+ % We want to insert a rule with the height and depth of the current
+ % leading; that is exactly what \strutbox is supposed to record.
+ \vskip-\baselineskip
+ %
+ % \vadjust-items are inserted at the left edge of the type. So
+ % the \llap here moves out into the left-hand margin.
+ \llap{%
+ %
+ % For a thicker or thinner bar, change the `1pt'.
+ \vrule height\baselineskip width1pt
+ %
+ % This is the space between the bar and the text.
+ \hskip 12pt
+ }%
+ }%
+}
+
% @include FILE -- \input text of FILE.
%
\def\include{\parseargusing\filenamecatcodes\includezzz}
@@ -926,6 +854,8 @@ where each line of input produces a line of output.}
{%
\makevalueexpandable % we want to expand any @value in FILE.
\turnoffactive % and allow special characters in the expansion
+ \indexnofonts % Allow `@@' and other weird things in file names.
+ \wlog{texinfo.tex: doing @include of #1^^J}%
\edef\temp{\noexpand\input #1 }%
%
% This trickery is to read FILE outside of a group, in case it makes
@@ -944,6 +874,8 @@ where each line of input produces a line of output.}
\catcode`>=\other
\catcode`+=\other
\catcode`-=\other
+ \catcode`\`=\other
+ \catcode`\'=\other
}
\def\pushthisfilestack{%
@@ -959,7 +891,7 @@ where each line of input produces a line of output.}
\def\popthisfilestack{\errthisfilestackempty}
\def\errthisfilestackempty{\errmessage{Internal error:
the stack of filenames is empty.}}
-
+%
\def\thisfile{}
% @center line
@@ -967,36 +899,46 @@ where each line of input produces a line of output.}
%
\parseargdef\center{%
\ifhmode
- \let\next\centerH
+ \let\centersub\centerH
\else
- \let\next\centerV
+ \let\centersub\centerV
\fi
- \next{\hfil \ignorespaces#1\unskip \hfil}%
+ \centersub{\hfil \ignorespaces#1\unskip \hfil}%
+ \let\centersub\relax % don't let the definition persist, just in case
}
-\def\centerH#1{%
- {%
- \hfil\break
- \advance\hsize by -\leftskip
- \advance\hsize by -\rightskip
- \line{#1}%
- \break
- }%
+\def\centerH#1{{%
+ \hfil\break
+ \advance\hsize by -\leftskip
+ \advance\hsize by -\rightskip
+ \line{#1}%
+ \break
+}}
+%
+\newcount\centerpenalty
+\def\centerV#1{%
+ % The idea here is the same as in \startdefun, \cartouche, etc.: if
+ % @center is the first thing after a section heading, we need to wipe
+ % out the negative parskip inserted by \sectionheading, but still
+ % prevent a page break here.
+ \centerpenalty = \lastpenalty
+ \ifnum\centerpenalty>10000 \vskip\parskip \fi
+ \ifnum\centerpenalty>9999 \penalty\centerpenalty \fi
+ \line{\kern\leftskip #1\kern\rightskip}%
}
-\def\centerV#1{\line{\kern\leftskip #1\kern\rightskip}}
% @sp n outputs n lines of vertical space
-
+%
\parseargdef\sp{\vskip #1\baselineskip}
% @comment ...line which is ignored...
% @c is the same as @comment
% @ignore ... @end ignore is another way to write a comment
-
+%
\def\comment{\begingroup \catcode`\^^M=\other%
\catcode`\@=\other \catcode`\{=\other \catcode`\}=\other%
\commentxxx}
{\catcode`\^^M=\other \gdef\commentxxx#1^^M{\endgroup}}
-
+%
\let\c=\comment
% @paragraphindent NCHARS
@@ -1089,107 +1031,6 @@ where each line of input produces a line of output.}
}
-% @asis just yields its argument. Used with @table, for example.
-%
-\def\asis#1{#1}
-
-% @math outputs its argument in math mode.
-%
-% One complication: _ usually means subscripts, but it could also mean
-% an actual _ character, as in @math{@var{some_variable} + 1}. So make
-% _ active, and distinguish by seeing if the current family is \slfam,
-% which is what @var uses.
-{
- \catcode`\_ = \active
- \gdef\mathunderscore{%
- \catcode`\_=\active
- \def_{\ifnum\fam=\slfam \_\else\sb\fi}%
- }
-}
-% Another complication: we want \\ (and @\) to output a \ character.
-% FYI, plain.tex uses \\ as a temporary control sequence (why?), but
-% this is not advertised and we don't care. Texinfo does not
-% otherwise define @\.
-%
-% The \mathchar is class=0=ordinary, family=7=ttfam, position=5C=\.
-\def\mathbackslash{\ifnum\fam=\ttfam \mathchar"075C \else\backslash \fi}
-%
-\def\math{%
- \tex
- \mathunderscore
- \let\\ = \mathbackslash
- \mathactive
- % make the texinfo accent commands work in math mode
- \let\"=\ddot
- \let\'=\acute
- \let\==\bar
- \let\^=\hat
- \let\`=\grave
- \let\u=\breve
- \let\v=\check
- \let\~=\tilde
- \let\dotaccent=\dot
- $\finishmath
-}
-\def\finishmath#1{#1$\endgroup} % Close the group opened by \tex.
-
-% Some active characters (such as <) are spaced differently in math.
-% We have to reset their definitions in case the @math was an argument
-% to a command which sets the catcodes (such as @item or @section).
-%
-{
- \catcode`^ = \active
- \catcode`< = \active
- \catcode`> = \active
- \catcode`+ = \active
- \gdef\mathactive{%
- \let^ = \ptexhat
- \let< = \ptexless
- \let> = \ptexgtr
- \let+ = \ptexplus
- }
-}
-
-% Some math mode symbols.
-\def\bullet{$\ptexbullet$}
-\def\geq{\ifmmode \ge\else $\ge$\fi}
-\def\leq{\ifmmode \le\else $\le$\fi}
-\def\minus{\ifmmode -\else $-$\fi}
-
-% @dots{} outputs an ellipsis using the current font.
-% We do .5em per period so that it has the same spacing in the cm
-% typewriter fonts as three actual period characters; on the other hand,
-% in other typewriter fonts three periods are wider than 1.5em. So do
-% whichever is larger.
-%
-\def\dots{%
- \leavevmode
- \setbox0=\hbox{...}% get width of three periods
- \ifdim\wd0 > 1.5em
- \dimen0 = \wd0
- \else
- \dimen0 = 1.5em
- \fi
- \hbox to \dimen0{%
- \hskip 0pt plus.25fil
- .\hskip 0pt plus1fil
- .\hskip 0pt plus1fil
- .\hskip 0pt plus.5fil
- }%
-}
-
-% @enddots{} is an end-of-sentence ellipsis.
-%
-\def\enddots{%
- \dots
- \spacefactor=\endofsentencespacefactor
-}
-
-% @comma{} is so commas can be inserted into text without messing up
-% Texinfo's parsing.
-%
-\let\comma = ,
-
% @refill is a no-op.
\let\refill=\relax
@@ -1254,9 +1095,8 @@ where each line of input produces a line of output.}
\newif\ifpdfmakepagedest
% when pdftex is run in dvi mode, \pdfoutput is defined (so \pdfoutput=1
-% can be set). So we test for \relax and 0 as well as \undefined,
-% borrowed from ifpdf.sty.
-\ifx\pdfoutput\undefined
+% can be set). So we test for \relax and 0 as well as being undefined.
+\ifx\pdfoutput\thisisundefined
\else
\ifx\pdfoutput\relax
\else
@@ -1271,50 +1111,24 @@ where each line of input produces a line of output.}
% for display in the outlines, and in other places. Thus, we have to
% double any backslashes. Otherwise, a name like "\node" will be
% interpreted as a newline (\n), followed by o, d, e. Not good.
-% http://www.ntg.nl/pipermail/ntg-pdftex/2004-July/000654.html
-% (and related messages, the final outcome is that it is up to the TeX
-% user to double the backslashes and otherwise make the string valid, so
-% that's what we do).
-
-% double active backslashes.
-%
-{\catcode`\@=0 \catcode`\\=\active
- @gdef@activebackslashdouble{%
- @catcode`@\=@active
- @let\=@doublebackslash}
-}
-
-% To handle parens, we must adopt a different approach, since parens are
-% not active characters. hyperref.dtx (which has the same problem as
-% us) handles it with this amazing macro to replace tokens, with minor
-% changes for Texinfo. It is included here under the GPL by permission
-% from the author, Heiko Oberdiek.
-%
-% #1 is the tokens to replace.
-% #2 is the replacement.
-% #3 is the control sequence with the string.
-%
-\def\HyPsdSubst#1#2#3{%
- \def\HyPsdReplace##1#1##2\END{%
- ##1%
- \ifx\\##2\\%
- \else
- #2%
- \HyReturnAfterFi{%
- \HyPsdReplace##2\END
- }%
- \fi
- }%
- \xdef#3{\expandafter\HyPsdReplace#3#1\END}%
-}
-\long\def\HyReturnAfterFi#1\fi{\fi#1}
-
-% #1 is a control sequence in which to do the replacements.
-\def\backslashparens#1{%
- \xdef#1{#1}% redefine it as its expansion; the definition is simply
- % \lastnode when called from \setref -> \pdfmkdest.
- \HyPsdSubst{(}{\realbackslash(}{#1}%
- \HyPsdSubst{)}{\realbackslash)}{#1}%
+%
+% See http://www.ntg.nl/pipermail/ntg-pdftex/2004-July/000654.html and
+% related messages. The final outcome is that it is up to the TeX user
+% to double the backslashes and otherwise make the string valid, so
+% that's what we do. pdftex 1.30.0 (ca.2005) introduced a primitive to
+% do this reliably, so we use it.
+
+% #1 is a control sequence in which to do the replacements,
+% which we \xdef.
+\def\txiescapepdf#1{%
+ \ifx\pdfescapestring\thisisundefined
+ % No primitive available; should we give a warning or log?
+ % Many times it won't matter.
+ \else
+ % The expandable \pdfescapestring primitive escapes parentheses,
+ % backslashes, and other special chars.
+ \xdef#1{\pdfescapestring{#1}}%
+ \fi
}
\newhelp\nopdfimagehelp{Texinfo supports .png, .jpg, .jpeg, and .pdf images
@@ -1324,11 +1138,17 @@ output) for that.)}
\ifpdf
%
- % Color manipulation macros based on pdfcolor.tex.
- \def\cmykDarkRed{0.28 1 1 0.35}
- \def\cmykBlack{0 0 0 1}
+ % Color manipulation macros based on pdfcolor.tex,
+ % except using rgb instead of cmyk; the latter is said to render as a
+ % very dark gray on-screen and a very dark halftone in print, instead
+ % of actual black.
+ \def\rgbDarkRed{0.50 0.09 0.12}
+ \def\rgbBlack{0 0 0}
+ %
+ % k sets the color for filling (usual text, etc.);
+ % K sets the color for stroking (thin rules, e.g., normal _'s).
+ \def\pdfsetcolor#1{\pdfliteral{#1 rg #1 RG}}
%
- \def\pdfsetcolor#1{\pdfliteral{#1 k}}
% Set color, and create a mark which defines \thiscolor accordingly,
% so that \makeheadline knows which color to restore.
\def\setcolor#1{%
@@ -1337,7 +1157,7 @@ output) for that.)}
\pdfsetcolor{#1}%
}
%
- \def\maincolor{\cmykBlack}
+ \def\maincolor{\rgbBlack}
\pdfsetcolor{\maincolor}
\edef\thiscolor{\maincolor}
\def\lastcolordefs{}
@@ -1367,32 +1187,34 @@ output) for that.)}
%
% #1 is image name, #2 width (might be empty/whitespace), #3 height (ditto).
\def\dopdfimage#1#2#3{%
- \def\imagewidth{#2}\setbox0 = \hbox{\ignorespaces #2}%
- \def\imageheight{#3}\setbox2 = \hbox{\ignorespaces #3}%
+ \def\pdfimagewidth{#2}\setbox0 = \hbox{\ignorespaces #2}%
+ \def\pdfimageheight{#3}\setbox2 = \hbox{\ignorespaces #3}%
%
- % pdftex (and the PDF format) support .png, .jpg, .pdf (among
- % others). Let's try in that order.
+ % pdftex (and the PDF format) support .pdf, .png, .jpg (among
+ % others). Let's try in that order, PDF first since if
+ % someone has a scalable image, presumably better to use that than a
+ % bitmap.
\let\pdfimgext=\empty
\begingroup
- \openin 1 #1.png \ifeof 1
- \openin 1 #1.jpg \ifeof 1
- \openin 1 #1.jpeg \ifeof 1
- \openin 1 #1.JPG \ifeof 1
- \openin 1 #1.pdf \ifeof 1
- \openin 1 #1.PDF \ifeof 1
+ \openin 1 #1.pdf \ifeof 1
+ \openin 1 #1.PDF \ifeof 1
+ \openin 1 #1.png \ifeof 1
+ \openin 1 #1.jpg \ifeof 1
+ \openin 1 #1.jpeg \ifeof 1
+ \openin 1 #1.JPG \ifeof 1
\errhelp = \nopdfimagehelp
\errmessage{Could not find image file #1 for pdf}%
- \else \gdef\pdfimgext{PDF}%
+ \else \gdef\pdfimgext{JPG}%
\fi
- \else \gdef\pdfimgext{pdf}%
+ \else \gdef\pdfimgext{jpeg}%
\fi
- \else \gdef\pdfimgext{JPG}%
+ \else \gdef\pdfimgext{jpg}%
\fi
- \else \gdef\pdfimgext{jpeg}%
+ \else \gdef\pdfimgext{png}%
\fi
- \else \gdef\pdfimgext{jpg}%
+ \else \gdef\pdfimgext{PDF}%
\fi
- \else \gdef\pdfimgext{png}%
+ \else \gdef\pdfimgext{pdf}%
\fi
\closein 1
\endgroup
@@ -1404,8 +1226,8 @@ output) for that.)}
\else
\immediate\pdfximage
\fi
- \ifdim \wd0 >0pt width \imagewidth \fi
- \ifdim \wd2 >0pt height \imageheight \fi
+ \ifdim \wd0 >0pt width \pdfimagewidth \fi
+ \ifdim \wd2 >0pt height \pdfimageheight \fi
\ifnum\pdftexversion<13
#1.\pdfimgext
\else
@@ -1420,10 +1242,9 @@ output) for that.)}
% such as \, aren't expanded when present in a section title.
\indexnofonts
\turnoffactive
- \activebackslashdouble
\makevalueexpandable
\def\pdfdestname{#1}%
- \backslashparens\pdfdestname
+ \txiescapepdf\pdfdestname
\safewhatsit{\pdfdest name{\pdfdestname} xyz}%
}}
%
@@ -1432,8 +1253,8 @@ output) for that.)}
%
% by default, use a color that is dark enough to print on paper as
% nearly black, but still distinguishable for online viewing.
- \def\urlcolor{\cmykDarkRed}
- \def\linkcolor{\cmykDarkRed}
+ \def\urlcolor{\rgbDarkRed}
+ \def\linkcolor{\rgbDarkRed}
\def\endlink{\setcolor{\maincolor}\pdfendlink}
%
% Adding outlines to PDF; macros for calculating structure of outlines
@@ -1455,29 +1276,24 @@ output) for that.)}
% page number. We could generate a destination for the section
% text in the case where a section has no node, but it doesn't
% seem worth the trouble, since most documents are normally structured.
- \def\pdfoutlinedest{#3}%
+ \edef\pdfoutlinedest{#3}%
\ifx\pdfoutlinedest\empty
\def\pdfoutlinedest{#4}%
\else
- % Doubled backslashes in the name.
- {\activebackslashdouble \xdef\pdfoutlinedest{#3}%
- \backslashparens\pdfoutlinedest}%
+ \txiescapepdf\pdfoutlinedest
\fi
%
- % Also double the backslashes in the display string.
- {\activebackslashdouble \xdef\pdfoutlinetext{#1}%
- \backslashparens\pdfoutlinetext}%
+ % Also escape PDF chars in the display string.
+ \edef\pdfoutlinetext{#1}%
+ \txiescapepdf\pdfoutlinetext
%
\pdfoutline goto name{\pdfmkpgn{\pdfoutlinedest}}#2{\pdfoutlinetext}%
}
%
\def\pdfmakeoutlines{%
\begingroup
- % Thanh's hack / proper braces in bookmarks
- \edef\mylbrace{\iftrue \string{\else}\fi}\let\{=\mylbrace
- \edef\myrbrace{\iffalse{\else\string}\fi}\let\}=\myrbrace
- %
% Read toc silently, to get counts of subentries for \pdfoutline.
+ \def\partentry##1##2##3##4{}% ignore parts in the outlines
\def\numchapentry##1##2##3##4{%
\def\thischapnum{##2}%
\def\thissecnum{0}%
@@ -1531,25 +1347,41 @@ output) for that.)}
% Latin 2 (0xea) gets translated to a | character. Info from
% Staszek Wawrykiewicz, 19 Jan 2004 04:09:24 +0100.
%
- % xx to do this right, we have to translate 8-bit characters to
- % their "best" equivalent, based on the @documentencoding. Right
- % now, I guess we'll just let the pdf reader have its way.
+ % TODO this right, we have to translate 8-bit characters to
+ % their "best" equivalent, based on the @documentencoding. Too
+ % much work for too little return. Just use the ASCII equivalents
+ % we use for the index sort strings.
+ %
\indexnofonts
\setupdatafile
+ % We can have normal brace characters in the PDF outlines, unlike
+ % Texinfo index files. So set that up.
+ \def\{{\lbracecharliteral}%
+ \def\}{\rbracecharliteral}%
\catcode`\\=\active \otherbackslash
\input \tocreadfilename
\endgroup
}
+ {\catcode`[=1 \catcode`]=2
+ \catcode`{=\other \catcode`}=\other
+ \gdef\lbracecharliteral[{]%
+ \gdef\rbracecharliteral[}]%
+ ]
%
\def\skipspaces#1{\def\PP{#1}\def\D{|}%
\ifx\PP\D\let\nextsp\relax
\else\let\nextsp\skipspaces
- \ifx\p\space\else\addtokens{\filename}{\PP}%
- \advance\filenamelength by 1
- \fi
+ \addtokens{\filename}{\PP}%
+ \advance\filenamelength by 1
\fi
\nextsp}
- \def\getfilename#1{\filenamelength=0\expandafter\skipspaces#1|\relax}
+ \def\getfilename#1{%
+ \filenamelength=0
+ % If we don't expand the argument now, \skipspaces will get
+ % snagged on things like "@value{foo}".
+ \edef\temp{#1}%
+ \expandafter\skipspaces\temp|\relax
+ }
\ifnum\pdftexversion < 14
\let \startlink \pdfannotlink
\else
@@ -1562,11 +1394,15 @@ output) for that.)}
% tried to figure out what each command should do in the context
% of @url. for now, just make @/ a no-op, that's the only one
% people have actually reported a problem with.
- %
+ %
\normalturnoffactive
\def\@{@}%
\let\/=\empty
\makevalueexpandable
+ % do we want to go so far as to use \indexnofonts instead of just
+ % special-casing \var here?
+ \def\var##1{##1}%
+ %
\leavevmode\setcolor{\urlcolor}%
\startlink attr{/Border [0 0 0]}%
user{/Subtype /Link /A << /S /URI /URI (#1) >>}%
@@ -1597,6 +1433,7 @@ output) for that.)}
\setcolor{\linkcolor}#1\endlink}
\def\done{\edef\st{\global\noexpand\toksA={\the\toksB}}\st}
\else
+ % non-pdf mode
\let\pdfmkdest = \gobble
\let\pdfurl = \gobble
\let\endlink = \relax
@@ -1627,6 +1464,10 @@ output) for that.)}
\def\bf{\fam=\bffam \setfontstyle{bf}}\def\bfstylename{bf}
\def\tt{\fam=\ttfam \setfontstyle{tt}}
+% Unfortunately, we have to override this for titles and the like, since
+% in those cases "rm" is bold. Sigh.
+\def\rmisbold{\rm\def\curfontstyle{bf}}
+
% Texinfo sort of supports the sans serif font style, which plain TeX does not.
% So we set up a \sf.
\newfam\sffam
@@ -1637,9 +1478,6 @@ output) for that.)}
\def\ttsl{\setfontstyle{ttsl}}
-% Default leading.
-\newdimen\textleading \textleading = 13.2pt
-
% Set the baselineskip to #1, and the lineskip and strut size
% correspondingly. There is no deep meaning behind these magic numbers
% used as factors; they just match (closely enough) what Knuth defined.
@@ -1651,6 +1489,7 @@ output) for that.)}
% can get a sort of poor man's double spacing by redefining this.
\def\baselinefactor{1}
%
+\newdimen\textleading
\def\setleading#1{%
\dimen0 = #1\relax
\normalbaselineskip = \baselinefactor\dimen0
@@ -1672,7 +1511,7 @@ output) for that.)}
% if we are producing pdf, and we have \pdffontattr, then define cmaps.
% (\pdffontattr was introduced many years ago, but people still run
% older pdftex's; it's easy to conditionalize, so we do.)
-\ifpdf \ifx\pdffontattr\undefined \else
+\ifpdf \ifx\pdffontattr\thisisundefined \else
\begingroup
\catcode`\^^M=\active \def^^M{^^J}% Output line endings as the ^^J char.
\catcode`\%=12 \immediate\pdfobj stream {%!PS-Adobe-3.0 Resource-CMap
@@ -1923,28 +1762,34 @@ end
\fi\fi
-% Set the font macro #1 to the font named #2, adding on the
-% specified font prefix (normally `cm').
+% Set the font macro #1 to the font named \fontprefix#2.
% #3 is the font's design size, #4 is a scale factor, #5 is the CMap
-% encoding (currently only OT1, OT1IT and OT1TT are allowed, pass
-% empty to omit).
+% encoding (only OT1, OT1IT and OT1TT are allowed, or empty to omit).
+% Example:
+% #1 = \textrm
+% #2 = \rmshape
+% #3 = 10
+% #4 = \mainmagstep
+% #5 = OT1
+%
\def\setfont#1#2#3#4#5{%
\font#1=\fontprefix#2#3 scaled #4
\csname cmap#5\endcsname#1%
}
% This is what gets called when #5 of \setfont is empty.
\let\cmap\gobble
-% emacs-page end of cmaps
+%
+% (end of cmaps)
% Use cm as the default font prefix.
% To specify the font prefix, you must define \fontprefix
% before you read in texinfo.tex.
-\ifx\fontprefix\undefined
+\ifx\fontprefix\thisisundefined
\def\fontprefix{cm}
\fi
% Support font families that don't use the same naming scheme as CM.
\def\rmshape{r}
-\def\rmbshape{bx} %where the normal face is bold
+\def\rmbshape{bx} % where the normal face is bold
\def\bfshape{b}
\def\bxshape{bx}
\def\ttshape{tt}
@@ -1959,9 +1804,8 @@ end
\def\scshape{csc}
\def\scbshape{csc}
-% Definitions for a main text size of 11pt. This is the default in
-% Texinfo.
-%
+% Definitions for a main text size of 11pt. (The default in Texinfo.)
+%
\def\definetextfontsizexi{%
% Text fonts (11.2pt, magstep1).
\def\textnominalsize{11pt}
@@ -2024,8 +1868,6 @@ end
\setfont\titlesc\scbshape{10}{\magstep4}{OT1}
\font\titlei=cmmi12 scaled \magstep3
\font\titlesy=cmsy10 scaled \magstep4
-\def\authorrm{\secrm}
-\def\authortt{\sectt}
\def\titleecsize{2074}
% Chapter (and unnumbered) fonts (17.28pt).
@@ -2084,17 +1926,17 @@ end
\font\reducedsy=cmsy10
\def\reducedecsize{1000}
-% reset the current fonts
-\textfonts
+\textleading = 13.2pt % line spacing for 11pt CM
+\textfonts % reset the current fonts
\rm
-} % end of 11pt text font size definitions
+} % end of 11pt text font size definitions, \definetextfontsizexi
% Definitions to make the main text be 10pt Computer Modern, with
% section, chapter, etc., sizes following suit. This is for the GNU
% Press printing of the Emacs 22 manual. Maybe other manuals in the
% future. Used with @smallbook, which sets the leading to 12pt.
-%
+%
\def\definetextfontsizex{%
% Text fonts (10pt).
\def\textnominalsize{10pt}
@@ -2157,8 +1999,6 @@ end
\setfont\titlesc\scbshape{10}{\magstep4}{OT1}
\font\titlei=cmmi12 scaled \magstep3
\font\titlesy=cmsy10 scaled \magstep4
-\def\authorrm{\secrm}
-\def\authortt{\sectt}
\def\titleecsize{2074}
% Chapter fonts (14.4pt).
@@ -2185,7 +2025,7 @@ end
\setfont\secsf\sfbshape{12}{1000}{OT1}
\let\secbf\secrm
\setfont\secsc\scbshape{10}{\magstep1}{OT1}
-\font\seci=cmmi12
+\font\seci=cmmi12
\font\secsy=cmsy10 scaled \magstep1
\def\sececsize{1200}
@@ -2217,29 +2057,28 @@ end
\font\reducedsy=cmsy9
\def\reducedecsize{0900}
-% reduce space between paragraphs
-\divide\parskip by 2
-
-% reset the current fonts
-\textfonts
+\divide\parskip by 2 % reduce space between paragraphs
+\textleading = 12pt % line spacing for 10pt CM
+\textfonts % reset the current fonts
\rm
-} % end of 10pt text font size definitions
+} % end of 10pt text font size definitions, \definetextfontsizex
% We provide the user-level command
% @fonttextsize 10
% (or 11) to redefine the text font size. pt is assumed.
-%
-\def\xword{10}
+%
\def\xiword{11}
+\def\xword{10}
+\def\xwordpt{10pt}
%
\parseargdef\fonttextsize{%
\def\textsizearg{#1}%
- \wlog{doing @fonttextsize \textsizearg}%
+ %\wlog{doing @fonttextsize \textsizearg}%
%
% Set \globaldefs so that documents can use this inside @tex, since
% makeinfo 4.8 does not support it, but we need it nonetheless.
- %
+ %
\begingroup \globaldefs=1
\ifx\textsizearg\xword \definetextfontsizex
\else \ifx\textsizearg\xiword \definetextfontsizexi
@@ -2289,8 +2128,8 @@ end
\let\tenttsl=\titlettsl
\def\curfontsize{title}%
\def\lsize{chap}\def\lllsize{subsec}%
- \resetmathfonts \setleading{25pt}}
-\def\titlefont#1{{\titlefonts\rm #1}}
+ \resetmathfonts \setleading{27pt}}
+\def\titlefont#1{{\titlefonts\rmisbold #1}}
\def\chapfonts{%
\let\tenrm=\chaprm \let\tenit=\chapit \let\tensl=\chapsl
\let\tenbf=\chapbf \let\tentt=\chaptt \let\smallcaps=\chapsc
@@ -2341,6 +2180,16 @@ end
\def\lsize{smaller}\def\lllsize{smaller}%
\resetmathfonts \setleading{9.5pt}}
+% Fonts for short table of contents.
+\setfont\shortcontrm\rmshape{12}{1000}{OT1}
+\setfont\shortcontbf\bfshape{10}{\magstep1}{OT1} % no cmb12
+\setfont\shortcontsl\slshape{12}{1000}{OT1}
+\setfont\shortconttt\ttshape{12}{1000}{OT1TT}
+
+% Define these just so they can be easily changed for other fonts.
+\def\angleleft{$\langle$}
+\def\angleright{$\rangle$}
+
% Set the fonts to use with the @small... environments.
\let\smallexamplefonts = \smallfonts
@@ -2354,53 +2203,215 @@ end
%
% By the way, for comparison, here's what fits with @example (10pt):
% 8.5x11=71 smallbook=60 a4=75 a5=58
-%
-% I wish the USA used A4 paper.
% --karl, 24jan03.
-
% Set up the default fonts, so we can use them for creating boxes.
%
\definetextfontsizexi
-% Define these so they can be easily changed for other fonts.
-\def\angleleft{$\langle$}
-\def\angleright{$\rangle$}
+
+\message{markup,}
+
+% Check if we are currently using a typewriter font. Since all the
+% Computer Modern typewriter fonts have zero interword stretch (and
+% shrink), and it is reasonable to expect all typewriter fonts to have
+% this property, we can check that font parameter.
+%
+\def\ifmonospace{\ifdim\fontdimen3\font=0pt }
+
+% Markup style infrastructure. \defmarkupstylesetup\INITMACRO will
+% define and register \INITMACRO to be called on markup style changes.
+% \INITMACRO can check \currentmarkupstyle for the innermost
+% style and the set of \ifmarkupSTYLE switches for all styles
+% currently in effect.
+\newif\ifmarkupvar
+\newif\ifmarkupsamp
+\newif\ifmarkupkey
+%\newif\ifmarkupfile % @file == @samp.
+%\newif\ifmarkupoption % @option == @samp.
+\newif\ifmarkupcode
+\newif\ifmarkupkbd
+%\newif\ifmarkupenv % @env == @code.
+%\newif\ifmarkupcommand % @command == @code.
+\newif\ifmarkuptex % @tex (and part of @math, for now).
+\newif\ifmarkupexample
+\newif\ifmarkupverb
+\newif\ifmarkupverbatim
+
+\let\currentmarkupstyle\empty
+
+\def\setupmarkupstyle#1{%
+ \csname markup#1true\endcsname
+ \def\currentmarkupstyle{#1}%
+ \markupstylesetup
+}
+
+\let\markupstylesetup\empty
+
+\def\defmarkupstylesetup#1{%
+ \expandafter\def\expandafter\markupstylesetup
+ \expandafter{\markupstylesetup #1}%
+ \def#1%
+}
+
+% Markup style setup for left and right quotes.
+\defmarkupstylesetup\markupsetuplq{%
+ \expandafter\let\expandafter \temp
+ \csname markupsetuplq\currentmarkupstyle\endcsname
+ \ifx\temp\relax \markupsetuplqdefault \else \temp \fi
+}
+
+\defmarkupstylesetup\markupsetuprq{%
+ \expandafter\let\expandafter \temp
+ \csname markupsetuprq\currentmarkupstyle\endcsname
+ \ifx\temp\relax \markupsetuprqdefault \else \temp \fi
+}
+
+{
+\catcode`\'=\active
+\catcode`\`=\active
+
+\gdef\markupsetuplqdefault{\let`\lq}
+\gdef\markupsetuprqdefault{\let'\rq}
+
+\gdef\markupsetcodequoteleft{\let`\codequoteleft}
+\gdef\markupsetcodequoteright{\let'\codequoteright}
+}
+
+\let\markupsetuplqcode \markupsetcodequoteleft
+\let\markupsetuprqcode \markupsetcodequoteright
+%
+\let\markupsetuplqexample \markupsetcodequoteleft
+\let\markupsetuprqexample \markupsetcodequoteright
+%
+\let\markupsetuplqkbd \markupsetcodequoteleft
+\let\markupsetuprqkbd \markupsetcodequoteright
+%
+\let\markupsetuplqsamp \markupsetcodequoteleft
+\let\markupsetuprqsamp \markupsetcodequoteright
+%
+\let\markupsetuplqverb \markupsetcodequoteleft
+\let\markupsetuprqverb \markupsetcodequoteright
+%
+\let\markupsetuplqverbatim \markupsetcodequoteleft
+\let\markupsetuprqverbatim \markupsetcodequoteright
+
+% Allow an option to not use regular directed right quote/apostrophe
+% (char 0x27), but instead the undirected quote from cmtt (char 0x0d).
+% The undirected quote is ugly, so don't make it the default, but it
+% works for pasting with more pdf viewers (at least evince), the
+% lilypond developers report. xpdf does work with the regular 0x27.
+%
+\def\codequoteright{%
+ \expandafter\ifx\csname SETtxicodequoteundirected\endcsname\relax
+ \expandafter\ifx\csname SETcodequoteundirected\endcsname\relax
+ '%
+ \else \char'15 \fi
+ \else \char'15 \fi
+}
+%
+% and a similar option for the left quote char vs. a grave accent.
+% Modern fonts display ASCII 0x60 as a grave accent, so some people like
+% the code environments to do likewise.
+%
+\def\codequoteleft{%
+ \expandafter\ifx\csname SETtxicodequotebacktick\endcsname\relax
+ \expandafter\ifx\csname SETcodequotebacktick\endcsname\relax
+ % [Knuth] pp. 380,381,391
+ % \relax disables Spanish ligatures ?` and !` of \tt font.
+ \relax`%
+ \else \char'22 \fi
+ \else \char'22 \fi
+}
+
+% Commands to set the quote options.
+%
+\parseargdef\codequoteundirected{%
+ \def\temp{#1}%
+ \ifx\temp\onword
+ \expandafter\let\csname SETtxicodequoteundirected\endcsname
+ = t%
+ \else\ifx\temp\offword
+ \expandafter\let\csname SETtxicodequoteundirected\endcsname
+ = \relax
+ \else
+ \errhelp = \EMsimple
+ \errmessage{Unknown @codequoteundirected value `\temp', must be on|off}%
+ \fi\fi
+}
+%
+\parseargdef\codequotebacktick{%
+ \def\temp{#1}%
+ \ifx\temp\onword
+ \expandafter\let\csname SETtxicodequotebacktick\endcsname
+ = t%
+ \else\ifx\temp\offword
+ \expandafter\let\csname SETtxicodequotebacktick\endcsname
+ = \relax
+ \else
+ \errhelp = \EMsimple
+ \errmessage{Unknown @codequotebacktick value `\temp', must be on|off}%
+ \fi\fi
+}
+
+% [Knuth] pp. 380,381,391, disable Spanish ligatures ?` and !` of \tt font.
+\def\noligaturesquoteleft{\relax\lq}
% Count depth in font-changes, for error checks
\newcount\fontdepth \fontdepth=0
-% Fonts for short table of contents.
-\setfont\shortcontrm\rmshape{12}{1000}{OT1}
-\setfont\shortcontbf\bfshape{10}{\magstep1}{OT1} % no cmb12
-\setfont\shortcontsl\slshape{12}{1000}{OT1}
-\setfont\shortconttt\ttshape{12}{1000}{OT1TT}
+% Font commands.
-%% Add scribe-like font environments, plus @l for inline lisp (usually sans
-%% serif) and @ii for TeX italic
+% #1 is the font command (\sl or \it), #2 is the text to slant.
+% If we are in a monospaced environment, however, 1) always use \ttsl,
+% and 2) do not add an italic correction.
+\def\dosmartslant#1#2{%
+ \ifusingtt
+ {{\ttsl #2}\let\next=\relax}%
+ {\def\next{{#1#2}\futurelet\next\smartitaliccorrection}}%
+ \next
+}
+\def\smartslanted{\dosmartslant\sl}
+\def\smartitalic{\dosmartslant\it}
-% \smartitalic{ARG} outputs arg in italics, followed by an italic correction
-% unless the following character is such as not to need one.
-\def\smartitalicx{\ifx\next,\else\ifx\next-\else\ifx\next.\else
- \ptexslash\fi\fi\fi}
-\def\smartslanted#1{{\ifusingtt\ttsl\sl #1}\futurelet\next\smartitalicx}
-\def\smartitalic#1{{\ifusingtt\ttsl\it #1}\futurelet\next\smartitalicx}
+% Output an italic correction unless \next (presumed to be the following
+% character) is such as not to need one.
+\def\smartitaliccorrection{%
+ \ifx\next,%
+ \else\ifx\next-%
+ \else\ifx\next.%
+ \else\ifx\next\.%
+ \else\ifx\next\comma%
+ \else\ptexslash
+ \fi\fi\fi\fi\fi
+ \aftersmartic
+}
-% like \smartslanted except unconditionally uses \ttsl.
-% @var is set to this for defun arguments.
-\def\ttslanted#1{{\ttsl #1}\futurelet\next\smartitalicx}
+% Unconditional use \ttsl, and no ic. @var is set to this for defuns.
+\def\ttslanted#1{{\ttsl #1}}
-% like \smartslanted except unconditionally use \sl. We never want
+% @cite is like \smartslanted except unconditionally use \sl. We never want
% ttsl for book titles, do we?
-\def\cite#1{{\sl #1}\futurelet\next\smartitalicx}
+\def\cite#1{{\sl #1}\futurelet\next\smartitaliccorrection}
+
+\def\aftersmartic{}
+\def\var#1{%
+ \let\saveaftersmartic = \aftersmartic
+ \def\aftersmartic{\null\let\aftersmartic=\saveaftersmartic}%
+ \smartslanted{#1}%
+}
\let\i=\smartitalic
\let\slanted=\smartslanted
-\let\var=\smartslanted
\let\dfn=\smartslanted
\let\emph=\smartitalic
-% @b, explicit bold.
+% Explicit font changes: @r, @sc, undocumented @ii.
+\def\r#1{{\rm #1}} % roman font
+\def\sc#1{{\smallcaps#1}} % smallcaps font
+\def\ii#1{{\it #1}} % italic font
+
+% @b, explicit bold. Also @strong.
\def\b#1{{\bf #1}}
\let\strong=\b
@@ -2432,30 +2443,21 @@ end
\catcode`@=\other
\def\endofsentencespacefactor{3000}% default
+% @t, explicit typewriter.
\def\t#1{%
{\tt \rawbackslash \plainfrenchspacing #1}%
\null
}
-\def\samp#1{`\tclose{#1}'\null}
-\setfont\keyrm\rmshape{8}{1000}{OT1}
-\font\keysy=cmsy9
-\def\key#1{{\keyrm\textfont2=\keysy \leavevmode\hbox{%
- \raise0.4pt\hbox{\angleleft}\kern-.08em\vtop{%
- \vbox{\hrule\kern-0.4pt
- \hbox{\raise0.4pt\hbox{\vphantom{\angleleft}}#1}}%
- \kern-0.4pt\hrule}%
- \kern-.06em\raise0.4pt\hbox{\angleright}}}}
-\def\key #1{{\nohyphenation \uppercase{#1}}\null}
-% The old definition, with no lozenge:
-%\def\key #1{{\ttsl \nohyphenation \uppercase{#1}}\null}
-\def\ctrl #1{{\tt \rawbackslash \hat}#1}
-% @file, @option are the same as @samp.
-\let\file=\samp
-\let\option=\samp
+% @samp.
+\def\samp#1{{\setupmarkupstyle{samp}\lq\tclose{#1}\rq\null}}
+
+% @indicateurl is \samp, that is, with quotes.
+\let\indicateurl=\samp
-% @code is a modification of @t,
-% which makes spaces the same size as normal in the surrounding text.
+% @code (and similar) prints in typewriter, but with spaces the same
+% size as normal in the surrounding text, without hyphenation, etc.
+% This is a subroutine for that.
\def\tclose#1{%
{%
% Change normal interword space to be same as for the current font.
@@ -2474,40 +2476,63 @@ end
\plainfrenchspacing
#1%
}%
- \null
+ \null % reset spacefactor to 1000
}
% We *must* turn on hyphenation at `-' and `_' in @code.
+% (But see \codedashfinish below.)
% Otherwise, it is too hard to avoid overfull hboxes
% in the Emacs manual, the Library manual, etc.
-
+%
% Unfortunately, TeX uses one parameter (\hyphenchar) to control
% both hyphenation at - and hyphenation within words.
% We must therefore turn them both off (\tclose does that)
-% and arrange explicitly to hyphenate at a dash.
-% -- rms.
+% and arrange explicitly to hyphenate at a dash. -- rms.
{
\catcode`\-=\active \catcode`\_=\active
\catcode`\'=\active \catcode`\`=\active
+ \global\let'=\rq \global\let`=\lq % default definitions
%
\global\def\code{\begingroup
- \catcode\rquoteChar=\active \catcode\lquoteChar=\active
- \let'\codequoteright \let`\codequoteleft
- %
+ \setupmarkupstyle{code}%
+ % The following should really be moved into \setupmarkupstyle handlers.
\catcode\dashChar=\active \catcode\underChar=\active
\ifallowcodebreaks
\let-\codedash
\let_\codeunder
\else
- \let-\realdash
+ \let-\normaldash
\let_\realunder
\fi
+ % Given -foo (with a single dash), we do not want to allow a break
+ % after the hyphen.
+ \global\let\codedashprev=\codedash
+ %
\codex
}
+ %
+ \gdef\codedash{\futurelet\next\codedashfinish}
+ \gdef\codedashfinish{%
+ \normaldash % always output the dash character itself.
+ %
+ % Now, output a discretionary to allow a line break, unless
+ % (a) the next character is a -, or
+ % (b) the preceding character is a -.
+ % E.g., given --posix, we do not want to allow a break after either -.
+ % Given --foo-bar, we do want to allow a break between the - and the b.
+ \ifx\next\codedash \else
+ \ifx\codedashprev\codedash
+ \else \discretionary{}{}{}\fi
+ \fi
+ % we need the space after the = for the case when \next itself is a
+ % space token; it would get swallowed otherwise. As in @code{- a}.
+ \global\let\codedashprev= \next
+ }
}
+\def\normaldash{-}
+%
+\def\codex #1{\tclose{#1}\endgroup}
-\def\realdash{-}
-\def\codedash{-\discretionary{}{}{}}
\def\codeunder{%
% this is all so @math{@code{var_name}+1} can work. In math mode, _
% is "active" (mathcode"8000) and \normalunderscore (or \char95, etc.)
@@ -2519,13 +2544,12 @@ end
\discretionary{}{}{}}%
{\_}%
}
-\def\codex #1{\tclose{#1}\endgroup}
% An additional complication: the above will allow breaks after, e.g.,
-% each of the four underscores in __typeof__. This is undesirable in
-% some manuals, especially if they don't have long identifiers in
-% general. @allowcodebreaks provides a way to control this.
-%
+% each of the four underscores in __typeof__. This is bad.
+% @allowcodebreaks provides a document-level way to turn breaking at -
+% and _ on and off.
+%
\newif\ifallowcodebreaks \allowcodebreakstrue
\def\keywordtrue{true}
@@ -2539,62 +2563,25 @@ end
\allowcodebreaksfalse
\else
\errhelp = \EMsimple
- \errmessage{Unknown @allowcodebreaks option `\txiarg'}%
+ \errmessage{Unknown @allowcodebreaks option `\txiarg', must be true|false}%
\fi\fi
}
-% @kbd is like @code, except that if the argument is just one @key command,
-% then @kbd has no effect.
-
-% @kbdinputstyle -- arg is `distinct' (@kbd uses slanted tty font always),
-% `example' (@kbd uses ttsl only inside of @example and friends),
-% or `code' (@kbd uses normal tty font always).
-\parseargdef\kbdinputstyle{%
- \def\txiarg{#1}%
- \ifx\txiarg\worddistinct
- \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\ttsl}%
- \else\ifx\txiarg\wordexample
- \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\tt}%
- \else\ifx\txiarg\wordcode
- \gdef\kbdexamplefont{\tt}\gdef\kbdfont{\tt}%
- \else
- \errhelp = \EMsimple
- \errmessage{Unknown @kbdinputstyle option `\txiarg'}%
- \fi\fi\fi
-}
-\def\worddistinct{distinct}
-\def\wordexample{example}
-\def\wordcode{code}
-
-% Default is `distinct.'
-\kbdinputstyle distinct
-
-\def\xkey{\key}
-\def\kbdfoo#1#2#3\par{\def\one{#1}\def\three{#3}\def\threex{??}%
-\ifx\one\xkey\ifx\threex\three \key{#2}%
-\else{\tclose{\kbdfont\look}}\fi
-\else{\tclose{\kbdfont\look}}\fi}
-
-% For @indicateurl, @env, @command quotes seem unnecessary, so use \code.
-\let\indicateurl=\code
-\let\env=\code
+% For @command, @env, @file, @option quotes seem unnecessary,
+% so use \code rather than \samp.
\let\command=\code
-
-% @clicksequence{File @click{} Open ...}
-\def\clicksequence#1{\begingroup #1\endgroup}
-
-% @clickstyle @arrow (by default)
-\parseargdef\clickstyle{\def\click{#1}}
-\def\click{\arrow}
+\let\env=\code
+\let\file=\code
+\let\option=\code
% @uref (abbreviation for `urlref') takes an optional (comma-separated)
% second argument specifying the text to display and an optional third
% arg as text to display instead of (rather than in addition to) the url
-% itself. First (mandatory) arg is the url. Perhaps eventually put in
-% a hypertex \special here.
-%
-\def\uref#1{\douref #1,,,\finish}
-\def\douref#1,#2,#3,#4\finish{\begingroup
+% itself. First (mandatory) arg is the url.
+% (This \urefnobreak definition isn't used now, leaving it for a while
+% for comparison.)
+\def\urefnobreak#1{\dourefnobreak #1,,,\finish}
+\def\dourefnobreak#1,#2,#3,#4\finish{\begingroup
\unsepspaces
\pdfurl{#1}%
\setbox0 = \hbox{\ignorespaces #3}%
@@ -2615,6 +2602,103 @@ end
\endlink
\endgroup}
+% This \urefbreak definition is the active one.
+\def\urefbreak{\begingroup \urefcatcodes \dourefbreak}
+\let\uref=\urefbreak
+\def\dourefbreak#1{\urefbreakfinish #1,,,\finish}
+\def\urefbreakfinish#1,#2,#3,#4\finish{% doesn't work in @example
+ \unsepspaces
+ \pdfurl{#1}%
+ \setbox0 = \hbox{\ignorespaces #3}%
+ \ifdim\wd0 > 0pt
+ \unhbox0 % third arg given, show only that
+ \else
+ \setbox0 = \hbox{\ignorespaces #2}%
+ \ifdim\wd0 > 0pt
+ \ifpdf
+ \unhbox0 % PDF: 2nd arg given, show only it
+ \else
+ \unhbox0\ (\urefcode{#1})% DVI: 2nd arg given, show both it and url
+ \fi
+ \else
+ \urefcode{#1}% only url given, so show it
+ \fi
+ \fi
+ \endlink
+\endgroup}
+
+% Allow line breaks around only a few characters (only).
+\def\urefcatcodes{%
+ \catcode\ampChar=\active \catcode\dotChar=\active
+ \catcode\hashChar=\active \catcode\questChar=\active
+ \catcode\slashChar=\active
+}
+{
+ \urefcatcodes
+ %
+ \global\def\urefcode{\begingroup
+ \setupmarkupstyle{code}%
+ \urefcatcodes
+ \let&\urefcodeamp
+ \let.\urefcodedot
+ \let#\urefcodehash
+ \let?\urefcodequest
+ \let/\urefcodeslash
+ \codex
+ }
+ %
+ % By default, they are just regular characters.
+ \global\def&{\normalamp}
+ \global\def.{\normaldot}
+ \global\def#{\normalhash}
+ \global\def?{\normalquest}
+ \global\def/{\normalslash}
+}
+
+% we put a little stretch before and after the breakable chars, to help
+% line breaking of long url's. The unequal skips make look better in
+% cmtt at least, especially for dots.
+\def\urefprestretch{\urefprebreak \hskip0pt plus.13em }
+\def\urefpoststretch{\urefpostbreak \hskip0pt plus.1em }
+%
+\def\urefcodeamp{\urefprestretch \&\urefpoststretch}
+\def\urefcodedot{\urefprestretch .\urefpoststretch}
+\def\urefcodehash{\urefprestretch \#\urefpoststretch}
+\def\urefcodequest{\urefprestretch ?\urefpoststretch}
+\def\urefcodeslash{\futurelet\next\urefcodeslashfinish}
+{
+ \catcode`\/=\active
+ \global\def\urefcodeslashfinish{%
+ \urefprestretch \slashChar
+ % Allow line break only after the final / in a sequence of
+ % slashes, to avoid line break between the slashes in http://.
+ \ifx\next/\else \urefpoststretch \fi
+ }
+}
+
+% One more complication: by default we'll break after the special
+% characters, but some people like to break before the special chars, so
+% allow that. Also allow no breaking at all, for manual control.
+%
+\parseargdef\urefbreakstyle{%
+ \def\txiarg{#1}%
+ \ifx\txiarg\wordnone
+ \def\urefprebreak{\nobreak}\def\urefpostbreak{\nobreak}
+ \else\ifx\txiarg\wordbefore
+ \def\urefprebreak{\allowbreak}\def\urefpostbreak{\nobreak}
+ \else\ifx\txiarg\wordafter
+ \def\urefprebreak{\nobreak}\def\urefpostbreak{\allowbreak}
+ \else
+ \errhelp = \EMsimple
+ \errmessage{Unknown @urefbreakstyle setting `\txiarg'}%
+ \fi\fi\fi
+}
+\def\wordafter{after}
+\def\wordbefore{before}
+\def\wordnone{none}
+
+\urefbreakstyle after
+
% @url synonym for @uref, since that's how everyone uses it.
%
\let\url=\uref
@@ -2636,34 +2720,81 @@ end
\let\email=\uref
\fi
-% Check if we are currently using a typewriter font. Since all the
-% Computer Modern typewriter fonts have zero interword stretch (and
-% shrink), and it is reasonable to expect all typewriter fonts to have
-% this property, we can check that font parameter.
-%
-\def\ifmonospace{\ifdim\fontdimen3\font=0pt }
+% @kbdinputstyle -- arg is `distinct' (@kbd uses slanted tty font always),
+% `example' (@kbd uses ttsl only inside of @example and friends),
+% or `code' (@kbd uses normal tty font always).
+\parseargdef\kbdinputstyle{%
+ \def\txiarg{#1}%
+ \ifx\txiarg\worddistinct
+ \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\ttsl}%
+ \else\ifx\txiarg\wordexample
+ \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\tt}%
+ \else\ifx\txiarg\wordcode
+ \gdef\kbdexamplefont{\tt}\gdef\kbdfont{\tt}%
+ \else
+ \errhelp = \EMsimple
+ \errmessage{Unknown @kbdinputstyle setting `\txiarg'}%
+ \fi\fi\fi
+}
+\def\worddistinct{distinct}
+\def\wordexample{example}
+\def\wordcode{code}
+
+% Default is `distinct'.
+\kbdinputstyle distinct
+
+% @kbd is like @code, except that if the argument is just one @key command,
+% then @kbd has no effect.
+\def\kbd#1{{\def\look{#1}\expandafter\kbdsub\look??\par}}
+
+\def\xkey{\key}
+\def\kbdsub#1#2#3\par{%
+ \def\one{#1}\def\three{#3}\def\threex{??}%
+ \ifx\one\xkey\ifx\threex\three \key{#2}%
+ \else{\tclose{\kbdfont\setupmarkupstyle{kbd}\look}}\fi
+ \else{\tclose{\kbdfont\setupmarkupstyle{kbd}\look}}\fi
+}
+
+% definition of @key that produces a lozenge. Doesn't adjust to text size.
+%\setfont\keyrm\rmshape{8}{1000}{OT1}
+%\font\keysy=cmsy9
+%\def\key#1{{\keyrm\textfont2=\keysy \leavevmode\hbox{%
+% \raise0.4pt\hbox{\angleleft}\kern-.08em\vtop{%
+% \vbox{\hrule\kern-0.4pt
+% \hbox{\raise0.4pt\hbox{\vphantom{\angleleft}}#1}}%
+% \kern-0.4pt\hrule}%
+% \kern-.06em\raise0.4pt\hbox{\angleright}}}}
+
+% definition of @key with no lozenge. If the current font is already
+% monospace, don't change it; that way, we respect @kbdinputstyle. But
+% if it isn't monospace, then use \tt.
+%
+\def\key#1{{\setupmarkupstyle{key}%
+ \nohyphenation
+ \ifmonospace\else\tt\fi
+ #1}\null}
+
+% @clicksequence{File @click{} Open ...}
+\def\clicksequence#1{\begingroup #1\endgroup}
+
+% @clickstyle @arrow (by default)
+\parseargdef\clickstyle{\def\click{#1}}
+\def\click{\arrow}
% Typeset a dimension, e.g., `in' or `pt'. The only reason for the
% argument is to make the input look right: @dmn{pt} instead of @dmn{}pt.
%
\def\dmn#1{\thinspace #1}
-\def\kbd#1{\def\look{#1}\expandafter\kbdfoo\look??\par}
-
% @l was never documented to mean ``switch to the Lisp font'',
% and it is not used as such in any manual I can find. We need it for
% Polish suppressed-l. --karl, 22sep96.
%\def\l#1{{\li #1}\null}
-% Explicit font changes: @r, @sc, undocumented @ii.
-\def\r#1{{\rm #1}} % roman font
-\def\sc#1{{\smallcaps#1}} % smallcaps font
-\def\ii#1{{\it #1}} % italic font
-
% @acronym for "FBI", "NATO", and the like.
% We print this one point size smaller, since it's intended for
% all-uppercase.
-%
+%
\def\acronym#1{\doacronym #1,,\finish}
\def\doacronym#1,#2,#3\finish{%
{\selectfonts\lsize #1}%
@@ -2671,11 +2802,12 @@ end
\ifx\temp\empty \else
\space ({\unsepspaces \ignorespaces \temp \unskip})%
\fi
+ \null % reset \spacefactor=1000
}
% @abbr for "Comput. J." and the like.
% No font change, but don't do end-of-sentence spacing.
-%
+%
\def\abbr#1{\doabbr #1,,\finish}
\def\doabbr#1,#2,#3\finish{%
{\plainfrenchspacing #1}%
@@ -2683,8 +2815,284 @@ end
\ifx\temp\empty \else
\space ({\unsepspaces \ignorespaces \temp \unskip})%
\fi
+ \null % reset \spacefactor=1000
+}
+
+% @asis just yields its argument. Used with @table, for example.
+%
+\def\asis#1{#1}
+
+% @math outputs its argument in math mode.
+%
+% One complication: _ usually means subscripts, but it could also mean
+% an actual _ character, as in @math{@var{some_variable} + 1}. So make
+% _ active, and distinguish by seeing if the current family is \slfam,
+% which is what @var uses.
+{
+ \catcode`\_ = \active
+ \gdef\mathunderscore{%
+ \catcode`\_=\active
+ \def_{\ifnum\fam=\slfam \_\else\sb\fi}%
+ }
+}
+% Another complication: we want \\ (and @\) to output a math (or tt) \.
+% FYI, plain.tex uses \\ as a temporary control sequence (for no
+% particular reason), but this is not advertised and we don't care.
+%
+% The \mathchar is class=0=ordinary, family=7=ttfam, position=5C=\.
+\def\mathbackslash{\ifnum\fam=\ttfam \mathchar"075C \else\backslash \fi}
+%
+\def\math{%
+ \tex
+ \mathunderscore
+ \let\\ = \mathbackslash
+ \mathactive
+ % make the texinfo accent commands work in math mode
+ \let\"=\ddot
+ \let\'=\acute
+ \let\==\bar
+ \let\^=\hat
+ \let\`=\grave
+ \let\u=\breve
+ \let\v=\check
+ \let\~=\tilde
+ \let\dotaccent=\dot
+ $\finishmath
+}
+\def\finishmath#1{#1$\endgroup} % Close the group opened by \tex.
+
+% Some active characters (such as <) are spaced differently in math.
+% We have to reset their definitions in case the @math was an argument
+% to a command which sets the catcodes (such as @item or @section).
+%
+{
+ \catcode`^ = \active
+ \catcode`< = \active
+ \catcode`> = \active
+ \catcode`+ = \active
+ \catcode`' = \active
+ \gdef\mathactive{%
+ \let^ = \ptexhat
+ \let< = \ptexless
+ \let> = \ptexgtr
+ \let+ = \ptexplus
+ \let' = \ptexquoteright
+ }
+}
+
+% ctrl is no longer a Texinfo command, but leave this definition for fun.
+\def\ctrl #1{{\tt \rawbackslash \hat}#1}
+
+% @inlinefmt{FMTNAME,PROCESSED-TEXT} and @inlineraw{FMTNAME,RAW-TEXT}.
+% Ignore unless FMTNAME == tex; then it is like @iftex and @tex,
+% except specified as a normal braced arg, so no newlines to worry about.
+%
+\def\outfmtnametex{tex}
+%
+\long\def\inlinefmt#1{\doinlinefmt #1,\finish}
+\long\def\doinlinefmt#1,#2,\finish{%
+ \def\inlinefmtname{#1}%
+ \ifx\inlinefmtname\outfmtnametex \ignorespaces #2\fi
+}
+%
+% @inlinefmtifelse{FMTNAME,THEN-TEXT,ELSE-TEXT} expands THEN-TEXT if
+% FMTNAME is tex, else ELSE-TEXT.
+\long\def\inlinefmtifelse#1{\doinlinefmtifelse #1,,,\finish}
+\long\def\doinlinefmtifelse#1,#2,#3,#4,\finish{%
+ \def\inlinefmtname{#1}%
+ \ifx\inlinefmtname\outfmtnametex \ignorespaces #2\else \ignorespaces #3\fi
+}
+%
+% For raw, must switch into @tex before parsing the argument, to avoid
+% setting catcodes prematurely. Doing it this way means that, for
+% example, @inlineraw{html, foo{bar} gets a parse error instead of being
+% ignored. But this isn't important because if people want a literal
+% *right* brace they would have to use a command anyway, so they may as
+% well use a command to get a left brace too. We could re-use the
+% delimiter character idea from \verb, but it seems like overkill.
+%
+\long\def\inlineraw{\tex \doinlineraw}
+\long\def\doinlineraw#1{\doinlinerawtwo #1,\finish}
+\def\doinlinerawtwo#1,#2,\finish{%
+ \def\inlinerawname{#1}%
+ \ifx\inlinerawname\outfmtnametex \ignorespaces #2\fi
+ \endgroup % close group opened by \tex.
}
+% @inlineifset{VAR, TEXT} expands TEXT if VAR is @set.
+%
+\long\def\inlineifset#1{\doinlineifset #1,\finish}
+\long\def\doinlineifset#1,#2,\finish{%
+ \def\inlinevarname{#1}%
+ \expandafter\ifx\csname SET\inlinevarname\endcsname\relax
+ \else\ignorespaces#2\fi
+}
+
+% @inlineifclear{VAR, TEXT} expands TEXT if VAR is not @set.
+%
+\long\def\inlineifclear#1{\doinlineifclear #1,\finish}
+\long\def\doinlineifclear#1,#2,\finish{%
+ \def\inlinevarname{#1}%
+ \expandafter\ifx\csname SET\inlinevarname\endcsname\relax \ignorespaces#2\fi
+}
+
+
+\message{glyphs,}
+% and logos.
+
+% @@ prints an @, as does @atchar{}.
+\def\@{\char64 }
+\let\atchar=\@
+
+% @{ @} @lbracechar{} @rbracechar{} all generate brace characters.
+% Unless we're in typewriter, use \ecfont because the CM text fonts do
+% not have braces, and we don't want to switch into math.
+\def\mylbrace{{\ifmonospace\else\ecfont\fi \char123}}
+\def\myrbrace{{\ifmonospace\else\ecfont\fi \char125}}
+\let\{=\mylbrace \let\lbracechar=\{
+\let\}=\myrbrace \let\rbracechar=\}
+\begingroup
+ % Definitions to produce \{ and \} commands for indices,
+ % and @{ and @} for the aux/toc files.
+ \catcode`\{ = \other \catcode`\} = \other
+ \catcode`\[ = 1 \catcode`\] = 2
+ \catcode`\! = 0 \catcode`\\ = \other
+ !gdef!lbracecmd[\{]%
+ !gdef!rbracecmd[\}]%
+ !gdef!lbraceatcmd[@{]%
+ !gdef!rbraceatcmd[@}]%
+!endgroup
+
+% @comma{} to avoid , parsing problems.
+\let\comma = ,
+
+% Accents: @, @dotaccent @ringaccent @ubaraccent @udotaccent
+% Others are defined by plain TeX: @` @' @" @^ @~ @= @u @v @H.
+\let\, = \ptexc
+\let\dotaccent = \ptexdot
+\def\ringaccent#1{{\accent23 #1}}
+\let\tieaccent = \ptext
+\let\ubaraccent = \ptexb
+\let\udotaccent = \d
+
+% Other special characters: @questiondown @exclamdown @ordf @ordm
+% Plain TeX defines: @AA @AE @O @OE @L (plus lowercase versions) @ss.
+\def\questiondown{?`}
+\def\exclamdown{!`}
+\def\ordf{\leavevmode\raise1ex\hbox{\selectfonts\lllsize \underbar{a}}}
+\def\ordm{\leavevmode\raise1ex\hbox{\selectfonts\lllsize \underbar{o}}}
+
+% Dotless i and dotless j, used for accents.
+\def\imacro{i}
+\def\jmacro{j}
+\def\dotless#1{%
+ \def\temp{#1}%
+ \ifx\temp\imacro \ifmmode\imath \else\ptexi \fi
+ \else\ifx\temp\jmacro \ifmmode\jmath \else\j \fi
+ \else \errmessage{@dotless can be used only with i or j}%
+ \fi\fi
+}
+
+% The \TeX{} logo, as in plain, but resetting the spacing so that a
+% period following counts as ending a sentence. (Idea found in latex.)
+%
+\edef\TeX{\TeX \spacefactor=1000 }
+
+% @LaTeX{} logo. Not quite the same results as the definition in
+% latex.ltx, since we use a different font for the raised A; it's most
+% convenient for us to use an explicitly smaller font, rather than using
+% the \scriptstyle font (since we don't reset \scriptstyle and
+% \scriptscriptstyle).
+%
+\def\LaTeX{%
+ L\kern-.36em
+ {\setbox0=\hbox{T}%
+ \vbox to \ht0{\hbox{%
+ \ifx\textnominalsize\xwordpt
+ % for 10pt running text, \lllsize (8pt) is too small for the A in LaTeX.
+ % Revert to plain's \scriptsize, which is 7pt.
+ \count255=\the\fam $\fam\count255 \scriptstyle A$%
+ \else
+ % For 11pt, we can use our lllsize.
+ \selectfonts\lllsize A%
+ \fi
+ }%
+ \vss
+ }}%
+ \kern-.15em
+ \TeX
+}
+
+% Some math mode symbols.
+\def\bullet{$\ptexbullet$}
+\def\geq{\ifmmode \ge\else $\ge$\fi}
+\def\leq{\ifmmode \le\else $\le$\fi}
+\def\minus{\ifmmode -\else $-$\fi}
+
+% @dots{} outputs an ellipsis using the current font.
+% We do .5em per period so that it has the same spacing in the cm
+% typewriter fonts as three actual period characters; on the other hand,
+% in other typewriter fonts three periods are wider than 1.5em. So do
+% whichever is larger.
+%
+\def\dots{%
+ \leavevmode
+ \setbox0=\hbox{...}% get width of three periods
+ \ifdim\wd0 > 1.5em
+ \dimen0 = \wd0
+ \else
+ \dimen0 = 1.5em
+ \fi
+ \hbox to \dimen0{%
+ \hskip 0pt plus.25fil
+ .\hskip 0pt plus1fil
+ .\hskip 0pt plus1fil
+ .\hskip 0pt plus.5fil
+ }%
+}
+
+% @enddots{} is an end-of-sentence ellipsis.
+%
+\def\enddots{%
+ \dots
+ \spacefactor=\endofsentencespacefactor
+}
+
+% @point{}, @result{}, @expansion{}, @print{}, @equiv{}.
+%
+% Since these characters are used in examples, they should be an even number of
+% \tt widths. Each \tt character is 1en, so two makes it 1em.
+%
+\def\point{$\star$}
+\def\arrow{\leavevmode\raise.05ex\hbox to 1em{\hfil$\rightarrow$\hfil}}
+\def\result{\leavevmode\raise.05ex\hbox to 1em{\hfil$\Rightarrow$\hfil}}
+\def\expansion{\leavevmode\hbox to 1em{\hfil$\mapsto$\hfil}}
+\def\print{\leavevmode\lower.1ex\hbox to 1em{\hfil$\dashv$\hfil}}
+\def\equiv{\leavevmode\hbox to 1em{\hfil$\ptexequiv$\hfil}}
+
+% The @error{} command.
+% Adapted from the TeXbook's \boxit.
+%
+\newbox\errorbox
+%
+{\tentt \global\dimen0 = 3em}% Width of the box.
+\dimen2 = .55pt % Thickness of rules
+% The text. (`r' is open on the right, `e' somewhat less so on the left.)
+\setbox0 = \hbox{\kern-.75pt \reducedsf \putworderror\kern-1.5pt}
+%
+\setbox\errorbox=\hbox to \dimen0{\hfil
+ \hsize = \dimen0 \advance\hsize by -5.8pt % Space to left+right.
+ \advance\hsize by -2\dimen2 % Rules.
+ \vbox{%
+ \hrule height\dimen2
+ \hbox{\vrule width\dimen2 \kern3pt % Space to left of text.
+ \vtop{\kern2.4pt \box0 \kern2.4pt}% Space above/below.
+ \kern3pt\vrule width\dimen2}% Space to right.
+ \hrule height\dimen2}
+ \hfil}
+%
+\def\error{\leavevmode\lower.7ex\copy\errorbox}
+
% @pounds{} is a sterling sign, which Knuth put in the CM italic font.
%
\def\pounds{{\it\$}}
@@ -2694,52 +3102,59 @@ end
% Theiling, which support regular, slanted, bold and bold slanted (and
% "outlined" (blackboard board, sort of) versions, which we don't need).
% It is available from http://www.ctan.org/tex-archive/fonts/eurosym.
-%
+%
% Although only regular is the truly official Euro symbol, we ignore
% that. The Euro is designed to be slightly taller than the regular
% font height.
-%
+%
% feymr - regular
% feymo - slanted
% feybr - bold
% feybo - bold slanted
-%
+%
% There is no good (free) typewriter version, to my knowledge.
% A feymr10 euro is ~7.3pt wide, while a normal cmtt10 char is ~5.25pt wide.
% Hmm.
-%
+%
% Also doesn't work in math. Do we need to do math with euro symbols?
% Hope not.
-%
-%
+%
+%
\def\euro{{\eurofont e}}
\def\eurofont{%
% We set the font at each command, rather than predefining it in
% \textfonts and the other font-switching commands, so that
% installations which never need the symbol don't have to have the
% font installed.
- %
+ %
% There is only one designed size (nominal 10pt), so we always scale
% that to the current nominal size.
- %
+ %
% By the way, simply using "at 1em" works for cmr10 and the like, but
% does not work for cmbx10 and other extended/shrunken fonts.
- %
+ %
\def\eurosize{\csname\curfontsize nominalsize\endcsname}%
%
- \ifx\curfontstyle\bfstylename
+ \ifx\curfontstyle\bfstylename
% bold:
\font\thiseurofont = \ifusingit{feybo10}{feybr10} at \eurosize
- \else
+ \else
% regular:
\font\thiseurofont = \ifusingit{feymo10}{feymr10} at \eurosize
\fi
\thiseurofont
}
-% Hacks for glyphs from the EC fonts similar to \euro. We don't
-% use \let for the aliases, because sometimes we redefine the original
-% macro, and the alias should reflect the redefinition.
+% Glyphs from the EC fonts. We don't use \let for the aliases, because
+% sometimes we redefine the original macro, and the alias should reflect
+% the redefinition.
+%
+% Use LaTeX names for the Icelandic letters.
+\def\DH{{\ecfont \char"D0}} % Eth
+\def\dh{{\ecfont \char"F0}} % eth
+\def\TH{{\ecfont \char"DE}} % Thorn
+\def\th{{\ecfont \char"FE}} % thorn
+%
\def\guillemetleft{{\ecfont \char"13}}
\def\guillemotleft{\guillemetleft}
\def\guillemetright{{\ecfont \char"14}}
@@ -2749,19 +3164,52 @@ end
\def\quotedblbase{{\ecfont \char"12}}
\def\quotesinglbase{{\ecfont \char"0D}}
%
+% This positioning is not perfect (see the ogonek LaTeX package), but
+% we have the precomposed glyphs for the most common cases. We put the
+% tests to use those glyphs in the single \ogonek macro so we have fewer
+% dummy definitions to worry about for index entries, etc.
+%
+% ogonek is also used with other letters in Lithuanian (IOU), but using
+% the precomposed glyphs for those is not so easy since they aren't in
+% the same EC font.
+\def\ogonek#1{{%
+ \def\temp{#1}%
+ \ifx\temp\macrocharA\Aogonek
+ \else\ifx\temp\macrochara\aogonek
+ \else\ifx\temp\macrocharE\Eogonek
+ \else\ifx\temp\macrochare\eogonek
+ \else
+ \ecfont \setbox0=\hbox{#1}%
+ \ifdim\ht0=1ex\accent"0C #1%
+ \else\ooalign{\unhbox0\crcr\hidewidth\char"0C \hidewidth}%
+ \fi
+ \fi\fi\fi\fi
+ }%
+}
+\def\Aogonek{{\ecfont \char"81}}\def\macrocharA{A}
+\def\aogonek{{\ecfont \char"A1}}\def\macrochara{a}
+\def\Eogonek{{\ecfont \char"86}}\def\macrocharE{E}
+\def\eogonek{{\ecfont \char"A6}}\def\macrochare{e}
+%
+% Use the ec* fonts (cm-super in outline format) for non-CM glyphs.
\def\ecfont{%
- % We can't distinguish serif/sanserif and italic/slanted, but this
+ % We can't distinguish serif/sans and italic/slanted, but this
% is used for crude hacks anyway (like adding French and German
% quotes to documents typeset with CM, where we lose kerning), so
% hopefully nobody will notice/care.
\edef\ecsize{\csname\curfontsize ecsize\endcsname}%
\edef\nominalsize{\csname\curfontsize nominalsize\endcsname}%
- \ifx\curfontstyle\bfstylename
- % bold:
- \font\thisecfont = ecb\ifusingit{i}{x}\ecsize \space at \nominalsize
+ \ifmonospace
+ % typewriter:
+ \font\thisecfont = ectt\ecsize \space at \nominalsize
\else
- % regular:
- \font\thisecfont = ec\ifusingit{ti}{rm}\ecsize \space at \nominalsize
+ \ifx\curfontstyle\bfstylename
+ % bold:
+ \font\thisecfont = ecb\ifusingit{i}{x}\ecsize \space at \nominalsize
+ \else
+ % regular:
+ \font\thisecfont = ec\ifusingit{ti}{rm}\ecsize \space at \nominalsize
+ \fi
\fi
\thisecfont
}
@@ -2783,8 +3231,8 @@ end
% Laurent Siebenmann reports \Orb undefined with:
% Textures 1.7.7 (preloaded format=plain 93.10.14) (68K) 16 APR 2004 02:38
% so we'll define it if necessary.
-%
-\ifx\Orb\undefined
+%
+\ifx\Orb\thisisundefined
\def\Orb{\mathhexbox20D}
\fi
@@ -2812,8 +3260,9 @@ end
\newif\ifsetshortcontentsaftertitlepage
\let\setshortcontentsaftertitlepage = \setshortcontentsaftertitlepagetrue
-\parseargdef\shorttitlepage{\begingroup\hbox{}\vskip 1.5in \chaprm \centerline{#1}%
- \endgroup\page\hbox{}\page}
+\parseargdef\shorttitlepage{%
+ \begingroup \hbox{}\vskip 1.5in \chaprm \centerline{#1}%
+ \endgroup\page\hbox{}\page}
\envdef\titlepage{%
% Open one extra group, as we want to close it in the middle of \Etitlepage.
@@ -2873,17 +3322,28 @@ end
\finishedtitlepagetrue
}
-%%% Macros to be used within @titlepage:
+% Settings used for typesetting titles: no hyphenation, no indentation,
+% don't worry much about spacing, ragged right. This should be used
+% inside a \vbox, and fonts need to be set appropriately first. Because
+% it is always used for titles, nothing else, we call \rmisbold. \par
+% should be specified before the end of the \vbox, since a vbox is a group.
+%
+\def\raggedtitlesettings{%
+ \rmisbold
+ \hyphenpenalty=10000
+ \parindent=0pt
+ \tolerance=5000
+ \ptexraggedright
+}
+
+% Macros to be used within @titlepage:
\let\subtitlerm=\tenrm
\def\subtitlefont{\subtitlerm \normalbaselineskip = 13pt \normalbaselines}
-\def\authorfont{\authorrm \normalbaselineskip = 16pt \normalbaselines
- \let\tt=\authortt}
-
\parseargdef\title{%
\checkenv\titlepage
- \leftline{\titlefonts\rm #1}
+ \vbox{\titlefonts \raggedtitlesettings #1\par}%
% print a rule at the page bottom also.
\finishedtitlepagefalse
\vskip4pt \hrule height 4pt width \hsize \vskip4pt
@@ -2904,12 +3364,12 @@ end
\else
\checkenv\titlepage
\ifseenauthor\else \vskip 0pt plus 1filll \seenauthortrue \fi
- {\authorfont \leftline{#1}}%
+ {\secfonts\rmisbold \leftline{#1}}%
\fi
}
-%%% Set up page headings and footings.
+% Set up page headings and footings.
\let\thispage=\folio
@@ -3003,10 +3463,14 @@ end
\def\headings #1 {\csname HEADINGS#1\endcsname}
-\def\HEADINGSoff{%
-\global\evenheadline={\hfil} \global\evenfootline={\hfil}
-\global\oddheadline={\hfil} \global\oddfootline={\hfil}}
-\HEADINGSoff
+\def\headingsoff{% non-global headings elimination
+ \evenheadline={\hfil}\evenfootline={\hfil}%
+ \oddheadline={\hfil}\oddfootline={\hfil}%
+}
+
+\def\HEADINGSoff{{\globaldefs=1 \headingsoff}} % global setting
+\HEADINGSoff % it's the default
+
% When we turn headings on, set the page number to 1.
% For double-sided printing, put current file name in lower left corner,
% chapter name on inside top of right hand pages, document
@@ -3057,7 +3521,7 @@ end
% This produces Day Month Year style of output.
% Only define if not already defined, in case a txi-??.tex file has set
% up a different format (e.g., txi-cs.tex does this).
-\ifx\today\undefined
+\ifx\today\thisisundefined
\def\today{%
\number\day\space
\ifcase\month
@@ -3118,7 +3582,7 @@ end
\begingroup
\advance\leftskip by-\tableindent
\advance\hsize by\tableindent
- \advance\rightskip by0pt plus1fil
+ \advance\rightskip by0pt plus1fil\relax
\leavevmode\unhbox0\par
\endgroup
%
@@ -3132,7 +3596,7 @@ end
% cause the example and the item to crash together. So we use this
% bizarre value of 10001 as a signal to \aboveenvbreak to insert
% \parskip glue after all. Section titles are handled this way also.
- %
+ %
\penalty 10001
\endgroup
\itemxneedsnegativevskipfalse
@@ -3226,9 +3690,18 @@ end
\parindent=0pt
\parskip=\smallskipamount
\ifdim\parskip=0pt \parskip=2pt \fi
+ %
+ % Try typesetting the item mark that if the document erroneously says
+ % something like @itemize @samp (intending @table), there's an error
+ % right away at the @itemize. It's not the best error message in the
+ % world, but it's better than leaving it to the @item. This means if
+ % the user wants an empty mark, they have to say @w{} not just @w.
\def\itemcontents{#1}%
+ \setbox0 = \hbox{\itemcontents}%
+ %
% @itemize with no arg is equivalent to @itemize @bullet.
\ifx\itemcontents\empty\def\itemcontents{\bullet}\fi
+ %
\let\item=\itemizeitem
}
@@ -3249,6 +3722,7 @@ end
\ifnum\lastpenalty<10000 \parskip=0in \fi
\noindent
\hbox to 0pt{\hss \itemcontents \kern\itemmargin}%
+ %
\vadjust{\penalty 1200}}% not good to break after first line of item.
\flushcr
}
@@ -3470,12 +3944,19 @@ end
%
% @headitem starts a heading row, which we typeset in bold.
% Assignments have to be global since we are inside the implicit group
-% of an alignment entry. Note that \everycr resets \everytab.
-\def\headitem{\checkenv\multitable \crcr \global\everytab={\bf}\the\everytab}%
+% of an alignment entry. \everycr resets \everytab so we don't have to
+% undo it ourselves.
+\def\headitemfont{\b}% for people to use in the template row; not changeable
+\def\headitem{%
+ \checkenv\multitable
+ \crcr
+ \global\everytab={\bf}% can't use \headitemfont since the parsing differs
+ \the\everytab % for the first item
+}%
%
% A \tab used to include \hskip1sp. But then the space in a template
% line is not enough. That is bad. So let's go back to just `&' until
-% we encounter the problem it was intended to solve again.
+% we again encounter the problem the 1sp was intended to solve.
% --karl, nathan@acm.org, 20apr99.
\def\tab{\checkenv\multitable &\the\everytab}%
@@ -3587,18 +4068,18 @@ end
\setbox0=\vbox{X}\global\multitablelinespace=\the\baselineskip
\global\advance\multitablelinespace by-\ht0
\fi
-%% Test to see if parskip is larger than space between lines of
-%% table. If not, do nothing.
-%% If so, set to same dimension as multitablelinespace.
+% Test to see if parskip is larger than space between lines of
+% table. If not, do nothing.
+% If so, set to same dimension as multitablelinespace.
\ifdim\multitableparskip>\multitablelinespace
\global\multitableparskip=\multitablelinespace
-\global\advance\multitableparskip-7pt %% to keep parskip somewhat smaller
- %% than skip between lines in the table.
+\global\advance\multitableparskip-7pt % to keep parskip somewhat smaller
+ % than skip between lines in the table.
\fi%
\ifdim\multitableparskip=0pt
\global\multitableparskip=\multitablelinespace
-\global\advance\multitableparskip-7pt %% to keep parskip somewhat smaller
- %% than skip between lines in the table.
+\global\advance\multitableparskip-7pt % to keep parskip somewhat smaller
+ % than skip between lines in the table.
\fi}
@@ -3750,7 +4231,7 @@ end
\def\value{\begingroup\makevalueexpandable\valuexxx}
\def\valuexxx#1{\expandablevalue{#1}\endgroup}
{
- \catcode`\- = \active \catcode`\_ = \active
+ \catcode`\-=\active \catcode`\_=\active
%
\gdef\makevalueexpandable{%
\let\value = \expandablevalue
@@ -3759,7 +4240,7 @@ end
% ..., but we might end up with active ones in the argument if
% we're called from @code, as @code{@value{foo-bar_}}, though.
% So \let them to their normal equivalents.
- \let-\realdash \let_\normalunderscore
+ \let-\normaldash \let_\normalunderscore
}
}
@@ -3771,6 +4252,11 @@ end
% it will fail (although perhaps we could fix that with sufficient work
% to do a one-level expansion on the result, instead of complete).
%
+% Unfortunately, this has the consequence that when _ is in the *value*
+% of an @set, it does not print properly in the roman fonts (get the cmr
+% dot accent at position 126 instead). No fix comes to mind, and it's
+% been this way since 2003 or earlier, so just ignore it.
+%
\def\expandablevalue#1{%
\expandafter\ifx\csname SET#1\endcsname\relax
{[No value for ``#1'']}%
@@ -3783,7 +4269,8 @@ end
% @ifset VAR ... @end ifset reads the `...' iff VAR has been defined
% with @set.
%
-% To get special treatment of `@end ifset,' call \makeond and the redefine.
+% To get the special treatment we need for `@end ifset,' we call
+% \makecond and then redefine.
%
\makecond{ifset}
\def\ifset{\parsearg{\doifset{\let\next=\ifsetfail}}}
@@ -3799,7 +4286,7 @@ end
}
\def\ifsetfail{\doignore{ifset}}
-% @ifclear VAR ... @end ifclear reads the `...' iff VAR has never been
+% @ifclear VAR ... @end executes the `...' iff VAR has never been
% defined with @set, or has been undefined with @clear.
%
% The `\else' inside the `\doifset' parameter is a trick to reuse the
@@ -3810,6 +4297,35 @@ end
\def\ifclear{\parsearg{\doifset{\else \let\next=\ifclearfail}}}
\def\ifclearfail{\doignore{ifclear}}
+% @ifcommandisdefined CMD ... @end executes the `...' if CMD (written
+% without the @) is in fact defined. We can only feasibly check at the
+% TeX level, so something like `mathcode' is going to considered
+% defined even though it is not a Texinfo command.
+%
+\makecond{ifcommanddefined}
+\def\ifcommanddefined{\parsearg{\doifcmddefined{\let\next=\ifcmddefinedfail}}}
+%
+\def\doifcmddefined#1#2{{%
+ \makevalueexpandable
+ \let\next=\empty
+ \expandafter\ifx\csname #2\endcsname\relax
+ #1% If not defined, \let\next as above.
+ \fi
+ \expandafter
+ }\next
+}
+\def\ifcmddefinedfail{\doignore{ifcommanddefined}}
+
+% @ifcommandnotdefined CMD ... handled similar to @ifclear above.
+\makecond{ifcommandnotdefined}
+\def\ifcommandnotdefined{%
+ \parsearg{\doifcmddefined{\else \let\next=\ifcmdnotdefinedfail}}}
+\def\ifcmdnotdefinedfail{\doignore{ifcommandnotdefined}}
+
+% Set the `txicommandconditionals' variable, so documents have a way to
+% test if the @ifcommand...defined conditionals are available.
+\set txicommandconditionals
+
% @dircategory CATEGORY -- specify a category of the dir file
% which this file should belong to. Ignore this in TeX.
\let\dircategory=\comment
@@ -3874,11 +4390,11 @@ end
\def\dosynindex#1#2#3{%
% Only do \closeout if we haven't already done it, else we'll end up
% closing the target index.
- \expandafter \ifx\csname donesynindex#2\endcsname \undefined
+ \expandafter \ifx\csname donesynindex#2\endcsname \relax
% The \closeout helps reduce unnecessary open files; the limit on the
% Acorn RISC OS is a mere 16 files.
\expandafter\closeout\csname#2indfile\endcsname
- \expandafter\let\csname\donesynindex#2\endcsname = 1
+ \expandafter\let\csname donesynindex#2\endcsname = 1
\fi
% redefine \fooindfile:
\expandafter\let\expandafter\temp\expandafter=\csname#3indfile\endcsname
@@ -3913,11 +4429,14 @@ end
\def\@{@}% change to @@ when we switch to @ as escape char in index files.
\def\ {\realbackslash\space }%
%
- % Need these in case \tex is in effect and \{ is a \delimiter again.
- % But can't use \lbracecmd and \rbracecmd because texindex assumes
- % braces and backslashes are used only as delimiters.
- \let\{ = \mylbrace
- \let\} = \myrbrace
+ % Need these unexpandable (because we define \tt as a dummy)
+ % definitions when @{ or @} appear in index entry text. Also, more
+ % complicated, when \tex is in effect and \{ is a \delimiter again.
+ % We can't use \lbracecmd and \rbracecmd because texindex assumes
+ % braces and backslashes are used only as delimiters. Perhaps we
+ % should define @lbrace and @rbrace commands a la @comma.
+ \def\{{{\tt\char123}}%
+ \def\}{{\tt\char125}}%
%
% I don't entirely understand this, but when an index entry is
% generated from a macro call, the \endinput which \scanmacro inserts
@@ -3928,7 +4447,7 @@ end
% processing continues to some further point. On the other hand, it
% seems \endinput does not hurt in the printed index arg, since that
% is still getting written without apparent harm.
- %
+ %
% Sample source (mac-idx3.tex, reported by Graham Percival to
% help-texinfo, 22may06):
% @macro funindex {WORD}
@@ -3936,12 +4455,12 @@ end
% @end macro
% ...
% @funindex commtest
- %
+ %
% The above is not enough to reproduce the bug, but it gives the flavor.
- %
+ %
% Sample whatsit resulting:
% .@write3{\entry{xyz}{@folio }{@code {xyz@endinput }}}
- %
+ %
% So:
\let\endinput = \empty
%
@@ -3970,7 +4489,7 @@ end
\def\commondummies{%
%
% \definedummyword defines \#1 as \string\#1\space, thus effectively
- % preventing its expansion. This is used only for control% words,
+ % preventing its expansion. This is used only for control words,
% not control letters, because the \space would be incorrect for
% control characters, but is needed to separate the control word
% from whatever follows.
@@ -3989,23 +4508,28 @@ end
\commondummiesnofonts
%
\definedummyletter\_%
+ \definedummyletter\-%
%
% Non-English letters.
\definedummyword\AA
\definedummyword\AE
+ \definedummyword\DH
\definedummyword\L
- \definedummyword\OE
\definedummyword\O
+ \definedummyword\OE
+ \definedummyword\TH
\definedummyword\aa
\definedummyword\ae
+ \definedummyword\dh
+ \definedummyword\exclamdown
\definedummyword\l
- \definedummyword\oe
\definedummyword\o
- \definedummyword\ss
- \definedummyword\exclamdown
- \definedummyword\questiondown
+ \definedummyword\oe
\definedummyword\ordf
\definedummyword\ordm
+ \definedummyword\questiondown
+ \definedummyword\ss
+ \definedummyword\th
%
% Although these internal commands shouldn't show up, sometimes they do.
\definedummyword\bf
@@ -4021,21 +4545,27 @@ end
\definedummyword\TeX
%
% Assorted special characters.
+ \definedummyword\arrow
\definedummyword\bullet
\definedummyword\comma
\definedummyword\copyright
\definedummyword\registeredsymbol
\definedummyword\dots
\definedummyword\enddots
+ \definedummyword\entrybreak
\definedummyword\equiv
\definedummyword\error
\definedummyword\euro
+ \definedummyword\expansion
+ \definedummyword\geq
\definedummyword\guillemetleft
\definedummyword\guillemetright
\definedummyword\guilsinglleft
\definedummyword\guilsinglright
- \definedummyword\expansion
+ \definedummyword\lbracechar
+ \definedummyword\leq
\definedummyword\minus
+ \definedummyword\ogonek
\definedummyword\pounds
\definedummyword\point
\definedummyword\print
@@ -4045,6 +4575,7 @@ end
\definedummyword\quoteleft
\definedummyword\quoteright
\definedummyword\quotesinglbase
+ \definedummyword\rbracechar
\definedummyword\result
\definedummyword\textdegree
%
@@ -4079,6 +4610,7 @@ end
\definedummyword\v
\definedummyword\H
\definedummyword\dotaccent
+ \definedummyword\ogonek
\definedummyword\ringaccent
\definedummyword\tieaccent
\definedummyword\ubaraccent
@@ -4089,18 +4621,27 @@ end
\definedummyword\b
\definedummyword\i
\definedummyword\r
+ \definedummyword\sansserif
\definedummyword\sc
+ \definedummyword\slanted
\definedummyword\t
%
% Commands that take arguments.
+ \definedummyword\abbr
\definedummyword\acronym
+ \definedummyword\anchor
\definedummyword\cite
\definedummyword\code
\definedummyword\command
\definedummyword\dfn
+ \definedummyword\dmn
+ \definedummyword\email
\definedummyword\emph
\definedummyword\env
\definedummyword\file
+ \definedummyword\image
+ \definedummyword\indicateurl
+ \definedummyword\inforef
\definedummyword\kbd
\definedummyword\key
\definedummyword\math
@@ -4128,7 +4669,7 @@ end
\def\definedummyaccent##1{\let##1\asis}%
% We can just ignore other control letters.
\def\definedummyletter##1{\let##1\empty}%
- % Hopefully, all control words can become @asis.
+ % All control words become @asis by default; overrides below.
\let\definedummyword\definedummyaccent
%
\commondummiesnofonts
@@ -4140,48 +4681,63 @@ end
%
\def\ { }%
\def\@{@}%
- % how to handle braces?
\def\_{\normalunderscore}%
+ \def\-{}% @- shouldn't affect sorting
+ %
+ % Unfortunately, texindex is not prepared to handle braces in the
+ % content at all. So for index sorting, we map @{ and @} to strings
+ % starting with |, since that ASCII character is between ASCII { and }.
+ \def\{{|a}%
+ \def\lbracechar{|a}%
+ %
+ \def\}{|b}%
+ \def\rbracechar{|b}%
%
% Non-English letters.
\def\AA{AA}%
\def\AE{AE}%
+ \def\DH{DZZ}%
\def\L{L}%
\def\OE{OE}%
\def\O{O}%
+ \def\TH{ZZZ}%
\def\aa{aa}%
\def\ae{ae}%
+ \def\dh{dzz}%
+ \def\exclamdown{!}%
\def\l{l}%
\def\oe{oe}%
- \def\o{o}%
- \def\ss{ss}%
- \def\exclamdown{!}%
- \def\questiondown{?}%
\def\ordf{a}%
\def\ordm{o}%
+ \def\o{o}%
+ \def\questiondown{?}%
+ \def\ss{ss}%
+ \def\th{zzz}%
%
\def\LaTeX{LaTeX}%
\def\TeX{TeX}%
%
% Assorted special characters.
% (The following {} will end up in the sort string, but that's ok.)
+ \def\arrow{->}%
\def\bullet{bullet}%
\def\comma{,}%
\def\copyright{copyright}%
- \def\registeredsymbol{R}%
\def\dots{...}%
\def\enddots{...}%
\def\equiv{==}%
\def\error{error}%
\def\euro{euro}%
+ \def\expansion{==>}%
+ \def\geq{>=}%
\def\guillemetleft{<<}%
\def\guillemetright{>>}%
\def\guilsinglleft{<}%
\def\guilsinglright{>}%
- \def\expansion{==>}%
+ \def\leq{<=}%
\def\minus{-}%
- \def\pounds{pounds}%
\def\point{.}%
+ \def\pounds{pounds}%
\def\print{-|}%
\def\quotedblbase{"}%
\def\quotedblleft{"}%
@@ -4189,22 +4745,31 @@ end
\def\quoteleft{`}%
\def\quoteright{'}%
\def\quotesinglbase{,}%
+ \def\registeredsymbol{R}%
\def\result{=>}%
- \def\textdegree{degrees}%
+ \def\textdegree{o}%
+ %
+ \expandafter\ifx\csname SETtxiindexlquoteignore\endcsname\relax
+ \else \indexlquoteignore \fi
%
% We need to get rid of all macros, leaving only the arguments (if present).
% Of course this is not nearly correct, but it is the best we can do for now.
% makeinfo does not expand macros in the argument to @deffn, which ends up
% writing an index entry, and texindex isn't prepared for an index sort entry
% that starts with \.
- %
+ %
% Since macro invocations are followed by braces, we can just redefine them
% to take a single TeX argument. The case of a macro invocation that
% goes to end-of-line is not handled.
- %
+ %
\macrolist
}
+% Undocumented (for FSFS 2nd ed.): @set txiindexlquoteignore makes us
+% ignore left quotes in the sort term.
+{\catcode`\`=\active
+ \gdef\indexlquoteignore{\let`=\empty}}
+
\let\indexbackslash=0 %overridden during \printindex.
\let\SETmarginindex=\relax % put index entries in margin (undocumented)?
@@ -4302,10 +4867,9 @@ end
%
% ..., ready, GO:
%
-\def\safewhatsit#1{%
-\ifhmode
+\def\safewhatsit#1{\ifhmode
#1%
-\else
+ \else
% \lastskip and \lastpenalty cannot both be nonzero simultaneously.
\whatsitskip = \lastskip
\edef\lastskipmacro{\the\lastskip}%
@@ -4329,7 +4893,6 @@ end
% to re-insert the same penalty (values >10000 are used for various
% signals); since we just inserted a non-discardable item, any
% following glue (such as a \parskip) would be a breakpoint. For example:
- %
% @deffn deffn-whatever
% @vindex index-whatever
% Description.
@@ -4342,8 +4905,7 @@ end
% (the whatsit from the \write), so we must insert a \nobreak.
\nobreak\vskip\whatsitskip
\fi
-\fi
-}
+\fi}
% The index entry written in the file actually looks like
% \entry {sortstring}{page}{topic}
@@ -4462,7 +5024,6 @@ end
% But this freezes the catcodes in the argument, and can cause problems to
% @code, which sets - active. This problem was fixed by a kludge---
% ``-'' was active throughout whole index, but this isn't really right.
-%
% The right solution is to prevent \entry from swallowing the whole text.
% --kasal, 21nov03
\def\entry{%
@@ -4499,10 +5060,17 @@ end
% columns.
\vskip 0pt plus1pt
%
+ % When reading the text of entry, convert explicit line breaks
+ % from @* into spaces. The user might give these in long section
+ % titles, for instance.
+ \def\*{\unskip\space\ignorespaces}%
+ \def\entrybreak{\hfil\break}%
+ %
% Swallow the left brace of the text (first parameter):
\afterassignment\doentry
\let\temp =
}
+\def\entrybreak{\unskip\space\ignorespaces}%
\def\doentry{%
\bgroup % Instead of the swallowed brace.
\noindent
@@ -4735,7 +5303,22 @@ end
\message{sectioning,}
% Chapters, sections, etc.
-% \unnumberedno is an oxymoron, of course. But we count the unnumbered
+% Let's start with @part.
+\outer\parseargdef\part{\partzzz{#1}}
+\def\partzzz#1{%
+ \chapoddpage
+ \null
+ \vskip.3\vsize % move it down on the page a bit
+ \begingroup
+ \noindent \titlefonts\rmisbold #1\par % the text
+ \let\lastnode=\empty % no node to associate with
+ \writetocentry{part}{#1}{}% but put it in the toc
+ \headingsoff % no headline or footline on the part page
+ \chapoddpage
+ \endgroup
+}
+
+% \unnumberedno is an oxymoron. But we count the unnumbered
% sections so that we can refer to them unambiguously in the pdf
% outlines by their "section number". We avoid collisions with chapter
% numbers by starting them at 10000. (If a document ever has 10000
@@ -4814,8 +5397,8 @@ end
\chardef\maxseclevel = 3
%
% A numbered section within an unnumbered changes to unnumbered too.
-% To achive this, remember the "biggest" unnum. sec. we are currently in:
-\chardef\unmlevel = \maxseclevel
+% To achieve this, remember the "biggest" unnum. sec. we are currently in:
+\chardef\unnlevel = \maxseclevel
%
% Trace whether the current chapter is an appendix or not:
% \chapheadtype is "N" or "A", unnumbered chapters are ignored.
@@ -4840,8 +5423,8 @@ end
% The heading type:
\def\headtype{#1}%
\if \headtype U%
- \ifnum \absseclevel < \unmlevel
- \chardef\unmlevel = \absseclevel
+ \ifnum \absseclevel < \unnlevel
+ \chardef\unnlevel = \absseclevel
\fi
\else
% Check for appendix sections:
@@ -4853,10 +5436,10 @@ end
\fi\fi
\fi
% Check for numbered within unnumbered:
- \ifnum \absseclevel > \unmlevel
+ \ifnum \absseclevel > \unnlevel
\def\headtype{U}%
\else
- \chardef\unmlevel = 3
+ \chardef\unnlevel = 3
\fi
\fi
% Now print the heading:
@@ -4910,7 +5493,9 @@ end
\gdef\chaplevelprefix{\the\chapno.}%
\resetallfloatnos
%
- \message{\putwordChapter\space \the\chapno}%
+ % \putwordChapter can contain complex things in translations.
+ \toks0=\expandafter{\putwordChapter}%
+ \message{\the\toks0 \space \the\chapno}%
%
% Write the actual heading.
\chapmacro{#1}{Ynumbered}{\the\chapno}%
@@ -4921,15 +5506,17 @@ end
\global\let\subsubsection = \numberedsubsubsec
}
-\outer\parseargdef\appendix{\apphead0{#1}} % normally apphead0 calls appendixzzz
+\outer\parseargdef\appendix{\apphead0{#1}} % normally calls appendixzzz
+%
\def\appendixzzz#1{%
\global\secno=0 \global\subsecno=0 \global\subsubsecno=0
\global\advance\appendixno by 1
\gdef\chaplevelprefix{\appendixletter.}%
\resetallfloatnos
%
- \def\appendixnum{\putwordAppendix\space \appendixletter}%
- \message{\appendixnum}%
+ % \putwordAppendix can contain complex things in translations.
+ \toks0=\expandafter{\putwordAppendix}%
+ \message{\the\toks0 \space \appendixletter}%
%
\chapmacro{#1}{Yappendix}{\appendixletter}%
%
@@ -4938,7 +5525,8 @@ end
\global\let\subsubsection = \appendixsubsubsec
}
-\outer\parseargdef\unnumbered{\unnmhead0{#1}} % normally unnmhead0 calls unnumberedzzz
+% normally unnmhead0 calls unnumberedzzz:
+\outer\parseargdef\unnumbered{\unnmhead0{#1}}
\def\unnumberedzzz#1{%
\global\secno=0 \global\subsecno=0 \global\subsubsecno=0
\global\advance\unnumberedno by 1
@@ -4982,40 +5570,47 @@ end
\let\top\unnumbered
% Sections.
+%
\outer\parseargdef\numberedsec{\numhead1{#1}} % normally calls seczzz
\def\seczzz#1{%
\global\subsecno=0 \global\subsubsecno=0 \global\advance\secno by 1
\sectionheading{#1}{sec}{Ynumbered}{\the\chapno.\the\secno}%
}
-\outer\parseargdef\appendixsection{\apphead1{#1}} % normally calls appendixsectionzzz
+% normally calls appendixsectionzzz:
+\outer\parseargdef\appendixsection{\apphead1{#1}}
\def\appendixsectionzzz#1{%
\global\subsecno=0 \global\subsubsecno=0 \global\advance\secno by 1
\sectionheading{#1}{sec}{Yappendix}{\appendixletter.\the\secno}%
}
\let\appendixsec\appendixsection
-\outer\parseargdef\unnumberedsec{\unnmhead1{#1}} % normally calls unnumberedseczzz
+% normally calls unnumberedseczzz:
+\outer\parseargdef\unnumberedsec{\unnmhead1{#1}}
\def\unnumberedseczzz#1{%
\global\subsecno=0 \global\subsubsecno=0 \global\advance\secno by 1
\sectionheading{#1}{sec}{Ynothing}{\the\unnumberedno.\the\secno}%
}
% Subsections.
-\outer\parseargdef\numberedsubsec{\numhead2{#1}} % normally calls numberedsubseczzz
+%
+% normally calls numberedsubseczzz:
+\outer\parseargdef\numberedsubsec{\numhead2{#1}}
\def\numberedsubseczzz#1{%
\global\subsubsecno=0 \global\advance\subsecno by 1
\sectionheading{#1}{subsec}{Ynumbered}{\the\chapno.\the\secno.\the\subsecno}%
}
-\outer\parseargdef\appendixsubsec{\apphead2{#1}} % normally calls appendixsubseczzz
+% normally calls appendixsubseczzz:
+\outer\parseargdef\appendixsubsec{\apphead2{#1}}
\def\appendixsubseczzz#1{%
\global\subsubsecno=0 \global\advance\subsecno by 1
\sectionheading{#1}{subsec}{Yappendix}%
{\appendixletter.\the\secno.\the\subsecno}%
}
-\outer\parseargdef\unnumberedsubsec{\unnmhead2{#1}} %normally calls unnumberedsubseczzz
+% normally calls unnumberedsubseczzz:
+\outer\parseargdef\unnumberedsubsec{\unnmhead2{#1}}
\def\unnumberedsubseczzz#1{%
\global\subsubsecno=0 \global\advance\subsecno by 1
\sectionheading{#1}{subsec}{Ynothing}%
@@ -5023,21 +5618,25 @@ end
}
% Subsubsections.
-\outer\parseargdef\numberedsubsubsec{\numhead3{#1}} % normally numberedsubsubseczzz
+%
+% normally numberedsubsubseczzz:
+\outer\parseargdef\numberedsubsubsec{\numhead3{#1}}
\def\numberedsubsubseczzz#1{%
\global\advance\subsubsecno by 1
\sectionheading{#1}{subsubsec}{Ynumbered}%
{\the\chapno.\the\secno.\the\subsecno.\the\subsubsecno}%
}
-\outer\parseargdef\appendixsubsubsec{\apphead3{#1}} % normally appendixsubsubseczzz
+% normally appendixsubsubseczzz:
+\outer\parseargdef\appendixsubsubsec{\apphead3{#1}}
\def\appendixsubsubseczzz#1{%
\global\advance\subsubsecno by 1
\sectionheading{#1}{subsubsec}{Yappendix}%
{\appendixletter.\the\secno.\the\subsecno.\the\subsubsecno}%
}
-\outer\parseargdef\unnumberedsubsubsec{\unnmhead3{#1}} %normally unnumberedsubsubseczzz
+% normally unnumberedsubsubseczzz:
+\outer\parseargdef\unnumberedsubsubsec{\unnmhead3{#1}}
\def\unnumberedsubsubseczzz#1{%
\global\advance\subsubsecno by 1
\sectionheading{#1}{subsubsec}{Ynothing}%
@@ -5053,15 +5652,6 @@ end
% Define @majorheading, @heading and @subheading
-% NOTE on use of \vbox for chapter headings, section headings, and such:
-% 1) We use \vbox rather than the earlier \line to permit
-% overlong headings to fold.
-% 2) \hyphenpenalty is set to 10000 because hyphenation in a
-% heading is obnoxious; this forbids it.
-% 3) Likewise, headings look best if no \parindent is used, and
-% if justification is not attempted. Hence \raggedright.
-
-
\def\majorheading{%
{\advance\chapheadingskip by 10pt \chapbreak }%
\parsearg\chapheadingzzz
@@ -5069,10 +5659,8 @@ end
\def\chapheading{\chapbreak \parsearg\chapheadingzzz}
\def\chapheadingzzz#1{%
- {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
- \parindent=0pt\raggedright
- \rm #1\hfill}}%
- \bigskip \par\penalty 200\relax
+ \vbox{\chapfonts \raggedtitlesettings #1\par}%
+ \nobreak\bigskip \nobreak
\suppressfirstparagraphindent
}
@@ -5088,14 +5676,13 @@ end
% (including whitespace, linebreaking, etc. around it),
% given all the information in convenient, parsed form.
-%%% Args are the skip and penalty (usually negative)
+% Args are the skip and penalty (usually negative)
\def\dobreak#1#2{\par\ifdim\lastskip<#1\removelastskip\penalty#2\vskip#1\fi}
-%%% Define plain chapter starts, and page on/off switching for it
% Parameter controlling skip before chapter headings (if needed)
-
\newskip\chapheadingskip
+% Define plain chapter starts, and page on/off switching for it.
\def\chapbreak{\dobreak \chapheadingskip {-4000}}
\def\chappager{\par\vfill\supereject}
% Because \domark is called before \chapoddpage, the filler page will
@@ -5105,9 +5692,8 @@ end
\chappager
\ifodd\pageno \else
\begingroup
- \evenheadline={\hfil}\evenfootline={\hfil}%
- \oddheadline={\hfil}\oddfootline={\hfil}%
- \hbox to 0pt{}%
+ \headingsoff
+ \null
\chappager
\endgroup
\fi
@@ -5163,7 +5749,10 @@ end
\xdef\lastchapterdefs{%
\gdef\noexpand\thischaptername{\the\toks0}%
\gdef\noexpand\thischapternum{\appendixletter}%
- \gdef\noexpand\thischapter{\putwordAppendix{} \noexpand\thischapternum:
+ % \noexpand\putwordAppendix avoids expanding indigestible
+ % commands in some of the translations.
+ \gdef\noexpand\thischapter{\noexpand\putwordAppendix{}
+ \noexpand\thischapternum:
\noexpand\thischaptername}%
}%
\else
@@ -5171,7 +5760,10 @@ end
\xdef\lastchapterdefs{%
\gdef\noexpand\thischaptername{\the\toks0}%
\gdef\noexpand\thischapternum{\the\chapno}%
- \gdef\noexpand\thischapter{\putwordChapter{} \noexpand\thischapternum:
+ % \noexpand\putwordChapter avoids expanding indigestible
+ % commands in some of the translations.
+ \gdef\noexpand\thischapter{\noexpand\putwordChapter{}
+ \noexpand\thischapternum:
\noexpand\thischaptername}%
}%
\fi\fi\fi
@@ -5190,7 +5782,7 @@ end
\domark
%
{%
- \chapfonts \rm
+ \chapfonts \rmisbold
%
% Have to define \lastsection before calling \donoderef, because the
% xref code eventually uses it. On the other hand, it has to be called
@@ -5227,8 +5819,7 @@ end
%
% Typeset the actual heading.
\nobreak % Avoid page breaks at the interline glue.
- \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \raggedright
- \hangindent=\wd0 \centerparametersmaybe
+ \vbox{\raggedtitlesettings \hangindent=\wd0 \centerparametersmaybe
\unhbox0 #1\par}%
}%
\nobreak\bigskip % no page break after a chapter title
@@ -5250,18 +5841,18 @@ end
\def\setchapterstyle #1 {\csname CHAPF#1\endcsname}
%
\def\unnchfopen #1{%
-\chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
- \parindent=0pt\raggedright
- \rm #1\hfill}}\bigskip \par\nobreak
+ \chapoddpage
+ \vbox{\chapfonts \raggedtitlesettings #1\par}%
+ \nobreak\bigskip\nobreak
}
\def\chfopen #1#2{\chapoddpage {\chapfonts
\vbox to 3in{\vfil \hbox to\hsize{\hfil #2} \hbox to\hsize{\hfil #1} \vfil}}%
\par\penalty 5000 %
}
\def\centerchfopen #1{%
-\chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
- \parindent=0pt
- \hfill {\rm #1}\hfill}}\bigskip \par\nobreak
+ \chapoddpage
+ \vbox{\chapfonts \raggedtitlesettings \hfill #1\hfill}%
+ \nobreak\bigskip \nobreak
}
\def\CHAPFopen{%
\global\let\chapmacro=\chfopen
@@ -5293,8 +5884,10 @@ end
%
\def\sectionheading#1#2#3#4{%
{%
+ \checkenv{}% should not be in an environment.
+ %
% Switch to the right set of fonts.
- \csname #2fonts\endcsname \rm
+ \csname #2fonts\endcsname \rmisbold
%
\def\sectionlevel{#2}%
\def\temptype{#3}%
@@ -5314,7 +5907,10 @@ end
\xdef\lastsectiondefs{%
\gdef\noexpand\thissectionname{\the\toks0}%
\gdef\noexpand\thissectionnum{#4}%
- \gdef\noexpand\thissection{\putwordSection{} \noexpand\thissectionnum:
+ % \noexpand\putwordSection avoids expanding indigestible
+ % commands in some of the translations.
+ \gdef\noexpand\thissection{\noexpand\putwordSection{}
+ \noexpand\thissectionnum:
\noexpand\thissectionname}%
}%
\fi
@@ -5324,12 +5920,20 @@ end
\xdef\lastsectiondefs{%
\gdef\noexpand\thissectionname{\the\toks0}%
\gdef\noexpand\thissectionnum{#4}%
- \gdef\noexpand\thissection{\putwordSection{} \noexpand\thissectionnum:
+ % \noexpand\putwordSection avoids expanding indigestible
+ % commands in some of the translations.
+ \gdef\noexpand\thissection{\noexpand\putwordSection{}
+ \noexpand\thissectionnum:
\noexpand\thissectionname}%
}%
\fi
\fi\fi\fi
%
+ % Go into vertical mode. Usually we'll already be there, but we
+ % don't want the following whatsit to end up in a preceding paragraph
+ % if the document didn't happen to have a blank line.
+ \par
+ %
% Output the mark. Pass it through \safewhatsit, to take care of
% the preceding space.
\safewhatsit\domark
@@ -5339,7 +5943,7 @@ end
%
% Now the second mark, after the heading break. No break points
% between here and the heading.
- \let\prevsectiondefs=\lastsectiondefs
+ \global\let\prevsectiondefs=\lastsectiondefs
\domark
%
% Only insert the space after the number if we have a section number.
@@ -5379,7 +5983,7 @@ end
\nobreak
%
% Output the actual section heading.
- \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \raggedright
+ \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \ptexraggedright
\hangindent=\wd0 % zero if no section number
\unhbox0 #1}%
}%
@@ -5393,15 +5997,15 @@ end
%
% We'll almost certainly start a paragraph next, so don't let that
% glue accumulate. (Not a breakpoint because it's preceded by a
- % discardable item.)
+ % discardable item.) However, when a paragraph is not started next
+ % (\startdefun, \cartouche, \center, etc.), this needs to be wiped out
+ % or the negative glue will cause weirdly wrong output, typically
+ % obscuring the section heading with something else.
\vskip-\parskip
- %
- % This is purely so the last item on the list is a known \penalty >
- % 10000. This is so \startdefun can avoid allowing breakpoints after
- % section headings. Otherwise, it would insert a valid breakpoint between:
- %
- % @section sec-whatever
- % @deffn def-whatever
+ %
+ % This is so the last item on the main vertical list is a known
+ % \penalty > 10000, so \startdefun, etc., can recognize the situation
+ % and do the needful.
\penalty 10001
}
@@ -5457,7 +6061,7 @@ end
% These characters do not print properly in the Computer Modern roman
% fonts, so we must take special care. This is more or less redundant
% with the Texinfo input format setup at the end of this file.
-%
+%
\def\activecatcodes{%
\catcode`\"=\active
\catcode`\$=\active
@@ -5507,7 +6111,7 @@ end
% redefined for the two-volume lispref. We always output on
% \jobname.toc even if this is redefined.
-%
+%
\def\tocreadfilename{\jobname.toc}
% Normal (long) toc.
@@ -5533,6 +6137,7 @@ end
\def\summarycontents{%
\startcontents{\putwordShortTOC}%
%
+ \let\partentry = \shortpartentry
\let\numchapentry = \shortchapentry
\let\appentry = \shortchapentry
\let\unnchapentry = \shortunnchapentry
@@ -5588,6 +6193,19 @@ end
% The last argument is the page number.
% The arguments in between are the chapter number, section number, ...
+% Parts, in the main contents. Replace the part number, which doesn't
+% exist, with an empty box. Let's hope all the numbers have the same width.
+% Also ignore the page number, which is conventionally not printed.
+\def\numeralbox{\setbox0=\hbox{8}\hbox to \wd0{\hfil}}
+\def\partentry#1#2#3#4{\dochapentry{\numeralbox\labelspace#1}{}}
+%
+% Parts, in the short toc.
+\def\shortpartentry#1#2#3#4{%
+ \penalty-300
+ \vskip.5\baselineskip plus.15\baselineskip minus.1\baselineskip
+ \shortchapentry{{\bf #1}}{\numeralbox}{}{}%
+}
+
% Chapters, in the main contents.
\def\numchapentry#1#2#3#4{\dochapentry{#2\labelspace#1}{#4}}
%
@@ -5677,46 +6295,12 @@ end
\message{environments,}
% @foo ... @end foo.
-% @point{}, @result{}, @expansion{}, @print{}, @equiv{}.
-%
-% Since these characters are used in examples, they should be an even number of
-% \tt widths. Each \tt character is 1en, so two makes it 1em.
-%
-\def\point{$\star$}
-\def\arrow{\leavevmode\raise.05ex\hbox to 1em{\hfil$\rightarrow$\hfil}}
-\def\result{\leavevmode\raise.05ex\hbox to 1em{\hfil$\Rightarrow$\hfil}}
-\def\expansion{\leavevmode\hbox to 1em{\hfil$\mapsto$\hfil}}
-\def\print{\leavevmode\lower.1ex\hbox to 1em{\hfil$\dashv$\hfil}}
-\def\equiv{\leavevmode\hbox to 1em{\hfil$\ptexequiv$\hfil}}
-
-% The @error{} command.
-% Adapted from the TeXbook's \boxit.
-%
-\newbox\errorbox
-%
-{\tentt \global\dimen0 = 3em}% Width of the box.
-\dimen2 = .55pt % Thickness of rules
-% The text. (`r' is open on the right, `e' somewhat less so on the left.)
-\setbox0 = \hbox{\kern-.75pt \reducedsf error\kern-1.5pt}
-%
-\setbox\errorbox=\hbox to \dimen0{\hfil
- \hsize = \dimen0 \advance\hsize by -5.8pt % Space to left+right.
- \advance\hsize by -2\dimen2 % Rules.
- \vbox{%
- \hrule height\dimen2
- \hbox{\vrule width\dimen2 \kern3pt % Space to left of text.
- \vtop{\kern2.4pt \box0 \kern2.4pt}% Space above/below.
- \kern3pt\vrule width\dimen2}% Space to right.
- \hrule height\dimen2}
- \hfil}
-%
-\def\error{\leavevmode\lower.7ex\copy\errorbox}
-
-% @tex ... @end tex escapes into raw Tex temporarily.
+% @tex ... @end tex escapes into raw TeX temporarily.
% One exception: @ is still an escape character, so that @end tex works.
-% But \@ or @@ will get a plain tex @ character.
+% But \@ or @@ will get a plain @ character.
\envdef\tex{%
+ \setupmarkupstyle{tex}%
\catcode `\\=0 \catcode `\{=1 \catcode `\}=2
\catcode `\$=3 \catcode `\&=4 \catcode `\#=6
\catcode `\^=7 \catcode `\_=8 \catcode `\~=\active \let~=\tie
@@ -5726,8 +6310,14 @@ end
\catcode `\|=\other
\catcode `\<=\other
\catcode `\>=\other
+ \catcode `\`=\other
+ \catcode `\'=\other
\escapechar=`\\
%
+ % ' is active in math mode (mathcode"8000). So reset it, and all our
+ % other math active characters (just in case), to plain's definitions.
+ \mathactive
+ %
\let\b=\ptexb
\let\bullet=\ptexbullet
\let\c=\ptexc
@@ -5745,7 +6335,7 @@ end
\let\/=\ptexslash
\let\*=\ptexstar
\let\t=\ptext
- \expandafter \let\csname top\endcsname=\ptextop % outer
+ \expandafter \let\csname top\endcsname=\ptextop % we've made it outer
\let\frenchspacing=\plainfrenchspacing
%
\def\endldots{\mathinner{\ldots\ldots\ldots\ldots}}%
@@ -5831,6 +6421,12 @@ end
\normbskip=\baselineskip \normpskip=\parskip \normlskip=\lineskip
% Flag to tell @lisp, etc., not to narrow margin.
\let\nonarrowing = t%
+ %
+ % If this cartouche directly follows a sectioning command, we need the
+ % \parskip glue (backspaced over by default) or the cartouche can
+ % collide with the section heading.
+ \ifnum\lastpenalty>10000 \vskip\parskip \penalty\lastpenalty \fi
+ %
\vbox\bgroup
\baselineskip=0pt\parskip=0pt\lineskip=0pt
\carttop
@@ -5844,7 +6440,7 @@ end
\lineskip=\normlskip
\parskip=\normpskip
\vskip -\parskip
- \comment % For explanation, see the end of \def\group.
+ \comment % For explanation, see the end of def\group.
}
\def\Ecartouche{%
\ifhmode\par\fi
@@ -5861,14 +6457,20 @@ end
% This macro is called at the beginning of all the @example variants,
% inside a group.
+\newdimen\nonfillparindent
\def\nonfillstart{%
\aboveenvbreak
- \hfuzz = 12pt % Don't be fussy
+ \ifdim\hfuzz < 12pt \hfuzz = 12pt \fi % Don't be fussy
\sepspaces % Make spaces be word-separators rather than space tokens.
\let\par = \lisppar % don't ignore blank lines
\obeylines % each line of input is a line of output
\parskip = 0pt
+ % Turn off paragraph indentation but redefine \indent to emulate
+ % the normal \indent.
+ \nonfillparindent=\parindent
\parindent = 0pt
+ \let\indent\nonfillindent
+ %
\emergencystretch = 0pt % don't try to avoid overfull boxes
\ifx\nonarrowing\relax
\advance \leftskip by \lispnarrowing
@@ -5879,6 +6481,24 @@ end
\let\exdent=\nofillexdent
}
+\begingroup
+\obeyspaces
+% We want to swallow spaces (but not other tokens) after the fake
+% @indent in our nonfill-environments, where spaces are normally
+% active and set to @tie, resulting in them not being ignored after
+% @indent.
+\gdef\nonfillindent{\futurelet\temp\nonfillindentcheck}%
+\gdef\nonfillindentcheck{%
+\ifx\temp %
+\expandafter\nonfillindentgobble%
+\else%
+\leavevmode\nonfillindentbox%
+\fi%
+}%
+\endgroup
+\def\nonfillindentgobble#1{\nonfillindent}
+\def\nonfillindentbox{\hbox to \nonfillparindent{\hss}}
+
% If you want all examples etc. small: @set dispenvsize small.
% If you want even small examples the full size: @set dispenvsize nosmall.
% This affects the following displayed environments:
@@ -5906,41 +6526,42 @@ end
}
% We often define two environments, @foo and @smallfoo.
-% Let's do it by one command:
-\def\makedispenv #1#2{
- \expandafter\envdef\csname#1\endcsname {\setnormaldispenv #2}
- \expandafter\envdef\csname small#1\endcsname {\setsmalldispenv #2}
+% Let's do it in one command. #1 is the env name, #2 the definition.
+\def\makedispenvdef#1#2{%
+ \expandafter\envdef\csname#1\endcsname {\setnormaldispenv #2}%
+ \expandafter\envdef\csname small#1\endcsname {\setsmalldispenv #2}%
\expandafter\let\csname E#1\endcsname \afterenvbreak
\expandafter\let\csname Esmall#1\endcsname \afterenvbreak
}
-% Define two synonyms:
-\def\maketwodispenvs #1#2#3{
- \makedispenv{#1}{#3}
- \makedispenv{#2}{#3}
+% Define two environment synonyms (#1 and #2) for an environment.
+\def\maketwodispenvdef#1#2#3{%
+ \makedispenvdef{#1}{#3}%
+ \makedispenvdef{#2}{#3}%
}
-
-% @lisp: indented, narrowed, typewriter font; @example: same as @lisp.
+%
+% @lisp: indented, narrowed, typewriter font;
+% @example: same as @lisp.
%
% @smallexample and @smalllisp: use smaller fonts.
% Originally contributed by Pavel@xerox.
%
-\maketwodispenvs {lisp}{example}{%
+\maketwodispenvdef{lisp}{example}{%
\nonfillstart
- \tt\quoteexpand
+ \tt\setupmarkupstyle{example}%
\let\kbdfont = \kbdexamplefont % Allow @kbd to do something special.
- \gobble % eat return
+ \gobble % eat return
}
% @display/@smalldisplay: same as @lisp except keep current font.
%
-\makedispenv {display}{%
+\makedispenvdef{display}{%
\nonfillstart
\gobble
}
% @format/@smallformat: same as @display except don't narrow margins.
%
-\makedispenv{format}{%
+\makedispenvdef{format}{%
\let\nonarrowing = t%
\nonfillstart
\gobble
@@ -5959,28 +6580,47 @@ end
\envdef\flushright{%
\let\nonarrowing = t%
\nonfillstart
- \advance\leftskip by 0pt plus 1fill
+ \advance\leftskip by 0pt plus 1fill\relax
\gobble
}
\let\Eflushright = \afterenvbreak
+% @raggedright does more-or-less normal line breaking but no right
+% justification. From plain.tex.
+\envdef\raggedright{%
+ \rightskip0pt plus2em \spaceskip.3333em \xspaceskip.5em\relax
+}
+\let\Eraggedright\par
+
+\envdef\raggedleft{%
+ \parindent=0pt \leftskip0pt plus2em
+ \spaceskip.3333em \xspaceskip.5em \parfillskip=0pt
+ \hbadness=10000 % Last line will usually be underfull, so turn off
+ % badness reporting.
+}
+\let\Eraggedleft\par
+
+\envdef\raggedcenter{%
+ \parindent=0pt \rightskip0pt plus1em \leftskip0pt plus1em
+ \spaceskip.3333em \xspaceskip.5em \parfillskip=0pt
+ \hbadness=10000 % Last line will usually be underfull, so turn off
+ % badness reporting.
+}
+\let\Eraggedcenter\par
+
+
% @quotation does normal linebreaking (hence we can't use \nonfillstart)
% and narrows the margins. We keep \parskip nonzero in general, since
% we're doing normal filling. So, when using \aboveenvbreak and
% \afterenvbreak, temporarily make \parskip 0.
%
-\envdef\quotation{%
- {\parskip=0pt \aboveenvbreak}% because \aboveenvbreak inserts \parskip
- \parindent=0pt
- %
- % @cartouche defines \nonarrowing to inhibit narrowing at next level down.
+\makedispenvdef{quotation}{\quotationstart}
+%
+\def\quotationstart{%
+ \indentedblockstart % same as \indentedblock, but increase right margin too.
\ifx\nonarrowing\relax
- \advance\leftskip by \lispnarrowing
\advance\rightskip by \lispnarrowing
- \exdentamount = \lispnarrowing
- \else
- \let\nonarrowing = \relax
\fi
\parsearg\quotationlabel
}
@@ -5990,12 +6630,13 @@ end
%
\def\Equotation{%
\par
- \ifx\quotationauthor\undefined\else
+ \ifx\quotationauthor\thisisundefined\else
% indent a bit.
\leftline{\kern 2\leftskip \sl ---\quotationauthor}%
\fi
{\parskip=0pt \afterenvbreak}%
}
+\def\Esmallquotation{\Equotation}
% If we're given an argument, typeset it in bold with a colon after.
\def\quotationlabel#1{%
@@ -6005,6 +6646,32 @@ end
\fi
}
+% @indentedblock is like @quotation, but indents only on the left and
+% has no optional argument.
+%
+\makedispenvdef{indentedblock}{\indentedblockstart}
+%
+\def\indentedblockstart{%
+ {\parskip=0pt \aboveenvbreak}% because \aboveenvbreak inserts \parskip
+ \parindent=0pt
+ %
+ % @cartouche defines \nonarrowing to inhibit narrowing at next level down.
+ \ifx\nonarrowing\relax
+ \advance\leftskip by \lispnarrowing
+ \exdentamount = \lispnarrowing
+ \else
+ \let\nonarrowing = \relax
+ \fi
+}
+
+% Keep a nonzero parskip for the environment, since we're doing normal filling.
+%
+\def\Eindentedblock{%
+ \par
+ {\parskip=0pt \afterenvbreak}%
+}
+\def\Esmallindentedblock{\Eindentedblock}
+
% LaTeX-like @verbatim...@end verbatim and @verb{<char>...<char>}
% If we want to allow any <char> as delimiter,
@@ -6020,18 +6687,16 @@ end
\do\ \do\\\do\{\do\}\do\$\do\&%
\do\#\do\^\do\^^K\do\_\do\^^A\do\%\do\~%
\do\<\do\>\do\|\do\@\do+\do\"%
+ % Don't do the quotes -- if we do, @set txicodequoteundirected and
+ % @set txicodequotebacktick will not have effect on @verb and
+ % @verbatim, and ?` and !` ligatures won't get disabled.
+ %\do\`\do\'%
}
%
% [Knuth] p. 380
\def\uncatcodespecials{%
\def\do##1{\catcode`##1=\other}\dospecials}
%
-% [Knuth] pp. 380,381,391
-% Disable Spanish ligatures ?` and !` of \tt font
-\begingroup
- \catcode`\`=\active\gdef`{\relax\lq}
-\endgroup
-%
% Setup for the @verb command.
%
% Eight spaces for a tab
@@ -6043,7 +6708,7 @@ end
\def\setupverb{%
\tt % easiest (and conventionally used) font for verbatim
\def\par{\leavevmode\endgraf}%
- \catcode`\`=\active
+ \setupmarkupstyle{verb}%
\tabeightspaces
% Respect line breaks,
% print special symbols as themselves, and
@@ -6054,73 +6719,46 @@ end
% Setup for the @verbatim environment
%
-% Real tab expansion
+% Real tab expansion.
\newdimen\tabw \setbox0=\hbox{\tt\space} \tabw=8\wd0 % tab amount
%
-\def\starttabbox{\setbox0=\hbox\bgroup}
-
-% Allow an option to not replace quotes with a regular directed right
-% quote/apostrophe (char 0x27), but instead use the undirected quote
-% from cmtt (char 0x0d). The undirected quote is ugly, so don't make it
-% the default, but it works for pasting with more pdf viewers (at least
-% evince), the lilypond developers report. xpdf does work with the
-% regular 0x27.
-%
-\def\codequoteright{%
- \expandafter\ifx\csname SETtxicodequoteundirected\endcsname\relax
- \expandafter\ifx\csname SETcodequoteundirected\endcsname\relax
- '%
- \else \char'15 \fi
- \else \char'15 \fi
-}
-%
-% and a similar option for the left quote char vs. a grave accent.
-% Modern fonts display ASCII 0x60 as a grave accent, so some people like
-% the code environments to do likewise.
-%
-\def\codequoteleft{%
- \expandafter\ifx\csname SETtxicodequotebacktick\endcsname\relax
- \expandafter\ifx\csname SETcodequotebacktick\endcsname\relax
- `%
- \else \char'22 \fi
- \else \char'22 \fi
-}
+% We typeset each line of the verbatim in an \hbox, so we can handle
+% tabs. The \global is in case the verbatim line starts with an accent,
+% or some other command that starts with a begin-group. Otherwise, the
+% entire \verbbox would disappear at the corresponding end-group, before
+% it is typeset. Meanwhile, we can't have nested verbatim commands
+% (can we?), so the \global won't be overwriting itself.
+\newbox\verbbox
+\def\starttabbox{\global\setbox\verbbox=\hbox\bgroup}
%
\begingroup
\catcode`\^^I=\active
\gdef\tabexpand{%
\catcode`\^^I=\active
\def^^I{\leavevmode\egroup
- \dimen0=\wd0 % the width so far, or since the previous tab
- \divide\dimen0 by\tabw
- \multiply\dimen0 by\tabw % compute previous multiple of \tabw
- \advance\dimen0 by\tabw % advance to next multiple of \tabw
- \wd0=\dimen0 \box0 \starttabbox
+ \dimen\verbbox=\wd\verbbox % the width so far, or since the previous tab
+ \divide\dimen\verbbox by\tabw
+ \multiply\dimen\verbbox by\tabw % compute previous multiple of \tabw
+ \advance\dimen\verbbox by\tabw % advance to next multiple of \tabw
+ \wd\verbbox=\dimen\verbbox \box\verbbox \starttabbox
}%
}
- \catcode`\'=\active
- \gdef\rquoteexpand{\catcode\rquoteChar=\active \def'{\codequoteright}}%
- %
- \catcode`\`=\active
- \gdef\lquoteexpand{\catcode\lquoteChar=\active \def`{\codequoteleft}}%
- %
- \gdef\quoteexpand{\rquoteexpand \lquoteexpand}%
\endgroup
% start the verbatim environment.
\def\setupverbatim{%
\let\nonarrowing = t%
\nonfillstart
- % Easiest (and conventionally used) font for verbatim
- \tt
- \def\par{\leavevmode\egroup\box0\endgraf}%
- \catcode`\`=\active
+ \tt % easiest (and conventionally used) font for verbatim
+ % The \leavevmode here is for blank lines. Otherwise, we would
+ % never \starttabox and the \egroup would end verbatim mode.
+ \def\par{\leavevmode\egroup\box\verbbox\endgraf}%
\tabexpand
- \quoteexpand
+ \setupmarkupstyle{verbatim}%
% Respect line breaks,
% print special symbols as themselves, and
- % make each space count
- % must do in this order:
+ % make each space count.
+ % Must do in this order:
\obeylines \uncatcodespecials \sepspaces
\everypar{\starttabbox}%
}
@@ -6176,6 +6814,8 @@ end
{%
\makevalueexpandable
\setupverbatim
+ \indexnofonts % Allow `@@' and other weird things in file names.
+ \wlog{texinfo.tex: doing @verbatiminclude of #1^^J}%
\input #1
\afterenvbreak
}%
@@ -6225,7 +6865,7 @@ end
% commands also insert a nobreak penalty, and we don't want to allow
% a break between a section heading and a defun.
%
- % As a minor refinement, we avoid "club" headers by signalling
+ % As a further refinement, we avoid "club" headers by signalling
% with penalty of 10003 after the very first @deffn in the
% sequence (see above), and penalty of 10002 after any following
% @def command.
@@ -6262,7 +6902,7 @@ end
#1#2 \endheader
% common ending:
\interlinepenalty = 10000
- \advance\rightskip by 0pt plus 1fil
+ \advance\rightskip by 0pt plus 1fil\relax
\endgraf
\nobreak\vskip -\parskip
\penalty\defunpenalty % signal to \startdefun and \dodefunx
@@ -6292,13 +6932,36 @@ end
\def\domakedefun#1#2#3{%
\envdef#1{%
\startdefun
+ \doingtypefnfalse % distinguish typed functions from all else
\parseargusing\activeparens{\printdefunline#3}%
}%
\def#2{\dodefunx#1}%
\def#3%
}
-%%% Untyped functions:
+\newif\ifdoingtypefn % doing typed function?
+\newif\ifrettypeownline % typeset return type on its own line?
+
+% @deftypefnnewline on|off says whether the return type of typed functions
+% are printed on their own line. This affects @deftypefn, @deftypefun,
+% @deftypeop, and @deftypemethod.
+%
+\parseargdef\deftypefnnewline{%
+ \def\temp{#1}%
+ \ifx\temp\onword
+ \expandafter\let\csname SETtxideftypefnnl\endcsname
+ = \empty
+ \else\ifx\temp\offword
+ \expandafter\let\csname SETtxideftypefnnl\endcsname
+ = \relax
+ \else
+ \errhelp = \EMsimple
+ \errmessage{Unknown @txideftypefnnl value `\temp',
+ must be on|off}%
+ \fi\fi
+}
+
+% Untyped functions:
% @deffn category name args
\makedefun{deffn}{\deffngeneral{}}
@@ -6317,7 +6980,7 @@ end
\defname{#2}{}{#3}\magicamp\defunargs{#4\unskip}%
}
-%%% Typed functions:
+% Typed functions:
% @deftypefn category type name args
\makedefun{deftypefn}{\deftypefngeneral{}}
@@ -6332,10 +6995,11 @@ end
%
\def\deftypefngeneral#1#2 #3 #4 #5\endheader{%
\dosubind{fn}{\code{#4}}{#1}%
+ \doingtypefntrue
\defname{#2}{#3}{#4}\defunargs{#5\unskip}%
}
-%%% Typed variables:
+% Typed variables:
% @deftypevr category type var args
\makedefun{deftypevr}{\deftypecvgeneral{}}
@@ -6353,7 +7017,7 @@ end
\defname{#2}{#3}{#4}\defunargs{#5\unskip}%
}
-%%% Untyped variables:
+% Untyped variables:
% @defvr category var args
\makedefun{defvr}#1 {\deftypevrheader{#1} {} }
@@ -6364,7 +7028,8 @@ end
% \defcvof {category of}class var args
\def\defcvof#1#2 {\deftypecvof{#1}#2 {} }
-%%% Type:
+% Types:
+
% @deftp category name args
\makedefun{deftp}#1 #2 #3\endheader{%
\doind{tp}{\code{#2}}%
@@ -6392,25 +7057,49 @@ end
% We are followed by (but not passed) the arguments, if any.
%
\def\defname#1#2#3{%
+ \par
% Get the values of \leftskip and \rightskip as they were outside the @def...
\advance\leftskip by -\defbodyindent
%
- % How we'll format the type name. Putting it in brackets helps
+ % Determine if we are typesetting the return type of a typed function
+ % on a line by itself.
+ \rettypeownlinefalse
+ \ifdoingtypefn % doing a typed function specifically?
+ % then check user option for putting return type on its own line:
+ \expandafter\ifx\csname SETtxideftypefnnl\endcsname\relax \else
+ \rettypeownlinetrue
+ \fi
+ \fi
+ %
+ % How we'll format the category name. Putting it in brackets helps
% distinguish it from the body text that may end up on the next line
% just below it.
\def\temp{#1}%
\setbox0=\hbox{\kern\deflastargmargin \ifx\temp\empty\else [\rm\temp]\fi}
%
- % Figure out line sizes for the paragraph shape.
+ % Figure out line sizes for the paragraph shape. We'll always have at
+ % least two.
+ \tempnum = 2
+ %
% The first line needs space for \box0; but if \rightskip is nonzero,
% we need only space for the part of \box0 which exceeds it:
\dimen0=\hsize \advance\dimen0 by -\wd0 \advance\dimen0 by \rightskip
+ %
+ % If doing a return type on its own line, we'll have another line.
+ \ifrettypeownline
+ \advance\tempnum by 1
+ \def\maybeshapeline{0in \hsize}%
+ \else
+ \def\maybeshapeline{}%
+ \fi
+ %
% The continuations:
\dimen2=\hsize \advance\dimen2 by -\defargsindent
- % (plain.tex says that \dimen1 should be used only as global.)
- \parshape 2 0in \dimen0 \defargsindent \dimen2
%
- % Put the type name to the right margin.
+ % The final paragraph shape:
+ \parshape \tempnum 0in \dimen0 \maybeshapeline \defargsindent \dimen2
+ %
+ % Put the category name at the right margin.
\noindent
\hbox to 0pt{%
\hfil\box0 \kern-\hsize
@@ -6432,8 +7121,16 @@ end
% . this still does not fix the ?` and !` ligatures, but so far no
% one has made identifiers using them :).
\df \tt
- \def\temp{#2}% return value type
- \ifx\temp\empty\else \tclose{\temp} \fi
+ \def\temp{#2}% text of the return type
+ \ifx\temp\empty\else
+ \tclose{\temp}% typeset the return type
+ \ifrettypeownline
+ % put return type on its own line; prohibit line break following:
+ \hfil\vadjust{\nobreak}\break
+ \else
+ \space % type on same line, so just followed by a space
+ \fi
+ \fi % no return type
#3% output function name
}%
{\rm\enskip}% hskip 0.5 em of \tenrm
@@ -6453,8 +7150,11 @@ end
\df \sl \hyphenchar\font=0
%
% On the other hand, if an argument has two dashes (for instance), we
- % want a way to get ttsl. Let's try @var for that.
- \let\var=\ttslanted
+ % want a way to get ttsl. We used to recommend @var for that, so
+ % leave the code in, but it's strange for @var to lead to typewriter.
+ % Nowadays we recommend @code, since the difference between a ttsl hyphen
+ % and a tt hyphen is pretty tiny. @code also disables ?` !`.
+ \def\var##1{{\setupmarkupstyle{var}\ttslanted{##1}}}%
#1%
\sl\hyphenchar\font=45
}
@@ -6551,7 +7251,7 @@ end
% To do this right we need a feature of e-TeX, \scantokens,
% which we arrange to emulate with a temporary file in ordinary TeX.
-\ifx\eTeXversion\undefined
+\ifx\eTeXversion\thisisundefined
\newwrite\macscribble
\def\scantokens#1{%
\toks0={#1}%
@@ -6562,25 +7262,30 @@ end
}
\fi
-\def\scanmacro#1{%
- \begingroup
- \newlinechar`\^^M
- \let\xeatspaces\eatspaces
- % Undo catcode changes of \startcontents and \doprintindex
- % When called from @insertcopying or (short)caption, we need active
- % backslash to get it printed correctly. Previously, we had
- % \catcode`\\=\other instead. We'll see whether a problem appears
- % with macro expansion. --kasal, 19aug04
- \catcode`\@=0 \catcode`\\=\active \escapechar=`\@
- % ... and \example
- \spaceisspace
- %
- % Append \endinput to make sure that TeX does not see the ending newline.
- % I've verified that it is necessary both for e-TeX and for ordinary TeX
- % --kasal, 29nov03
- \scantokens{#1\endinput}%
- \endgroup
-}
+\def\scanmacro#1{\begingroup
+ \newlinechar`\^^M
+ \let\xeatspaces\eatspaces
+ %
+ % Undo catcode changes of \startcontents and \doprintindex
+ % When called from @insertcopying or (short)caption, we need active
+ % backslash to get it printed correctly. Previously, we had
+ % \catcode`\\=\other instead. We'll see whether a problem appears
+ % with macro expansion. --kasal, 19aug04
+ \catcode`\@=0 \catcode`\\=\active \escapechar=`\@
+ %
+ % ... and for \example:
+ \spaceisspace
+ %
+ % The \empty here causes a following catcode 5 newline to be eaten as
+ % part of reading whitespace after a control sequence. It does not
+ % eat a catcode 13 newline. There's no good way to handle the two
+ % cases (untried: maybe e-TeX's \everyeof could help, though plain TeX
+ % would then have different behavior). See the Macro Details node in
+ % the manual for the workaround we recommend for macros and
+ % line-oriented commands.
+ %
+ \scantokens{#1\empty}%
+\endgroup}
\def\scanexp#1{%
\edef\temp{\noexpand\scanmacro{#1}}%
@@ -6608,7 +7313,7 @@ end
% This does \let #1 = #2, with \csnames; that is,
% \let \csname#1\endcsname = \csname#2\endcsname
% (except of course we have to play expansion games).
-%
+%
\def\cslet#1#2{%
\expandafter\let
\csname#1\expandafter\endcsname
@@ -6634,17 +7339,18 @@ end
% Macro bodies are absorbed as an argument in a context where
% all characters are catcode 10, 11 or 12, except \ which is active
-% (as in normal texinfo). It is necessary to change the definition of \.
-
+% (as in normal texinfo). It is necessary to change the definition of \
+% to recognize macro arguments; this is the job of \mbodybackslash.
+%
% Non-ASCII encodings make 8-bit characters active, so un-activate
% them to avoid their expansion. Must do this non-globally, to
% confine the change to the current group.
-
+%
% It's necessary to have hard CRs when the macro is executed. This is
-% done by making ^^M (\endlinechar) catcode 12 when reading the macro
+% done by making ^^M (\endlinechar) catcode 12 when reading the macro
% body, and then making it the \newlinechar in \scanmacro.
-
-\def\scanctxt{%
+%
+\def\scanctxt{% used as subroutine
\catcode`\"=\other
\catcode`\+=\other
\catcode`\<=\other
@@ -6657,13 +7363,13 @@ end
\ifx\declaredencoding\ascii \else \setnonasciicharscatcodenonglobal\other \fi
}
-\def\scanargctxt{%
+\def\scanargctxt{% used for copying and captions, not macros.
\scanctxt
\catcode`\\=\other
\catcode`\^^M=\other
}
-\def\macrobodyctxt{%
+\def\macrobodyctxt{% used for @macro definitions
\scanctxt
\catcode`\{=\other
\catcode`\}=\other
@@ -6671,32 +7377,56 @@ end
\usembodybackslash
}
-\def\macroargctxt{%
+\def\macroargctxt{% used when scanning invocations
\scanctxt
- \catcode`\\=\other
+ \catcode`\\=0
}
+% why catcode 0 for \ in the above? To recognize \\ \{ \} as "escapes"
+% for the single characters \ { }. Thus, we end up with the "commands"
+% that would be written @\ @{ @} in a Texinfo document.
+%
+% We already have @{ and @}. For @\, we define it here, and only for
+% this purpose, to produce a typewriter backslash (so, the @\ that we
+% define for @math can't be used with @macro calls):
+%
+\def\\{\normalbackslash}%
+%
+% We would like to do this for \, too, since that is what makeinfo does.
+% But it is not possible, because Texinfo already has a command @, for a
+% cedilla accent. Documents must use @comma{} instead.
+%
+% \anythingelse will almost certainly be an error of some kind.
+
% \mbodybackslash is the definition of \ in @macro bodies.
% It maps \foo\ => \csname macarg.foo\endcsname => #N
% where N is the macro parameter number.
% We define \csname macarg.\endcsname to be \realbackslash, so
% \\ in macro replacement text gets you a backslash.
-
+%
{\catcode`@=0 @catcode`@\=@active
@gdef@usembodybackslash{@let\=@mbodybackslash}
@gdef@mbodybackslash#1\{@csname macarg.#1@endcsname}
}
\expandafter\def\csname macarg.\endcsname{\realbackslash}
+\def\margbackslash#1{\char`\#1 }
+
\def\macro{\recursivefalse\parsearg\macroxxx}
\def\rmacro{\recursivetrue\parsearg\macroxxx}
\def\macroxxx#1{%
- \getargs{#1}% now \macname is the macname and \argl the arglist
+ \getargs{#1}% now \macname is the macname and \argl the arglist
\ifx\argl\empty % no arguments
- \paramno=0%
+ \paramno=0\relax
\else
\expandafter\parsemargdef \argl;%
+ \if\paramno>256\relax
+ \ifx\eTeXversion\thisisundefined
+ \errhelp = \EMsimple
+ \errmessage{You need eTeX to compile a file with macros with more than 256 arguments}
+ \fi
+ \fi
\fi
\if1\csname ismacro.\the\macname\endcsname
\message{Warning: redefining \the\macname}%
@@ -6743,46 +7473,269 @@ end
% an opening brace, and that opening brace is not consumed.
\def\getargs#1{\getargsxxx#1{}}
\def\getargsxxx#1#{\getmacname #1 \relax\getmacargs}
-\def\getmacname #1 #2\relax{\macname={#1}}
+\def\getmacname#1 #2\relax{\macname={#1}}
\def\getmacargs#1{\def\argl{#1}}
+% For macro processing make @ a letter so that we can make Texinfo private macro names.
+\edef\texiatcatcode{\the\catcode`\@}
+\catcode `@=11\relax
+
% Parse the optional {params} list. Set up \paramno and \paramlist
-% so \defmacro knows what to do. Define \macarg.blah for each blah
-% in the params list, to be ##N where N is the position in that list.
+% so \defmacro knows what to do. Define \macarg.BLAH for each BLAH
+% in the params list to some hook where the argument si to be expanded. If
+% there are less than 10 arguments that hook is to be replaced by ##N where N
+% is the position in that list, that is to say the macro arguments are to be
+% defined `a la TeX in the macro body.
+%
% That gets used by \mbodybackslash (above).
-
+%
% We need to get `macro parameter char #' into several definitions.
-% The technique used is stolen from LaTeX: let \hash be something
+% The technique used is stolen from LaTeX: let \hash be something
% unexpandable, insert that wherever you need a #, and then redefine
% it to # just before using the token list produced.
%
% The same technique is used to protect \eatspaces till just before
% the macro is used.
-
-\def\parsemargdef#1;{\paramno=0\def\paramlist{}%
- \let\hash\relax\let\xeatspaces\relax\parsemargdefxxx#1,;,}
+%
+% If there are 10 or more arguments, a different technique is used, where the
+% hook remains in the body, and when macro is to be expanded the body is
+% processed again to replace the arguments.
+%
+% In that case, the hook is \the\toks N-1, and we simply set \toks N-1 to the
+% argument N value and then \edef the body (nothing else will expand because of
+% the catcode regime underwhich the body was input).
+%
+% If you compile with TeX (not eTeX), and you have macros with 10 or more
+% arguments, you need that no macro has more than 256 arguments, otherwise an
+% error is produced.
+\def\parsemargdef#1;{%
+ \paramno=0\def\paramlist{}%
+ \let\hash\relax
+ \let\xeatspaces\relax
+ \parsemargdefxxx#1,;,%
+ % In case that there are 10 or more arguments we parse again the arguments
+ % list to set new definitions for the \macarg.BLAH macros corresponding to
+ % each BLAH argument. It was anyhow needed to parse already once this list
+ % in order to count the arguments, and as macros with at most 9 arguments
+ % are by far more frequent than macro with 10 or more arguments, defining
+ % twice the \macarg.BLAH macros does not cost too much processing power.
+ \ifnum\paramno<10\relax\else
+ \paramno0\relax
+ \parsemmanyargdef@@#1,;,% 10 or more arguments
+ \fi
+}
\def\parsemargdefxxx#1,{%
\if#1;\let\next=\relax
\else \let\next=\parsemargdefxxx
- \advance\paramno by 1%
+ \advance\paramno by 1
\expandafter\edef\csname macarg.\eatspaces{#1}\endcsname
{\xeatspaces{\hash\the\paramno}}%
\edef\paramlist{\paramlist\hash\the\paramno,}%
\fi\next}
+\def\parsemmanyargdef@@#1,{%
+ \if#1;\let\next=\relax
+ \else
+ \let\next=\parsemmanyargdef@@
+ \edef\tempb{\eatspaces{#1}}%
+ \expandafter\def\expandafter\tempa
+ \expandafter{\csname macarg.\tempb\endcsname}%
+ % Note that we need some extra \noexpand\noexpand, this is because we
+ % don't want \the to be expanded in the \parsermacbody as it uses an
+ % \xdef .
+ \expandafter\edef\tempa
+ {\noexpand\noexpand\noexpand\the\toks\the\paramno}%
+ \advance\paramno by 1\relax
+ \fi\next}
+
% These two commands read recursive and nonrecursive macro bodies.
% (They're different since rec and nonrec macros end differently.)
+%
+\catcode `\@\texiatcatcode
\long\def\parsemacbody#1@end macro%
{\xdef\temp{\eatcr{#1}}\endgroup\defmacro}%
\long\def\parsermacbody#1@end rmacro%
{\xdef\temp{\eatcr{#1}}\endgroup\defmacro}%
+\catcode `\@=11\relax
+
+\let\endargs@\relax
+\let\nil@\relax
+\def\nilm@{\nil@}%
+\long\def\nillm@{\nil@}%
+
+% This macro is expanded during the Texinfo macro expansion, not during its
+% definition. It gets all the arguments values and assigns them to macros
+% macarg.ARGNAME
+%
+% #1 is the macro name
+% #2 is the list of argument names
+% #3 is the list of argument values
+\def\getargvals@#1#2#3{%
+ \def\macargdeflist@{}%
+ \def\saveparamlist@{#2}% Need to keep a copy for parameter expansion.
+ \def\paramlist{#2,\nil@}%
+ \def\macroname{#1}%
+ \begingroup
+ \macroargctxt
+ \def\argvaluelist{#3,\nil@}%
+ \def\@tempa{#3}%
+ \ifx\@tempa\empty
+ \setemptyargvalues@
+ \else
+ \getargvals@@
+ \fi
+}
-% This defines the macro itself. There are six cases: recursive and
-% nonrecursive macros of zero, one, and many arguments.
+%
+\def\getargvals@@{%
+ \ifx\paramlist\nilm@
+ % Some sanity check needed here that \argvaluelist is also empty.
+ \ifx\argvaluelist\nillm@
+ \else
+ \errhelp = \EMsimple
+ \errmessage{Too many arguments in macro `\macroname'!}%
+ \fi
+ \let\next\macargexpandinbody@
+ \else
+ \ifx\argvaluelist\nillm@
+ % No more arguments values passed to macro. Set remaining named-arg
+ % macros to empty.
+ \let\next\setemptyargvalues@
+ \else
+ % pop current arg name into \@tempb
+ \def\@tempa##1{\pop@{\@tempb}{\paramlist}##1\endargs@}%
+ \expandafter\@tempa\expandafter{\paramlist}%
+ % pop current argument value into \@tempc
+ \def\@tempa##1{\longpop@{\@tempc}{\argvaluelist}##1\endargs@}%
+ \expandafter\@tempa\expandafter{\argvaluelist}%
+ % Here \@tempb is the current arg name and \@tempc is the current arg value.
+ % First place the new argument macro definition into \@tempd
+ \expandafter\macname\expandafter{\@tempc}%
+ \expandafter\let\csname macarg.\@tempb\endcsname\relax
+ \expandafter\def\expandafter\@tempe\expandafter{%
+ \csname macarg.\@tempb\endcsname}%
+ \edef\@tempd{\long\def\@tempe{\the\macname}}%
+ \push@\@tempd\macargdeflist@
+ \let\next\getargvals@@
+ \fi
+ \fi
+ \next
+}
+
+\def\push@#1#2{%
+ \expandafter\expandafter\expandafter\def
+ \expandafter\expandafter\expandafter#2%
+ \expandafter\expandafter\expandafter{%
+ \expandafter#1#2}%
+}
+
+% Replace arguments by their values in the macro body, and place the result
+% in macro \@tempa
+\def\macvalstoargs@{%
+ % To do this we use the property that token registers that are \the'ed
+ % within an \edef expand only once. So we are going to place all argument
+ % values into respective token registers.
+ %
+ % First we save the token context, and initialize argument numbering.
+ \begingroup
+ \paramno0\relax
+ % Then, for each argument number #N, we place the corresponding argument
+ % value into a new token list register \toks#N
+ \expandafter\putargsintokens@\saveparamlist@,;,%
+ % Then, we expand the body so that argument are replaced by their
+ % values. The trick for values not to be expanded themselves is that they
+ % are within tokens and that tokens expand only once in an \edef .
+ \edef\@tempc{\csname mac.\macroname .body\endcsname}%
+ % Now we restore the token stack pointer to free the token list registers
+ % which we have used, but we make sure that expanded body is saved after
+ % group.
+ \expandafter
+ \endgroup
+ \expandafter\def\expandafter\@tempa\expandafter{\@tempc}%
+ }
+
+\def\macargexpandinbody@{%
+ %% Define the named-macro outside of this group and then close this group.
+ \expandafter
+ \endgroup
+ \macargdeflist@
+ % First the replace in body the macro arguments by their values, the result
+ % is in \@tempa .
+ \macvalstoargs@
+ % Then we point at the \norecurse or \gobble (for recursive) macro value
+ % with \@tempb .
+ \expandafter\let\expandafter\@tempb\csname mac.\macroname .recurse\endcsname
+ % Depending on whether it is recursive or not, we need some tailing
+ % \egroup .
+ \ifx\@tempb\gobble
+ \let\@tempc\relax
+ \else
+ \let\@tempc\egroup
+ \fi
+ % And now we do the real job:
+ \edef\@tempd{\noexpand\@tempb{\macroname}\noexpand\scanmacro{\@tempa}\@tempc}%
+ \@tempd
+}
+
+\def\putargsintokens@#1,{%
+ \if#1;\let\next\relax
+ \else
+ \let\next\putargsintokens@
+ % First we allocate the new token list register, and give it a temporary
+ % alias \@tempb .
+ \toksdef\@tempb\the\paramno
+ % Then we place the argument value into that token list register.
+ \expandafter\let\expandafter\@tempa\csname macarg.#1\endcsname
+ \expandafter\@tempb\expandafter{\@tempa}%
+ \advance\paramno by 1\relax
+ \fi
+ \next
+}
+
+% Save the token stack pointer into macro #1
+\def\texisavetoksstackpoint#1{\edef#1{\the\@cclvi}}
+% Restore the token stack pointer from number in macro #1
+\def\texirestoretoksstackpoint#1{\expandafter\mathchardef\expandafter\@cclvi#1\relax}
+% newtoks that can be used non \outer .
+\def\texinonouternewtoks{\alloc@ 5\toks \toksdef \@cclvi}
+
+% Tailing missing arguments are set to empty
+\def\setemptyargvalues@{%
+ \ifx\paramlist\nilm@
+ \let\next\macargexpandinbody@
+ \else
+ \expandafter\setemptyargvaluesparser@\paramlist\endargs@
+ \let\next\setemptyargvalues@
+ \fi
+ \next
+}
+
+\def\setemptyargvaluesparser@#1,#2\endargs@{%
+ \expandafter\def\expandafter\@tempa\expandafter{%
+ \expandafter\def\csname macarg.#1\endcsname{}}%
+ \push@\@tempa\macargdeflist@
+ \def\paramlist{#2}%
+}
+
+% #1 is the element target macro
+% #2 is the list macro
+% #3,#4\endargs@ is the list value
+\def\pop@#1#2#3,#4\endargs@{%
+ \def#1{#3}%
+ \def#2{#4}%
+}
+\long\def\longpop@#1#2#3,#4\endargs@{%
+ \long\def#1{#3}%
+ \long\def#2{#4}%
+}
+
+% This defines a Texinfo @macro. There are eight cases: recursive and
+% nonrecursive macros of zero, one, up to nine, and many arguments.
% Much magic with \expandafter here.
% \xdef is used so that macro definitions will survive the file
% they're defined in; @include reads the file inside a group.
+%
\def\defmacro{%
\let\hash=##% convert placeholders to macro parameter chars
\ifrecursive
@@ -6797,17 +7750,25 @@ end
\expandafter\noexpand\csname\the\macname xxx\endcsname}%
\expandafter\xdef\csname\the\macname xxx\endcsname##1{%
\egroup\noexpand\scanmacro{\temp}}%
- \else % many
- \expandafter\xdef\csname\the\macname\endcsname{%
- \bgroup\noexpand\macroargctxt
- \noexpand\csname\the\macname xx\endcsname}%
- \expandafter\xdef\csname\the\macname xx\endcsname##1{%
- \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}%
- \expandafter\expandafter
- \expandafter\xdef
- \expandafter\expandafter
- \csname\the\macname xxx\endcsname
- \paramlist{\egroup\noexpand\scanmacro{\temp}}%
+ \else
+ \ifnum\paramno<10\relax % at most 9
+ \expandafter\xdef\csname\the\macname\endcsname{%
+ \bgroup\noexpand\macroargctxt
+ \noexpand\csname\the\macname xx\endcsname}%
+ \expandafter\xdef\csname\the\macname xx\endcsname##1{%
+ \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}%
+ \expandafter\expandafter
+ \expandafter\xdef
+ \expandafter\expandafter
+ \csname\the\macname xxx\endcsname
+ \paramlist{\egroup\noexpand\scanmacro{\temp}}%
+ \else % 10 or more
+ \expandafter\xdef\csname\the\macname\endcsname{%
+ \noexpand\getargvals@{\the\macname}{\argl}%
+ }%
+ \global\expandafter\let\csname mac.\the\macname .body\endcsname\temp
+ \global\expandafter\let\csname mac.\the\macname .recurse\endcsname\gobble
+ \fi
\fi
\else
\ifcase\paramno
@@ -6824,29 +7785,40 @@ end
\egroup
\noexpand\norecurse{\the\macname}%
\noexpand\scanmacro{\temp}\egroup}%
- \else % many
- \expandafter\xdef\csname\the\macname\endcsname{%
- \bgroup\noexpand\macroargctxt
- \expandafter\noexpand\csname\the\macname xx\endcsname}%
- \expandafter\xdef\csname\the\macname xx\endcsname##1{%
- \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}%
- \expandafter\expandafter
- \expandafter\xdef
- \expandafter\expandafter
- \csname\the\macname xxx\endcsname
- \paramlist{%
- \egroup
- \noexpand\norecurse{\the\macname}%
- \noexpand\scanmacro{\temp}\egroup}%
+ \else % at most 9
+ \ifnum\paramno<10\relax
+ \expandafter\xdef\csname\the\macname\endcsname{%
+ \bgroup\noexpand\macroargctxt
+ \expandafter\noexpand\csname\the\macname xx\endcsname}%
+ \expandafter\xdef\csname\the\macname xx\endcsname##1{%
+ \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}%
+ \expandafter\expandafter
+ \expandafter\xdef
+ \expandafter\expandafter
+ \csname\the\macname xxx\endcsname
+ \paramlist{%
+ \egroup
+ \noexpand\norecurse{\the\macname}%
+ \noexpand\scanmacro{\temp}\egroup}%
+ \else % 10 or more:
+ \expandafter\xdef\csname\the\macname\endcsname{%
+ \noexpand\getargvals@{\the\macname}{\argl}%
+ }%
+ \global\expandafter\let\csname mac.\the\macname .body\endcsname\temp
+ \global\expandafter\let\csname mac.\the\macname .recurse\endcsname\norecurse
+ \fi
\fi
\fi}
+\catcode `\@\texiatcatcode\relax
+
\def\norecurse#1{\bgroup\cslet{#1}{macsave.#1}}
% \braceorline decides whether the next nonwhitespace character is a
% {. If so it reads up to the closing }, if not, it reads the whole
% line. Whatever was read is then fed to the next control sequence
-% as an argument (by \parsebrace or \parsearg)
+% as an argument (by \parsebrace or \parsearg).
+%
\def\braceorline#1{\let\macnamexxx=#1\futurelet\nchar\braceorlinexxx}
\def\braceorlinexxx{%
\ifx\nchar\bgroup\else
@@ -6856,7 +7828,8 @@ end
% @alias.
% We need some trickery to remove the optional spaces around the equal
-% sign. Just make them active and then expand them all to nothing.
+% sign. Make them active and then expand them all to nothing.
+%
\def\alias{\parseargusing\obeyspaces\aliasxxx}
\def\aliasxxx #1{\aliasyyy#1\relax}
\def\aliasyyy #1=#2\relax{%
@@ -6877,7 +7850,8 @@ end
% @inforef is relatively simple.
\def\inforef #1{\inforefzzz #1,,,,**}
-\def\inforefzzz #1,#2,#3,#4**{\putwordSee{} \putwordInfo{} \putwordfile{} \file{\ignorespaces #3{}},
+\def\inforefzzz #1,#2,#3,#4**{%
+ \putwordSee{} \putwordInfo{} \putwordfile{} \file{\ignorespaces #3{}},
node \samp{\ignorespaces#1{}}}
% @node's only job in TeX is to define \lastnode, which is used in
@@ -6938,11 +7912,32 @@ end
\toks0 = \expandafter{\lastsection}%
\immediate \writexrdef{title}{\the\toks0 }%
\immediate \writexrdef{snt}{\csname #2\endcsname}% \Ynumbered etc.
- \safewhatsit{\writexrdef{pg}{\folio}}% will be written later, during \shipout
+ \safewhatsit{\writexrdef{pg}{\folio}}% will be written later, at \shipout
}%
\fi
}
+% @xrefautosectiontitle on|off says whether @section(ing) names are used
+% automatically in xrefs, if the third arg is not explicitly specified.
+% This was provided as a "secret" @set xref-automatic-section-title
+% variable, now it's official.
+%
+\parseargdef\xrefautomaticsectiontitle{%
+ \def\temp{#1}%
+ \ifx\temp\onword
+ \expandafter\let\csname SETxref-automatic-section-title\endcsname
+ = \empty
+ \else\ifx\temp\offword
+ \expandafter\let\csname SETxref-automatic-section-title\endcsname
+ = \relax
+ \else
+ \errhelp = \EMsimple
+ \errmessage{Unknown @xrefautomaticsectiontitle value `\temp',
+ must be on|off}%
+ \fi\fi
+}
+
+%
% @xref, @pxref, and @ref generate cross-references. For \xrefX, #1 is
% the node name, #2 the name of the Info cross-reference, #3 the printed
% node name, #4 the name of the Info file, #5 the name of the printed
@@ -6951,26 +7946,41 @@ end
\def\pxref#1{\putwordsee{} \xrefX[#1,,,,,,,]}
\def\xref#1{\putwordSee{} \xrefX[#1,,,,,,,]}
\def\ref#1{\xrefX[#1,,,,,,,]}
+%
+\newbox\toprefbox
+\newbox\printedrefnamebox
+\newbox\infofilenamebox
+\newbox\printedmanualbox
+%
\def\xrefX[#1,#2,#3,#4,#5,#6]{\begingroup
\unsepspaces
- \def\printedmanual{\ignorespaces #5}%
+ %
+ % Get args without leading/trailing spaces.
\def\printedrefname{\ignorespaces #3}%
- \setbox1=\hbox{\printedmanual\unskip}%
- \setbox0=\hbox{\printedrefname\unskip}%
- \ifdim \wd0 = 0pt
+ \setbox\printedrefnamebox = \hbox{\printedrefname\unskip}%
+ %
+ \def\infofilename{\ignorespaces #4}%
+ \setbox\infofilenamebox = \hbox{\infofilename\unskip}%
+ %
+ \def\printedmanual{\ignorespaces #5}%
+ \setbox\printedmanualbox = \hbox{\printedmanual\unskip}%
+ %
+ % If the printed reference name (arg #3) was not explicitly given in
+ % the @xref, figure out what we want to use.
+ \ifdim \wd\printedrefnamebox = 0pt
% No printed node name was explicitly given.
- \expandafter\ifx\csname SETxref-automatic-section-title\endcsname\relax
- % Use the node name inside the square brackets.
+ \expandafter\ifx\csname SETxref-automatic-section-title\endcsname \relax
+ % Not auto section-title: use node name inside the square brackets.
\def\printedrefname{\ignorespaces #1}%
\else
- % Use the actual chapter/section title appear inside
- % the square brackets. Use the real section title if we have it.
- \ifdim \wd1 > 0pt
- % It is in another manual, so we don't have it.
+ % Auto section-title: use chapter/section title inside
+ % the square brackets if we have it.
+ \ifdim \wd\printedmanualbox > 0pt
+ % It is in another manual, so we don't have it; use node name.
\def\printedrefname{\ignorespaces #1}%
\else
\ifhavexrefs
- % We know the real title if we have the xref values.
+ % We (should) know the real title if we have the xref values.
\def\printedrefname{\refx{#1-title}{}}%
\else
% Otherwise just copy the Info node name.
@@ -6984,13 +7994,20 @@ end
\ifpdf
{\indexnofonts
\turnoffactive
+ \makevalueexpandable
% This expands tokens, so do it after making catcode changes, so _
- % etc. don't get their TeX definitions.
+ % etc. don't get their TeX definitions. This ignores all spaces in
+ % #4, including (wrongly) those in the middle of the filename.
\getfilename{#4}%
%
- % See comments at \activebackslashdouble.
- {\activebackslashdouble \xdef\pdfxrefdest{#1}%
- \backslashparens\pdfxrefdest}%
+ % This (wrongly) does not take account of leading or trailing
+ % spaces in #1, which should be ignored.
+ \edef\pdfxrefdest{#1}%
+ \ifx\pdfxrefdest\empty
+ \def\pdfxrefdest{Top}% no empty targets
+ \else
+ \txiescapepdf\pdfxrefdest % escape PDF special chars
+ \fi
%
\leavevmode
\startlink attr{/Border [0 0 0]}%
@@ -7017,29 +8034,42 @@ end
\iffloat\Xthisreftitle
% If the user specified the print name (third arg) to the ref,
% print it instead of our usual "Figure 1.2".
- \ifdim\wd0 = 0pt
+ \ifdim\wd\printedrefnamebox = 0pt
\refx{#1-snt}{}%
\else
\printedrefname
\fi
%
- % if the user also gave the printed manual name (fifth arg), append
+ % If the user also gave the printed manual name (fifth arg), append
% "in MANUALNAME".
- \ifdim \wd1 > 0pt
+ \ifdim \wd\printedmanualbox > 0pt
\space \putwordin{} \cite{\printedmanual}%
\fi
\else
% node/anchor (non-float) references.
%
- % If we use \unhbox0 and \unhbox1 to print the node names, TeX does not
- % insert empty discretionaries after hyphens, which means that it will
- % not find a line break at a hyphen in a node names. Since some manuals
- % are best written with fairly long node names, containing hyphens, this
- % is a loss. Therefore, we give the text of the node name again, so it
- % is as if TeX is seeing it for the first time.
- \ifdim \wd1 > 0pt
- \putwordSection{} ``\printedrefname'' \putwordin{} \cite{\printedmanual}%
+ % If we use \unhbox to print the node names, TeX does not insert
+ % empty discretionaries after hyphens, which means that it will not
+ % find a line break at a hyphen in a node names. Since some manuals
+ % are best written with fairly long node names, containing hyphens,
+ % this is a loss. Therefore, we give the text of the node name
+ % again, so it is as if TeX is seeing it for the first time.
+ %
+ \ifdim \wd\printedmanualbox > 0pt
+ % Cross-manual reference with a printed manual name.
+ %
+ \crossmanualxref{\cite{\printedmanual\unskip}}%
+ %
+ \else\ifdim \wd\infofilenamebox > 0pt
+ % Cross-manual reference with only an info filename (arg 4), no
+ % printed manual name (arg 5). This is essentially the same as
+ % the case above; we output the filename, since we have nothing else.
+ %
+ \crossmanualxref{\code{\infofilename\unskip}}%
+ %
\else
+ % Reference within this manual.
+ %
% _ (for example) has to be the character _ for the purposes of the
% control sequence corresponding to the node, but it has to expand
% into the usual \leavevmode...\vrule stuff for purposes of
@@ -7051,7 +8081,7 @@ end
\setbox2 = \hbox{\ignorespaces \refx{#1-snt}{}}%
\ifdim \wd2 > 0pt \refx{#1-snt}\space\fi
}%
- % output the `[mynode]' via a macro so it can be overridden.
+ % output the `[mynode]' via the macro below so it can be overridden.
\xrefprintnodename\printedrefname
%
% But we always want a comma and a space:
@@ -7059,11 +8089,37 @@ end
%
% output the `page 3'.
\turnoffactive \putwordpage\tie\refx{#1-pg}{}%
- \fi
+ \fi\fi
\fi
\endlink
\endgroup}
+% Output a cross-manual xref to #1. Used just above (twice).
+%
+% Only include the text "Section ``foo'' in" if the foo is neither
+% missing or Top. Thus, @xref{,,,foo,The Foo Manual} outputs simply
+% "see The Foo Manual", the idea being to refer to the whole manual.
+%
+% But, this being TeX, we can't easily compare our node name against the
+% string "Top" while ignoring the possible spaces before and after in
+% the input. By adding the arbitrary 7sp below, we make it much less
+% likely that a real node name would have the same width as "Top" (e.g.,
+% in a monospaced font). Hopefully it will never happen in practice.
+%
+% For the same basic reason, we retypeset the "Top" at every
+% reference, since the current font is indeterminate.
+%
+\def\crossmanualxref#1{%
+ \setbox\toprefbox = \hbox{Top\kern7sp}%
+ \setbox2 = \hbox{\ignorespaces \printedrefname \unskip \kern7sp}%
+ \ifdim \wd2 > 7sp % nonempty?
+ \ifdim \wd2 = \wd\toprefbox \else % same as Top?
+ \putwordSection{} ``\printedrefname'' \putwordin{}\space
+ \fi
+ \fi
+ #1%
+}
+
% This macro is called from \xrefX for the `[nodename]' part of xref
% output. It's a separate macro only so it can be changed more easily,
% since square brackets don't work well in some documents. Particularly
@@ -7114,7 +8170,8 @@ end
\angleleft un\-de\-fined\angleright
\iflinks
\ifhavexrefs
- \message{\linenumber Undefined cross reference `#1'.}%
+ {\toks0 = {#1}% avoid expansion of possibly-complex value
+ \message{\linenumber Undefined cross reference `\the\toks0'.}}%
\else
\ifwarnedxrefs\else
\global\warnedxrefstrue
@@ -7278,7 +8335,7 @@ end
% space to prevent strange expansion errors.)
\def\supereject{\par\penalty -20000\footnoteno =0 }
-% @footnotestyle is meaningful for info output only.
+% @footnotestyle is meaningful for Info output only.
\let\footnotestyle=\comment
{\catcode `\@=11
@@ -7341,6 +8398,8 @@ end
% expands into a box, it must come within the paragraph, lest it
% provide a place where TeX can split the footnote.
\footstrut
+ %
+ % Invoke rest of plain TeX footnote routine.
\futurelet\next\fo@t
}
}%end \catcode `\@=11
@@ -7428,7 +8487,7 @@ end
it from ftp://tug.org/tex/epsf.tex.}
%
\def\image#1{%
- \ifx\epsfbox\undefined
+ \ifx\epsfbox\thisisundefined
\ifwarnednoepsf \else
\errhelp = \noepsfhelp
\errmessage{epsf.tex not found, images will be ignored}%
@@ -7444,7 +8503,7 @@ end
% #2 is (optional) width, #3 is (optional) height.
% #4 is (ignored optional) html alt text.
% #5 is (ignored optional) extension.
-% #6 is just the usual extra ignored arg for parsing this stuff.
+% #6 is just the usual extra ignored arg for parsing stuff.
\newif\ifimagevmode
\def\imagexxx#1,#2,#3,#4,#5,#6\finish{\begingroup
\catcode`\^^M = 5 % in case we're inside an example
@@ -7452,6 +8511,13 @@ end
% If the image is by itself, center it.
\ifvmode
\imagevmodetrue
+ \else \ifx\centersub\centerV
+ % for @center @image, we need a vbox so we can have our vertical space
+ \imagevmodetrue
+ \vbox\bgroup % vbox has better behavior than vtop herev
+ \fi\fi
+ %
+ \ifimagevmode
\nobreak\medskip
% Usually we'll have text after the image which will insert
% \parskip glue, so insert it here too to equalize the space
@@ -7461,9 +8527,13 @@ end
\fi
%
% Leave vertical mode so that indentation from an enclosing
- % environment such as @quotation is respected. On the other hand, if
- % it's at the top level, we don't want the normal paragraph indentation.
- \noindent
+ % environment such as @quotation is respected.
+ % However, if we're at the top level, we don't want the
+ % normal paragraph indentation.
+ % On the other hand, if we are in the case of @center @image, we don't
+ % want to start a paragraph, which will create a hsize-width box and
+ % eradicate the centering.
+ \ifx\centersub\centerV\else \noindent \fi
%
% Output the image.
\ifpdf
@@ -7475,7 +8545,10 @@ end
\epsfbox{#1.eps}%
\fi
%
- \ifimagevmode \medskip \fi % space after the standalone image
+ \ifimagevmode
+ \medskip % space after a standalone image
+ \fi
+ \ifx\centersub\centerV \egroup \fi
\endgroup}
@@ -7747,10 +8820,9 @@ end
\message{localization,}
-% @documentlanguage is usually given very early, just after
-% @setfilename. If done too late, it may not override everything
-% properly. Single argument is the language (de) or locale (de_DE)
-% abbreviation. It would be nice if we could set up a hyphenation file.
+% For single-language documents, @documentlanguage is usually given very
+% early, just after @documentencoding. Single argument is the language
+% (de) or locale (de_DE) abbreviation.
%
{
\catcode`\_ = \active
@@ -7763,31 +8835,60 @@ end
\ifeof 1
\documentlanguagetrywithoutunderscore{#1_\finish}%
\else
+ \globaldefs = 1 % everything in the txi-LL files needs to persist
\input txi-#1.tex
\fi
\closein 1
- \endgroup
+ \endgroup % end raw TeX
\endgroup}
-}
%
% If they passed de_DE, and txi-de_DE.tex doesn't exist,
% try txi-de.tex.
-%
-\def\documentlanguagetrywithoutunderscore#1_#2\finish{%
+%
+\gdef\documentlanguagetrywithoutunderscore#1_#2\finish{%
\openin 1 txi-#1.tex
\ifeof 1
\errhelp = \nolanghelp
\errmessage{Cannot read language file txi-#1.tex}%
\else
+ \globaldefs = 1 % everything in the txi-LL files needs to persist
\input txi-#1.tex
\fi
\closein 1
}
+}% end of special _ catcode
%
\newhelp\nolanghelp{The given language definition file cannot be found or
-is empty. Maybe you need to install it? In the current directory
-should work if nowhere else does.}
+is empty. Maybe you need to install it? Putting it in the current
+directory should work if nowhere else does.}
+
+% This macro is called from txi-??.tex files; the first argument is the
+% \language name to set (without the "\lang@" prefix), the second and
+% third args are \{left,right}hyphenmin.
+%
+% The language names to pass are determined when the format is built.
+% See the etex.log file created at that time, e.g.,
+% /usr/local/texlive/2008/texmf-var/web2c/pdftex/etex.log.
+%
+% With TeX Live 2008, etex now includes hyphenation patterns for all
+% available languages. This means we can support hyphenation in
+% Texinfo, at least to some extent. (This still doesn't solve the
+% accented characters problem.)
+%
+\catcode`@=11
+\def\txisetlanguage#1#2#3{%
+ % do not set the language if the name is undefined in the current TeX.
+ \expandafter\ifx\csname lang@#1\endcsname \relax
+ \message{no patterns for #1}%
+ \else
+ \global\language = \csname lang@#1\endcsname
+ \fi
+ % but there is no harm in adjusting the hyphenmin values regardless.
+ \global\lefthyphenmin = #2\relax
+ \global\righthyphenmin = #3\relax
+}
+% Helpers for encodings.
% Set the catcode of characters 128 through 255 to the specified number.
%
\def\setnonasciicharscatcode#1{%
@@ -7828,7 +8929,7 @@ should work if nowhere else does.}
\setnonasciicharscatcode\active
\lattwochardefs
%
- \else \ifx \declaredencoding \latone
+ \else \ifx \declaredencoding \latone
\setnonasciicharscatcode\active
\latonechardefs
%
@@ -7840,7 +8941,7 @@ should work if nowhere else does.}
\setnonasciicharscatcode\active
\utfeightchardefs
%
- \else
+ \else
\message{Unknown document encoding #1, ignoring.}%
%
\fi % utfeight
@@ -7852,7 +8953,7 @@ should work if nowhere else does.}
% A message to be logged when using a character that isn't available
% the default font encoding (OT1).
-%
+%
\def\missingcharmsg#1{\message{Character missing in OT1 encoding: #1.}}
% Take account of \c (plain) vs. \, (Texinfo) difference.
@@ -7865,21 +8966,21 @@ should work if nowhere else does.}
%
% Latin1 (ISO-8859-1) character definitions.
\def\latonechardefs{%
- \gdef^^a0{~}
+ \gdef^^a0{\tie}
\gdef^^a1{\exclamdown}
- \gdef^^a2{\missingcharmsg{CENT SIGN}}
+ \gdef^^a2{\missingcharmsg{CENT SIGN}}
\gdef^^a3{{\pounds}}
\gdef^^a4{\missingcharmsg{CURRENCY SIGN}}
\gdef^^a5{\missingcharmsg{YEN SIGN}}
- \gdef^^a6{\missingcharmsg{BROKEN BAR}}
+ \gdef^^a6{\missingcharmsg{BROKEN BAR}}
\gdef^^a7{\S}
- \gdef^^a8{\"{}}
- \gdef^^a9{\copyright}
+ \gdef^^a8{\"{}}
+ \gdef^^a9{\copyright}
\gdef^^aa{\ordf}
- \gdef^^ab{\missingcharmsg{LEFT-POINTING DOUBLE ANGLE QUOTATION MARK}}
+ \gdef^^ab{\guillemetleft}
\gdef^^ac{$\lnot$}
- \gdef^^ad{\-}
- \gdef^^ae{\registeredsymbol}
+ \gdef^^ad{\-}
+ \gdef^^ae{\registeredsymbol}
\gdef^^af{\={}}
%
\gdef^^b0{\textdegree}
@@ -7895,7 +8996,7 @@ should work if nowhere else does.}
\gdef^^b9{$^1$}
\gdef^^ba{\ordm}
%
- \gdef^^bb{\missingcharmsg{RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK}}
+ \gdef^^bb{\guillemetright}
\gdef^^bc{$1\over4$}
\gdef^^bd{$1\over2$}
\gdef^^be{$3\over4$}
@@ -7906,7 +9007,7 @@ should work if nowhere else does.}
\gdef^^c2{\^A}
\gdef^^c3{\~A}
\gdef^^c4{\"A}
- \gdef^^c5{\ringaccent A}
+ \gdef^^c5{\ringaccent A}
\gdef^^c6{\AE}
\gdef^^c7{\cedilla C}
\gdef^^c8{\`E}
@@ -7918,7 +9019,7 @@ should work if nowhere else does.}
\gdef^^ce{\^I}
\gdef^^cf{\"I}
%
- \gdef^^d0{\missingcharmsg{LATIN CAPITAL LETTER ETH}}
+ \gdef^^d0{\DH}
\gdef^^d1{\~N}
\gdef^^d2{\`O}
\gdef^^d3{\'O}
@@ -7932,7 +9033,7 @@ should work if nowhere else does.}
\gdef^^db{\^U}
\gdef^^dc{\"U}
\gdef^^dd{\'Y}
- \gdef^^de{\missingcharmsg{LATIN CAPITAL LETTER THORN}}
+ \gdef^^de{\TH}
\gdef^^df{\ss}
%
\gdef^^e0{\`a}
@@ -7952,7 +9053,7 @@ should work if nowhere else does.}
\gdef^^ee{\^{\dotless i}}
\gdef^^ef{\"{\dotless i}}
%
- \gdef^^f0{\missingcharmsg{LATIN SMALL LETTER ETH}}
+ \gdef^^f0{\dh}
\gdef^^f1{\~n}
\gdef^^f2{\`o}
\gdef^^f3{\'o}
@@ -7966,7 +9067,7 @@ should work if nowhere else does.}
\gdef^^fb{\^u}
\gdef^^fc{\"u}
\gdef^^fd{\'y}
- \gdef^^fe{\missingcharmsg{LATIN SMALL LETTER THORN}}
+ \gdef^^fe{\th}
\gdef^^ff{\"y}
}
@@ -7987,8 +9088,8 @@ should work if nowhere else does.}
% Latin2 (ISO-8859-2) character definitions.
\def\lattwochardefs{%
- \gdef^^a0{~}
- \gdef^^a1{\missingcharmsg{LATIN CAPITAL LETTER A WITH OGONEK}}
+ \gdef^^a0{\tie}
+ \gdef^^a1{\ogonek{A}}
\gdef^^a2{\u{}}
\gdef^^a3{\L}
\gdef^^a4{\missingcharmsg{CURRENCY SIGN}}
@@ -8005,8 +9106,8 @@ should work if nowhere else does.}
\gdef^^af{\dotaccent Z}
%
\gdef^^b0{\textdegree}
- \gdef^^b1{\missingcharmsg{LATIN SMALL LETTER A WITH OGONEK}}
- \gdef^^b2{\missingcharmsg{OGONEK}}
+ \gdef^^b1{\ogonek{a}}
+ \gdef^^b2{\ogonek{ }}
\gdef^^b3{\l}
\gdef^^b4{\'{}}
\gdef^^b5{\v l}
@@ -8031,14 +9132,14 @@ should work if nowhere else does.}
\gdef^^c7{\cedilla C}
\gdef^^c8{\v C}
\gdef^^c9{\'E}
- \gdef^^ca{\missingcharmsg{LATIN CAPITAL LETTER E WITH OGONEK}}
+ \gdef^^ca{\ogonek{E}}
\gdef^^cb{\"E}
\gdef^^cc{\v E}
\gdef^^cd{\'I}
\gdef^^ce{\^I}
\gdef^^cf{\v D}
%
- \gdef^^d0{\missingcharmsg{LATIN CAPITAL LETTER D WITH STROKE}}
+ \gdef^^d0{\DH}
\gdef^^d1{\'N}
\gdef^^d2{\v N}
\gdef^^d3{\'O}
@@ -8047,7 +9148,7 @@ should work if nowhere else does.}
\gdef^^d6{\"O}
\gdef^^d7{$\times$}
\gdef^^d8{\v R}
- \gdef^^d9{\ringaccent U}
+ \gdef^^d9{\ringaccent U}
\gdef^^da{\'U}
\gdef^^db{\H U}
\gdef^^dc{\"U}
@@ -8065,14 +9166,14 @@ should work if nowhere else does.}
\gdef^^e7{\cedilla c}
\gdef^^e8{\v c}
\gdef^^e9{\'e}
- \gdef^^ea{\missingcharmsg{LATIN SMALL LETTER E WITH OGONEK}}
+ \gdef^^ea{\ogonek{e}}
\gdef^^eb{\"e}
\gdef^^ec{\v e}
- \gdef^^ed{\'\i}
- \gdef^^ee{\^\i}
+ \gdef^^ed{\'{\dotless{i}}}
+ \gdef^^ee{\^{\dotless{i}}}
\gdef^^ef{\v d}
%
- \gdef^^f0{\missingcharmsg{LATIN SMALL LETTER D WITH STROKE}}
+ \gdef^^f0{\dh}
\gdef^^f1{\'n}
\gdef^^f2{\v n}
\gdef^^f3{\'o}
@@ -8091,11 +9192,11 @@ should work if nowhere else does.}
}
% UTF-8 character definitions.
-%
+%
% This code to support UTF-8 is based on LaTeX's utf8.def, with some
% changes for Texinfo conventions. It is included here under the GPL by
% permission from Frank Mittelbach and the LaTeX team.
-%
+%
\newcount\countUTFx
\newcount\countUTFy
\newcount\countUTFz
@@ -8160,7 +9261,7 @@ should work if nowhere else does.}
\gdef\DeclareUnicodeCharacter#1#2{%
\countUTFz = "#1\relax
- \wlog{\space\space defining Unicode char U+#1 (decimal \the\countUTFz)}%
+ %\wlog{\space\space defining Unicode char U+#1 (decimal \the\countUTFz)}%
\begingroup
\parseXMLCharref
\def\UTFviiiTwoOctets##1##2{%
@@ -8245,6 +9346,7 @@ should work if nowhere else does.}
\DeclareUnicodeCharacter{00CE}{\^I}
\DeclareUnicodeCharacter{00CF}{\"I}
+ \DeclareUnicodeCharacter{00D0}{\DH}
\DeclareUnicodeCharacter{00D1}{\~N}
\DeclareUnicodeCharacter{00D2}{\`O}
\DeclareUnicodeCharacter{00D3}{\'O}
@@ -8257,6 +9359,7 @@ should work if nowhere else does.}
\DeclareUnicodeCharacter{00DB}{\^U}
\DeclareUnicodeCharacter{00DC}{\"U}
\DeclareUnicodeCharacter{00DD}{\'Y}
+ \DeclareUnicodeCharacter{00DE}{\TH}
\DeclareUnicodeCharacter{00DF}{\ss}
\DeclareUnicodeCharacter{00E0}{\`a}
@@ -8276,6 +9379,7 @@ should work if nowhere else does.}
\DeclareUnicodeCharacter{00EE}{\^{\dotless{i}}}
\DeclareUnicodeCharacter{00EF}{\"{\dotless{i}}}
+ \DeclareUnicodeCharacter{00F0}{\dh}
\DeclareUnicodeCharacter{00F1}{\~n}
\DeclareUnicodeCharacter{00F2}{\`o}
\DeclareUnicodeCharacter{00F3}{\'o}
@@ -8288,16 +9392,21 @@ should work if nowhere else does.}
\DeclareUnicodeCharacter{00FB}{\^u}
\DeclareUnicodeCharacter{00FC}{\"u}
\DeclareUnicodeCharacter{00FD}{\'y}
+ \DeclareUnicodeCharacter{00FE}{\th}
\DeclareUnicodeCharacter{00FF}{\"y}
\DeclareUnicodeCharacter{0100}{\=A}
\DeclareUnicodeCharacter{0101}{\=a}
\DeclareUnicodeCharacter{0102}{\u{A}}
\DeclareUnicodeCharacter{0103}{\u{a}}
+ \DeclareUnicodeCharacter{0104}{\ogonek{A}}
+ \DeclareUnicodeCharacter{0105}{\ogonek{a}}
\DeclareUnicodeCharacter{0106}{\'C}
\DeclareUnicodeCharacter{0107}{\'c}
\DeclareUnicodeCharacter{0108}{\^C}
\DeclareUnicodeCharacter{0109}{\^c}
+ \DeclareUnicodeCharacter{0118}{\ogonek{E}}
+ \DeclareUnicodeCharacter{0119}{\ogonek{e}}
\DeclareUnicodeCharacter{010A}{\dotaccent{C}}
\DeclareUnicodeCharacter{010B}{\dotaccent{c}}
\DeclareUnicodeCharacter{010C}{\v{C}}
@@ -8445,6 +9554,8 @@ should work if nowhere else does.}
\DeclareUnicodeCharacter{0233}{\=y}
\DeclareUnicodeCharacter{0237}{\dotless{j}}
+ \DeclareUnicodeCharacter{02DB}{\ogonek{ }}
+
\DeclareUnicodeCharacter{1E02}{\dotaccent{B}}
\DeclareUnicodeCharacter{1E03}{\dotaccent{b}}
\DeclareUnicodeCharacter{1E04}{\udotaccent{B}}
@@ -8618,8 +9729,8 @@ should work if nowhere else does.}
% Prevent underfull vbox error messages.
\vbadness = 10000
-% Don't be so finicky about underfull hboxes, either.
-\hbadness = 2000
+% Don't be very finicky about underfull hboxes, either.
+\hbadness = 6666
% Following George Bush, get rid of widows and orphans.
\widowpenalty=10000
@@ -8826,25 +9937,21 @@ should work if nowhere else does.}
\message{and turning on texinfo input format.}
+\def^^L{\par} % remove \outer, so ^L can appear in an @comment
+
+% DEL is a comment character, in case @c does not suffice.
+\catcode`\^^? = 14
+
% Define macros to output various characters with catcode for normal text.
-\catcode`\"=\other
-\catcode`\~=\other
-\catcode`\^=\other
-\catcode`\_=\other
-\catcode`\|=\other
-\catcode`\<=\other
-\catcode`\>=\other
-\catcode`\+=\other
-\catcode`\$=\other
-\def\normaldoublequote{"}
-\def\normaltilde{~}
-\def\normalcaret{^}
-\def\normalunderscore{_}
-\def\normalverticalbar{|}
-\def\normalless{<}
-\def\normalgreater{>}
-\def\normalplus{+}
-\def\normaldollar{$}%$ font-lock fix
+\catcode`\"=\other \def\normaldoublequote{"}
+\catcode`\$=\other \def\normaldollar{$}%$ font-lock fix
+\catcode`\+=\other \def\normalplus{+}
+\catcode`\<=\other \def\normalless{<}
+\catcode`\>=\other \def\normalgreater{>}
+\catcode`\^=\other \def\normalcaret{^}
+\catcode`\_=\other \def\normalunderscore{_}
+\catcode`\|=\other \def\normalverticalbar{|}
+\catcode`\~=\other \def\normaltilde{~}
% This macro is used to make a character print one way in \tt
% (where it can probably be output as-is), and another way in other fonts,
@@ -8871,11 +9978,9 @@ should work if nowhere else does.}
\catcode`\"=\active
\def\activedoublequote{{\tt\char34}}
\let"=\activedoublequote
-\catcode`\~=\active
-\def~{{\tt\char126}}
+\catcode`\~=\active \def\activetilde{{\tt\char126}} \let~ = \activetilde
\chardef\hat=`\^
-\catcode`\^=\active
-\def^{{\tt \hat}}
+\catcode`\^=\active \def\activehat{{\tt \hat}} \let^ = \activehat
\catcode`\_=\active
\def_{\ifusingtt\normalunderscore\_}
@@ -8885,16 +9990,26 @@ should work if nowhere else does.}
\catcode`\|=\active
\def|{{\tt\char124}}
+
\chardef \less=`\<
-\catcode`\<=\active
-\def<{{\tt \less}}
+\catcode`\<=\active \def\activeless{{\tt \less}}\let< = \activeless
\chardef \gtr=`\>
-\catcode`\>=\active
-\def>{{\tt \gtr}}
-\catcode`\+=\active
-\def+{{\tt \char 43}}
-\catcode`\$=\active
-\def${\ifusingit{{\sl\$}}\normaldollar}%$ font-lock fix
+\catcode`\>=\active \def\activegtr{{\tt \gtr}}\let> = \activegtr
+\catcode`\+=\active \def+{{\tt \char 43}}
+\catcode`\$=\active \def${\ifusingit{{\sl\$}}\normaldollar}%$ font-lock fix
+
+% used for headline/footline in the output routine, in case the page
+% breaks in the middle of an @tex block.
+\def\texinfochars{%
+ \let< = \activeless
+ \let> = \activegtr
+ \let~ = \activetilde
+ \let^ = \activehat
+ \markupsetuplqdefault \markupsetuprqdefault
+ \let\b = \strong
+ \let\i = \smartitalic
+ % in principle, all other definitions in \tex have to be undone too.
+}
% If a .fmt file is being used, characters that might appear in a file
% name cannot be active until we have parsed the command line.
@@ -8922,32 +10037,48 @@ should work if nowhere else does.}
% In texinfo, backslash is an active character; it prints the backslash
% in fixed width font.
-\catcode`\\=\active
-@def@normalbackslash{{@tt@backslashcurfont}}
+\catcode`\\=\active % @ for escape char from now on.
+
+% The story here is that in math mode, the \char of \backslashcurfont
+% ends up printing the roman \ from the math symbol font (because \char
+% in math mode uses the \mathcode, and plain.tex sets
+% \mathcode`\\="026E). It seems better for @backslashchar{} to always
+% print a typewriter backslash, hence we use an explicit \mathchar,
+% which is the decimal equivalent of "715c (class 7, e.g., use \fam;
+% ignored family value; char position "5C). We can't use " for the
+% usual hex value because it has already been made active.
+@def@normalbackslash{{@tt @ifmmode @mathchar29020 @else @backslashcurfont @fi}}
+@let@backslashchar = @normalbackslash % @backslashchar{} is for user documents.
+
% On startup, @fixbackslash assigns:
% @let \ = @normalbackslash
-
% \rawbackslash defines an active \ to do \backslashcurfont.
% \otherbackslash defines an active \ to be a literal `\' character with
-% catcode other.
+% catcode other. We switch back and forth between these.
@gdef@rawbackslash{@let\=@backslashcurfont}
@gdef@otherbackslash{@let\=@realbackslash}
% Same as @turnoffactive except outputs \ as {\tt\char`\\} instead of
-% the literal character `\'.
-%
-@def@normalturnoffactive{%
- @let\=@normalbackslash
- @let"=@normaldoublequote
- @let~=@normaltilde
- @let^=@normalcaret
- @let_=@normalunderscore
- @let|=@normalverticalbar
- @let<=@normalless
- @let>=@normalgreater
- @let+=@normalplus
- @let$=@normaldollar %$ font-lock fix
- @unsepspaces
+% the literal character `\'. Also revert - to its normal character, in
+% case the active - from code has slipped in.
+%
+{@catcode`- = @active
+ @gdef@normalturnoffactive{%
+ @let-=@normaldash
+ @let"=@normaldoublequote
+ @let$=@normaldollar %$ font-lock fix
+ @let+=@normalplus
+ @let<=@normalless
+ @let>=@normalgreater
+ @let\=@normalbackslash
+ @let^=@normalcaret
+ @let_=@normalunderscore
+ @let|=@normalverticalbar
+ @let~=@normaltilde
+ @markupsetuplqdefault
+ @markupsetuprqdefault
+ @unsepspaces
+ }
}
% Make _ and + \other characters, temporarily.
@@ -8976,11 +10107,28 @@ should work if nowhere else does.}
% Say @foo, not \foo, in error messages.
@escapechar = `@@
-% These look ok in all fonts, so just make them not special.
-@catcode`@& = @other
-@catcode`@# = @other
-@catcode`@% = @other
+% These (along with & and #) are made active for url-breaking, so need
+% active definitions as the normal characters.
+@def@normaldot{.}
+@def@normalquest{?}
+@def@normalslash{/}
+% These look ok in all fonts, so just make them not special.
+% @hashchar{} gets its own user-level command, because of #line.
+@catcode`@& = @other @def@normalamp{&}
+@catcode`@# = @other @def@normalhash{#}
+@catcode`@% = @other @def@normalpercent{%}
+
+@let @hashchar = @normalhash
+
+@c Finally, make ` and ' active, so that txicodequoteundirected and
+@c txicodequotebacktick work right in, e.g., @w{@code{`foo'}}. If we
+@c don't make ` and ' active, @code will not get them as active chars.
+@c Do this last of all since we use ` in the previous @catcode assignments.
+@catcode`@'=@active
+@catcode`@`=@active
+@markupsetuplqdefault
+@markupsetuprqdefault
@c Local variables:
@c eval: (add-hook 'write-file-hooks 'time-stamp)
@@ -8992,3 +10140,6 @@ should work if nowhere else does.}
@c vim:sw=2:
+@ignore
+ arch-tag: e1b36e32-c96e-4135-a41a-0b2efa2ea115
+@end ignore
diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS
index de7fa20..8a5b8c1 100644
--- a/etc/ORG-NEWS
+++ b/etc/ORG-NEWS
@@ -8,6 +8,103 @@ See the end of the file for license conditions.
Please send Org bug reports to emacs-orgmode@gnu.org.
+* Version 8.3
+** Incompatible changes
+*** 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.
+*** Signature changes
+The following functions require an additional argument. See their
+docstring for more information.
+- ~org-html-format-headline-function~
+- ~org-html-format-inlinetask-function~
+- ~org-latex-format-headline-function~
+- ~org-latex-format-inlinetask-function~
+** Removed functions
+*** 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 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).
+*** 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.
+** New features
+*** 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.
+*** 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=.
+*** 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.
+*** 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 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.
+*** Improve 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.
+** Miscellaneous
+*** 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.
* Version 8.2
** Incompatible changes
diff --git a/lisp/ob-C.el b/lisp/ob-C.el
index bbd0525..076276e 100644
--- a/lisp/ob-C.el
+++ b/lisp/ob-C.el
@@ -2,7 +2,8 @@
;; Copyright (C) 2010-2014 Free Software Foundation, Inc.
-;; Author: Eric Schulte, Thierry Banel
+;; Author: Eric Schulte
+;; Thierry Banel
;; Keywords: literate programming, reproducible research
;; Homepage: http://orgmode.org
@@ -30,10 +31,10 @@
;; - not much in the way of error feedback
;;; Code:
-(require 'ob)
-(require 'cc-mode)
(eval-when-compile
(require 'cl))
+(require 'ob)
+(require 'cc-mode)
(declare-function org-entry-get "org"
(pom property &optional inherit literal-nil))
@@ -45,16 +46,32 @@
(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-D-compiler "rdmd"
- "Command used to compile and execute a D source code file.")
+(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)
@@ -65,45 +82,50 @@ is currently being evaluated.")
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 it's
+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) ;; unused
-;; "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-expand-body:C++ (body params)
+ "Expand a block of C++ code with org-babel according to it's
+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) ;; unused
-;; "Expand a block of D code with org-babel according to it's
-;;header arguments (calls `org-babel-C-expand')."
-;; (let ((org-babel-c-variant 'd)) (org-babel-C-expand body params)))
+(defun org-babel-expand-body:D (body params)
+ "Expand a block of D code with org-babel according to it's
+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) ;; unused
-;; "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-expand-body:C (body params)
+ "Expand a block of C code with org-babel according to it's
+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-"
- (cond
- ((equal org-babel-c-variant 'c ) ".c" )
- ((equal org-babel-c-variant 'cpp) ".cpp")
- ((equal org-babel-c-variant 'd ) ".d" ))))
+ (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) ""))
@@ -111,43 +133,47 @@ or `org-babel-execute:C++' or `org-babel-execute:D'."
(flags (mapconcat 'identity
(if (listp flags) flags (list flags)) " "))
(full-body
- (cond ((equal org-babel-c-variant 'c ) (org-babel-C-expand-C body params))
- ((equal org-babel-c-variant 'cpp) (org-babel-C-expand-C++ body params))
- ((equal org-babel-c-variant 'd ) (org-babel-C-expand-D body params)))))
+ (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))
- (if (memq org-babel-c-variant '(c cpp)) ;; no separate compilation for D
- (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)
- flags
- (org-babel-process-file-name tmp-src-file)) ""))
+ (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-trim
- (org-remove-indentation
- (org-babel-eval
- (cond ((memq org-babel-c-variant '(c cpp))
- (concat tmp-bin-file cmdline))
- ((equal org-babel-c-variant 'd)
- (format "%s %s %s %s"
- org-babel-D-compiler
- flags
- (org-babel-process-file-name tmp-src-file)
- cmdline)))
- "")))))
- (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)))))
- ))
+ (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
@@ -158,24 +184,34 @@ it's header arguments."
"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)))
+ (colnames (cdar (org-babel-get-header params :colname-names)))
(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))))))
+ (unless (listp includes) (setq includes (list includes)))
+ (setq includes (append includes '("<string.h>" "<stdio.h>" "<stdlib.h>")))
(mapconcat 'identity
(list
;; includes
(mapconcat
(lambda (inc) (format "#include %s" inc))
- (if (listp includes) includes (list includes)) "\n")
+ 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)
@@ -185,18 +221,28 @@ it's header arguments."
"Expand a block of D code with org-babel according to
it's 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)))))
+ (unless (listp imports) (setq imports (list imports)))
+ (setq imports (append imports '("std.stdio" "std.conv")))
(mapconcat 'identity
(list
"module mmm;"
;; imports
(mapconcat
(lambda (inc) (format "import %s;" inc))
- (if (listp imports) imports (list imports)) "\n")
+ 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)
@@ -231,46 +277,68 @@ support for sessions"
"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) '("int" "%d"))
- ((floatp val) '("double" "%f"))
+ ((integerp val) 'integerp)
+ ((floatp val) 'floatp)
((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 (if (equal org-babel-c-variant 'd) "[ " "{ ")
- (mapconcat (lambda (v)
- (cdr (org-babel-C-format-val type v)))
- val
- ", ")
- (if (equal org-babel-c-variant 'd) " ]" " }")))))))
- (t ;; treat unknown types as string
- (list
- (if (equal org-babel-c-variant 'd) "string" "const char*")
- "\"%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))
+ (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
@@ -293,6 +361,68 @@ of the same value."
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<nbcols; c++)
+ if (strcmp(header[c],column)==0)
+ return c;
+ return -1;
+}
+"
+ )
+ (d
+ "int get_column_num (string[] header, string column)
+{
+ foreach (c, h; header)
+ if (h==column)
+ return to!int(c);
+ return -1;
+}
+"
+ )))
+
+(defun org-babel-C-header-to-C (head)
+ "Convert an elisp list of header table into a C or D vector
+specifying a variable with the name of the table."
+ (let ((table (car head))
+ (headers (cdr head)))
+ (concat
+ (format
+ (case org-babel-c-variant
+ ((c cpp) "const char* %s_header[%d] = {%s};")
+ (d "string %s_header[%d] = [%s];"))
+ table
+ (length headers)
+ (mapconcat (lambda (h) (format "%S" h)) headers ","))
+ "\n"
+ (case org-babel-c-variant
+ ((c cpp)
+ (format
+ "const char* %s_h (int row, const char* col) { return %s[row][get_column_num(%d,%s_header,col)]; }"
+ table table (length headers) table))
+ (d
+ (format
+ "string %s_h (ulong row, string col) { return %s[row][get_column_num(%s_header,col)]; }"
+ table table table))))))
+
(provide 'ob-C)
;;; ob-C.el ends here
diff --git a/lisp/ob-J.el b/lisp/ob-J.el
index 13ea3fe..500ce9e 100644
--- a/lisp/ob-J.el
+++ b/lisp/ob-J.el
@@ -67,9 +67,9 @@ This function is called by `org-babel-execute-src-block'"
(let* ((processed-params (org-babel-process-params params))
(sessionp (cdr (assoc :session params)))
(session (org-babel-j-initiate-session sessionp))
- (vars (second processed-params))
- (result-params (third processed-params))
- (result-type (fourth processed-params))
+ (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")))
@@ -141,10 +141,10 @@ Don't trust first line."
(a (obj-get-string-alignment x))
(lines (split-string x "\n" t))
b)
- (cond ((minusp a)
+ (cond ((< a 0)
(setq b (obj-match-second-space-right (nth 0 lines)))
(concat (make-string (+ a b) ? ) x))
- ((plusp a)
+ ((> a 0)
(setq b (obj-match-second-space-left (nth 0 lines)))
(concat (make-string (- a b) ? ) x))
(t x))))
diff --git a/lisp/ob-R.el b/lisp/ob-R.el
index 62aa7f2..ea33031 100644
--- a/lisp/ob-R.el
+++ b/lisp/ob-R.el
@@ -35,6 +35,8 @@
(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))
@@ -87,34 +89,62 @@ this variable.")
: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)))))
+(defconst ob-R-transfer-variable-table-with-header
+ "%s <- local({
+ con <- textConnection(
+ %S
+ )
+ res <- 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 <- 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 "},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")))
+ (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.
@@ -126,8 +156,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
@@ -162,7 +204,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
@@ -187,36 +229,25 @@ This function is called by `org-babel-execute-src-block'."
(defun org-babel-R-assign-elisp (name value colnames-p rownames-p)
"Construct R code assigning the elisp VALUE to a variable named NAME."
(if (listp value)
- (let ((max (apply #'max (mapcar #'length (org-remove-if-not
- #'sequencep value))))
- (min (apply #'min (mapcar #'length (org-remove-if-not
- #'sequencep value))))
- (transition-file (org-babel-temp-file "R-import-")))
- ;; ensure VALUE has an orgtbl structure (depth of at least 2)
+ (let* ((lengths (mapcar 'length (org-remove-if-not 'sequencep value)))
+ (max (if lengths (apply 'max lengths) 0))
+ (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)
@@ -224,7 +255,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
@@ -233,6 +265,9 @@ This function is called by `org-babel-execute-src-block'."
;; Session buffer exists, but with dead process
(set-buffer session))
(require 'ess) (R)
+ (ess-wait-for-process
+ (get-process (or ess-local-process-name
+ ess-current-process-name)))
(rename-buffer
(if (bufferp session)
(buffer-name session)
@@ -249,11 +284,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")
@@ -373,7 +403,7 @@ last statement in BODY, as elisp."
column-names-p)))
(output
(mapconcat
- #'org-babel-chomp
+ 'org-babel-chomp
(butlast
(delq nil
(mapcar
@@ -385,7 +415,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/lisp/ob-awk.el b/lisp/ob-awk.el
index ed98afd..6c0fb86 100644
--- a/lisp/ob-awk.el
+++ b/lisp/ob-awk.el
@@ -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
diff --git a/lisp/ob-clojure.el b/lisp/ob-clojure.el
index a933fdc..a3e6cbe 100644
--- a/lisp/ob-clojure.el
+++ b/lisp/ob-clojure.el
@@ -48,15 +48,9 @@
(eval-when-compile
(require 'cl))
-(declare-function cider-current-ns "ext:cider-interaction" ())
-(declare-function cider-get-raw-value "ext:cider-client" (eval-result))
-(declare-function cider-eval-sync "ext:cider-client" (input &optional ns session))
(declare-function nrepl-send-string-sync "ext:nrepl-client" (input &optional ns session))
-(declare-function nrepl-current-tooling-session "ext:nrepl-client" ())
-
(declare-function nrepl-current-connection-buffer "ext:nrepl" ())
(declare-function nrepl-eval "ext:nrepl" (body))
-
(declare-function slime-eval "ext:slime" (sexp &optional package))
(defvar org-babel-tangle-lang-exts)
@@ -90,16 +84,10 @@
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."
@@ -108,9 +96,14 @@
(case org-babel-clojure-backend
(cider
(require 'cider)
- (setq result
- (or (cider-get-raw-value (cider-eval-sync expanded))
- (error "nREPL not connected! Use M-x cider-jack-in RET"))))
+ (let ((result-params (cdr (assoc :result-params params))))
+ (setq result
+ (plist-get
+ (nrepl-send-string-sync expanded)
+ (if (or (member "output" result-params)
+ (member "pp" result-params))
+ :stdout
+ :value)))))
(nrepl
(require 'nrepl)
(setq result
diff --git a/lisp/ob-comint.el b/lisp/ob-comint.el
index 0b97424..7c768d3 100644
--- a/lisp/ob-comint.el
+++ b/lisp/ob-comint.el
@@ -148,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/lisp/ob-core.el b/lisp/ob-core.el
index 0adfc33..e01c4d2 100644
--- a/lisp/ob-core.el
+++ b/lisp/ob-core.el
@@ -38,6 +38,7 @@
(defvar org-src-lang-modes)
(defvar org-babel-library-of-babel)
(declare-function show-all "outline" ())
+(declare-function org-every "org" (pred seq))
(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))
@@ -202,9 +203,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.")
@@ -283,6 +284,8 @@ Returns a list
;; 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-babel-exp-reference-buffer nil
@@ -470,6 +473,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)
@@ -567,11 +571,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.")
@@ -853,7 +863,7 @@ arguments and pop open the results in a preview buffer."
(mapconcat
(lambda (group)
(let ((arg (org-icompleting-read
- "value: "
+ "Value: "
(cons "default"
(mapcar #'symbol-name group)))))
(if (and arg (not (string= "default" arg)))
@@ -982,7 +992,7 @@ with a prefix argument then this is passed on to
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)))
@@ -1427,7 +1437,7 @@ specified in the properties of the current outline entry."
(org-entry-get org-babel-current-src-block-location
(concat "header-args:" lang) 'inherit))))))
-(defvar org-src-preserve-indentation)
+(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)))
@@ -1591,7 +1601,7 @@ shown below.
;; row and column names
(defun org-babel-del-hlines (table)
"Remove all 'hlines from TABLE."
- (remove 'hline table))
+ (remq 'hline table))
(defun org-babel-get-colnames (table)
"Return the column names of TABLE.
@@ -1856,10 +1866,13 @@ 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))
+ (block (progn (org-babel-where-is-src-block-head) (match-string 0)))
+ (headers (progn (org-babel-where-is-src-block-head) (match-string 4)))
+ (stars (concat (make-string (or (org-current-level) 1) ?*) " "))
+ lower-case-p)
+ (if (let (case-fold-search) (string-match "#\\+begin_src" block))
+ (setq lower-case-p t))
(if info
(mapc
(lambda (place)
@@ -1873,9 +1886,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]")
@@ -1895,11 +1909,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)
@@ -2080,9 +2095,11 @@ 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.
-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.
+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. This
is a good option if you code block will output html
@@ -2094,8 +2111,9 @@ latex --- results are added inside of a #+BEGIN_LATEX block.
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
+ 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."
(if (stringp result)
(progn
@@ -2157,12 +2175,15 @@ 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)
+ (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)))))))
;; insert results based on type
@@ -2184,9 +2205,9 @@ code ---- the results are extracted in the syntax of the source
((funcall proper-list-p result)
(goto-char beg)
(insert (concat (orgtbl-to-orgtbl
- (if (or (eq 'hline (car result))
- (and (listp (car result))
- (listp (cdr (car result)))))
+ (if (org-every
+ (lambda (el) (or (listp el) (eq el 'hline)))
+ result)
result (list result))
'(:fmt (lambda (cell) (format "%s" cell)))) "\n"))
(goto-char beg) (when (org-at-table-p) (org-table-align)))
@@ -2210,10 +2231,16 @@ code ---- the results are extracted in the syntax of the source
(funcall wrap "#+BEGIN_LaTeX" "#+END_LaTeX"))
((member "org" result-params)
(goto-char beg) (if (org-at-table-p) (org-cycle))
- (funcall wrap "#+BEGIN_SRC org" "#+END_SRC"))
+ (if inlinep
+ (funcall wrap "src_org{" "}" nil t)
+ (funcall wrap "#+BEGIN_SRC org" "#+END_SRC")))
((member "code" result-params)
- (funcall wrap (format "#+BEGIN_SRC %s%s" (or lang "none") results-switches)
- "#+END_SRC"))
+ (let ((lang (or lang "none")))
+ (if inlinep
+ (funcall wrap (format "src_%s[%s]{" lang results-switches)
+ "}" nil t)
+ (funcall wrap (format "#+BEGIN_SRC %s%s" lang results-switches)
+ "#+END_SRC"))))
((member "raw" result-params)
(goto-char beg) (if (org-at-table-p) (org-cycle)))
((or (member "drawer" result-params)
@@ -2252,6 +2279,15 @@ code ---- the results are extracted in the syntax of the source
(if keep-keyword (1+ (match-end 0)) (1- (match-beginning 0)))
(progn (forward-line 1) (org-babel-result-end))))))))
+(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."
(save-excursion
@@ -2426,6 +2462,16 @@ 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)))))
@@ -2618,7 +2664,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 "
@@ -2732,9 +2779,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)))
@@ -2742,12 +2789,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)
@@ -2881,6 +2928,51 @@ For the format of SAFE-LIST, see `org-babel-safe-header-args'."
(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/lisp/ob-ditaa.el b/lisp/ob-ditaa.el
index 26f0e4f..888cafc 100644
--- a/lisp/ob-ditaa.el
+++ b/lisp/ob-ditaa.el
@@ -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/lisp/ob-dot.el b/lisp/ob-dot.el
index b35d7bb..1e399e7 100644
--- a/lisp/ob-dot.el
+++ b/lisp/ob-dot.el
@@ -55,7 +55,9 @@
(replace-regexp-in-string
(concat "\$" (regexp-quote name))
(if (stringp value) value (format "%S" value))
- body))))
+ body
+ t
+ t))))
vars)
body))
diff --git a/lisp/ob-eval.el b/lisp/ob-eval.el
index 057590f..b3ce2af 100644
--- a/lisp/ob-eval.el
+++ b/lisp/ob-eval.el
@@ -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/lisp/ob-exp.el b/lisp/ob-exp.el
index 220a3c3..492bc35 100644
--- a/lisp/ob-exp.el
+++ b/lisp/ob-exp.el
@@ -24,6 +24,7 @@
;;; Code:
(require 'ob-core)
+(require 'org-src)
(eval-when-compile
(require 'cl))
@@ -47,6 +48,7 @@
(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
@@ -65,7 +67,12 @@ be executed."
(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))
results)
(when org-babel-exp-reference-buffer
@@ -74,13 +81,17 @@ be executed."
;; 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)))
@@ -176,7 +187,9 @@ may make them unreachable."
(point)))))
(case type
(inline-src-block
- (let* ((info (org-babel-parse-inline-src-block-match))
+ (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))
@@ -305,10 +318,10 @@ The function respects the value of the :exports header argument."
(clean (lambda () (unless (eq type 'inline) (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"
@@ -330,7 +343,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 "24.5"
+ :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))))
@@ -341,7 +376,9 @@ replaced with its value."
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)))
diff --git a/lisp/ob-forth.el b/lisp/ob-forth.el
new file mode 100644
index 0000000..cc2795a
--- a/dev/null
+++ b/lisp/ob-forth.el
@@ -0,0 +1,86 @@
+;;; ob-forth.el --- org-babel functions for Forth
+
+;; Copyright (C) 2014 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 <http://www.gnu.org/licenses/>.
+
+;;; 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/lisp/ob-gnuplot.el b/lisp/ob-gnuplot.el
index 7d7db2a..a350186 100644
--- a/lisp/ob-gnuplot.el
+++ b/lisp/ob-gnuplot.el
@@ -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)
@@ -264,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/lisp/ob-groovy.el b/lisp/ob-groovy.el
index 9bb17e6..0068df9 100644
--- a/lisp/ob-groovy.el
+++ b/lisp/ob-groovy.el
@@ -36,8 +36,14 @@
(defvar org-babel-tangle-lang-exts) ;; Autoloaded
(add-to-list 'org-babel-tangle-lang-exts '("groovy" . "groovy"))
(defvar org-babel-default-header-args:groovy '())
-(defvar org-babel-groovy-command "groovy"
- "Name of the command to use for executing Groovy code.")
+(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
diff --git a/lisp/ob-haskell.el b/lisp/ob-haskell.el
index 22240ad..0006670 100644
--- a/lisp/ob-haskell.el
+++ b/lisp/ob-haskell.el
@@ -147,7 +147,6 @@ specifying a variable of the same value."
(concat "[" (mapconcat #'org-babel-haskell-var-to-haskell var ", ") "]")
(format "%S" var)))
-(defvar org-src-preserve-indentation)
(defvar org-export-copy-to-kill-ring)
(declare-function org-export-to-file "ox"
(backend file
diff --git a/lisp/ob-java.el b/lisp/ob-java.el
index 22f8785..8c64171 100644
--- a/lisp/ob-java.el
+++ b/lisp/ob-java.el
@@ -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/lisp/ob-js.el b/lisp/ob-js.el
index 7789449..47355b3 100644
--- a/lisp/ob-js.el
+++ b/lisp/ob-js.el
@@ -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/lisp/ob-keys.el b/lisp/ob-keys.el
index 90b5196..dc1f437 100644
--- a/lisp/ob-keys.el
+++ b/lisp/ob-keys.el
@@ -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/lisp/ob-latex.el b/lisp/ob-latex.el
index 35b6650..6a74611 100644
--- a/lisp/ob-latex.el
+++ b/lisp/ob-latex.el
@@ -135,13 +135,18 @@ 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)))
+ ;; 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}
@@ -151,6 +156,12 @@ This function is called by `org-babel-execute-src-block'."
(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}")))
@@ -179,7 +190,7 @@ This function is called by `org-babel-execute-src-block'."
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)))
diff --git a/lisp/ob-lilypond.el b/lisp/ob-lilypond.el
index 9b57546..43433a3 100644
--- a/lisp/ob-lilypond.el
+++ b/lisp/ob-lilypond.el
@@ -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)
@@ -39,62 +41,82 @@
(defvar org-babel-default-header-args:lilypond '()
"Default header arguments for lilypond code blocks.
NOTE: The arguments are determined at lilypond compile time.
-See (ly-set-header-args)")
+See (org-babel-lilypond-set-header-args)")
-(defvar ly-compile-post-tangle t
+(defvar org-babel-lilypond-compile-post-tangle t
"Following the org-babel-tangle (C-c C-v t) command,
-ly-compile-post-tangle determines whether ob-lilypond should
+org-babel-lilypond-compile-post-tangle determines whether ob-lilypond should
automatically attempt to compile the resultant tangled file.
If the value is nil, no automated compilation takes place.
Default value is t")
-(defvar ly-display-pdf-post-tangle t
+(defvar org-babel-lilypond-display-pdf-post-tangle t
"Following a successful LilyPond compilation
-ly-display-pdf-post-tangle determines whether to automate the
+org-babel-lilypond-display-pdf-post-tangle determines whether to automate the
drawing / redrawing of the resultant pdf. If the value is nil,
the pdf is not automatically redrawn. Default value is t")
-(defvar ly-play-midi-post-tangle t
+(defvar org-babel-lilypond-play-midi-post-tangle t
"Following a successful LilyPond compilation
-ly-play-midi-post-tangle determines whether to automate the
+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 ly-OSX-ly-path
- "/Applications/lilypond.app/Contents/Resources/bin/lilypond")
-(defvar ly-OSX-pdf-path "open")
-(defvar ly-OSX-midi-path "open")
-
-(defvar ly-nix-ly-path "/usr/bin/lilypond")
-(defvar ly-nix-pdf-path "evince")
-(defvar ly-nix-midi-path "timidity")
-
-(defvar ly-w32-ly-path "lilypond")
-(defvar ly-w32-pdf-path "")
-(defvar ly-w32-midi-path "")
-
-(defvar ly-gen-png nil
+(defconst org-babel-lilypond-ly-command
+ "Command to execute lilypond on your system.")
+(defconst org-babel-lilypond-pdf-command
+ "Command to show a PDF file on your system.")
+(defconst org-babel-lilypond-midi-command
+ "Command to play a MIDI file on your system.")
+(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
-LY-GEN-PNG to t")
+ORG-BABEL-LILYPOND-GEN-PNG to t")
-(defvar ly-gen-svg nil
+(defvar org-babel-lilypond-gen-svg nil
"Image generation (SVG) can be turned on by default by setting
-LY-GEN-SVG to t")
+ORG-BABEL-LILYPOND-GEN-SVG to t")
-(defvar ly-gen-html nil
+(defvar org-babel-lilypond-gen-html nil
"HTML generation can be turned on by default by setting
-LY-GEN-HTML to t")
+ORG-BABEL-LILYPOND-GEN-HTML to t")
-(defvar ly-gen-pdf nil
+(defvar org-babel-lilypond-gen-pdf nil
"PDF generation can be turned on by default by setting
-LY-GEN-PDF to t")
+ORG-BABEL-LILYPOND-GEN-PDF to t")
-(defvar ly-use-eps nil
+(defvar org-babel-lilypond-use-eps nil
"You can force the compiler to use the EPS backend by setting
-LY-USE-EPS to t")
+ORG-BABEL-LILYPOND-USE-EPS to t")
-(defvar ly-arrange-mode nil
- "Arrange mode is turned on by setting LY-ARRANGE-MODE
+(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...
:tangle yes, :noweb yes
@@ -123,20 +145,20 @@ Depending on whether we are in arrange mode either:
1. Attempt to execute lilypond block according to header settings
(This is the default basic mode)
2. Tangle all lilypond blocks and process the result (arrange mode)"
- (ly-set-header-args ly-arrange-mode)
- (if ly-arrange-mode
- (ly-tangle)
- (ly-process-basic body params)))
+ (org-babel-lilypond-set-header-args org-babel-lilypond-arrange-mode)
+ (if org-babel-lilypond-arrange-mode
+ (org-babel-lilypond-tangle)
+ (org-babel-lilypond-process-basic body params)))
-(defun ly-tangle ()
+(defun org-babel-lilypond-tangle ()
"ob-lilypond specific tangle, attempts to invoke
=ly-execute-tangled-ly= if tangle is successful. Also passes
specific arguments to =org-babel-tangle="
(interactive)
(if (org-babel-tangle nil "yes" "lilypond")
- (ly-execute-tangled-ly) nil))
+ (org-babel-lilypond-execute-tangled-ly) nil))
-(defun ly-process-basic (body params)
+(defun org-babel-lilypond-process-basic (body params)
"Execute a lilypond block in basic mode."
(let* ((result-params (cdr (assoc :result-params params)))
(out-file (cdr (assoc :file params)))
@@ -148,7 +170,7 @@ specific arguments to =org-babel-tangle="
(insert (org-babel-expand-body:generic body params)))
(org-babel-eval
(concat
- (ly-determine-ly-path)
+ org-babel-lilypond-ly-command
" -dbackend=eps "
"-dno-gs-load-fonts "
"-dinclude-eps-fonts "
@@ -167,45 +189,43 @@ specific arguments to =org-babel-tangle="
"Return an error because LilyPond exporter does not support sessions."
(error "Sorry, LilyPond does not currently support sessions!"))
-(defun ly-execute-tangled-ly ()
+(defun org-babel-lilypond-execute-tangled-ly ()
"Compile result of block tangle with lilypond.
If error in compilation, attempt to mark the error in lilypond org file"
- (when ly-compile-post-tangle
- (let ((ly-tangled-file (ly-switch-extension
+ (when org-babel-lilypond-compile-post-tangle
+ (let ((org-babel-lilypond-tangled-file (org-babel-lilypond-switch-extension
(buffer-file-name) ".lilypond"))
- (ly-temp-file (ly-switch-extension
+ (org-babel-lilypond-temp-file (org-babel-lilypond-switch-extension
(buffer-file-name) ".ly")))
- (if (file-exists-p ly-tangled-file)
- (progn
- (when (file-exists-p ly-temp-file)
- (delete-file ly-temp-file))
- (rename-file ly-tangled-file
- ly-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)
- (ly-compile-lilyfile ly-temp-file)
+ (org-babel-lilypond-compile-lilyfile org-babel-lilypond-temp-file)
(goto-char (point-min))
- (if (not (ly-check-for-compile-error ly-temp-file))
- (progn
- (other-window -1)
- (ly-attempt-to-open-pdf ly-temp-file)
- (ly-attempt-to-play-midi ly-temp-file))
- (error "Error in Compilation!")))) nil)
-
-(defun ly-compile-lilyfile (file-name &optional test)
+ (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 (ly-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
- (arg-5 (if ly-gen-png "--png" "")) ;&rest...
- (arg-6 (if ly-gen-html "--html" ""))
- (arg-7 (if ly-gen-pdf "--pdf" ""))
- (arg-8 (if ly-use-eps "-dbackend=eps" ""))
- (arg-9 (if ly-gen-svg "-dbackend=svg" ""))
+ (arg-5 (if org-babel-lilypond-gen-png "--png" "")) ;&rest...
+ (arg-6 (if org-babel-lilypond-gen-html "--html" ""))
+ (arg-7 (if org-babel-lilypond-gen-pdf "--pdf" ""))
+ (arg-8 (if org-babel-lilypond-use-eps "-dbackend=eps" ""))
+ (arg-9 (if org-babel-lilypond-gen-svg "-dbackend=svg" ""))
(arg-10 (concat "--output=" (file-name-sans-extension file-name)))
(arg-11 file-name))
(if test
@@ -215,7 +235,7 @@ FILE-NAME is full path to lilypond (.ly) file"
arg-1 arg-2 arg-3 arg-4 arg-5 arg-6
arg-7 arg-8 arg-9 arg-10 arg-11))))
-(defun ly-check-for-compile-error (file-name &optional test)
+(defun org-babel-lilypond-check-for-compile-error (file-name &optional test)
"Check for compile error.
This is performed by parsing the *lilypond* buffer
containing the output message from the compilation.
@@ -223,27 +243,26 @@ 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
- (ly-process-compile-error file-name))
- is-error)))
+ (if test
+ is-error
+ (when is-error
+ (org-babel-lilypond-process-compile-error file-name)))))
-(defun ly-process-compile-error (file-name)
+(defun org-babel-lilypond-process-compile-error (file-name)
"Process the compilation error that has occurred.
FILE-NAME is full path to lilypond file"
- (let ((line-num (ly-parse-line-num)))
- (let ((error-lines (ly-parse-error-line file-name line-num)))
- (ly-mark-error-line file-name error-lines)
+ (let ((line-num (org-babel-lilypond-parse-line-num)))
+ (let ((error-lines (org-babel-lilypond-parse-error-line file-name line-num)))
+ (org-babel-lilypond-mark-error-line file-name error-lines)
(error "Error: Compilation Failed!"))))
-(defun ly-mark-error-line (file-name line)
+(defun org-babel-lilypond-mark-error-line (file-name line)
"Mark the erroneous lines in the lilypond org buffer.
FILE-NAME is full path to lilypond file.
LINE is the erroneous line"
(switch-to-buffer-other-window
(concat (file-name-nondirectory
- (ly-switch-extension file-name ".org"))))
+ (org-babel-lilypond-switch-extension file-name ".org"))))
(let ((temp (point)))
(goto-char (point-min))
(setq case-fold-search nil)
@@ -254,7 +273,7 @@ LINE is the erroneous line"
(goto-char (- (point) (length line))))
(goto-char temp))))
-(defun ly-parse-line-num (&optional buffer)
+(defun org-babel-lilypond-parse-line-num (&optional buffer)
"Extract error line number."
(when buffer
(set-buffer buffer))
@@ -276,12 +295,12 @@ LINE is the erroneous line"
nil)))
nil)))
-(defun ly-parse-error-line (file-name lineNo)
+(defun org-babel-lilypond-parse-error-line (file-name lineNo)
"Extract the erroneous line from the tangled .ly file
FILE-NAME is full path to lilypond file.
LINENO is the number of the erroneous line"
(with-temp-buffer
- (insert-file-contents (ly-switch-extension file-name ".ly")
+ (insert-file-contents (org-babel-lilypond-switch-extension file-name ".ly")
nil nil nil t)
(if (> lineNo 0)
(progn
@@ -290,128 +309,95 @@ LINENO is the number of the erroneous line"
(buffer-substring (point) (point-at-eol)))
nil)))
-(defun ly-attempt-to-open-pdf (file-name &optional test)
+(defun org-babel-lilypond-attempt-to-open-pdf (file-name &optional test)
"Attempt to display the generated pdf file
FILE-NAME is full path to lilypond file
If TEST is non-nil, the shell command is returned and is not run"
- (when ly-display-pdf-post-tangle
- (let ((pdf-file (ly-switch-extension file-name ".pdf")))
+ (when org-babel-lilypond-display-pdf-post-tangle
+ (let ((pdf-file (org-babel-lilypond-switch-extension file-name ".pdf")))
(if (file-exists-p pdf-file)
(let ((cmd-string
- (concat (ly-determine-pdf-path) " " pdf-file)))
+ (concat org-babel-lilypond-pdf-command " " pdf-file)))
(if test
cmd-string
(start-process
"\"Audition pdf\""
"*lilypond*"
- (ly-determine-pdf-path)
+ org-babel-lilypond-pdf-command
pdf-file)))
(message "No pdf file generated so can't display!")))))
-(defun ly-attempt-to-play-midi (file-name &optional test)
+(defun org-babel-lilypond-attempt-to-play-midi (file-name &optional test)
"Attempt to play the generated MIDI file
FILE-NAME is full path to lilypond file
If TEST is non-nil, the shell command is returned and is not run"
- (when ly-play-midi-post-tangle
- (let ((midi-file (ly-switch-extension file-name ".midi")))
+ (when org-babel-lilypond-play-midi-post-tangle
+ (let ((midi-file (org-babel-lilypond-switch-extension file-name ".midi")))
(if (file-exists-p midi-file)
(let ((cmd-string
- (concat (ly-determine-midi-path) " " midi-file)))
+ (concat org-babel-lilypond-midi-command " " midi-file)))
(if test
cmd-string
(start-process
"\"Audition midi\""
"*lilypond*"
- (ly-determine-midi-path)
+ org-babel-lilypond-midi-command
midi-file)))
(message "No midi file generated so can't play!")))))
-(defun ly-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")
- ly-OSX-ly-path)
- ((string= sys-type "windows-nt")
- ly-w32-ly-path)
- (t ly-nix-ly-path))))
-
-(defun ly-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")
- ly-OSX-pdf-path)
- ((string= sys-type "windows-nt")
- ly-w32-pdf-path)
- (t ly-nix-pdf-path))))
-
-(defun ly-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")
- ly-OSX-midi-path)
- ((string= sys-type "windows-nt")
- ly-w32-midi-path)
- (t ly-nix-midi-path))))
-
-(defun ly-toggle-midi-play ()
+(defun org-babel-lilypond-toggle-midi-play ()
"Toggle whether midi will be played following a successful compilation."
(interactive)
- (setq ly-play-midi-post-tangle
- (not ly-play-midi-post-tangle))
+ (setq org-babel-lilypond-play-midi-post-tangle
+ (not org-babel-lilypond-play-midi-post-tangle))
(message (concat "Post-Tangle MIDI play has been "
- (if ly-play-midi-post-tangle
+ (if org-babel-lilypond-play-midi-post-tangle
"ENABLED." "DISABLED."))))
-(defun ly-toggle-pdf-display ()
+(defun org-babel-lilypond-toggle-pdf-display ()
"Toggle whether pdf will be displayed following a successful compilation."
(interactive)
- (setq ly-display-pdf-post-tangle
- (not ly-display-pdf-post-tangle))
+ (setq org-babel-lilypond-display-pdf-post-tangle
+ (not org-babel-lilypond-display-pdf-post-tangle))
(message (concat "Post-Tangle PDF display has been "
- (if ly-display-pdf-post-tangle
+ (if org-babel-lilypond-display-pdf-post-tangle
"ENABLED." "DISABLED."))))
-(defun ly-toggle-png-generation ()
+(defun org-babel-lilypond-toggle-png-generation ()
"Toggle whether png image will be generated by compilation."
(interactive)
- (setq ly-gen-png (not ly-gen-png))
+ (setq org-babel-lilypond-gen-png (not org-babel-lilypond-gen-png))
(message (concat "PNG image generation has been "
- (if ly-gen-png "ENABLED." "DISABLED."))))
+ (if org-babel-lilypond-gen-png "ENABLED." "DISABLED."))))
-(defun ly-toggle-html-generation ()
+(defun org-babel-lilypond-toggle-html-generation ()
"Toggle whether html will be generated by compilation."
(interactive)
- (setq ly-gen-html (not ly-gen-html))
+ (setq org-babel-lilypond-gen-html (not org-babel-lilypond-gen-html))
(message (concat "HTML generation has been "
- (if ly-gen-html "ENABLED." "DISABLED."))))
+ (if org-babel-lilypond-gen-html "ENABLED." "DISABLED."))))
-(defun ly-toggle-pdf-generation ()
+(defun org-babel-lilypond-toggle-pdf-generation ()
"Toggle whether pdf will be generated by compilation."
(interactive)
- (setq ly-gen-pdf (not ly-gen-pdf))
+ (setq org-babel-lilypond-gen-pdf (not org-babel-lilypond-gen-pdf))
(message (concat "PDF generation has been "
- (if ly-gen-pdf "ENABLED." "DISABLED."))))
+ (if org-babel-lilypond-gen-pdf "ENABLED." "DISABLED."))))
-(defun ly-toggle-arrange-mode ()
+(defun org-babel-lilypond-toggle-arrange-mode ()
"Toggle whether in Arrange mode or Basic mode."
(interactive)
- (setq ly-arrange-mode
- (not ly-arrange-mode))
+ (setq org-babel-lilypond-arrange-mode
+ (not org-babel-lilypond-arrange-mode))
(message (concat "Arrange mode has been "
- (if ly-arrange-mode "ENABLED." "DISABLED."))))
+ (if org-babel-lilypond-arrange-mode "ENABLED." "DISABLED."))))
-(defun ly-switch-extension (file-name ext)
+(defun org-babel-lilypond-switch-extension (file-name ext)
"Utility command to swap current FILE-NAME extension with EXT"
(concat (file-name-sans-extension
file-name) ext))
-(defun ly-get-header-args (mode)
+(defun org-babel-lilypond-get-header-args (mode)
"Default arguments to use when evaluating a lilypond
source block. These depend upon whether we are in arrange
mode i.e. ARRANGE-MODE is t"
@@ -425,11 +411,11 @@ mode i.e. ARRANGE-MODE is t"
'((:results . "file")
(:exports . "results")))))
-(defun ly-set-header-args (mode)
+(defun org-babel-lilypond-set-header-args (mode)
"Set org-babel-default-header-args:lilypond
-dependent on LY-ARRANGE-MODE"
+dependent on ORG-BABEL-LILYPOND-ARRANGE-MODE"
(setq org-babel-default-header-args:lilypond
- (ly-get-header-args mode)))
+ (org-babel-lilypond-get-header-args mode)))
(provide 'ob-lilypond)
diff --git a/lisp/ob-lisp.el b/lisp/ob-lisp.el
index 9e10340..a59dab3 100644
--- a/lisp/ob-lisp.el
+++ b/lisp/ob-lisp.el
@@ -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."
@@ -86,7 +86,7 @@ current directory string."
default-directory)))
(format
(if dir (format org-babel-lisp-dir-fmt dir)
- "(progn %s)")
+ "(progn %s\n)")
(buffer-substring-no-properties
(point-min) (point-max)))))
(cdr (assoc :package params)))))))
diff --git a/lisp/ob-maxima.el b/lisp/ob-maxima.el
index 7435f1d..4e559d1 100644
--- a/lisp/ob-maxima.el
+++ b/lisp/ob-maxima.el
@@ -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/lisp/ob-ocaml.el b/lisp/ob-ocaml.el
index 7f0e298..2439150 100644
--- a/lisp/ob-ocaml.el
+++ b/lisp/ob-ocaml.el
@@ -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)
diff --git a/lisp/ob-octave.el b/lisp/ob-octave.el
index 8cc66b6..14b55d2 100644
--- a/lisp/ob-octave.el
+++ b/lisp/ob-octave.el
@@ -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
@@ -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/lisp/ob-python.el b/lisp/ob-python.el
index baa5764..5a6a3ae 100644
--- a/lisp/ob-python.el
+++ b/lisp/ob-python.el
@@ -56,8 +56,6 @@ This will typically be either 'python or 'python-mode."
:package-version '(Org . "8.0")
:type 'symbol)
-(defvar org-src-preserve-indentation)
-
(defcustom org-babel-python-hline-to "None"
"Replace hlines in incoming tables with this when translating to python."
:group 'org-babel
@@ -82,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) ""))
diff --git a/lisp/ob-ruby.el b/lisp/ob-ruby.el
index fd59ef4..26285eb 100644
--- a/lisp/ob-ruby.el
+++ b/lisp/ob-ruby.el
@@ -209,21 +209,32 @@ return the value of the last statement in BODY, as elisp."
;; 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 "conf.echo=false" body "conf.echo=true" 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/lisp/ob-scheme.el b/lisp/ob-scheme.el
index b7117e9..2095534 100644
--- a/lisp/ob-scheme.el
+++ b/lisp/ob-scheme.el
@@ -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/lisp/ob-screen.el b/lisp/ob-screen.el
index 2acbbeb..1d4ccdd 100644
--- a/lisp/ob-screen.el
+++ b/lisp/ob-screen.el
@@ -106,7 +106,7 @@ In case you want to use a different screen than one selected by your $PATH")
(defun org-babel-screen-session-write-temp-file (session body)
"Save BODY in a temp file that is named after SESSION."
- (let ((tmpfile (concat "/tmp/screen.org-babel-session-" session)))
+ (let ((tmpfile (org-babel-temp-file "screen-")))
(with-temp-file tmpfile
(insert body)
@@ -121,7 +121,7 @@ The terminal should shortly flicker."
(interactive)
(let* ((session "org-babel-testing")
(random-string (format "%s" (random 99999)))
- (tmpfile "/tmp/org-babel-screen.test")
+ (tmpfile (org-babel-temp-file "ob-screen-test-"))
(body (concat "echo '" random-string "' > " tmpfile "\nexit\n"))
process tmp-string)
(org-babel-execute:screen body org-babel-default-header-args:screen)
diff --git a/lisp/ob-shell.el b/lisp/ob-shell.el
index 3ede701..aa14a69 100644
--- a/lisp/ob-shell.el
+++ b/lisp/ob-shell.el
@@ -38,19 +38,6 @@
(defvar org-babel-default-header-args:sh '())
-(defcustom org-babel-sh-command shell-file-name
- "Command used to invoke a shell.
-Set by default to the value of `shell-file-name'. This will be
-passed to `shell-command-on-region'"
- :group 'org-babel
- :type 'string)
-
-(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."
- :group 'org-babel
- :type 'string)
-
(defcustom org-babel-shell-names
'("sh" "bash" "csh" "ash" "dash" "ksh" "mksh" "posh")
"List of names of shell supported by babel shell code blocks."
@@ -63,7 +50,7 @@ passed to `shell-command-on-region'"
(lambda (name)
(eval `(defun ,(intern (concat "org-babel-execute:" name)) (body params)
,(format "Execute a block of %s commands with Babel." name)
- (let ((org-babel-sh-command ,name))
+ (let ((shell-file-name ,name))
(org-babel-execute:shell body params)))))
(second value))))
@@ -105,6 +92,42 @@ This function is called by `org-babel-execute-src-block'."
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: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:sh (params)
"Return list of shell statements assigning the block's variables."
@@ -114,16 +137,21 @@ This function is called by `org-babel-execute-src-block'."
"hline"))))
(mapcar
(lambda (pair)
- (format "%s=%s"
- (car pair)
- (org-babel-sh-var-to-sh (cdr pair) sep hline)))
+ (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 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 hline)))
+ (concat "'" (replace-regexp-in-string
+ "'" "'\"'\"'"
+ (org-babel-sh-var-to-string var sep hline))
+ "'"))
(defun org-babel-sh-var-to-string (var &optional sep hline)
"Convert an elisp value to a string."
@@ -147,7 +175,13 @@ Emacs-lisp table, otherwise return the results as a string."
(when (and session (not (string= session "none")))
(save-window-excursion
(or (org-babel-comint-buffer-livep session)
- (progn (shell session) (get-buffer (current-buffer)))))))
+ (progn
+ (shell session)
+ ;; Needed for Emacs 23 since the marker is initially
+ ;; undefined and the filter functions try to use it without
+ ;; checking.
+ (set-marker comint-last-output-start (point))
+ (get-buffer (current-buffer)))))))
(defvar org-babel-sh-eoe-indicator "echo 'org_babel_sh_eoe'"
"String to indicate that evaluation has completed.")
@@ -176,7 +210,7 @@ return the value of the last statement in BODY."
(call-process-shell-command
(if shebang
script-file
- (format "%s %s" org-babel-sh-command script-file))
+ (format "%s %s" shell-file-name script-file))
stdin-file
(current-buffer) nil cmdline)
(buffer-string))))
@@ -214,7 +248,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
diff --git a/lisp/ob-sql.el b/lisp/ob-sql.el
index 7b85df8..493b3dc 100644
--- a/lisp/ob-sql.el
+++ b/lisp/ob-sql.el
@@ -78,15 +78,24 @@
(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 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 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'."
@@ -117,14 +126,15 @@ 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 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 --set=\"ON_ERROR_STOP=1\" %s -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 "")))
diff --git a/lisp/ob-table.el b/lisp/ob-table.el
index 831e352..6658313 100644
--- a/lisp/ob-table.el
+++ b/lisp/ob-table.el
@@ -62,23 +62,27 @@ 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.
+
+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))
-#+begin_src emacs-lisp :var results=source-block(n=val_at_col_2, m=3) :results silent
-results
-#+end_src
+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
-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.
diff --git a/lisp/ob-tangle.el b/lisp/ob-tangle.el
index be7e9a6..1c159a5 100644
--- a/lisp/ob-tangle.el
+++ b/lisp/ob-tangle.el
@@ -88,6 +88,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
@@ -103,12 +108,25 @@ 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-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
@@ -232,13 +250,14 @@ used to limit the exported source code blocks by language."
(concat base-name "." ext) base-name))))
(when file-name
;; Possibly create the parent directories for file.
- (when (let ((m (funcall get-spec :mkdirp)))
- (and m (not (string= m "no"))))
- (make-directory (file-name-directory file-name) 'parents))
+ (let ((m (funcall get-spec :mkdirp))
+ (fnd (file-name-directory file-name)))
+ (and m fnd (not (string= m "no"))
+ (make-directory fnd 'parents)))
;; delete any old versions of file
- (when (and (file-exists-p file-name)
- (not (member file-name (mapcar #'car path-collector))))
- (delete-file file-name))
+ (and (file-exists-p file-name)
+ (not (member file-name (mapcar #'car path-collector)))
+ (delete-file file-name))
;; drop source-block to file
(with-temp-buffer
(when (fboundp lang-f) (ignore-errors (funcall lang-f)))
@@ -341,8 +360,15 @@ that the appropriate major-mode is set. SPEC has the form:
(insert-comment (lambda (text)
(when (and comments (not (string= comments "no"))
(> (length text) 0))
- (comment-region (point) (progn (insert text) (point)))
- (end-of-line nil) (insert "\n")))))
+ (if org-babel-tangle-uncomment-comments
+ ;; just plain comments with no processing
+ (insert text)
+ ;; ensure comments are made to be
+ ;; comments, and add a trailing newline
+ (comment-region
+ (point) (progn (insert text) (point)))
+ (end-of-line nil)
+ (insert "\n"))))))
(when comment (funcall insert-comment comment))
(when link-p
(funcall
diff --git a/lisp/org-agenda.el b/lisp/org-agenda.el
index 0cf5028..1bec8dc 100644
--- a/lisp/org-agenda.el
+++ b/lisp/org-agenda.el
@@ -361,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
@@ -391,32 +397,36 @@ the daily/weekly agenda, see `org-agenda-skip-function'.")
(repeat :inline t :tag "Conditions for skipping"
(choice
:tag "Condition type"
- (list :tag "Regexp matches" :inline t (const :format "" regexp) (regexp))
- (list :tag "Regexp does not match" :inline t (const :format "" notregexp) (regexp))
+ (list :tag "Regexp matches" :inline t
+ (const :format "" 'regexp)
+ (regexp))
+ (list :tag "Regexp does not match" :inline t
+ (const :format "" 'notregexp)
+ (regexp))
(list :tag "TODO state is" :inline t
- (const todo)
+ (const 'todo)
(choice
- (const :tag "any not-done state" todo)
- (const :tag "any done state" done)
- (const :tag "any state" any)
+ (const :tag "Any not-done state" 'todo)
+ (const :tag "Any done state" 'done)
+ (const :tag "Any state" 'any)
(list :tag "Keyword list"
(const :format "" quote)
(repeat (string :tag "Keyword")))))
(list :tag "TODO state is not" :inline t
- (const nottodo)
+ (const 'nottodo)
(choice
- (const :tag "any not-done state" todo)
- (const :tag "any done state" done)
- (const :tag "any state" any)
+ (const :tag "Any not-done state" 'todo)
+ (const :tag "Any done state" 'done)
+ (const :tag "Any state" 'any)
(list :tag "Keyword list"
(const :format "" quote)
(repeat (string :tag "Keyword")))))
- (const :tag "scheduled" scheduled)
- (const :tag "not scheduled" notscheduled)
- (const :tag "deadline" deadline)
- (const :tag "no deadline" notdeadline)
- (const :tag "timestamp" timestamp)
- (const :tag "no timestamp" nottimestamp))))))
+ (const :tag "scheduled" 'scheduled)
+ (const :tag "not scheduled" 'notscheduled)
+ (const :tag "deadline" 'deadline)
+ (const :tag "no deadline" 'notdeadline)
+ (const :tag "timestamp" 'timestamp)
+ (const :tag "no timestamp" 'nottimestamp))))))
(list :tag "Non-standard skipping condition"
:value (org-agenda-skip-function)
(const org-agenda-skip-function)
@@ -607,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"
@@ -650,8 +651,8 @@ of custom agenda commands."
:tag "Org Agenda Match View"
:group 'org-agenda)
(defgroup org-agenda-search-view nil
- "Options concerning the general tags/property/todo match agenda view."
- :tag "Org Agenda Match View"
+ "Options concerning the search agenda view."
+ :tag "Org Agenda Search View"
:group 'org-agenda)
(defvar org-agenda-archives-mode nil
@@ -2093,12 +2094,11 @@ When nil, `q' will kill the single agenda buffer."
org-agenda-info
org-agenda-pre-window-conf
org-agenda-columns-active
- org-agenda-tag-filter-overlays
org-agenda-tag-filter
- org-agenda-cat-filter-overlays
org-agenda-category-filter
- org-agenda-re-filter-overlays
+ 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-filtered-by-category
@@ -2145,6 +2145,7 @@ The following commands are available:
;; Keep global-font-lock-mode from turning on font-lock-mode
(org-set-local 'font-lock-global-modes (list 'not major-mode))
(setq mode-name "Org-Agenda")
+ (setq indent-tabs-mode nil)
(use-local-map org-agenda-mode-map)
(easy-menu-add org-agenda-menu)
(if org-startup-truncated (setq truncate-lines t))
@@ -2158,10 +2159,11 @@ The following commands are available:
nil t)
(unless org-agenda-keep-modes
(setq org-agenda-follow-mode org-agenda-start-with-follow-mode
- org-agenda-entry-text-mode org-agenda-start-with-entry-text-mode
- org-agenda-clockreport-mode org-agenda-start-with-clockreport-mode
- org-agenda-show-log org-agenda-start-with-log-mode))
-
+ org-agenda-entry-text-mode org-agenda-start-with-entry-text-mode))
+ (setq org-agenda-show-log org-agenda-start-with-log-mode)
+ (setq org-agenda-clockreport-mode org-agenda-start-with-clockreport-mode)
+ (add-to-invisibility-spec '(org-filtered))
+ (add-to-invisibility-spec '(org-link))
(easy-menu-change
'("Agenda") "Agenda Files"
(append
@@ -2305,6 +2307,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)
@@ -2608,7 +2611,7 @@ type."
:package-version '(Org . "8.0")
:group 'org-agenda-custom-commands
:type '(choice (symbol :tag "No limit" nil)
- (integer :tag "Max number of entries")
+ (integer :tag "Max number of TODOs")
(repeat
(cons (choice :tag "Agenda type"
(const agenda)
@@ -2616,7 +2619,7 @@ type."
(const tags)
(const search)
(const timeline))
- (integer :tag "Max number of entries")))))
+ (integer :tag "Max number of TODOs")))))
(defcustom org-agenda-max-tags nil
"Maximum number of tagged entries to display in an agenda.
@@ -2627,7 +2630,7 @@ type."
:package-version '(Org . "8.0")
:group 'org-agenda-custom-commands
:type '(choice (symbol :tag "No limit" nil)
- (integer :tag "Max number of entries")
+ (integer :tag "Max number of tagged entries")
(repeat
(cons (choice :tag "Agenda type"
(const agenda)
@@ -2635,7 +2638,7 @@ type."
(const tags)
(const search)
(const timeline))
- (integer :tag "Max number of entries")))))
+ (integer :tag "Max number of tagged entries")))))
(defcustom org-agenda-max-effort nil
"Maximum cumulated effort duration for the agenda.
@@ -2646,7 +2649,7 @@ to limit entries to in this type."
:package-version '(Org . "8.0")
:group 'org-agenda-custom-commands
:type '(choice (symbol :tag "No limit" nil)
- (integer :tag "Max number of entries")
+ (integer :tag "Max number of minutes")
(repeat
(cons (choice :tag "Agenda type"
(const agenda)
@@ -2654,7 +2657,7 @@ to limit entries to in this type."
(const tags)
(const search)
(const timeline))
- (integer :tag "Max number of entries")))))
+ (integer :tag "Max number of minutes")))))
(defvar org-keys nil)
(defvar org-match nil)
@@ -3309,19 +3312,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)
@@ -3331,19 +3335,12 @@ If AGENDA-BUFFER-NAME, use this as the buffer name for the agenda to write."
(org-let (if nosettings nil org-agenda-exporter-settings)
'(save-excursion
(save-window-excursion
- (org-agenda-mark-filtered-text)
(let ((bs (copy-sequence (buffer-string))) beg content)
- (org-agenda-unmark-filtered-text)
(with-temp-buffer
(rename-buffer org-agenda-write-buffer-name t)
(set-buffer-modified-p nil)
(insert bs)
(org-agenda-remove-marked-text 'org-filtered)
- (while (setq beg (text-property-any (point-min) (point-max)
- 'org-filtered t))
- (delete-region
- beg (or (next-single-property-change beg 'org-filtered)
- (point-max))))
(run-hooks 'org-agenda-before-write-hook)
(cond
((org-bound-and-true-p org-mobile-creating-agendas)
@@ -3363,7 +3360,7 @@ If AGENDA-BUFFER-NAME, use this as the buffer name for the agenda to write."
content)))
(find-file file)
(erase-buffer)
- (mapcar (lambda (s) (org-paste-subtree 1 s)) (reverse content))
+ (dolist (s content) (org-paste-subtree 1 s))
(write-file file)
(kill-buffer (current-buffer))
(message "Org file written to %s" file)))
@@ -3409,28 +3406,6 @@ If AGENDA-BUFFER-NAME, use this as the buffer name for the agenda to write."
org-agenda-buffer-name)))
(when open (org-open-file file)))
-(defvar org-agenda-tag-filter-overlays nil)
-(defvar org-agenda-cat-filter-overlays nil)
-(defvar org-agenda-re-filter-overlays nil)
-
-(defun org-agenda-mark-filtered-text ()
- "Mark all text hidden by filtering with a text property."
- (let ((inhibit-read-only t))
- (mapc
- (lambda (o)
- (when (equal (overlay-buffer o) (current-buffer))
- (put-text-property
- (overlay-start o) (overlay-end o)
- 'org-filtered t)))
- (append org-agenda-tag-filter-overlays
- org-agenda-cat-filter-overlays
- org-agenda-re-filter-overlays))))
-
-(defun org-agenda-unmark-filtered-text ()
- "Remove the filtering text property."
- (let ((inhibit-read-only t))
- (remove-text-properties (point-min) (point-max) '(org-filtered t))))
-
(defun org-agenda-remove-marked-text (property &optional value)
"Delete all text marked with VALUE of PROPERTY.
VALUE defaults to t."
@@ -3439,7 +3414,7 @@ VALUE defaults to t."
(while (setq beg (text-property-any (point-min) (point-max)
property value))
(delete-region
- beg (or (next-single-property-change beg 'org-filtered)
+ beg (or (next-single-property-change beg property)
(point-max))))))
(defun org-agenda-add-entry-text ()
@@ -3563,8 +3538,8 @@ 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-while-redo nil)
(defvar org-agenda-tag-filter-preset nil
"A preset of the tags filter used for secondary agenda filtering.
This must be a list of strings, each string must be a single tag preceded
@@ -3595,6 +3570,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
@@ -3616,10 +3601,12 @@ generating a new one."
;; does not have org variables local
org-agenda-this-buffer-is-sticky))))
-(defun org-agenda-prepare-window (abuf)
- "Setup agenda buffer in the window."
- (let* ((awin (get-buffer-window abuf))
- wconf)
+(defun org-agenda-prepare-window (abuf filter-alist)
+ "Setup agenda buffer in the window.
+ABUF is the buffer for the agenda window.
+FILTER-ALIST is an alist of filters we need to apply when
+`org-agenda-persistent-filter' is non-nil."
+ (let* ((awin (get-buffer-window abuf)) wconf)
(cond
((equal (current-buffer) abuf) nil)
(awin (select-window awin))
@@ -3633,66 +3620,77 @@ generating a new one."
((equal org-agenda-window-setup 'reorganize-frame)
(delete-other-windows)
(org-switch-to-buffer-other-window abuf)))
- ;; additional test in case agenda is invoked from within agenda
- ;; buffer via elisp link
+ (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))))
(defun org-agenda-prepare (&optional name)
- (if (org-agenda-use-sticky-p)
- (progn
- ;; Popup existing buffer
- (org-agenda-prepare-window (get-buffer org-agenda-buffer-name))
- (message "Sticky Agenda buffer, use `r' to refresh")
- (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)
- (unless org-agenda-persistent-filter
- (setq org-agenda-tag-filter nil
- org-agenda-category-filter nil
- org-agenda-regexp-filter 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)
- (if org-agenda-multi
+ (let ((filter-alist (if org-agenda-persistent-filter
+ (list `(tag . ,org-agenda-tag-filter)
+ `(re . ,org-agenda-regexp-filter)
+ `(effort . ,org-agenda-effort-filter)
+ `(car . ,org-agenda-category-filter)))))
+ (if (org-agenda-use-sticky-p)
(progn
- (setq buffer-read-only nil)
- (goto-char (point-max))
- (unless (or (bobp) org-agenda-compact-blocks
- (not org-agenda-block-separator))
- (insert "\n"
- (if (stringp org-agenda-block-separator)
- org-agenda-block-separator
- (make-string (window-width) org-agenda-block-separator))
- "\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 (get-buffer-create org-agenda-buffer-name))
- (setq buffer-read-only nil)
- (org-agenda-reset-markers)
- (let ((inhibit-read-only t)) (erase-buffer))
- (org-agenda-mode)
- (setq org-agenda-buffer (current-buffer))
- (setq org-agenda-contributing-files nil)
- (setq org-agenda-columns-active nil)
- (org-agenda-prepare-buffers (org-agenda-files nil 'ifmode))
- (setq org-todo-keywords-for-agenda
- (org-uniquify org-todo-keywords-for-agenda))
- (setq org-done-keywords-for-agenda
- (org-uniquify org-done-keywords-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)
- (org-set-local 'org-agenda-name name)))
- (setq buffer-read-only nil)))
+ (put 'org-agenda-tag-filter :preset-filter nil)
+ (put 'org-agenda-category-filter :preset-filter nil)
+ (put 'org-agenda-regexp-filter :preset-filter nil)
+ ;; Popup existing buffer
+ (org-agenda-prepare-window (get-buffer org-agenda-buffer-name)
+ filter-alist)
+ (message "Sticky Agenda buffer, use `r' to refresh")
+ (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)
+ (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)
+ (goto-char (point-max))
+ (unless (or (bobp) org-agenda-compact-blocks
+ (not org-agenda-block-separator))
+ (insert "\n"
+ (if (stringp org-agenda-block-separator)
+ org-agenda-block-separator
+ (make-string (window-width) org-agenda-block-separator))
+ "\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
+ (get-buffer-create org-agenda-buffer-name) filter-alist)
+ (setq buffer-read-only nil)
+ (org-agenda-reset-markers)
+ (let ((inhibit-read-only t)) (erase-buffer))
+ (org-agenda-mode)
+ (setq org-agenda-buffer (current-buffer))
+ (setq org-agenda-contributing-files nil)
+ (setq org-agenda-columns-active nil)
+ (org-agenda-prepare-buffers (org-agenda-files nil 'ifmode))
+ (setq org-todo-keywords-for-agenda
+ (org-uniquify org-todo-keywords-for-agenda))
+ (setq org-done-keywords-for-agenda
+ (org-uniquify org-done-keywords-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)
+ (org-set-local 'org-agenda-name name)))
+ (setq buffer-read-only nil))))
(defvar org-agenda-overriding-columns-format) ; From org-colview.el
(defun org-agenda-finalize ()
@@ -3744,19 +3742,35 @@ generating a new one."
(save-excursion
(goto-char (point-min))
(while (equal (forward-line) 0)
- (when (setq mrk (or (get-text-property (point) 'org-hd-marker)
- (get-text-property (point) 'org-hd-marker)))
+ (when (setq mrk (get-text-property (point) 'org-hd-marker))
(put-text-property (point-at-bol) (point-at-eol)
'tags (org-with-point-at mrk
(delete-dups
(mapcar 'downcase (org-get-tags-at))))))))))
(run-hooks 'org-agenda-finalize-hook)
- (when (or org-agenda-tag-filter (get 'org-agenda-tag-filter :preset-filter))
+ (when org-agenda-top-headline-filter
+ (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))
- (when (or org-agenda-category-filter (get 'org-agenda-category-filter :preset-filter))
+ (when (get 'org-agenda-tag-filter :preset-filter)
+ (org-agenda-filter-apply
+ (get 'org-agenda-tag-filter :preset-filter) 'tag))
+ (when org-agenda-category-filter
(org-agenda-filter-apply org-agenda-category-filter 'category))
- (when (or org-agenda-regexp-filter (get 'org-agenda-regexp-filter :preset-filter))
+ (when (get 'org-agenda-category-filter :preset-filter)
+ (org-agenda-filter-apply
+ (get 'org-agenda-category-filter :preset-filter) 'category))
+ (when org-agenda-regexp-filter
(org-agenda-filter-apply org-agenda-regexp-filter 'regexp))
+ (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 ()
@@ -3857,11 +3871,12 @@ dimming them."
e (point-at-eol)
ov (make-overlay b e))
(if invis1
- (overlay-put ov 'invisible t)
+ (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))))))
- (when (org-called-interactively-p 'interactive)
- (message "Dim or hide blocked tasks...done")))
+ (when (org-called-interactively-p 'interactive)
+ (message "Dim or hide blocked tasks...done")))
(defvar org-agenda-skip-function nil
"Function to be called at each match during agenda construction.
@@ -4321,14 +4336,6 @@ items if they have an hour specification like [h]h:mm."
(setq p (plist-put p :tstart clocktable-start))
(setq p (plist-put p :tend clocktable-end))
(setq p (plist-put p :scope 'agenda))
- (when (and (eq org-agenda-clockreport-mode 'with-filter)
- (setq filter (or org-agenda-tag-filter-while-redo
- (get 'org-agenda-tag-filter :preset-filter))))
- (setq p (plist-put p :tags (mapconcat (lambda (x)
- (if (string-match "[<>=]" x)
- ""
- x))
- filter ""))))
(setq tbl (apply 'org-clock-get-clocktable p))
(insert tbl)))
(goto-char (point-min))
@@ -4461,7 +4468,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)
@@ -4627,7 +4634,6 @@ in `org-agenda-text-search-extra-files'."
(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)
@@ -4646,8 +4652,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))))))))))
@@ -5373,7 +5378,7 @@ 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
ee txt beg end inherited-tags todo-state-end-pos)
(goto-char (point-min))
(while (re-search-forward regexp nil t)
@@ -5420,9 +5425,7 @@ the documentation of `org-diary'."
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)))
+ 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)
@@ -5436,10 +5439,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
@@ -5460,7 +5462,7 @@ This function is invoked if `org-agenda-todo-ignore-deadlines',
;;;###autoload
(defun org-agenda-check-for-timestamp-as-reason-to-ignore-todo-item
- (&optional end)
+ (&optional end)
"Do we have a reason to ignore this TODO entry because it has a time stamp?"
(when (or org-agenda-todo-ignore-with-date
org-agenda-todo-ignore-scheduled
@@ -5558,7 +5560,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))
@@ -5602,8 +5604,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)
@@ -5630,11 +5631,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")
@@ -5653,7 +5653,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)
@@ -5672,7 +5672,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)
@@ -5697,10 +5696,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 'tags tags
- 'level level
- 'type "sexp" 'warntime warntime)
+ 'date date 'todo-state todo-state
+ 'level level 'type "sexp" 'warntime warntime)
(push txt ee)))))
(nreverse ee)))
@@ -5809,7 +5806,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)
@@ -5821,7 +5818,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
@@ -5873,9 +5869,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))
@@ -6021,7 +6015,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))
@@ -6081,8 +6075,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))
@@ -6127,8 +6120,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)
@@ -6168,7 +6159,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)
@@ -6247,8 +6238,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))
@@ -6316,8 +6306,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))))))
@@ -6335,7 +6323,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)
@@ -6356,9 +6344,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))
@@ -6400,8 +6387,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.
@@ -6472,9 +6458,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))
@@ -6483,15 +6466,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)
@@ -6542,16 +6527,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)
@@ -6578,7 +6553,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
@@ -6599,14 +6573,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
@@ -6742,10 +6714,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))
@@ -6776,8 +6751,10 @@ The optional STRING argument forces conversion into a 5 character wide string
HH:MM."
(save-match-data
(when
- (or (string-match "\\<\\([012]?[0-9]\\)\\(:\\([0-5][0-9]\\)\\)\\([AaPp][Mm]\\)?\\> *" s)
- (string-match "\\<\\([012]?[0-9]\\)\\(:\\([0-5][0-9]\\)\\)?\\([AaPp][Mm]\\)\\> *" s))
+ (and
+ (or (string-match "\\<\\([012]?[0-9]\\)\\(:\\([0-5][0-9]\\)\\)\\([AaPp][Mm]\\)?\\> *" s)
+ (string-match "\\<\\([012]?[0-9]\\)\\(:\\([0-5][0-9]\\)\\)?\\([AaPp][Mm]\\)\\> *" s))
+ (not (eq (get-text-property 1 'face s) 'org-link)))
(let* ((h (string-to-number (match-string 1 s)))
(m (if (match-end 3) (string-to-number (match-string 3 s)) 0))
(ampm (if (match-end 4) (downcase (match-string 4 s))))
@@ -6830,7 +6807,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
@@ -6840,7 +6817,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
@@ -6858,26 +6837,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)
@@ -6923,25 +6915,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))))
@@ -7005,7 +6997,7 @@ The optional argument TYPE tells the agenda type."
(cond ((< ta tb) -1)
((< tb ta) +1))))
-(defsubst org-cmp-ts (a b &optional type)
+(defsubst org-cmp-ts (a b type)
"Compare the timestamps values of entries A and B.
When TYPE is \"scheduled\", \"deadline\", \"timestamp\" or
\"timestamp_ia\", compare within each of these type. When TYPE
@@ -7013,9 +7005,11 @@ is the empty string, compare all timestamps without respect of
their type."
(let* ((def (if org-sort-agenda-notime-is-late most-positive-fixnum -1))
(ta (or (and (string-match type (or (get-text-property 1 'type a) ""))
- (get-text-property 1 'ts-date a)) def))
+ (get-text-property 1 'ts-date a))
+ def))
(tb (or (and (string-match type (or (get-text-property 1 'type b) ""))
- (get-text-property 1 'ts-date b)) def)))
+ (get-text-property 1 'ts-date b))
+ def)))
(cond ((< ta tb) -1)
((< tb ta) +1))))
@@ -7041,7 +7035,7 @@ their type."
(org-cmp-ts a b "deadline")))
(deadline-down (if deadline-up (- deadline-up) nil))
(tsia-up (and (org-em 'tsia-up 'tsia-down ss)
- (org-cmp-ts a b "iatimestamp_ia")))
+ (org-cmp-ts a b "timestamp_ia")))
(tsia-down (if tsia-up (- tsia-up) nil))
(ts-up (and (org-em 'ts-up 'ts-down ss)
(org-cmp-ts a b "timestamp")))
@@ -7049,8 +7043,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)))
@@ -7100,6 +7097,7 @@ 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
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)
@@ -7278,6 +7276,8 @@ 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))
@@ -7296,6 +7296,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
@@ -7306,14 +7307,21 @@ 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)
- (and (or tag-filter tag-preset) (org-agenda-filter-apply tag-filter 'tag))
- (and (or cat-filter cat-preset) (org-agenda-filter-apply cat-filter 'category))
- (and (or re-filter re-preset) (org-agenda-filter-apply re-filter 'regexp))
+ (put 'org-agenda-effort-filter :preset-filter effort-preset)
+ (let ((tag (or tag-filter tag-preset))
+ (cat (or cat-filter cat-preset))
+ (effort (or effort-filter effort-preset))
+ (re (or re-filter re-preset)))
+ (when tag (org-agenda-filter-apply tag 'tag))
+ (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))
(org-goto-line line)
@@ -7330,7 +7338,7 @@ The category is that of the current line."
(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
@@ -7339,7 +7347,7 @@ The category is that of the current line."
(org-agenda-filter-apply
(setq org-agenda-category-filter
(list (concat "+" cat))) 'category))
- ((error "No category at point"))))))
+ (t (error "No category at point"))))))
(defun org-find-top-headline (&optional pos)
"Find the topmost parent headline and return it."
@@ -7360,10 +7368,10 @@ The top headline is that of the current line."
(progn
(setq org-agenda-filtered-by-top-headline nil
org-agenda-top-headline-filter nil)
- (org-agenda-filter-show-all-cat))
- (let ((cat (org-find-top-headline (org-get-at-bol 'org-hd-marker))))
- (if cat (org-agenda-filter-top-headline-apply cat strip)
- (error "No top-level category at point")))))
+ (org-agenda-filter-show-all-top-filter))
+ (let ((toph (org-find-top-headline (org-get-at-bol 'org-hd-marker))))
+ (if toph (org-agenda-filter-top-headline-apply toph strip)
+ (error "No top-level headline at point")))))
(defvar org-agenda-regexp-filter nil)
(defun org-agenda-filter-by-regexp (strip)
@@ -7378,12 +7386,45 @@ With two prefix arguments, remove the regexp filters."
(read-from-minibuffer
(if (equal strip '(4))
"Filter out entries matching regexp: "
- "Narrow to entries matching regexp: ")))))
+ "Narrow to entries matching regexp: ")))))
(push flt org-agenda-regexp-filter)
(org-agenda-filter-apply org-agenda-regexp-filter 'regexp))
(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)
@@ -7392,7 +7433,12 @@ With two prefix arguments, remove the regexp filters."
(when org-agenda-category-filter
(org-agenda-filter-show-all-cat))
(when org-agenda-regexp-filter
- (org-agenda-filter-show-all-re)))
+ (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)
"Keep only those lines in the agenda buffer that have a specific tag.
@@ -7409,19 +7455,12 @@ to switch to narrowing."
(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 "")
(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: "
+ "%s by tag [%s ], [TAB], %s[/]:off, [+-]:narrow"
(if narrow "Narrow" "Filter") tag-chars
(if org-agenda-auto-exclude-function "[RET], " ""))
(setq char (read-char-exclusive)))
@@ -7430,23 +7469,8 @@ to switch to narrowing."
(cond ((equal char ?-) (setq strip t narrow t))
((equal char ?+) (setq strip nil narrow t)))
(message
- "Narrow by tag [%s ], [TAB], [/]:off, [>=<]:effort: " tag-chars)
+ "Narrow by tag [%s ], [TAB], [/]:off" 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)
- (setq char (read-char-exclusive))
- (when (or (< char ?0) (> char ?9))
- (error "Need 1-9,0 to select effort"))))
(when (equal char ?\t)
(unless (local-variable-p 'org-global-tags-completion-table (current-buffer))
(org-set-local 'org-global-tags-completion-table
@@ -7464,40 +7488,26 @@ 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))
+ (org-agenda-filter-apply org-agenda-tag-filter 'tag))))
((equal 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))
+ (org-agenda-filter-apply org-agenda-tag-filter 'tag)))
((equal 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))
+ (org-agenda-filter-apply org-agenda-tag-filter 'tag))
((or (equal char ?\ )
(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 (and maybe-refresh
- (eq org-agenda-clockreport-mode 'with-filter))
- (org-agenda-redo))))
+ (org-agenda-filter-apply org-agenda-tag-filter 'tag))
+ (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."
@@ -7532,10 +7542,8 @@ to switch to narrowing."
(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)))
+ (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))))
@@ -7569,7 +7577,15 @@ 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-effort-form (e)
@@ -7588,11 +7604,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.
@@ -7617,13 +7631,12 @@ When NO-OPERATOR is non-nil, do not add the + operator to returned tags."
;; 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))
- (if (and (eq type 'category)
- (not (equal (substring (car filter) 0 1) "-")))
- ;; Only set `org-agenda-filtered-by-category' to t
- ;; when a unique category is used as the filter
- (setq org-agenda-filtered-by-category t))
+ (setq org-agenda-filter-form (org-agenda-filter-make-matcher filter type))
+ ;; Only set `org-agenda-filtered-by-category' to t when a unique
+ ;; category is used as the filter:
+ (setq org-agenda-filtered-by-category
+ (and (eq type 'category)
+ (not (equal (substring (car filter) 0 1) "-"))))
(org-agenda-set-mode-name)
(save-excursion
(goto-char (point-min))
@@ -7635,8 +7648,8 @@ When NO-OPERATOR is non-nil, do not add the + operator to returned tags."
(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))
+ cat (org-get-at-eol 'org-category 1)
+ txt (org-get-at-eol 'txt 1))
(if (not (eval org-agenda-filter-form))
(org-agenda-filter-hide-line type))
(beginning-of-line 2))
@@ -7653,8 +7666,8 @@ When NO-OPERATOR is non-nil, do not add the + operator to returned tags."
(let* ((pos (org-get-at-bol 'org-hd-marker))
(tophl (and pos (org-find-top-headline pos))))
(if (and tophl (funcall (if negative 'identity 'not)
- (string= hl tophl)))
- (org-agenda-filter-hide-line 'category)))
+ (string= hl tophl)))
+ (org-agenda-filter-hide-line 'top-headline)))
(beginning-of-line 2)))
(if (get-char-property (point) 'invisible)
(org-agenda-previous-line))
@@ -7663,50 +7676,38 @@ When NO-OPERATOR is non-nil, do not add the + operator to returned tags."
(defun org-agenda-filter-hide-line (type)
"Hide lines with TYPE in the agenda buffer."
- (let (ov)
- (setq ov (make-overlay (max (point-min) (point-at-bol))
- (1+ (point-at-eol))))
- (overlay-put ov 'invisible t)
- (overlay-put ov 'type type)
- (cond ((eq type 'tag) (push ov org-agenda-tag-filter-overlays))
- ((eq type 'category) (push ov org-agenda-cat-filter-overlays))
- ((eq type 'regexp) (push ov org-agenda-re-filter-overlays)))))
-
-(defun org-agenda-fix-tags-filter-overlays-at (&optional pos)
- (setq pos (or pos (point)))
+ (let* ((b (max (point-min) (1- (point-at-bol))))
+ (e (point-at-eol)))
+ (let ((inhibit-read-only t))
+ (add-text-properties
+ b e `(invisible org-filtered org-filter-type ,type)))))
+
+(defun org-agenda-remove-filter (type)
+ (interactive)
+ "Remove filter of type TYPE from the agenda buffer."
(save-excursion
- (dolist (ov (overlays-at pos))
- (when (and (overlay-get ov 'invisible)
- (eq (overlay-get ov 'type) 'tag))
+ (goto-char (point-min))
+ (let ((inhibit-read-only t) pos)
+ (while (setq pos (text-property-any (point) (point-max) 'org-filter-type type))
(goto-char pos)
- (if (< (overlay-start ov) (point-at-eol))
- (move-overlay ov (point-at-eol)
- (overlay-end ov)))))))
+ (remove-text-properties
+ (point) (next-single-property-change (point) 'org-filter-type)
+ `(invisible org-filtered org-filter-type ,type))))
+ (set (intern (format "org-agenda-%s-filter" (intern-soft type))) nil)
+ (setq org-agenda-filter-form nil)
+ (org-agenda-set-mode-name)
+ (org-agenda-finalize)))
(defun org-agenda-filter-show-all-tag nil
- "Remove tag filter overlays from the agenda buffer."
- (mapc 'delete-overlay org-agenda-tag-filter-overlays)
- (setq org-agenda-tag-filter-overlays nil
- org-agenda-tag-filter nil
- org-agenda-filter-form nil)
- (org-agenda-set-mode-name))
-
+ (org-agenda-remove-filter 'tag))
(defun org-agenda-filter-show-all-re nil
- "Remove regexp filter overlays from the agenda buffer."
- (mapc 'delete-overlay org-agenda-re-filter-overlays)
- (setq org-agenda-re-filter-overlays nil
- org-agenda-regexp-filter nil
- org-agenda-filter-form nil)
- (org-agenda-set-mode-name))
-
+ (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
- "Remove category filter overlays from the agenda buffer."
- (mapc 'delete-overlay org-agenda-cat-filter-overlays)
- (setq org-agenda-cat-filter-overlays nil
- org-agenda-filtered-by-category nil
- org-agenda-category-filter nil
- org-agenda-filter-form nil)
- (org-agenda-set-mode-name))
+ (org-agenda-remove-filter 'category))
+(defun org-agenda-filter-show-all-top-filter nil
+ (org-agenda-remove-filter 'top-headline))
(defun org-agenda-manipulate-query-add ()
"Manipulate the query by adding a search term with positive selection.
@@ -8113,15 +8114,12 @@ so that the date SD will be in that range."
(format " (maximum number of lines is %d)"
(if (integerp arg) arg org-agenda-entry-text-maxlines))))))
-(defun org-agenda-clockreport-mode (&optional with-filter)
- "Toggle clocktable mode in an agenda buffer.
-With prefix arg WITH-FILTER, make the clocktable respect the current
-agenda filter."
- (interactive "P")
+(defun org-agenda-clockreport-mode ()
+ "Toggle clocktable mode in an agenda buffer."
+ (interactive)
(org-agenda-check-type t 'agenda)
- (if with-filter
- (setq org-agenda-clockreport-mode 'with-filter)
- (setq org-agenda-clockreport-mode (not org-agenda-clockreport-mode)))
+ (setq org-agenda-clockreport-mode (not org-agenda-clockreport-mode))
+ (setq org-agenda-start-with-clockreport-mode org-agenda-clockreport-mode)
(org-agenda-set-mode-name)
(org-agenda-redo)
(message "Clocktable mode is %s"
@@ -8142,6 +8140,7 @@ With a double `C-u' prefix arg, show *only* log items, nothing else."
nil 'clockcheck))
(special '(closed clock state))
(t (not org-agenda-show-log))))
+ (setq org-agenda-start-with-log-mode org-agenda-show-log)
(org-agenda-set-mode-name)
(org-agenda-redo)
(message "Log mode is %s"
@@ -8241,6 +8240,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
@@ -8259,10 +8271,7 @@ When called with a prefix argument, include all archive files as well."
" Archives"
(format " :%s:" org-archive-tag))
"")
- (if org-agenda-clockreport-mode
- (if (eq org-agenda-clockreport-mode 'with-filter)
- " Clock{}" " Clock")
- "")))
+ (if org-agenda-clockreport-mode " Clock" "")))
(force-mode-line-update))
(define-obsolete-function-alias
@@ -8330,7 +8339,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)))
@@ -8348,6 +8357,9 @@ When called with a prefix argument, include all archive files as well."
(when (outline-invisible-p)
(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)))))
@@ -8464,8 +8476,8 @@ 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 \\[universal-argument] \\[universal-argument] \\[universal-argument], clear the refile cache.
+When GOTO is '(16) or \\[universal-argument] \\[universal-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")
@@ -8631,7 +8643,8 @@ if it was hidden in the outline."
(interactive "p")
(let ((win (selected-window)))
(org-agenda-goto t)
- (org-recenter-heading 1)
+ (org-back-to-heading)
+ (set-window-start (selected-window) (point-at-bol))
(cond
((= more 0)
(hide-subtree)
@@ -8665,11 +8678,6 @@ if it was hidden in the outline."
(message "Remote: SUBTREE AND ALL DRAWERS")))
(select-window win)))
-(defun org-recenter-heading (n)
- (save-excursion
- (org-back-to-heading)
- (recenter n)))
-
(defvar org-agenda-cycle-counter nil)
(defun org-agenda-cycle-show (&optional n)
"Show the current entry in another window, with default settings.
@@ -8714,7 +8722,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.
@@ -8813,7 +8822,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."
@@ -8862,7 +8872,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
@@ -9178,8 +9188,8 @@ Called with a universal prefix arg, show the priority instead of setting it."
(goto-char (point-max))
(while (not (bobp))
(when (equal marker (org-get-at-bol 'org-marker))
+ (remove-text-properties (point-at-bol) (point-at-eol) '(display))
(org-move-to-column (- (window-width) (length stamp)) t)
- (org-agenda-fix-tags-filter-overlays-at (point))
(if (featurep 'xemacs)
;; Use `duplicable' property to trigger undo recording
(let ((ex (make-extent nil nil))
@@ -9189,9 +9199,9 @@ Called with a universal prefix arg, show the priority instead of setting it."
ex (list 'invisible t 'end-glyph gl 'duplicable t))
(insert-extent ex (1- (point)) (point-at-eol)))
(add-text-properties
- (1- (point)) (point-at-eol)
+ (1- (point)) (point-at-eol)
(list 'display (org-add-props stamp nil
- 'face 'secondary-selection))))
+ 'face '(secondary-selection default)))))
(beginning-of-line 1))
(beginning-of-line 0)))))
@@ -9479,9 +9489,9 @@ a timestamp can be added there."
(if org-adapt-indentation (org-indent-to-column 2)))
(defun org-agenda-insert-diary-make-new-entry (text)
- "Make new entry as last child of current entry.
-Add TEXT as headline, and position the cursor in the second line so that
-a timestamp can be added there."
+ "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)
@@ -9670,7 +9680,7 @@ This is a command that has to be installed in `calendar-mode-map'."
(overlay-put ov 'type 'org-marked-entry-overlay))
(end-of-line 1)
(or (ignore-errors
- (goto-char (next-single-property-change (point) 'txt)))
+ (goto-char (next-single-property-change (point) 'org-hd-marker)))
(beginning-of-line 2))
(while (and (get-char-property (point) 'invisible) (not (eobp)))
(beginning-of-line 2))
@@ -9688,7 +9698,7 @@ This is a command that has to be installed in `calendar-mode-map'."
(let ((entries-marked 0) txt-at-point)
(save-excursion
(goto-char (point-min))
- (goto-char (next-single-property-change (point) 'txt))
+ (goto-char (next-single-property-change (point) 'org-hd-marker))
(while (and (re-search-forward regexp nil t)
(setq txt-at-point (get-text-property (point) 'txt)))
(when (string-match regexp txt-at-point)
@@ -9724,7 +9734,7 @@ This is a command that has to be installed in `calendar-mode-map'."
(save-excursion
(goto-char (point-min))
(while (ignore-errors
- (goto-char (next-single-property-change (point) 'txt)))
+ (goto-char (next-single-property-change (point) 'org-hd-marker)))
(org-agenda-bulk-toggle))))
(defun org-agenda-bulk-toggle ()
@@ -9947,33 +9957,33 @@ current HH:MM time."
`((,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)
"Drag an agenda line forward by ARG lines.
When the optional argument `backward' is non-nil, move backward."
(interactive "p")
- (let ((inhibit-read-only t) lst)
+ (let ((inhibit-read-only t) lst line)
(if (or (not (get-text-property (point) 'txt))
(save-excursion
(dotimes (n arg)
(move-beginning-of-line (if backward 0 2))
- (forward-char 1)
(push (not (get-text-property (point) 'txt)) lst))
(delq nil lst)))
- (message "Cannot move line %s" (if backward "backward" "forward"))
- (let ((end (save-excursion (move-end-of-line 1) (point)))
- (col (current-column)) line)
+ (message "Cannot move line forward")
+ (let ((end (save-excursion (move-beginning-of-line 2) (point))))
(move-beginning-of-line 1)
(setq line (buffer-substring (point) end))
- (delete-region (point) (1+ end))
- (move-end-of-line (funcall (if backward '1- '1+) (1- arg)))
- (insert "\n" line)
- (org-move-to-column col)
+ (delete-region (point) end)
+ (move-beginning-of-line (funcall (if backward '1- '1+) arg))
+ (insert line)
(org-agenda-reapply-filters)
- (org-agenda-mark-clocking-task)))))
+ (org-agenda-mark-clocking-task)
+ (move-beginning-of-line 0)))))
(defun org-agenda-drag-line-backward (arg)
"Drag an agenda line backward by ARG lines."
@@ -10095,7 +10105,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))
diff --git a/lisp/org-attach.el b/lisp/org-attach.el
index 0412b63..5c341a5 100644
--- a/lisp/org-attach.el
+++ b/lisp/org-attach.el
@@ -208,7 +208,9 @@ the directory and (if necessary) the corresponding ID will be created."
(save-excursion
(save-restriction
(widen)
- (goto-char org-entry-property-inherited-from)
+ (if (marker-position org-entry-property-inherited-from)
+ (goto-char org-entry-property-inherited-from)
+ (org-back-to-heading t))
(let (org-attach-allow-inheritance)
(org-attach-dir create-if-not-exists-p)))))
(org-attach-check-absolute-path attach-dir)
diff --git a/lisp/org-bbdb.el b/lisp/org-bbdb.el
index b9841a6..cfd5b3b 100644
--- a/lisp/org-bbdb.el
+++ b/lisp/org-bbdb.el
@@ -400,8 +400,11 @@ This is used by Org to re-create the anniversary hash table."
(defun org-bbdb-complete-link ()
"Read a bbdb link with name completion."
(require 'bbdb-com)
- (concat "bbdb:"
- (bbdb-record-name (car (bbdb-completing-read-record "Name: ")))))
+ (let ((rec (bbdb-completing-read-record "Name: ")))
+ (concat "bbdb:"
+ (bbdb-record-name (if (listp rec)
+ (car rec)
+ rec)))))
(defun org-bbdb-anniv-export-ical ()
"Extract anniversaries from BBDB and convert them to icalendar format."
diff --git a/lisp/org-bibtex.el b/lisp/org-bibtex.el
index ed645e5..7b2ed48 100644
--- a/lisp/org-bibtex.el
+++ b/lisp/org-bibtex.el
@@ -203,7 +203,7 @@
(:pages . "One or more page numbers or range of numbers, such as 42-111 or 7,41,73-97 or 43+ (the ‘+’ in this last example indicates pages following that don’t form simple range). BibTEX requires double dashes for page ranges (--).")
(:publisher . "The publisher’s name.")
(:school . "The name of the school where a thesis was written.")
- (:series . "The name of a series or set of books. When citing an entire book, the the title field gives its title and an optional series field gives the name of a series or multi-volume set in which the book is published.")
+ (:series . "The name of a series or set of books. When citing an entire book, the title field gives its title and an optional series field gives the name of a series or multi-volume set in which the book is published.")
(:title . "The work’s title, typed as explained in the LaTeX book.")
(:type . "The type of a technical report for example, 'Research Note'.")
(:volume . "The volume of a journal or multi-volume book.")
@@ -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-export-tags-as-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-export-tags-as-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
@@ -371,7 +386,9 @@ This variable is relevant only if `org-bibtex-export-tags-as-keywords' is t."
(bibtex-beginning-of-entry)
(if (re-search-forward "keywords.*=.*{\\(.*\\)}" nil t)
(progn (goto-char (match-end 1)) (insert ", "))
- (bibtex-make-field "keywords" t t))
+ (search-forward ",\n" nil t)
+ (insert " keywords={},\n")
+ (search-backward "}," nil t))
(insert (mapconcat #'identity tags ", ")))
(buffer-string))))))
@@ -534,7 +551,7 @@ With optional argument OPTIONAL, also prompt for optional fields."
;;; Bibtex <-> Org-mode headline translation functions
(defun org-bibtex (&optional filename)
"Export each headline in the current file to a bibtex entry.
-Headlines are exported using `org-bibtex-export-headline'."
+Headlines are exported using `org-bibtex-headline'."
(interactive
(list (read-file-name
"Bibtex file: " nil nil nil
diff --git a/lisp/org-capture.el b/lisp/org-capture.el
index cf6c9e2..9e33d25 100644
--- a/lisp/org-capture.el
+++ b/lisp/org-capture.el
@@ -1533,8 +1533,8 @@ The template may still contain \"%?\" for cursor positioning."
(v-x (or (org-get-x-clipboard 'PRIMARY)
(org-get-x-clipboard 'CLIPBOARD)
(org-get-x-clipboard 'SECONDARY)))
- (v-t (format-time-string (car org-time-stamp-formats) ct))
- (v-T (format-time-string (cdr org-time-stamp-formats) ct))
+ (v-t (format-time-string (car org-time-stamp-formats) ct1))
+ (v-T (format-time-string (cdr org-time-stamp-formats) ct1))
(v-u (concat "[" (substring v-t 1 -1) "]"))
(v-U (concat "[" (substring v-T 1 -1) "]"))
;; `initial' and `annotation' might habe been passed.
@@ -1591,7 +1591,7 @@ The template may still contain \"%?\" for cursor positioning."
(insert template)
(goto-char (point-min))
(org-capture-steal-local-variables buffer)
- (setq buffer-file-name nil)
+ (setq buffer-file-name nil mark-active nil)
;; %[] Insert contents of a file.
(goto-char (point-min))
@@ -1678,7 +1678,9 @@ The template may still contain \"%?\" for cursor positioning."
(or (equal (char-before) ?:) (insert ":"))
(insert ins)
(or (equal (char-after) ?:) (insert ":"))
- (and (org-at-heading-p) (org-set-tags nil 'align)))))
+ (and (org-at-heading-p)
+ (let ((org-ignore-region t))
+ (org-set-tags nil 'align))))))
((equal char "C")
(cond ((= (length clipboards) 1) (insert (car clipboards)))
((> (length clipboards) 1)
diff --git a/lisp/org-clock.el b/lisp/org-clock.el
index d47bf59..2ffcbfa 100644
--- a/lisp/org-clock.el
+++ b/lisp/org-clock.el
@@ -36,6 +36,7 @@
(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-table-goto-line "org-table" (n))
(defvar org-time-stamp-formats)
(defvar org-ts-what)
(defvar org-frame-title-format-backup frame-title-format)
@@ -413,6 +414,25 @@ 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 :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
@@ -775,11 +795,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))
@@ -1130,7 +1151,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)))
@@ -1670,12 +1693,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 +1728,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 +1754,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
@@ -1816,58 +1845,79 @@ 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.
+
+With one universal prefix argument, show the total time for
+today. With two universal prefix arguments, show the total time
+for a custom range, entered at the prompt. With three universal
+prefix arguments, show 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
+ 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* ((c 60) (h (floor (/ time 60))) (m (- time (* 60 h)))
- (l (if level (org-get-valid-level level 0) 0))
- (off 0)
- ov tx)
- (org-move-to-column c)
- (unless (eolp) (skip-chars-backward "^ \t"))
- (skip-chars-backward " \t")
- (setq ov (make-overlay (point-at-bol) (point-at-eol))
- tx (concat (buffer-substring (point-at-bol) (point))
- (make-string (+ off (max 0 (- c (current-column)))) ?.)
- (org-add-props (concat (make-string l ?*) " "
- (org-minutes-to-clocksum-string time)
- (make-string (- 16 l) ?\ ))
- (list 'face 'org-clock-overlay))
+ (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))
+ (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)
@@ -1930,7 +1980,7 @@ fontified, and then returned."
(org-mode)
(org-create-dblock props)
(org-update-dblock)
- (font-lock-fontify-buffer)
+ (font-lock-ensure)
(forward-line 2)
(buffer-substring (point) (progn
(re-search-forward "^[ \t]*#\\+END" nil t)
@@ -2118,10 +2168,12 @@ If you can combine both, the month starting day will have priority."
((> (+ 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))))
+ (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)))
+ ((eq key 'interactive) nil)
+ (t (user-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)))
@@ -2136,10 +2188,15 @@ If you can combine both, the month starting day will have priority."
((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)))))
+ (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))))
+ (if (eq key 'interactive)
+ (list (org-read-date nil t nil "Range start? ")
+ (org-read-date nil t nil "Range end? ")
+ "(Range interactively set)")
+ (list ts te txt)))))
(defun org-count-quarter (n)
(cond
@@ -2339,6 +2396,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))
@@ -2545,6 +2603,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
@@ -2559,13 +2622,10 @@ from the dynamic block definition."
total-time))
(defun org-clocktable-indent-string (level)
- (if (= level 1)
- ""
- (let ((str "\\__"))
- (while (> level 2)
- (setq level (1- level)
- str (concat str "___")))
- (concat str " "))))
+ (if (= level 1) ""
+ (let ((str " "))
+ (dotimes (k (1- level) str)
+ (setq str (concat "\\emsp" str))))))
(defun org-clocktable-steps (params)
"Step through the range to make a number of clock tables."
diff --git a/lisp/org-colview.el b/lisp/org-colview.el
index 07d140f..41ee0c1 100644
--- a/lisp/org-colview.el
+++ b/lisp/org-colview.el
@@ -1201,8 +1201,6 @@ 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)
(goto-char (point-min))
@@ -1214,9 +1212,9 @@ of fields."
(/ (1+ (length (match-string 1))) 2)
(length (match-string 1)))))
(get-char-property (match-beginning 0) 'org-columns-key))
- (when (save-excursion
- (goto-char (point-at-bol))
- (or (looking-at re-comment)
+ (when (or (org-in-commented-heading-p t)
+ (save-excursion
+ (beginning-of-line)
(looking-at re-archive)))
(org-end-of-subtree t)
(throw 'next t))
diff --git a/lisp/org-compat.el b/lisp/org-compat.el
index 70c41d5..f76b86c 100644
--- a/lisp/org-compat.el
+++ b/lisp/org-compat.el
@@ -312,8 +312,7 @@ Works on both Emacs and XEmacs."
(defun org-in-invisibility-spec-p (arg)
"Is ARG a member of `buffer-invisibility-spec'?"
(if (consp buffer-invisibility-spec)
- (member arg buffer-invisibility-spec)
- nil))
+ (member arg buffer-invisibility-spec)))
(defmacro org-xemacs-without-invisibility (&rest body)
"Turn off extents with invisibility while executing BODY."
@@ -347,18 +346,8 @@ Works on both Emacs and XEmacs."
"Move to column COLUMN.
Pass COLUMN and FORCE to `move-to-column'.
Pass BUFFER to the XEmacs version of `move-to-column'."
- (let* ((with-bracket-link
- (save-excursion
- (forward-line 0)
- (looking-at (concat "^.*" org-bracket-link-regexp))))
- (buffer-invisibility-spec
- (cond
- ((or (not (derived-mode-p 'org-mode))
- (and with-bracket-link (org-invisible-p2)))
- (remove '(org-link) buffer-invisibility-spec))
- (with-bracket-link
- (remove t buffer-invisibility-spec))
- (t buffer-invisibility-spec))))
+ (let ((buffer-invisibility-spec
+ (remove '(org-filtered) buffer-invisibility-spec)))
(if (featurep 'xemacs)
(org-xemacs-without-invisibility
(move-to-column column force buffer))
@@ -433,6 +422,10 @@ TIME defaults to the current time."
(unless (fboundp 'user-error)
(defalias 'user-error 'error))
+;; `font-lock-ensure' is only available from 24.4.50 on
+(unless (fboundp 'font-lock-ensure)
+ (defalias 'font-lock-ensure '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
diff --git a/lisp/org-element.el b/lisp/org-element.el
index f0b6495..cb0c1af 100644
--- a/lisp/org-element.el
+++ b/lisp/org-element.el
@@ -73,9 +73,9 @@
;; 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.
+;; 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.
@@ -153,12 +153,8 @@
"-\\{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))
- "\\|"
+ ;; Clock lines.
+ (regexp-quote org-clock-string) "\\|"
;; Lists.
(let ((term (case org-plain-list-ordered-item-terminator
(?\) ")") (?. "\\.") (otherwise "[.)]")))
@@ -194,8 +190,8 @@ is not sufficient to know if point is at a paragraph ending. See
"Complete list of object types.")
(defconst org-element-recursive-objects
- '(bold italic link subscript radio-target strike-through superscript
- table-cell underline)
+ '(bold footnote-reference italic link subscript radio-target strike-through
+ superscript table-cell underline)
"List of recursive object types.")
(defvar org-element-block-name-alist
@@ -341,15 +337,9 @@ 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))
+ (item . :tag))
"Alist between element types and location of secondary value.")
-(defconst org-element-object-variables '(org-link-abbrev-alist-local)
- "List of buffer-local variables used when parsing objects.
-These variables are copied to the temporary buffer created by
-`org-export-secondary-string'.")
-
;;; Accessors and Setters
@@ -783,12 +773,15 @@ containing `:raw-value', `:title', `:alt-title', `:begin',
`:end', `:pre-blank', `:contents-begin' and `:contents-end',
`:level', `:priority', `:tags', `:todo-keyword',`:todo-type',
`:scheduled', `:deadline', `:closed', `:archivedp', `:commentedp'
-and `:footnote-section-p' keywords.
+`: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.
@@ -809,24 +802,48 @@ Assume point is at beginning of the headline."
(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))
+ ;; Find property drawer associated to current headline and
+ ;; extract properties.
+ ;;
+ ;; Upcase property names. It avoids confusion between
+ ;; properties obtained through property drawer and default
+ ;; properties from the parser (e.g. `:end' and :END:)
+ (let ((end (save-excursion
+ (org-with-limited-levels (outline-next-heading))
+ (point)))
+ plist)
+ (save-excursion
+ (while (and (null plist)
+ (re-search-forward org-property-start-re end t))
+ (let ((drawer (org-element-at-point)))
+ (when (and (eq (org-element-type drawer) 'property-drawer)
+ ;; Make sure drawer is not associated
+ ;; to an inlinetask.
+ (let ((p drawer))
+ (while (and (setq p (org-element-property
+ :parent p))
+ (not (eq (org-element-type p)
+ 'inlinetask))))
+ (not p)))
+ (let ((end (org-element-property :contents-end drawer)))
+ (when end
+ (forward-line)
+ (while (< (point) end)
+ (when (looking-at org-property-re)
+ (setq plist
+ (plist-put
+ plist
+ (intern
+ (concat ":" (upcase (match-string 2))))
+ (org-match-string-no-properties 3))))
+ (forward-line)))))))
+ 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))
+ (forward-line)
+ (when (looking-at org-planning-line-re)
(let ((end (line-end-position)) plist)
(while (re-search-forward
org-keyword-time-not-clock-regexp end t)
@@ -841,7 +858,7 @@ Assume point is at beginning of the headline."
(t (setq plist (plist-pu