summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--Makefile2
-rw-r--r--README_maintainer1
-rw-r--r--contrib/README7
-rw-r--r--contrib/lisp/ob-eukleides.el2
-rw-r--r--contrib/lisp/ob-fomus.el2
-rw-r--r--contrib/lisp/ob-julia.el2
-rw-r--r--contrib/lisp/ob-mathomatic.el2
-rw-r--r--contrib/lisp/ob-oz.el4
-rw-r--r--contrib/lisp/ob-stata.el313
-rw-r--r--contrib/lisp/ob-tcl.el2
-rw-r--r--contrib/lisp/org-annotate-file.el116
-rw-r--r--contrib/lisp/org-bibtex-extras.el26
-rw-r--r--contrib/lisp/org-bookmark.el2
-rw-r--r--contrib/lisp/org-checklist.el2
-rw-r--r--contrib/lisp/org-choose.el2
-rw-r--r--contrib/lisp/org-collector.el2
-rw-r--r--contrib/lisp/org-colview-xemacs.el2
-rw-r--r--contrib/lisp/org-contacts.el124
-rw-r--r--contrib/lisp/org-contribdir.el2
-rw-r--r--contrib/lisp/org-depend.el2
-rw-r--r--contrib/lisp/org-download.el336
-rw-r--r--contrib/lisp/org-drill.el601
-rw-r--r--contrib/lisp/org-ebib.el47
-rw-r--r--contrib/lisp/org-effectiveness.el98
-rw-r--r--contrib/lisp/org-elisp-symbol.el2
-rw-r--r--contrib/lisp/org-eval-light.el2
-rw-r--r--contrib/lisp/org-eval.el2
-rw-r--r--contrib/lisp/org-eww.el157
-rw-r--r--contrib/lisp/org-expiry.el7
-rw-r--r--contrib/lisp/org-git-link.el29
-rw-r--r--contrib/lisp/org-index.el4160
-rw-r--r--contrib/lisp/org-interactive-query.el2
-rw-r--r--contrib/lisp/org-invoice.el2
-rw-r--r--contrib/lisp/org-jira.el2
-rw-r--r--contrib/lisp/org-learn.el2
-rw-r--r--contrib/lisp/org-license.el97
-rw-r--r--contrib/lisp/org-mac-iCal.el2
-rw-r--r--contrib/lisp/org-mac-link.el611
-rw-r--r--contrib/lisp/org-mairix.el2
-rw-r--r--contrib/lisp/org-mew.el2
-rw-r--r--contrib/lisp/org-mime.el19
-rw-r--r--contrib/lisp/org-mtags.el255
-rw-r--r--contrib/lisp/org-notify.el2
-rw-r--r--contrib/lisp/org-notmuch.el36
-rw-r--r--contrib/lisp/org-passwords.el384
-rw-r--r--contrib/lisp/org-registry.el2
-rw-r--r--contrib/lisp/org-screen.el2
-rw-r--r--contrib/lisp/org-screenshot.el2
-rw-r--r--contrib/lisp/org-secretary.el2
-rw-r--r--contrib/lisp/org-sudoku.el2
-rw-r--r--contrib/lisp/org-toc.el2
-rw-r--r--contrib/lisp/org-track.el2
-rw-r--r--contrib/lisp/org-velocity.el4
-rw-r--r--contrib/lisp/org-vm.el2
-rw-r--r--contrib/lisp/org-wikinodes.el11
-rw-r--r--contrib/lisp/org-wl.el2
-rw-r--r--contrib/lisp/orgtbl-sqlinsert.el2
-rw-r--r--contrib/lisp/ox-bibtex.el358
-rw-r--r--contrib/lisp/ox-confluence.el2
-rw-r--r--contrib/lisp/ox-deck.el10
-rw-r--r--contrib/lisp/ox-extra.el190
-rw-r--r--contrib/lisp/ox-freemind.el2
-rw-r--r--contrib/lisp/ox-gfm.el193
-rw-r--r--contrib/lisp/ox-groff.el27
-rw-r--r--contrib/lisp/ox-koma-letter.el617
-rw-r--r--contrib/lisp/ox-rss.el55
-rw-r--r--contrib/lisp/ox-s5.el8
-rw-r--r--contrib/lisp/ox-taskjuggler.el54
-rw-r--r--doc/Makefile5
-rw-r--r--doc/doclicense.texi2
-rw-r--r--doc/htmlxref.cnf2
-rw-r--r--doc/org.texi1550
-rw-r--r--doc/orgcard.tex8
-rw-r--r--doc/orgguide.texi101
-rw-r--r--doc/texinfo.tex3161
-rw-r--r--etc/ORG-NEWS203
-rw-r--r--etc/styles/OrgOdtStyles.xml20
-rw-r--r--etc/styles/README2
-rw-r--r--lisp/ob-C.el401
-rw-r--r--lisp/ob-J.el179
-rw-r--r--lisp/ob-R.el152
-rw-r--r--lisp/ob-asymptote.el2
-rw-r--r--lisp/ob-awk.el20
-rw-r--r--lisp/ob-calc.el2
-rw-r--r--lisp/ob-clojure.el84
-rw-r--r--lisp/ob-comint.el4
-rw-r--r--lisp/ob-coq.el77
-rw-r--r--lisp/ob-core.el305
-rw-r--r--lisp/ob-css.el2
-rw-r--r--lisp/ob-ditaa.el20
-rw-r--r--lisp/ob-dot.el6
-rw-r--r--lisp/ob-emacs-lisp.el2
-rw-r--r--lisp/ob-eval.el9
-rw-r--r--lisp/ob-exp.el386
-rw-r--r--lisp/ob-forth.el86
-rw-r--r--lisp/ob-fortran.el8
-rw-r--r--lisp/ob-gnuplot.el35
-rw-r--r--lisp/ob-groovy.el126
-rw-r--r--lisp/ob-haskell.el3
-rw-r--r--lisp/ob-io.el2
-rw-r--r--lisp/ob-java.el24
-rw-r--r--lisp/ob-js.el9
-rw-r--r--lisp/ob-keys.el3
-rw-r--r--lisp/ob-latex.el19
-rw-r--r--lisp/ob-ledger.el2
-rw-r--r--lisp/ob-lilypond.el288
-rw-r--r--lisp/ob-lisp.el12
-rw-r--r--lisp/ob-lob.el33
-rw-r--r--lisp/ob-makefile.el5
-rw-r--r--lisp/ob-matlab.el2
-rw-r--r--lisp/ob-maxima.el14
-rw-r--r--lisp/ob-mscgen.el2
-rw-r--r--lisp/ob-ocaml.el61
-rw-r--r--lisp/ob-octave.el14
-rw-r--r--lisp/ob-org.el2
-rw-r--r--lisp/ob-perl.el2
-rw-r--r--lisp/ob-picolisp.el2
-rw-r--r--lisp/ob-plantuml.el2
-rw-r--r--lisp/ob-python.el18
-rw-r--r--lisp/ob-ref.el187
-rw-r--r--lisp/ob-ruby.el43
-rw-r--r--lisp/ob-sass.el2
-rw-r--r--lisp/ob-scala.el2
-rw-r--r--lisp/ob-scheme.el28
-rw-r--r--lisp/ob-screen.el6
-rw-r--r--lisp/ob-shell.el (renamed from lisp/ob-sh.el)116
-rw-r--r--lisp/ob-shen.el2
-rw-r--r--lisp/ob-sql.el21
-rw-r--r--lisp/ob-sqlite.el2
-rw-r--r--lisp/ob-table.el40
-rw-r--r--lisp/ob-tangle.el65
-rw-r--r--lisp/ob.el2
-rw-r--r--lisp/org-agenda.el988
-rw-r--r--lisp/org-archive.el18
-rw-r--r--lisp/org-attach.el39
-rw-r--r--lisp/org-bbdb.el9
-rw-r--r--lisp/org-bibtex.el56
-rw-r--r--lisp/org-capture.el59
-rw-r--r--lisp/org-clock.el377
-rw-r--r--lisp/org-colview.el29
-rw-r--r--lisp/org-compat.el36
-rw-r--r--lisp/org-crypt.el12
-rw-r--r--lisp/org-ctags.el2
-rw-r--r--lisp/org-datetree.el2
-rw-r--r--lisp/org-docview.el17
-rw-r--r--lisp/org-element.el4151
-rw-r--r--lisp/org-entities.el16
-rw-r--r--lisp/org-eshell.el2
-rw-r--r--lisp/org-faces.el111
-rw-r--r--lisp/org-feed.el9
-rw-r--r--lisp/org-footnote.el74
-rw-r--r--lisp/org-gnus.el16
-rw-r--r--lisp/org-habit.el19
-rw-r--r--lisp/org-id.el2
-rw-r--r--lisp/org-indent.el2
-rw-r--r--lisp/org-info.el2
-rw-r--r--lisp/org-inlinetask.el6
-rw-r--r--lisp/org-irc.el6
-rw-r--r--lisp/org-list.el33
-rw-r--r--lisp/org-macro.el37
-rw-r--r--lisp/org-macs.el23
-rw-r--r--lisp/org-mhe.el2
-rw-r--r--lisp/org-mobile.el5
-rw-r--r--lisp/org-mouse.el17
-rw-r--r--lisp/org-pcomplete.el2
-rw-r--r--lisp/org-plot.el2
-rw-r--r--lisp/org-protocol.el2
-rw-r--r--lisp/org-rmail.el12
-rw-r--r--lisp/org-src.el97
-rw-r--r--lisp/org-table.el1405
-rw-r--r--lisp/org-timer.el45
-rw-r--r--lisp/org-w3m.el2
-rwxr-xr-x[-rw-r--r--]lisp/org.el6644
-rw-r--r--lisp/ox-ascii.el773
-rw-r--r--lisp/ox-beamer.el74
-rw-r--r--lisp/ox-html.el1026
-rw-r--r--lisp/ox-icalendar.el342
-rw-r--r--lisp/ox-latex.el1328
-rw-r--r--lisp/ox-man.el96
-rw-r--r--lisp/ox-md.el238
-rw-r--r--lisp/ox-odt.el437
-rw-r--r--lisp/ox-org.el93
-rw-r--r--lisp/ox-publish.el101
-rw-r--r--lisp/ox-texinfo.el1494
-rw-r--r--lisp/ox.el1233
-rw-r--r--mk/default.mk48
-rw-r--r--mk/eldo.el2
-rw-r--r--mk/org-fixup.el16
-rw-r--r--mk/server.mk2
-rw-r--r--mk/targets.mk24
-rw-r--r--request-assign-future.txt2
-rw-r--r--testing/README22
-rw-r--r--testing/examples/babel.org56
-rw-r--r--testing/examples/include.html1
-rw-r--r--testing/examples/include.org25
-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/examples/open-at-point.org8
-rw-r--r--testing/examples/setupfile.org1
-rw-r--r--testing/lisp/test-ob-C.el161
-rw-r--r--testing/lisp/test-ob-R.el2
-rw-r--r--testing/lisp/test-ob-awk.el11
-rw-r--r--testing/lisp/test-ob-emacs-lisp.el2
-rw-r--r--testing/lisp/test-ob-exp.el232
-rw-r--r--testing/lisp/test-ob-fortran.el2
-rw-r--r--testing/lisp/test-ob-header-arg-defaults.el2
-rw-r--r--testing/lisp/test-ob-lilypond.el367
-rw-r--r--testing/lisp/test-ob-lob.el52
-rw-r--r--testing/lisp/test-ob-maxima.el2
-rw-r--r--testing/lisp/test-ob-octave.el2
-rw-r--r--testing/lisp/test-ob-perl.el2
-rw-r--r--testing/lisp/test-ob-python.el2
-rw-r--r--testing/lisp/test-ob-ruby.el35
-rw-r--r--testing/lisp/test-ob-sh.el52
-rw-r--r--testing/lisp/test-ob-shell.el92
-rw-r--r--testing/lisp/test-ob-table.el2
-rw-r--r--testing/lisp/test-ob-tangle.el2
-rw-r--r--testing/lisp/test-ob.el131
-rw-r--r--testing/lisp/test-org-clock.el2
-rw-r--r--testing/lisp/test-org-element.el1007
-rw-r--r--testing/lisp/test-org-footnote.el2
-rw-r--r--testing/lisp/test-org-list.el6
-rw-r--r--testing/lisp/test-org-macro.el2
-rw-r--r--testing/lisp/test-org-open-at-point.el61
-rw-r--r--testing/lisp/test-org-src.el2
-rw-r--r--testing/lisp/test-org-table.el619
-rw-r--r--testing/lisp/test-org.el1360
-rw-r--r--testing/lisp/test-ox.el567
-rw-r--r--testing/lisp/test-property-inheritance.el2
-rw-r--r--testing/org-batch-test-init.el20
-rw-r--r--testing/org-test.el40
233 files changed, 27262 insertions, 16617 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 f95bcb2..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)
@@ -30,6 +29,7 @@ help helpall::
$(info make single - build Org ELisp files, single Emacs per source)
$(info make autoloads - create org-loaddefs.el to load Org in-place)
$(info make test - build Org ELisp files and run test suite)
+ $(info make vanilla - run Emacs with this Org-mode and no personal config)
helpall::
$(info make test-dirty - check without building first)
$(info make compile-dirty - build only stale Org ELisp files)
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 15df87c..7bffeee 100644
--- a/contrib/README
+++ b/contrib/README
@@ -24,10 +24,12 @@ org-contacts.el --- Contacts management
org-contribdir.el --- Dummy file to mark the org contrib Lisp directory
org-depend.el --- TODO dependencies for Org-mode
org-drill.el --- Self-testing with org-learn
+org-effectiveness.el --- Measuring your personal effectiveness
org-element.el --- Parser and applications for Org syntax
org-elisp-symbol.el --- Org links to emacs-lisp symbols
org-eval-light.el --- Evaluate in-buffer code on demand
org-eval.el --- The <lisp> tag, adapted from Muse
+org-eww.el --- Store link to url of eww
org-expiry.el --- Expiry mechanism for Org entries
org-export-generic.el --- Export framework for configurable backends
org-git-link.el --- Provide org links to specific file version
@@ -36,9 +38,9 @@ org-interactive-query.el --- Interactive modification of tags query
org-invoice.el --- Help manage client invoices in OrgMode
org-jira.el --- Add a jira:ticket protocol to Org
org-learn.el --- SuperMemo's incremental learning algorithm
+org-license.el --- Insert free licenses to your org documents
org-mac-iCal.el --- Imports events from iCal.app to the Emacs diary
-org-mac-link-grabber.el --- Grab links and URLs from various Mac applications
-org-mac-message.el --- Links to Apple Mail.app messages from within Org-mode
+org-mac-link.el --- Grab links and URLs from various Mac applications
org-mairix.el --- Hook mairix search into Org for different MUAs
org-man.el --- Support for links to manpages in Org-mode
org-mew.el --- Support for links to Mew messages
@@ -79,6 +81,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-eukleides.el b/contrib/lisp/ob-eukleides.el
index e25ed1c..c8ce881 100644
--- a/contrib/lisp/ob-eukleides.el
+++ b/contrib/lisp/ob-eukleides.el
@@ -1,6 +1,6 @@
;;; ob-eukleides.el --- Org-babel functions for eukleides evaluation
-;; Copyright (C) 2010-2013 Free Software Foundation, Inc.
+;; Copyright (C) 2010-2014 Free Software Foundation, Inc.
;; Author: Luis Anaya
;; Keywords: literate programming, reproducible research
diff --git a/contrib/lisp/ob-fomus.el b/contrib/lisp/ob-fomus.el
index 58183fb..1db32e4 100644
--- a/contrib/lisp/ob-fomus.el
+++ b/contrib/lisp/ob-fomus.el
@@ -1,6 +1,6 @@
;;; ob-fomus.el --- Org-babel functions for fomus evaluation
-;; Copyright (C) 2011-2013 Torsten Anders
+;; Copyright (C) 2011-2014 Torsten Anders
;; Author: Torsten Anders
;; Keywords: literate programming, reproducible research
diff --git a/contrib/lisp/ob-julia.el b/contrib/lisp/ob-julia.el
index 3aed818..4d8deb2 100644
--- a/contrib/lisp/ob-julia.el
+++ b/contrib/lisp/ob-julia.el
@@ -1,6 +1,6 @@
;;; ob-julia.el --- org-babel functions for julia code evaluation
-;; Copyright (C) 2013 G. Jay Kerns
+;; Copyright (C) 2013, 2014 G. Jay Kerns
;; Author: G. Jay Kerns, based on ob-R.el by Eric Schulte and Dan Davison
;; This file is not part of GNU Emacs.
diff --git a/contrib/lisp/ob-mathomatic.el b/contrib/lisp/ob-mathomatic.el
index 585604e..bfd8ecf 100644
--- a/contrib/lisp/ob-mathomatic.el
+++ b/contrib/lisp/ob-mathomatic.el
@@ -1,6 +1,6 @@
;;; ob-mathomatic.el --- Org-babel functions for mathomatic evaluation
-;; Copyright (C) 2009-2013 Free Software Foundation, Inc.
+;; Copyright (C) 2009-2014 Free Software Foundation, Inc.
;; Author: Eric S Fraga
;; Eric Schulte
diff --git a/contrib/lisp/ob-oz.el b/contrib/lisp/ob-oz.el
index ce8e8a6..3531d95 100644
--- a/contrib/lisp/ob-oz.el
+++ b/contrib/lisp/ob-oz.el
@@ -1,6 +1,6 @@
;;; ob-oz.el --- Org-babel functions for Oz evaluation
-;; Copyright (C) 2009-2013 Torsten Anders and Eric Schulte
+;; Copyright (C) 2009-2014 Torsten Anders and Eric Schulte
;; Author: Torsten Anders and Eric Schulte
;; Keywords: literate programming, reproducible research
@@ -90,7 +90,7 @@
(require 'ob)
;;; major mode for editing Oz programs
-(require 'mozart)
+(require 'mozart nil t)
;;
;; Interface to communicate with Oz.
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/ob-tcl.el b/contrib/lisp/ob-tcl.el
index e8d735b..50afe5a 100644
--- a/contrib/lisp/ob-tcl.el
+++ b/contrib/lisp/ob-tcl.el
@@ -1,6 +1,6 @@
;;; ob-tcl.el --- Org-babel functions for tcl evaluation
-;; Copyright (C) 2009-2013 Free Software Foundation, Inc.
+;; Copyright (C) 2009-2014 Free Software Foundation, Inc.
;; Authors: Dan Davison
;; Eric Schulte
diff --git a/contrib/lisp/org-annotate-file.el b/contrib/lisp/org-annotate-file.el
index bdb9acb..b8e8bd9 100644
--- a/contrib/lisp/org-annotate-file.el
+++ b/contrib/lisp/org-annotate-file.el
@@ -1,6 +1,6 @@
;;; org-annotate-file.el --- Annotate a file with org syntax
-;; Copyright (C) 2008-2013 Philip Jackson
+;; Copyright (C) 2008-2014 Philip Jackson
;; Author: Philip Jackson <phil@shellarchive.co.uk>
;; Version: 0.2
@@ -25,7 +25,7 @@
;;; Commentary:
;; This is yet another implementation to allow the annotation of a
-;; file without modification of the file itself. The annotation is in
+;; file without modification of the file itself. The annotation is in
;; org syntax so you can use all of the org features you are used to.
;; To use you might put the following in your .emacs:
@@ -47,30 +47,41 @@
;; and next time you hit C-c C-l you will hit those notes again.
;;
;; To put a subheading with a text search for the current line set
-;; `org-annotate-file-add-search` to non-nil value. Then when you hit
+;; `org-annotate-file-add-search` to non-nil value. Then when you hit
;; C-c C-l (on the above line for example) you will get:
;; * ~/org-annotate-file.el
-;; ** `org-annotate-file-add-search` to non-nil value. Then whe...
+;; ** `org-annotate-file-add-search` to non-nil value. Then whe...
;; Note that both of the above will be links.
-(require 'org)
-
-(defvar org-annotate-file-storage-file "~/.org-annotate-file.org"
- "File in which to keep annotations.")
+;;; Code:
-(defvar org-annotate-file-add-search nil
- "If non-nil then add a link as a second level to the actual
-location in the file")
-
-(defvar org-annotate-file-always-open t
- "non-nil means always expand the full tree when you visit
-`org-annotate-file-storage-file'.")
+(require 'org)
-(defun org-annotate-file-elipsify-desc (string &optional after)
- "Strip starting and ending whitespace and replace any chars
-that appear after the value in `after' with '...'"
+(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.
+Trim whitespace at beginning and end of STRING and replace any
+ characters that appear after the occurrence of AFTER with '...'"
(let* ((after (number-to-string (or after 30)))
(replace-map (list (cons "^[ \t]*" "")
(cons "[ \t]*$" "")
@@ -82,46 +93,61 @@ that appear after the value in `after' with '...'"
replace-map)
string))
+;;;###autoload
(defun org-annotate-file ()
- "Put a section for the current file into your annotation file"
+ "Visit `org-annotate-file-storage-file` and add a new annotation section.
+The annotation is opened at the new section which will be referencing
+the point in the current file."
(interactive)
(unless (buffer-file-name)
- (error "This buffer has no associated file"))
- (org-annotate-file-show-section))
-
-(defun org-annotate-file-show-section (&optional buffer)
- "Visit the buffer named `org-annotate-file-storage-file' and
-show the relevant section"
- (let* ((filename (abbreviate-file-name (or buffer (buffer-file-name))))
- (line (buffer-substring-no-properties (point-at-bol) (point-at-eol)))
- (link (org-make-link-string (concat "file:" filename) filename))
+ (error "This buffer has no associated file!"))
+ (switch-to-buffer
+ (org-annotate-file-show-section org-annotate-file-storage-file)))
+
+;;;###autoload
+(defun org-annotate-file-show-section (storage-file &optional annotated-buffer)
+ "Add or show annotation entry in STORAGE-FILE and return the buffer.
+The annotation will link to ANNOTATED-BUFFER if specified,
+ otherwise the current buffer is used."
+ (let ((filename (abbreviate-file-name (or annotated-buffer
+ (buffer-file-name))))
+ (line (buffer-substring-no-properties (point-at-bol) (point-at-eol)))
+ (annotation-buffer (find-file-noselect storage-file)))
+ (with-current-buffer annotation-buffer
+ (org-annotate-file-annotate filename line))
+ annotation-buffer))
+
+(defun org-annotate-file-annotate (filename line)
+ "Add annotation for FILENAME at LINE using current buffer."
+ (let* ((link (org-make-link-string (concat "file:" filename) filename))
(search-link (org-make-link-string
(concat "file:" filename "::" line)
- (org-annotate-file-elipsify-desc line))))
- (with-current-buffer (find-file org-annotate-file-storage-file)
- (unless (eq major-mode 'org-mode)
- (org-mode))
- (goto-char (point-min))
- (widen)
- (when org-annotate-file-always-open
- (show-all))
+ (org-annotate-file-ellipsify-desc line))))
+ (unless (eq major-mode 'org-mode)
+ (org-mode))
+ (goto-char (point-min))
+ (widen)
+ (when org-annotate-file-always-open
+ (show-all))
+ (unless (search-forward-regexp
+ (concat "^* " (regexp-quote link)) nil t)
+ (org-annotate-file-add-upper-level link))
+ (beginning-of-line)
+ (org-narrow-to-subtree)
+ ;; deal with a '::' search if need be
+ (when org-annotate-file-add-search
(unless (search-forward-regexp
- (concat "^* " (regexp-quote link)) nil t)
- (org-annotate-file-add-upper-level link))
- (beginning-of-line)
- (org-narrow-to-subtree)
- ;; deal with a '::' search if need be
- (when org-annotate-file-add-search
- (unless (search-forward-regexp
- (concat "^** " (regexp-quote search-link)) nil t)
- (org-annotate-file-add-second-level search-link))))))
+ (concat "^** " (regexp-quote search-link)) nil t)
+ (org-annotate-file-add-second-level search-link)))))
(defun org-annotate-file-add-upper-level (link)
+ "Add and link heading to LINK."
(goto-char (point-min))
(call-interactively 'org-insert-heading)
(insert link))
(defun org-annotate-file-add-second-level (link)
+ "Add and link subheading to LINK."
(goto-char (point-at-eol))
(call-interactively 'org-insert-subheading)
(insert link))
diff --git a/contrib/lisp/org-bibtex-extras.el b/contrib/lisp/org-bibtex-extras.el
index 93c97a9..5f05039 100644
--- a/contrib/lisp/org-bibtex-extras.el
+++ b/contrib/lisp/org-bibtex-extras.el
@@ -1,6 +1,6 @@
;;; org-bibtex-extras --- extras for working with org-bibtex entries
-;; Copyright (C) 2008-2013 Free Software Foundation, Inc.
+;; Copyright (C) 2008-2014 Free Software Foundation, Inc.
;; Author: Eric Schulte <eric dot schulte at gmx dot com>
;; Keywords: outlines, hypermedia, bibtex, d3
@@ -75,25 +75,14 @@ For example, to point to your `obe-bibtex-file' use the following.
"Return all citations from `obe-bibtex-file'."
(or obe-citations
(save-window-excursion
- (find-file obe-bibtex-file)
+ (find-file (or obe-bibtex-file
+ (error "`obe-bibtex-file' has not been configured")))
(goto-char (point-min))
(while (re-search-forward " :CUSTOM_ID: \\(.+\\)$" nil t)
(push (org-no-properties (match-string 1))
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 obe-bibtex-file)
- (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
@@ -105,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-bookmark.el b/contrib/lisp/org-bookmark.el
index 44588b6..9a69bbb 100644
--- a/contrib/lisp/org-bookmark.el
+++ b/contrib/lisp/org-bookmark.el
@@ -1,5 +1,5 @@
;;; org-bookmark.el - Support for links to bookmark
-;; Copyright (C) 2008-2013 Free Software Foundation, Inc.
+;; Copyright (C) 2008-2014 Free Software Foundation, Inc.
;;
;; Author: Tokuya Kameshima <kames AT fa2.so-net.ne.jp>
;; Version: 1.0
diff --git a/contrib/lisp/org-checklist.el b/contrib/lisp/org-checklist.el
index faa5998..2bc00c0 100644
--- a/contrib/lisp/org-checklist.el
+++ b/contrib/lisp/org-checklist.el
@@ -1,6 +1,6 @@
;;; org-checklist.el --- org functions for checklist handling
-;; Copyright (C) 2008-2013 James TD Smith
+;; Copyright (C) 2008-2014 James TD Smith
;; Author: James TD Smith (@ ahktenzero (. mohorovi cc))
;; Version: 1.0
diff --git a/contrib/lisp/org-choose.el b/contrib/lisp/org-choose.el
index 8e5935d..c1006d0 100644
--- a/contrib/lisp/org-choose.el
+++ b/contrib/lisp/org-choose.el
@@ -1,6 +1,6 @@
;;; org-choose.el --- decision management for org-mode
-;; Copyright (C) 2009-2013 Tom Breton (Tehom)
+;; Copyright (C) 2009-2014 Tom Breton (Tehom)
;; This file is not part of GNU Emacs.
diff --git a/contrib/lisp/org-collector.el b/contrib/lisp/org-collector.el
index d62a462..5894707 100644
--- a/contrib/lisp/org-collector.el
+++ b/contrib/lisp/org-collector.el
@@ -1,6 +1,6 @@
;;; org-collector --- collect properties into tables
-;; Copyright (C) 2008-2013 Free Software Foundation, Inc.
+;; Copyright (C) 2008-2014 Free Software Foundation, Inc.
;; Author: Eric Schulte <schulte dot eric at gmail dot com>
;; Keywords: outlines, hypermedia, calendar, wp, experimentation,
diff --git a/contrib/lisp/org-colview-xemacs.el b/contrib/lisp/org-colview-xemacs.el
index f9b35d3..67a2aad 100644
--- a/contrib/lisp/org-colview-xemacs.el
+++ b/contrib/lisp/org-colview-xemacs.el
@@ -1,6 +1,6 @@
;;; org-colview-xemacs.el --- Column View in Org-mode, XEmacs-specific version
-;; Copyright (C) 2004-2013
+;; Copyright (C) 2004-2014
;; Carsten Dominik
;; Author: Carsten Dominik <carsten at orgmode dot org>
diff --git a/contrib/lisp/org-contacts.el b/contrib/lisp/org-contacts.el
index dbbc057..88aef9d 100644
--- a/contrib/lisp/org-contacts.el
+++ b/contrib/lisp/org-contacts.el
@@ -1,6 +1,6 @@
;;; org-contacts.el --- Contacts management
-;; Copyright (C) 2010-2013 Julien Danjou <julien@danjou.info>
+;; Copyright (C) 2010-2014 Julien Danjou <julien@danjou.info>
;; Author: Julien Danjou <julien@danjou.info>
;; Keywords: outlines, hypermedia, calendar
@@ -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-contribdir.el b/contrib/lisp/org-contribdir.el
index 8132750..d94e7a0 100644
--- a/contrib/lisp/org-contribdir.el
+++ b/contrib/lisp/org-contribdir.el
@@ -1,5 +1,5 @@
;;; org-contribdir.el --- Mark the location of the contrib directory
-;; Copyright (C) 2009-2013 Free Software Foundation, Inc.
+;; Copyright (C) 2009-2014 Free Software Foundation, Inc.
;;
;; Author: Carsten Dominik <carsten at orgmode dot org>
;; Keywords: outlines, hypermedia, calendar, wp
diff --git a/contrib/lisp/org-depend.el b/contrib/lisp/org-depend.el
index dc99a1d..1cd4130 100644
--- a/contrib/lisp/org-depend.el
+++ b/contrib/lisp/org-depend.el
@@ -1,5 +1,5 @@
;;; org-depend.el --- TODO dependencies for Org-mode
-;; Copyright (C) 2008-2013 Free Software Foundation, Inc.
+;; Copyright (C) 2008-2014 Free Software Foundation, Inc.
;;
;; Author: Carsten Dominik <carsten at orgmode dot org>
;; Keywords: outlines, hypermedia, calendar, wp
diff --git a/contrib/lisp/org-download.el b/contrib/lisp/org-download.el
new file mode 100644
index 0000000..39312cf
--- a/dev/null
+++ b/contrib/lisp/org-download.el
@@ -0,0 +1,336 @@
+;;; org-download.el --- Image drag-and-drop for Emacs org-mode
+
+;; Copyright (C) 2014 Free Software Foundation, Inc.
+
+;; Author: Oleh Krehel
+;; Keywords: images, screenshots, download
+;; 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:
+;;
+;; This extension facilitates moving images from point A to point B.
+;;
+;; Point A (the source) can be:
+;; 1. An image inside your browser that you can drag to Emacs.
+;; 2. An image on your file system that you can drag to Emacs.
+;; 3. A local or remote image address in kill-ring.
+;; Use the `org-download-yank' command for this.
+;; Remember that you can use "0 w" in `dired' to get an address.
+;; 4. An screenshot taken using `gnome-screenshot' or `scrot' or `gm'.
+;; Use the `org-download-screenshot' command for this.
+;; Customize the backend with `org-download-screenshot-method'.
+;;
+;; Point B (the target) is an Emacs `org-mode' buffer where the inline
+;; link will be inserted. Several customization options will determine
+;; where exactly on the file system the file will be stored.
+;;
+;; They are:
+;; `org-download-method':
+;; a. 'attach => use `org-mode' attachment machinery
+;; b. 'directory => construct the directory in two stages:
+;; 1. first part of the folder name is:
+;; * either "." (current folder)
+;; * or `org-download-image-dir' (if it's not nil).
+;; `org-download-image-dir' becomes buffer-local when set,
+;; so each file can customize this value, e.g with:
+;; # -*- mode: Org; org-download-image-dir: ~/Pictures/foo; -*-
+;; 2. second part is:
+;; * `org-download-heading-lvl' is nil => ""
+;; * `org-download-heading-lvl' is n => the name of current
+;; heading with level n. Level count starts with 0,
+;; i.e. * is 0, ** is 1, *** is 2 etc.
+;; `org-download-heading-lvl' becomes buffer-local when set,
+;; so each file can customize this value, e.g with:
+;; # -*- mode: Org; org-download-heading-lvl: nil; -*-
+;;
+;; `org-download-timestamp':
+;; optionally add a timestamp to the file name.
+;;
+;; Customize `org-download-backend' to choose between `url-retrieve'
+;; (the default) or `wget' or `curl'.
+;;
+;;; Code:
+
+
+(eval-when-compile
+ (require 'cl))
+(require 'url-parse)
+(require 'url-http)
+
+(defgroup org-download nil
+ "Image drag-and-drop for org-mode."
+ :group 'org
+ :prefix "org-download-")
+
+(defcustom org-download-method 'directory
+ "The way images should be stored."
+ :type '(choice
+ (const :tag "Directory" directory)
+ (const :tag "Attachment" attach))
+ :group 'org-download)
+
+(defcustom org-download-image-dir nil
+ "If set, images will be stored in this directory instead of \".\".
+See `org-download--dir-1' for more info."
+ :type '(choice
+ (const :tag "Default" nil)
+ (string :tag "Directory"))
+ :group 'org-download)
+(make-variable-buffer-local 'org-download-image-dir)
+
+(defcustom org-download-heading-lvl 0
+ "Heading level to be used in `org-download--dir-2'."
+ :group 'org-download)
+(make-variable-buffer-local 'org-download-heading-lvl)
+
+(defcustom org-download-backend t
+ "Method to use for downloading."
+ :type '(choice
+ (const :tag "wget" "wget \"%s\" -O \"%s\"")
+ (const :tag "curl" "curl \"%s\" -o \"%s\"")
+ (const :tag "url-retrieve" t))
+ :group 'org-download)
+
+(defcustom org-download-timestamp "_%Y-%m-%d_%H:%M:%S"
+ "This `format-time-string'-style string will be appended to the file name.
+Set this to \"\" if you don't want time stamps."
+ :type 'string
+ :group 'org-download)
+
+(defcustom org-download-screenshot-method "gnome-screenshot -a -f %s"
+ "The tool to capture screenshots."
+ :type '(choice
+ (const :tag "gnome-screenshot" "gnome-screenshot -a -f %s")
+ (const :tag "scrot" "scrot -s %s")
+ (const :tag "gm" "gm import %s"))
+ :group 'org-download)
+
+(defcustom org-download-image-width 0
+ "When non-zero add #+attr_html: :width tag to the image."
+ :type 'integer
+ :group 'org-download)
+
+(defun org-download-get-heading (lvl)
+ "Return the heading of the current entry's LVL level parent."
+ (save-excursion
+ (let ((cur-lvl (org-current-level)))
+ (unless (= cur-lvl 1)
+ (org-up-heading-all (- (1- (org-current-level)) lvl)))
+ (substring-no-properties
+ (org-get-heading)))))
+
+(defun org-download--dir-1 ()
+ "Return the first part of the directory path for `org-download--dir'.
+It's `org-download-image-dir', unless it's nil. Then it's \".\"."
+ (or org-download-image-dir "."))
+
+(defun org-download--dir-2 ()
+ "Return the second part of the directory path for `org-download--dir'.
+Unless `org-download-heading-lvl' is nil, it's the name of the current
+`org-download-heading-lvl'-leveled heading. Otherwise it's \"\"."
+ (and org-download-heading-lvl
+ (org-download-get-heading
+ org-download-heading-lvl)))
+
+(defun org-download--dir ()
+ "Return the directory path for image storage.
+
+The path is composed from `org-download--dir-1' and `org-download--dir-2'.
+The directory is created if it didn't exist before."
+ (let* ((part1 (org-download--dir-1))
+ (part2 (org-download--dir-2))
+ (dir (if part2
+ (format "%s/%s" part1 part2)
+ part1)))
+ (unless (file-exists-p dir)
+ (make-directory dir t))
+ dir))
+
+(defun org-download--fullname (link)
+ "Return the file name where LINK will be saved to.
+
+It's affected by `org-download-timestamp' and `org-download--dir'."
+ (let ((filename
+ (file-name-nondirectory
+ (car (url-path-and-query
+ (url-generic-parse-url link)))))
+ (dir (org-download--dir)))
+ (format "%s/%s%s.%s"
+ dir
+ (file-name-sans-extension filename)
+ (format-time-string org-download-timestamp)
+ (file-name-extension filename))))
+
+(defun org-download--image (link filename)
+ "Save LINK to FILENAME asynchronously and show inline images in current buffer."
+ (when (string-match "^file://\\(.*\\)" link)
+ (setq link (url-unhex-string (match-string 1 link))))
+ (cond ((file-exists-p link)
+ (org-download--image/command "cp \"%s\" \"%s\"" link filename))
+ ((eq org-download-backend t)
+ (org-download--image/url-retrieve link filename))
+ (t
+ (org-download--image/command org-download-backend link filename))))
+
+(defun org-download--image/command (command link filename)
+ "Using COMMAND, save LINK to FILENAME.
+COMMAND is a format-style string with two slots for LINK and FILENAME."
+ (require 'async)
+ (async-start
+ `(lambda() (shell-command
+ ,(format command link
+ (expand-file-name filename))))
+ (lexical-let ((cur-buf (current-buffer)))
+ (lambda(x)
+ (with-current-buffer cur-buf
+ (org-display-inline-images))))))
+
+(defun org-download--image/url-retrieve (link filename)
+ "Save LINK to FILENAME using `url-retrieve'."
+ (url-retrieve
+ link
+ (lambda (status filename buffer)
+ ;; Write current buffer to FILENAME
+ ;; and update inline images in BUFFER
+ (let ((err (plist-get status :error)))
+ (if err (error
+ "\"%s\" %s" link
+ (downcase (nth 2 (assq (nth 2 err) url-http-codes))))))
+ (delete-region
+ (point-min)
+ (progn
+ (re-search-forward "\n\n" nil 'move)
+ (point)))
+ (let ((coding-system-for-write 'no-conversion))
+ (write-region nil nil filename nil nil nil 'confirm))
+ (with-current-buffer buffer
+ (org-display-inline-images)))
+ (list
+ (expand-file-name filename)
+ (current-buffer))
+ nil t))
+
+(defun org-download-yank ()
+ "Call `org-download-image' with current kill."
+ (interactive)
+ (org-download-image (current-kill 0)))
+
+(defun org-download-screenshot ()
+ "Capture screenshot and insert the resulting file.
+The screenshot tool is determined by `org-download-screenshot-method'."
+ (interactive)
+ (let ((link "/tmp/screenshot.png"))
+ (shell-command (format org-download-screenshot-method link))
+ (org-download-image link)))
+
+(defun org-download-image (link)
+ "Save image at address LINK to `org-download--dir'."
+ (interactive "sUrl: ")
+ (let ((filename
+ (if (eq org-download-method 'attach)
+ (let ((org-download-image-dir (progn (require 'org-attach)
+ (org-attach-dir t)))
+ org-download-heading-lvl)
+ (org-download--fullname link))
+ (org-download--fullname link))))
+ (when (image-type-from-file-name filename)
+ (org-download--image link filename)
+ (when (eq org-download-method 'attach)
+ (org-attach-attach filename nil 'none))
+ (if (looking-back "^[ \t]+")
+ (delete-region (match-beginning 0) (match-end 0))
+ (newline))
+ (insert (format "#+DOWNLOADED: %s @ %s\n%s [[%s]]"
+ link
+ (format-time-string "%Y-%m-%d %H:%M:%S")
+ (if (= org-download-image-width 0)
+ ""
+ (format "#+attr_html: :width %dpx\n" org-download-image-width))
+ filename))
+ (org-display-inline-images))))
+
+(defun org-download--at-comment-p ()
+ "Check if current line begins with #+DOWLOADED:."
+ (save-excursion
+ (move-beginning-of-line nil)
+ (looking-at "#\\+DOWNLOADED:")))
+
+(defun org-download-delete ()
+ "Delete inline image link on current line, and the file that it points to."
+ (interactive)
+ (cond ((org-download--at-comment-p)
+ (delete-region (line-beginning-position)
+ (line-end-position))
+ (org-download--delete (line-beginning-position)
+ nil
+ 1))
+ ((region-active-p)
+ (org-download--delete (region-beginning)
+ (region-end))
+ (delete-region (region-beginning)
+ (region-end)))
+
+ (t (org-download--delete (line-beginning-position)
+ (line-end-position)))))
+
+(defun org-download--delete (beg end &optional times)
+ "Delete inline image links and the files they point to between BEG and END.
+
+When TIMES isn't nil, delete only TIMES links."
+ (unless times
+ (setq times most-positive-fixnum))
+ (save-excursion
+ (goto-char beg)
+ (while (and (>= (decf times) 0)
+ (re-search-forward "\\[\\[\\([^]]*\\)\\]\\]" end t))
+ (let ((str (match-string-no-properties 1)))
+ (delete-region (match-beginning 0)
+ (match-end 0))
+ (when (file-exists-p str)
+ (delete-file str))))))
+
+(defun org-download-dnd (uri action)
+ "When in `org-mode' and URI points to image, download it.
+Otherwise, pass URI and ACTION back to dnd dispatch."
+ (if (eq major-mode 'org-mode)
+ ;; probably shouldn't redirect
+ (unless (org-download-image uri)
+ (message "not an image URL"))
+ ;; redirect to someone else
+ (let ((dnd-protocol-alist
+ (rassq-delete-all
+ 'org-download-dnd
+ (copy-alist dnd-protocol-alist))))
+ (dnd-handle-one-url nil action uri))))
+
+(defun org-download-enable ()
+ "Enable org-download."
+ (unless (eq (cdr (assoc "^\\(https?\\|ftp\\|file\\|nfs\\)://" dnd-protocol-alist))
+ 'org-download-dnd)
+ (setq dnd-protocol-alist
+ `(("^\\(https?\\|ftp\\|file\\|nfs\\)://" . org-download-dnd) ,@dnd-protocol-alist))))
+
+(defun org-download-disable ()
+ "Disable org-download."
+ (rassq-delete-all 'org-download-dnd dnd-protocol-alist))
+
+(org-download-enable)
+
+(provide 'org-download)
+
+;;; org-download.el ends here
diff --git a/contrib/lisp/org-drill.el b/contrib/lisp/org-drill.el
index 5bf6dd4..e5b0d49 100644
--- a/contrib/lisp/org-drill.el
+++ b/contrib/lisp/org-drill.el
@@ -1,73 +1,72 @@
-;; -*- coding: utf-8-unix -*-
+;;; -*- coding: utf-8-unix -*-
;;; org-drill.el - Self-testing using spaced repetition
;;;
-;; Author: Paul Sexton <eeeickythump@gmail.com>
-;; Version: 2.3.7
-;; Repository at http://bitbucket.org/eeeickythump/org-drill/
-;;
-;; This file is not part of GNU Emacs.
-;;
-;; This program is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 3, 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 and synopsis:
+;;; Author: Paul Sexton <eeeickythump@gmail.com>
+;;; Version: 2.4.1
+;;; Repository at http://bitbucket.org/eeeickythump/org-drill/
;;;
-;; Uses the SuperMemo spaced repetition algorithms to conduct interactive
-;; "drill sessions", where the material to be remembered is presented to the
-;; student in random order. The student rates his or her recall of each item,
-;; and this information is used to schedule the item for later revision.
-;;
-;; Each drill session can be restricted to topics in the current buffer
-;; (default), one or several files, all agenda files, or a subtree. A single
-;; topic can also be drilled.
-;;
-;; Different "card types" can be defined, which present their information to
-;; the student in different ways.
-;;
-;; See the file README.org for more detailed documentation.
-;;
-;;; Code:
+;;;
+;;; Synopsis
+;;; ========
+;;;
+;;; Uses the SuperMemo spaced repetition algorithms to conduct interactive
+;;; "drill sessions", where the material to be remembered is presented to the
+;;; student in random order. The student rates his or her recall of each item,
+;;; and this information is used to schedule the item for later revision.
+;;;
+;;; Each drill session can be restricted to topics in the current buffer
+;;; (default), one or several files, all agenda files, or a subtree. A single
+;;; topic can also be drilled.
+;;;
+;;; Different "card types" can be defined, which present their information to
+;;; the student in different ways.
+;;;
+;;; See the file README.org for more detailed documentation.
+
(eval-when-compile (require 'cl))
(eval-when-compile (require 'hi-lock))
+(require 'cl-lib)
+(require 'hi-lock)
(require 'org)
(require 'org-id)
(require 'org-learn)
+
(defgroup org-drill nil
"Options concerning interactive drill sessions in Org mode (org-drill)."
:tag "Org-Drill"
:group 'org-link)
-(defcustom org-drill-question-tag "drill"
+
+
+(defcustom org-drill-question-tag
+ "drill"
"Tag which topics must possess in order to be identified as review topics
by `org-drill'."
:group 'org-drill
:type 'string)
-(defcustom org-drill-maximum-items-per-session 30
+
+(defcustom org-drill-maximum-items-per-session
+ 30
"Each drill session will present at most this many topics for review.
Nil means unlimited."
:group 'org-drill
:type '(choice integer (const nil)))
-(defcustom org-drill-maximum-duration 20
+
+
+(defcustom org-drill-maximum-duration
+ 20
"Maximum duration of a drill session, in minutes.
Nil means unlimited."
:group 'org-drill
:type '(choice integer (const nil)))
-(defcustom org-drill-failure-quality 2
+
+(defcustom org-drill-failure-quality
+ 2
"If the quality of recall for an item is this number or lower,
it is regarded as an unambiguous failure, and the repetition
interval for the card is reset to 0 days. If the quality is higher
@@ -81,7 +80,9 @@ really sensible."
:group 'org-drill
:type '(choice (const 2) (const 1)))
-(defcustom org-drill-forgetting-index 10
+
+(defcustom org-drill-forgetting-index
+ 10
"What percentage of items do you consider it is 'acceptable' to
forget each drill session? The default is 10%. A warning message
is displayed at the end of the session if the percentage forgotten
@@ -89,13 +90,17 @@ climbs above this number."
:group 'org-drill
:type 'integer)
-(defcustom org-drill-leech-failure-threshold 15
+
+(defcustom org-drill-leech-failure-threshold
+ 15
"If an item is forgotten more than this many times, it is tagged
as a 'leech' item."
:group 'org-drill
:type '(choice integer (const nil)))
-(defcustom org-drill-leech-method 'skip
+
+(defcustom org-drill-leech-method
+ 'skip
"How should 'leech items' be handled during drill sessions?
Possible values:
- nil :: Leech items are treated the same as normal items.
@@ -104,62 +109,89 @@ Possible values:
but a warning message is printed when each leech item is
presented."
:group 'org-drill
- :type '(choice (const 'warn) (const 'skip) (const nil)))
+ :type '(choice (const warn) (const skip) (const nil)))
+
(defface org-drill-visible-cloze-face
'((t (:foreground "darkseagreen")))
"The face used to hide the contents of cloze phrases."
:group 'org-drill)
+
(defface org-drill-visible-cloze-hint-face
'((t (:foreground "dark slate blue")))
"The face used to hide the contents of cloze phrases."
:group 'org-drill)
+
(defface org-drill-hidden-cloze-face
'((t (:foreground "deep sky blue" :background "blue")))
"The face used to hide the contents of cloze phrases."
:group 'org-drill)
-(defcustom org-drill-use-visible-cloze-face-p nil
+
+(defcustom org-drill-use-visible-cloze-face-p
+ nil
"Use a special face to highlight cloze-deleted text in org mode
buffers?"
:group 'org-drill
:type 'boolean)
-(defcustom org-drill-hide-item-headings-p nil
+
+(defcustom org-drill-hide-item-headings-p
+ nil
"Conceal the contents of the main heading of each item during drill
sessions? You may want to enable this behaviour if item headings or tags
contain information that could 'give away' the answer."
:group 'org-drill
:type 'boolean)
-(defcustom org-drill-new-count-color "royal blue"
+
+(defcustom org-drill-new-count-color
+ "royal blue"
"Foreground colour used to display the count of remaining new items
during a drill session."
:group 'org-drill
:type 'color)
-(defcustom org-drill-mature-count-color "green"
+(defcustom org-drill-mature-count-color
+ "green"
"Foreground colour used to display the count of remaining mature items
during a drill session. Mature items are due for review, but are not new."
:group 'org-drill
:type 'color)
-(defcustom org-drill-failed-count-color "red"
+(defcustom org-drill-failed-count-color
+ "red"
"Foreground colour used to display the count of remaining failed items
during a drill session."
:group 'org-drill
:type 'color)
-(defcustom org-drill-done-count-color "sienna"
+(defcustom org-drill-done-count-color
+ "sienna"
"Foreground colour used to display the count of reviewed items
during a drill session."
:group 'org-drill
:type 'color)
+(defcustom org-drill-left-cloze-delimiter
+ "["
+ "String used within org buffers to delimit cloze deletions."
+ :group 'org-drill
+ :type 'string)
+
+(defcustom org-drill-right-cloze-delimiter
+ "]"
+ "String used within org buffers to delimit cloze deletions."
+ :group 'org-drill
+ :type 'string)
+
+
(setplist 'org-drill-cloze-overlay-defaults
- '(display "[...]"
+ `(display ,(format "%s...%s"
+ org-drill-left-cloze-delimiter
+ org-drill-right-cloze-delimiter)
face org-drill-hidden-cloze-face
window t))
@@ -171,21 +203,35 @@ during a drill session."
face default
window t))
+
(defvar org-drill-hint-separator "||"
"String which, if it occurs within a cloze expression, signifies that the
rest of the expression after the string is a `hint', to be displayed instead of
the hidden cloze during a test.")
-(defvar org-drill-cloze-regexp
- (concat "\\(\\[[[:cntrl:][:graph:][:space:]]+?\\)\\(\\|"
+(defun org-drill--compute-cloze-regexp ()
+ (concat "\\("
+ (regexp-quote org-drill-left-cloze-delimiter)
+ "[[:cntrl:][:graph:][:space:]]+?\\)\\(\\|"
(regexp-quote org-drill-hint-separator)
- ".+?\\)\\(\\]\\)"))
+ ".+?\\)\\("
+ (regexp-quote org-drill-right-cloze-delimiter)
+ "\\)"))
+
+(defun org-drill--compute-cloze-keywords ()
+ (list (list (org-drill--compute-cloze-regexp)
+ (copy-list '(1 'org-drill-visible-cloze-face nil))
+ (copy-list '(2 'org-drill-visible-cloze-hint-face t))
+ (copy-list '(3 'org-drill-visible-cloze-face nil))
+ )))
+
+(defvar-local org-drill-cloze-regexp
+ (org-drill--compute-cloze-regexp))
+
+
+(defvar-local org-drill-cloze-keywords
+ (org-drill--compute-cloze-keywords))
-(defvar org-drill-cloze-keywords
- `((,org-drill-cloze-regexp
- (1 'org-drill-visible-cloze-face nil)
- (2 'org-drill-visible-cloze-hint-face t)
- (3 'org-drill-visible-cloze-face nil))))
(defcustom org-drill-card-type-alist
'((nil org-drill-present-simple-card)
@@ -234,7 +280,9 @@ even if their bodies are empty."
:type '(alist :key-type (choice string (const nil))
:value-type function))
-(defcustom org-drill-scope 'file
+
+(defcustom org-drill-scope
+ 'file
"The scope in which to search for drill items when conducting a
drill session. This can be any of:
@@ -256,18 +304,34 @@ directory All files with the extension '.org' in the same
;; 'file-no-restriction' means current file/buffer, ignoring restrictions
;; 'directory' means all *.org files in current directory
:group 'org-drill
- :type '(choice (const 'file) (const 'tree) (const 'file-no-restriction)
- (const 'file-with-archives) (const 'agenda)
- (const 'agenda-with-archives) (const 'directory)
- list))
+ :type '(choice (const :tag "The current buffer, respecting the restriction if any." file)
+ (const :tag "The subtree started with the entry at point" tree)
+ (const :tag "The current buffer, without restriction" file-no-restriction)
+ (const :tag "The current buffer, and any archives associated with it." file-with-archives)
+ (const :tag "All agenda files" agenda)
+ (const :tag "All agenda files with any archive files associated with them." agenda-with-archives)
+ (const :tag "All files with the extension '.org' in the same directory as the current file (includes the current file if it is an .org file.)" directory)
+ (repeat :tag "List of files to scan for drill items." file)))
+
+
+(defcustom org-drill-match
+ nil
+ "If non-nil, a string specifying a tags/property/TODO query. During
+drill sessions, only items that match this query will be considered."
+ :group 'org-drill
+ :type '(choice (const nil) string))
+
-(defcustom org-drill-save-buffers-after-drill-sessions-p t
+(defcustom org-drill-save-buffers-after-drill-sessions-p
+ t
"If non-nil, prompt to save all modified buffers after a drill session
finishes."
:group 'org-drill
:type 'boolean)
-(defcustom org-drill-spaced-repetition-algorithm 'sm5
+
+(defcustom org-drill-spaced-repetition-algorithm
+ 'sm5
"Which SuperMemo spaced repetition algorithm to use for scheduling items.
Available choices are:
- SM2 :: the SM2 algorithm, used in SuperMemo 2.0
@@ -280,9 +344,11 @@ Available choices are:
adjusting intervals when items are reviewed early or late has been taken
from SM11, a later version of the algorithm, and included in Simple8."
:group 'org-drill
- :type '(choice (const 'sm2) (const 'sm5) (const 'simple8)))
+ :type '(choice (const sm2) (const sm5) (const simple8)))
+
-(defcustom org-drill-optimal-factor-matrix nil
+(defcustom org-drill-optimal-factor-matrix
+ nil
"DO NOT CHANGE THE VALUE OF THIS VARIABLE.
Persistent matrix of optimal factors, used by the SuperMemo SM5 algorithm.
@@ -294,14 +360,18 @@ pace of learning."
:group 'org-drill
:type 'sexp)
-(defcustom org-drill-sm5-initial-interval 4.0
+
+(defcustom org-drill-sm5-initial-interval
+ 4.0
"In the SM5 algorithm, the initial interval after the first
successful presentation of an item is always 4 days. If you wish to change
this, you can do so here."
:group 'org-drill
:type 'float)
-(defcustom org-drill-add-random-noise-to-intervals-p nil
+
+(defcustom org-drill-add-random-noise-to-intervals-p
+ nil
"If true, the number of days until an item's next repetition
will vary slightly from the interval calculated by the SM2
algorithm. The variation is very small when the interval is
@@ -309,7 +379,9 @@ small, but scales up with the interval."
:group 'org-drill
:type 'boolean)
-(defcustom org-drill-adjust-intervals-for-early-and-late-repetitions-p nil
+
+(defcustom org-drill-adjust-intervals-for-early-and-late-repetitions-p
+ nil
"If true, when the student successfully reviews an item 1 or more days
before or after the scheduled review date, this will affect that date of
the item's next scheduled review, according to the algorithm presented at
@@ -324,7 +396,9 @@ is used."
:group 'org-drill
:type 'boolean)
-(defcustom org-drill-cloze-text-weight 4
+
+(defcustom org-drill-cloze-text-weight
+ 4
"For card types 'hide1_firstmore', 'show1_lastmore' and 'show1_firstless',
this number determines how often the 'less favoured' situation
should arise. It will occur 1 in every N trials, where N is the
@@ -343,12 +417,15 @@ all weighted card types are treated as their unweighted equivalents."
:group 'org-drill
:type '(choice integer (const nil)))
-(defcustom org-drill-cram-hours 12
+
+(defcustom org-drill-cram-hours
+ 12
"When in cram mode, items are considered due for review if
they were reviewed at least this many hours ago."
:group 'org-drill
:type 'integer)
+
;;; NEW items have never been presented in a drill session before.
;;; MATURE items HAVE been presented at least once before.
;;; - YOUNG mature items were scheduled no more than
@@ -361,13 +438,17 @@ they were reviewed at least this many hours ago."
;;; LAST-INTERVAL * (ORG-DRILL-OVERDUE-INTERVAL-FACTOR - 1) days,
;;; regardless of young/old status.
-(defcustom org-drill-days-before-old 10
+
+(defcustom org-drill-days-before-old
+ 10
"When an item's inter-repetition interval rises above this value in days,
it is no longer considered a 'young' (recently learned) item."
:group 'org-drill
:type 'integer)
-(defcustom org-drill-overdue-interval-factor 1.2
+
+(defcustom org-drill-overdue-interval-factor
+ 1.2
"An item is considered overdue if its scheduled review date is
more than (ORG-DRILL-OVERDUE-INTERVAL-FACTOR - 1) * LAST-INTERVAL
days in the past. For example, a value of 1.2 means an additional
@@ -379,7 +460,9 @@ should never be less than 1.0."
:group 'org-drill
:type 'float)
-(defcustom org-drill-learn-fraction 0.5
+
+(defcustom org-drill-learn-fraction
+ 0.5
"Fraction between 0 and 1 that governs how quickly the spaces
between successive repetitions increase, for all items. The
default value is 0.5. Higher values make spaces increase more
@@ -389,6 +472,7 @@ exponential effect on inter-repetition spacing."
:group 'org-drill
:type 'float)
+
(defvar drill-answer nil
"Global variable that can be bound to a correct answer when an
item is being presented. If this variable is non-nil, the default
@@ -399,6 +483,7 @@ This variable is useful for card types that compute their answers
-- for example, a card type that asks the student to translate a
random number to another language. ")
+
(defvar *org-drill-session-qualities* nil)
(defvar *org-drill-start-time* 0)
(defvar *org-drill-new-entries* nil)
@@ -428,8 +513,10 @@ for review unless they were already reviewed in the recent past?")
"DRILL_TOTAL_REPEATS" "DRILL_FAILURE_COUNT" "DRILL_AVERAGE_QUALITY"
"DRILL_EASE" "DRILL_LAST_QUALITY" "DRILL_LAST_REVIEWED"))
+
;;; Make the above settings safe as file-local variables.
+
(put 'org-drill-question-tag 'safe-local-variable 'stringp)
(put 'org-drill-maximum-items-per-session 'safe-local-variable
'(lambda (val) (or (integerp val) (null val))))
@@ -454,15 +541,22 @@ for review unless they were already reviewed in the recent past?")
(put 'org-drill-overdue-interval-factor 'safe-local-variable 'floatp)
(put 'org-drill-scope 'safe-local-variable
'(lambda (val) (or (symbolp val) (listp val))))
+(put 'org-drill-match 'safe-local-variable
+ '(lambda (val) (or (stringp val) (null val))))
(put 'org-drill-save-buffers-after-drill-sessions-p 'safe-local-variable 'booleanp)
(put 'org-drill-cloze-text-weight 'safe-local-variable
'(lambda (val) (or (null val) (integerp val))))
+(put 'org-drill-left-cloze-delimiter 'safe-local-variable 'stringp)
+(put 'org-drill-right-cloze-delimiter 'safe-local-variable 'stringp)
+
;;;; Utilities ================================================================
+
(defun free-marker (m)
(set-marker m nil))
+
(defmacro pop-random (place)
(let ((idx (gensym)))
`(if (null ,place)
@@ -472,18 +566,20 @@ for review unless they were already reviewed in the recent past?")
(setq ,place (append (subseq ,place 0 ,idx)
(subseq ,place (1+ ,idx)))))))))
+
(defmacro push-end (val place)
"Add VAL to the end of the sequence stored in PLACE. Return the new
value."
`(setq ,place (append ,place (list ,val))))
+
(defun shuffle-list (list)
"Randomly permute the elements of LIST (all permutations equally likely)."
;; Adapted from 'shuffle-vector' in cookie1.el
(let ((i 0)
- j
- temp
- (len (length list)))
+ j
+ temp
+ (len (length list)))
(while (< i len)
(setq j (+ i (random* (- len i))))
(setq temp (nth i list))
@@ -492,28 +588,43 @@ value."
(setq i (1+ i))))
list)
+
(defun round-float (floatnum fix)
"Round the floating point number FLOATNUM to FIX decimal places.
Example: (round-float 3.56755765 3) -> 3.568"
(let ((n (expt 10 fix)))
(/ (float (round (* floatnum n))) n)))
+
(defun command-keybinding-to-string (cmd)
"Return a human-readable description of the key/keys to which the command
CMD is bound, or nil if it is not bound to a key."
(let ((key (where-is-internal cmd overriding-local-map t)))
(if key (key-description key))))
+
(defun time-to-inactive-org-timestamp (time)
(format-time-string
(concat "[" (substring (cdr org-time-stamp-formats) 1 -1) "]")
time))
-(defun org-map-drill-entries (func &optional scope &rest skip)
+
+(defun time-to-active-org-timestamp (time)
+ (format-time-string
+ (concat "<" (substring (cdr org-time-stamp-formats) 1 -1) ">")
+ time))
+
+
+(defun org-map-drill-entries (func &optional scope drill-match &rest skip)
"Like `org-map-entries', but only drill entries are processed."
- (let ((org-drill-scope (or scope org-drill-scope)))
+ (let ((org-drill-scope (or scope org-drill-scope))
+ (org-drill-match (or drill-match org-drill-match)))
(apply 'org-map-entries func
- (concat "+" org-drill-question-tag)
+ (concat "+" org-drill-question-tag
+ (if (and (stringp org-drill-match)
+ (not (member '(?+ ?- ?|) (elt org-drill-match 0))))
+ "+" "")
+ (or org-drill-match ""))
(case org-drill-scope
(file nil)
(file-no-restriction 'file)
@@ -523,6 +634,7 @@ CMD is bound, or nil if it is not bound to a key."
(t org-drill-scope))
skip)))
+
(defmacro with-hidden-cloze-text (&rest body)
`(progn
(org-drill-hide-clozed-text)
@@ -531,6 +643,7 @@ CMD is bound, or nil if it is not bound to a key."
,@body)
(org-drill-unhide-clozed-text))))
+
(defmacro with-hidden-cloze-hints (&rest body)
`(progn
(org-drill-hide-cloze-hints)
@@ -539,6 +652,7 @@ CMD is bound, or nil if it is not bound to a key."
,@body)
(org-drill-unhide-text))))
+
(defmacro with-hidden-comments (&rest body)
`(progn
(if org-drill-hide-item-headings-p
@@ -549,6 +663,7 @@ CMD is bound, or nil if it is not bound to a key."
,@body)
(org-drill-unhide-text))))
+
(defun org-drill-days-since-last-review ()
"Nil means a last review date has not yet been stored for
the item.
@@ -562,6 +677,7 @@ this should never happen."
(time-to-days (apply 'encode-time
(org-parse-time-string datestr)))))))
+
(defun org-drill-hours-since-last-review ()
"Like `org-drill-days-since-last-review', but return value is
in hours rather than days."
@@ -573,6 +689,7 @@ in hours rather than days."
(org-parse-time-string datestr))))
(* 60 60))))))
+
(defun org-drill-entry-p (&optional marker)
"Is MARKER, or the point, in a 'drill item'? This will return nil if
the point is inside a subheading of a drill item -- to handle that
@@ -582,10 +699,12 @@ situation use `org-part-of-drill-entry-p'."
(org-drill-goto-entry marker))
(member org-drill-question-tag (org-get-local-tags))))
+
(defun org-drill-goto-entry (marker)
(switch-to-buffer (marker-buffer marker))
(goto-char marker))
+
(defun org-part-of-drill-entry-p ()
"Is the current entry either the main heading of a 'drill item',
or a subheading within a drill item?"
@@ -593,6 +712,7 @@ or a subheading within a drill item?"
;; Does this heading INHERIT the drill tag
(member org-drill-question-tag (org-get-tags-at))))
+
(defun org-drill-goto-drill-entry-heading ()
"Move the point to the heading which holds the :drill: tag for this
drill entry."
@@ -604,11 +724,14 @@ drill entry."
(unless (org-up-heading-safe)
(error "Cannot find a parent heading that is marked as a drill entry"))))
+
+
(defun org-drill-entry-leech-p ()
"Is the current entry a 'leech item'?"
(and (org-drill-entry-p)
(member "leech" (org-get-local-tags))))
+
;; (defun org-drill-entry-due-p ()
;; (cond
;; (*org-drill-cram-mode*
@@ -626,6 +749,7 @@ drill entry."
;; (- (time-to-days (current-time))
;; (time-to-days item-time))))))))))
+
(defun org-drill-entry-days-overdue ()
"Returns:
- NIL if the item is not to be regarded as scheduled for review at all.
@@ -655,6 +779,7 @@ drill entry."
(- (time-to-days (current-time))
(time-to-days item-time))))))))
+
(defun org-drill-entry-overdue-p (&optional days-overdue last-interval)
"Returns true if entry that is scheduled DAYS-OVERDUE dasy in the past,
and whose last inter-repetition interval was LAST-INTERVAL, should be
@@ -670,28 +795,34 @@ from the entry at point."
(> (/ (+ days-overdue last-interval 1.0) last-interval)
org-drill-overdue-interval-factor)))
+
+
(defun org-drill-entry-due-p ()
(let ((due (org-drill-entry-days-overdue)))
(and (not (null due))
(not (minusp due)))))
+
(defun org-drill-entry-new-p ()
(and (org-drill-entry-p)
(let ((item-time (org-get-scheduled-time (point))))
(null item-time))))
+
(defun org-drill-entry-last-quality (&optional default)
(let ((quality (org-entry-get (point) "DRILL_LAST_QUALITY")))
(if quality
(string-to-number quality)
default)))
+
(defun org-drill-entry-failure-count ()
(let ((quality (org-entry-get (point) "DRILL_FAILURE_COUNT")))
(if quality
(string-to-number quality)
0)))
+
(defun org-drill-entry-average-quality (&optional default)
(let ((val (org-entry-get (point) "DRILL_AVERAGE_QUALITY")))
(if val
@@ -722,16 +853,17 @@ from the entry at point."
(string-to-number val)
default)))
+
;;; From http://www.supermemo.com/english/ol/sm5.htm
(defun org-drill-random-dispersal-factor ()
"Returns a random number between 0.5 and 1.5."
(let ((a 0.047)
(b 0.092)
(p (- (random* 1.0) 0.5)))
- (flet ((sign (n)
- (cond ((zerop n) 0)
- ((plusp n) 1)
- (t -1))))
+ (cl-flet ((sign (n)
+ (cond ((zerop n) 0)
+ ((plusp n) 1)
+ (t -1))))
(/ (+ 100 (* (* (/ -1 b) (log (- 1 (* (/ b a ) (abs p)))))
(sign p)))
100.0))))
@@ -744,9 +876,10 @@ from the entry at point."
(- variation)
mean))
+
(defun org-drill-early-interval-factor (optimal-factor
- optimal-interval
- days-ahead)
+ optimal-interval
+ days-ahead)
"Arguments:
- OPTIMAL-FACTOR: interval-factor if the item had been tested
exactly when it was supposed to be.
@@ -763,6 +896,7 @@ in the matrix."
(- optimal-factor
(* delta-ofmax (/ days-ahead (+ days-ahead (* 0.6 optimal-interval)))))))
+
(defun org-drill-get-item-data ()
"Returns a list of 6 items, containing all the stored recall
data for the item at point:
@@ -800,6 +934,7 @@ in the matrix."
(t ; virgin item
(list 0 0 0 0 nil nil)))))
+
(defun org-drill-store-item-data (last-interval repeats failures
total-repeats meanq
ease)
@@ -815,8 +950,11 @@ in the matrix."
(org-set-property "DRILL_EASE"
(number-to-string (round-float ease 3))))
+
+
;;; SM2 Algorithm =============================================================
+
(defun determine-next-interval-sm2 (last-interval n ef quality
failures meanq total-repeats)
"Arguments:
@@ -865,6 +1003,8 @@ Returns a list: (INTERVAL REPEATS EF FAILURES MEAN TOTAL-REPEATS OFMATRIX), wher
;;; SM5 Algorithm =============================================================
+
+
(defun initial-optimal-factor-sm5 (n ef)
(if (= 1 n)
org-drill-sm5-initial-interval
@@ -873,17 +1013,19 @@ Returns a list: (INTERVAL REPEATS EF FAILURES MEAN TOTAL-REPEATS OFMATRIX), wher
(defun get-optimal-factor-sm5 (n ef of-matrix)
(let ((factors (assoc n of-matrix)))
(or (and factors
- (let ((ef-of (assoc ef (cdr factors))))
- (and ef-of (cdr ef-of))))
- (initial-optimal-factor-sm5 n ef))))
+ (let ((ef-of (assoc ef (cdr factors))))
+ (and ef-of (cdr ef-of))))
+ (initial-optimal-factor-sm5 n ef))))
+
(defun inter-repetition-interval-sm5 (last-interval n ef &optional of-matrix)
(let ((of (get-optimal-factor-sm5 n ef (or of-matrix
org-drill-optimal-factor-matrix))))
(if (= 1 n)
- of
+ of
(* of last-interval))))
+
(defun determine-next-interval-sm5 (last-interval n ef quality
failures meanq total-repeats
of-matrix &optional delta-days)
@@ -894,10 +1036,12 @@ Returns a list: (INTERVAL REPEATS EF FAILURES MEAN TOTAL-REPEATS OFMATRIX), wher
(unless of-matrix
(setq of-matrix org-drill-optimal-factor-matrix))
(setq of-matrix (cl-copy-tree of-matrix))
+
(setq meanq (if meanq
(/ (+ quality (* meanq total-repeats 1.0))
(1+ total-repeats))
quality))
+
(let ((next-ef (modify-e-factor ef quality))
(old-ef ef)
(new-of (modify-of (get-optimal-factor-sm5 n ef of-matrix)
@@ -910,10 +1054,13 @@ Returns a list: (INTERVAL REPEATS EF FAILURES MEAN TOTAL-REPEATS OFMATRIX), wher
(inter-repetition-interval-sm5
last-interval n ef of-matrix)
delta-days)))
+
(setq of-matrix
(set-optimal-factor n next-ef of-matrix
(round-float new-of 3))) ; round OF to 3 d.p.
+
(setq ef next-ef)
+
(cond
;; "Failed" -- reset repetitions to 0,
((<= quality org-drill-failure-quality)
@@ -938,8 +1085,10 @@ Returns a list: (INTERVAL REPEATS EF FAILURES MEAN TOTAL-REPEATS OFMATRIX), wher
(1+ total-repeats)
of-matrix)))))
+
;;; Simple8 Algorithm =========================================================
+
(defun org-drill-simple8-first-interval (failures)
"Arguments:
- FAILURES: integer >= 0. The total number of times the item has
@@ -949,6 +1098,7 @@ Returns the optimal FIRST interval for an item which has previously been
forgotten on FAILURES occasions."
(* 2.4849 (exp (* -0.057 failures))))
+
(defun org-drill-simple8-interval-factor (ease repetition)
"Arguments:
- EASE: floating point number >= 1.2. Corresponds to `AF' in SM8 algorithm.
@@ -959,6 +1109,7 @@ The factor by which the last interval should be
multiplied to give the next interval. Corresponds to `RF' or `OF'."
(+ 1.2 (* (- ease 1.2) (expt org-drill-learn-fraction (log repetition 2)))))
+
(defun org-drill-simple8-quality->ease (quality)
"Returns the ease (`AF' in the SM8 algorithm) which corresponds
to a mean item quality of QUALITY."
@@ -968,6 +1119,7 @@ to a mean item quality of QUALITY."
(* -1.2403 quality)
1.4515))
+
(defun determine-next-interval-simple8 (last-interval repeats quality
failures meanq totaln
&optional delta-days)
@@ -1034,7 +1186,11 @@ See the documentation for `org-drill-get-item-data' for a description of these."
(org-drill-simple8-quality->ease meanq)
failures
meanq
- totaln)))
+ totaln
+ )))
+
+
+
;;; Essentially copied from `org-learn.el', but modified to
;;; optionally call the SM2 or simple8 functions.
@@ -1087,7 +1243,7 @@ item will be scheduled exactly this many days into the future."
(cond
((= 0 days-ahead)
- (org-schedule t))
+ (org-schedule '(4)))
((minusp days-ahead)
(org-schedule nil (current-time)))
(t
@@ -1207,13 +1363,14 @@ How well did you do? (0-5, ?=help, e=edit, t=tags, q=quit)"
(sit-for 0.5)))))
(org-set-property "DRILL_LAST_QUALITY" (format "%d" quality))
(org-set-property "DRILL_LAST_REVIEWED"
- (time-to-inactive-org-timestamp (current-time))))
+ (time-to-active-org-timestamp (current-time))))
quality))
((= ch ?e)
'edit)
(t
nil))))
+
;; (defun org-drill-hide-all-subheadings-except (heading-list)
;; "Returns a list containing the position of each immediate subheading of
;; the current topic."
@@ -1234,6 +1391,8 @@ How well did you do? (0-5, ?=help, e=edit, t=tags, q=quit)"
;; "" 'tree))
;; (reverse drill-sections)))
+
+
(defun org-drill-hide-subheadings-if (test)
"TEST is a function taking no arguments. TEST will be called for each
of the immediate subheadings of the current drill item, with the point
@@ -1256,11 +1415,13 @@ the current topic."
"" 'tree))
(reverse drill-sections)))
+
(defun org-drill-hide-all-subheadings-except (heading-list)
(org-drill-hide-subheadings-if
(lambda () (let ((drill-heading (org-get-heading t)))
(not (member drill-heading heading-list))))))
+
(defun org-drill-presentation-prompt (&rest fmt-and-args)
(let* ((item-start-time (current-time))
(input nil)
@@ -1341,22 +1502,26 @@ Consider reformulating the item to make it easier to remember.\n"
(?s 'skip)
(otherwise t))))
+
(defun org-pos-in-regexp (pos regexp &optional nlines)
(save-excursion
(goto-char pos)
(org-in-regexp regexp nlines)))
+
(defun org-drill-hide-region (beg end &optional text)
"Hide the buffer region between BEG and END with an 'invisible text'
visual overlay, or with the string TEXT if it is supplied."
(let ((ovl (make-overlay beg end)))
(overlay-put ovl 'category
'org-drill-hidden-text-overlay)
+ (overlay-put ovl 'priority 9999)
(when (stringp text)
(overlay-put ovl 'invisible nil)
(overlay-put ovl 'face 'default)
(overlay-put ovl 'display text))))
+
(defun org-drill-hide-heading-at-point (&optional text)
(unless (org-at-heading-p)
(error "Point is not on a heading."))
@@ -1365,11 +1530,13 @@ visual overlay, or with the string TEXT if it is supplied."
(end-of-line)
(org-drill-hide-region beg (point) text))))
+
(defun org-drill-hide-comments ()
(save-excursion
(while (re-search-forward "^#.*$" nil t)
(org-drill-hide-region (match-beginning 0) (match-end 0)))))
+
(defun org-drill-unhide-text ()
;; This will also unhide the item's heading.
(save-excursion
@@ -1377,16 +1544,20 @@ visual overlay, or with the string TEXT if it is supplied."
(when (eql 'org-drill-hidden-text-overlay (overlay-get ovl 'category))
(delete-overlay ovl)))))
+
(defun org-drill-hide-clozed-text ()
(save-excursion
(while (re-search-forward org-drill-cloze-regexp nil t)
;; Don't hide org links, partly because they might contain inline
- ;; images which we want to keep visible
+ ;; images which we want to keep visible.
+ ;; And don't hide LaTeX math fragments.
(unless (save-match-data
- (org-pos-in-regexp (match-beginning 0)
- org-bracket-link-regexp 1))
+ (or (org-pos-in-regexp (match-beginning 0)
+ org-bracket-link-regexp 1)
+ (org-inside-LaTeX-fragment-p)))
(org-drill-hide-matched-cloze-text)))))
+
(defun org-drill-hide-matched-cloze-text ()
"Hide the current match with a 'cloze' visual overlay."
(let ((ovl (make-overlay (match-beginning 0) (match-end 0)))
@@ -1394,6 +1565,7 @@ visual overlay, or with the string TEXT if it is supplied."
(match-string 0))))
(overlay-put ovl 'category
'org-drill-cloze-overlay-defaults)
+ (overlay-put ovl 'priority 9999)
(when (and hint-sep-pos
(> hint-sep-pos 1))
(let ((hint (substring-no-properties
@@ -1407,6 +1579,7 @@ visual overlay, or with the string TEXT if it is supplied."
(format (if (string-match-p (regexp-quote "...") hint) "[%s]" "[%s...]")
hint))))))
+
(defun org-drill-hide-cloze-hints ()
(save-excursion
(while (re-search-forward org-drill-cloze-regexp nil t)
@@ -1416,6 +1589,7 @@ visual overlay, or with the string TEXT if it is supplied."
(null (match-beginning 2))) ; hint subexpression matched
(org-drill-hide-region (match-beginning 2) (match-end 2))))))
+
(defmacro with-replaced-entry-text (text &rest body)
"During the execution of BODY, the entire text of the current entry is
concealed by an overlay that displays the string TEXT."
@@ -1426,6 +1600,7 @@ concealed by an overlay that displays the string TEXT."
,@body)
(org-drill-unreplace-entry-text))))
+
(defmacro with-replaced-entry-text-multi (replacements &rest body)
"During the execution of BODY, the entire text of the current entry is
concealed by an overlay that displays the overlays in REPLACEMENTS."
@@ -1436,6 +1611,7 @@ concealed by an overlay that displays the overlays in REPLACEMENTS."
,@body)
(org-drill-unreplace-entry-text))))
+
(defun org-drill-replace-entry-text (text &optional multi-p)
"Make an overlay that conceals the entire text of the item, not
including properties or the contents of subheadings. The overlay shows
@@ -1454,16 +1630,19 @@ Note: does not actually alter the item."
(save-excursion
(outline-next-heading)
(point)))))
+ (overlay-put ovl 'priority 9999)
(overlay-put ovl 'category
'org-drill-replaced-text-overlay)
(overlay-put ovl 'display text)))))
+
(defun org-drill-unreplace-entry-text ()
(save-excursion
(dolist (ovl (overlays-in (point-min) (point-max)))
(when (eql 'org-drill-replaced-text-overlay (overlay-get ovl 'category))
(delete-overlay ovl)))))
+
(defun org-drill-replace-entry-text-multi (replacements)
"Make overlays that conceal the entire text of the item, not
including properties or the contents of subheadings. The overlay shows
@@ -1480,10 +1659,12 @@ Note: does not actually alter the item."
(if (= i (1- (length replacements)))
p-max
(+ p-min (* 2 i) 1))))
+ (overlay-put ovl 'priority 9999)
(overlay-put ovl 'category
'org-drill-replaced-text-overlay)
(overlay-put ovl 'display (nth i replacements)))))
+
(defmacro with-replaced-entry-heading (heading &rest body)
`(progn
(org-drill-replace-entry-heading ,heading)
@@ -1492,18 +1673,21 @@ Note: does not actually alter the item."
,@body)
(org-drill-unhide-text))))
+
(defun org-drill-replace-entry-heading (heading)
"Make an overlay that conceals the heading of the item. The overlay shows
the string TEXT.
Note: does not actually alter the item."
(org-drill-hide-heading-at-point heading))
+
(defun org-drill-unhide-clozed-text ()
(save-excursion
(dolist (ovl (overlays-in (point-min) (point-max)))
(when (eql 'org-drill-cloze-overlay-defaults (overlay-get ovl 'category))
(delete-overlay ovl)))))
+
(defun org-drill-get-entry-text (&optional keep-properties-p)
(let ((text (org-agenda-get-some-entry-text (point-marker) 100)))
(if keep-properties-p
@@ -1526,6 +1710,7 @@ Note: does not actually alter the item."
(defun org-drill-entry-empty-p () (org-entry-empty-p))
+
;;; Presentation functions ====================================================
;;
;; Each of these is called with point on topic heading. Each needs to show the
@@ -1540,12 +1725,14 @@ Note: does not actually alter the item."
(with-hidden-cloze-hints
(with-hidden-cloze-text
(org-drill-hide-all-subheadings-except nil)
+ (org-preview-latex-fragment) ; overlay all LaTeX fragments with images
(ignore-errors
(org-display-inline-images t))
(org-cycle-hide-drawers 'all)
(prog1 (org-drill-presentation-prompt)
(org-drill-hide-subheadings-if 'org-drill-entry-p))))))
+
(defun org-drill-present-default-answer (reschedule-fn)
(cond
(drill-answer
@@ -1557,12 +1744,14 @@ Note: does not actually alter the item."
(t
(org-drill-hide-subheadings-if 'org-drill-entry-p)
(org-drill-unhide-clozed-text)
+ (org-preview-latex-fragment)
(ignore-errors
(org-display-inline-images t))
(org-cycle-hide-drawers 'all)
(with-hidden-cloze-hints
(funcall reschedule-fn)))))
+
(defun org-drill-present-two-sided-card ()
(with-hidden-comments
(with-hidden-cloze-hints
@@ -1573,12 +1762,15 @@ Note: does not actually alter the item."
(goto-char (nth (random* (min 2 (length drill-sections)))
drill-sections))
(org-show-subtree)))
+ (org-preview-latex-fragment)
(ignore-errors
(org-display-inline-images t))
(org-cycle-hide-drawers 'all)
(prog1 (org-drill-presentation-prompt)
(org-drill-hide-subheadings-if 'org-drill-entry-p)))))))
+
+
(defun org-drill-present-multi-sided-card ()
(with-hidden-comments
(with-hidden-cloze-hints
@@ -1588,12 +1780,14 @@ Note: does not actually alter the item."
(save-excursion
(goto-char (nth (random* (length drill-sections)) drill-sections))
(org-show-subtree)))
+ (org-preview-latex-fragment)
(ignore-errors
(org-display-inline-images t))
(org-cycle-hide-drawers 'all)
(prog1 (org-drill-presentation-prompt)
(org-drill-hide-subheadings-if 'org-drill-entry-p)))))))
+
(defun org-drill-present-multicloze-hide-n (number-to-hide
&optional
force-show-first
@@ -1628,7 +1822,8 @@ items if FORCE-SHOW-FIRST or FORCE-SHOW-LAST is non-nil)."
(let ((in-regexp? (save-match-data
(org-pos-in-regexp (match-beginning 0)
org-bracket-link-regexp 1))))
- (unless in-regexp?
+ (unless (or in-regexp?
+ (org-inside-LaTeX-fragment-p))
(incf match-count)))))
(if (minusp number-to-hide)
(setq number-to-hide (+ match-count number-to-hide)))
@@ -1655,8 +1850,9 @@ items if FORCE-SHOW-FIRST or FORCE-SHOW-LAST is non-nil)."
(setq cnt 0)
(while (re-search-forward org-drill-cloze-regexp item-end t)
(unless (save-match-data
- (org-pos-in-regexp (match-beginning 0)
- org-bracket-link-regexp 1))
+ (or (org-pos-in-regexp (match-beginning 0)
+ org-bracket-link-regexp 1)
+ (org-inside-LaTeX-fragment-p)))
(incf cnt)
(if (memq cnt match-nums)
(org-drill-hide-matched-cloze-text)))))))
@@ -1666,6 +1862,7 @@ items if FORCE-SHOW-FIRST or FORCE-SHOW-LAST is non-nil)."
;; while (org-pos-in-regexp (match-beginning 0)
;; org-bracket-link-regexp 1))
;; (org-drill-hide-matched-cloze-text)))))
+ (org-preview-latex-fragment)
(ignore-errors
(org-display-inline-images t))
(org-cycle-hide-drawers 'all)
@@ -1673,6 +1870,7 @@ items if FORCE-SHOW-FIRST or FORCE-SHOW-LAST is non-nil)."
(org-drill-hide-subheadings-if 'org-drill-entry-p)
(org-drill-unhide-clozed-text))))))
+
(defun org-drill-present-multicloze-hide-nth (to-hide)
"Hide the TO-HIDE'th piece of clozed text. 1 is the first piece. If
TO-HIDE is negative, count backwards, so -1 means the last item, -2
@@ -1694,7 +1892,8 @@ the second to last, etc."
(let ((in-regexp? (save-match-data
(org-pos-in-regexp (match-beginning 0)
org-bracket-link-regexp 1))))
- (unless in-regexp?
+ (unless (or in-regexp?
+ (org-inside-LaTeX-fragment-p))
(incf match-count)))))
(if (minusp to-hide)
(setq to-hide (+ 1 to-hide match-count)))
@@ -1708,11 +1907,16 @@ the second to last, etc."
(setq cnt 0)
(while (re-search-forward org-drill-cloze-regexp item-end t)
(unless (save-match-data
- (org-pos-in-regexp (match-beginning 0)
- org-bracket-link-regexp 1))
+ ;; Don't consider this a cloze region if it is part of an
+ ;; org link, or if it occurs inside a LaTeX math
+ ;; fragment
+ (or (org-pos-in-regexp (match-beginning 0)
+ org-bracket-link-regexp 1)
+ (org-inside-LaTeX-fragment-p)))
(incf cnt)
(if (= cnt to-hide)
(org-drill-hide-matched-cloze-text)))))))
+ (org-preview-latex-fragment)
(ignore-errors
(org-display-inline-images t))
(org-cycle-hide-drawers 'all)
@@ -1720,24 +1924,29 @@ the second to last, etc."
(org-drill-hide-subheadings-if 'org-drill-entry-p)
(org-drill-unhide-clozed-text))))))
+
(defun org-drill-present-multicloze-hide1 ()
"Hides one of the pieces of text that are marked for cloze deletion,
chosen at random."
(org-drill-present-multicloze-hide-n 1))
+
(defun org-drill-present-multicloze-hide2 ()
"Hides two of the pieces of text that are marked for cloze deletion,
chosen at random."
(org-drill-present-multicloze-hide-n 2))
+
(defun org-drill-present-multicloze-hide-first ()
"Hides the first piece of text that is marked for cloze deletion."
(org-drill-present-multicloze-hide-nth 1))
+
(defun org-drill-present-multicloze-hide-last ()
"Hides the last piece of text that is marked for cloze deletion."
(org-drill-present-multicloze-hide-nth -1))
+
(defun org-drill-present-multicloze-hide1-firstmore ()
"Commonly, hides the FIRST piece of text that is marked for
cloze deletion. Uncommonly, hide one of the other pieces of text,
@@ -1767,6 +1976,7 @@ the value of `org-drill-cloze-text-weight'."
;; Commonly, hide first item
(org-drill-present-multicloze-hide-first))))
+
(defun org-drill-present-multicloze-show1-lastmore ()
"Commonly, hides all pieces except the last. Uncommonly, shows
any random piece. The effect is similar to 'show1cloze' except
@@ -1791,6 +2001,7 @@ the value of `org-drill-cloze-text-weight'."
;; Commonly, show the LAST item
(org-drill-present-multicloze-hide-n -1 nil t))))
+
(defun org-drill-present-multicloze-show1-firstless ()
"Commonly, hides all pieces except one, where the shown piece
is guaranteed NOT to be the first piece. Uncommonly, shows any
@@ -1816,49 +2027,19 @@ the value of `org-drill-cloze-text-weight'."
;; Commonly, show any item, except the first
(org-drill-present-multicloze-hide-n -1 nil nil t))))
+
(defun org-drill-present-multicloze-show1 ()
"Similar to `org-drill-present-multicloze-hide1', but hides all
the pieces of text that are marked for cloze deletion, except for one
piece which is chosen at random."
(org-drill-present-multicloze-hide-n -1))
+
(defun org-drill-present-multicloze-show2 ()
"Similar to `org-drill-present-multicloze-show1', but reveals two
pieces rather than one."
(org-drill-present-multicloze-hide-n -2))
-;; (defun org-drill-present-multicloze-show1 ()
-;; "Similar to `org-drill-present-multicloze-hide1', but hides all
-;; the pieces of text that are marked for cloze deletion, except for one
-;; piece which is chosen at random."
-;; (with-hidden-comments
-;; (with-hidden-cloze-hints
-;; (let ((item-end nil)
-;; (match-count 0)
-;; (body-start (or (cdr (org-get-property-block))
-;; (point))))
-;; (org-drill-hide-all-subheadings-except nil)
-;; (save-excursion
-;; (outline-next-heading)
-;; (setq item-end (point)))
-;; (save-excursion
-;; (goto-char body-start)
-;; (while (re-search-forward org-drill-cloze-regexp item-end t)
-;; (incf match-count)))
-;; (when (plusp match-count)
-;; (let ((match-to-hide (random* match-count)))
-;; (save-excursion
-;; (goto-char body-start)
-;; (dotimes (n match-count)
-;; (re-search-forward org-drill-cloze-regexp
-;; item-end t)
-;; (unless (= n match-to-hide)
-;; (org-drill-hide-matched-cloze-text))))))
-;; (org-display-inline-images t)
-;; (org-cycle-hide-drawers 'all)
-;; (prog1 (org-drill-presentation-prompt)
-;; (org-drill-hide-subheadings-if 'org-drill-entry-p)
-;; (org-drill-unhide-clozed-text))))))
(defun org-drill-present-card-using-text (question &optional answer)
"Present the string QUESTION as the only visible content of the card.
@@ -1874,6 +2055,7 @@ If ANSWER is supplied, set the global variable `drill-answer' to its value."
(prog1 (org-drill-presentation-prompt)
(org-drill-hide-subheadings-if 'org-drill-entry-p)))))
+
(defun org-drill-present-card-using-multiple-overlays (replacements &optional answer)
"TEXTS is a list of valid values for the 'display' text property.
Present these overlays, in sequence, as the only
@@ -1890,6 +2072,7 @@ If ANSWER is supplied, set the global variable `drill-answer' to its value."
(prog1 (org-drill-presentation-prompt)
(org-drill-hide-subheadings-if 'org-drill-entry-p)))))
+
(defun org-drill-entry ()
"Present the current topic for interactive review, as in `org-drill'.
Review will occur regardless of whether the topic is due for review or whether
@@ -1907,7 +2090,7 @@ See `org-drill' for more details."
;; (error "Point is not inside a drill entry"))
;;(unless (org-at-heading-p)
;; (org-back-to-heading))
- (let ((card-type (org-entry-get (point) "DRILL_CARD_TYPE"))
+ (let ((card-type (org-entry-get (point) "DRILL_CARD_TYPE" t))
(answer-fn 'org-drill-present-default-answer)
(present-empty-cards nil)
(cont nil)
@@ -1949,6 +2132,7 @@ See `org-drill' for more details."
(funcall answer-fn
(lambda () (org-drill-reschedule)))))))))))))
+
(defun org-drill-entries-pending-p ()
(or *org-drill-again-entries*
*org-drill-current-item*
@@ -1961,6 +2145,7 @@ See `org-drill' for more details."
*org-drill-overdue-entries*
*org-drill-again-entries*))))
+
(defun org-drill-pending-entry-count ()
(+ (if (markerp *org-drill-current-item*) 1 0)
(length *org-drill-new-entries*)
@@ -1970,6 +2155,7 @@ See `org-drill' for more details."
(length *org-drill-overdue-entries*)
(length *org-drill-again-entries*)))
+
(defun org-drill-maximum-duration-reached-p ()
"Returns true if the current drill session has continued past its
maximum duration."
@@ -1979,6 +2165,7 @@ maximum duration."
(> (- (float-time (current-time)) *org-drill-start-time*)
(* org-drill-maximum-duration 60))))
+
(defun org-drill-maximum-item-count-reached-p ()
"Returns true if the current drill session has reached the
maximum number of items."
@@ -1987,6 +2174,7 @@ maximum number of items."
(>= (length *org-drill-done-entries*)
org-drill-maximum-items-per-session)))
+
(defun org-drill-pop-next-pending-entry ()
(block org-drill-pop-next-pending-entry
(let ((m nil))
@@ -2034,6 +2222,7 @@ maximum number of items."
(return-from org-drill-pop-next-pending-entry nil)))))
m)))
+
(defun org-drill-entries (&optional resuming-p)
"Returns nil, t, or a list of markers representing entries that were
'failed' and need to be presented again before the session ends.
@@ -2086,6 +2275,8 @@ RESUMING-P is true if we are resuming a suspended drill session."
(push m *org-drill-done-entries*)))
(setq *org-drill-current-item* nil))))))))))
+
+
(defun org-drill-final-report ()
(let ((pass-percent
(round (* 100 (count-if (lambda (qual)
@@ -2172,7 +2363,10 @@ order to make items appear more frequently over time."
*org-drill-overdue-entry-count*
(round (* 100 *org-drill-overdue-entry-count*)
(+ *org-drill-dormant-entry-count*
- *org-drill-due-entry-count*)))))))
+ *org-drill-due-entry-count*)))
+ ))))
+
+
(defun org-drill-free-markers (markers)
"MARKERS is a list of markers, all of which will be freed (set to
@@ -2268,7 +2462,7 @@ one of the following values:
sym1)))))
-(defun org-drill (&optional scope resume-p)
+(defun org-drill (&optional scope drill-match resume-p)
"Begin an interactive 'drill session'. The user is asked to
review a series of topics (headers). Each topic is initially
presented as a 'question', often with part of the topic content
@@ -2296,10 +2490,24 @@ SCOPE determines the scope in which to search for
questions. It accepts the same values as `org-drill-scope',
which see.
+DRILL-MATCH, if supplied, is a string specifying a tags/property/
+todo query. Only items matching the query will be considered.
+It accepts the same values as `org-drill-match', which see.
+
If RESUME-P is non-nil, resume a suspended drill session rather
than starting a new one."
(interactive)
+ ;; Check org version. Org 7.9.3f introduced a backwards-incompatible change
+ ;; to the arguments accepted by `org-schedule'. At the time of writing there
+ ;; are still lots of people using versions of org older than this.
+ (let ((majorv (first (mapcar 'string-to-number (split-string (org-release) "[.]")))))
+ (if (and (< majorv 8)
+ (not (string-match-p "universal prefix argument" (documentation 'org-schedule))))
+ (read-char-exclusive
+ (format "Warning: org-drill requires org mode 7.9.3f or newer. Scheduling of failed cards will not
+work correctly with older versions of org mode. Your org mode version (%s) appears to be older than
+7.9.3f. Please consider installing a more recent version of org mode." (org-release)))))
(let ((end-pos nil)
(overdue-data nil)
(cnt 0))
@@ -2368,7 +2576,7 @@ than starting a new one."
(:old
(push (point-marker) *org-drill-old-mature-entries*))
)))))
- scope)
+ scope drill-match)
(org-drill-order-overdue-entries overdue-data)
(setq *org-drill-overdue-entry-count*
(length *org-drill-overdue-entries*))))
@@ -2405,7 +2613,8 @@ than starting a new one."
(org-drill-save-optimal-factor-matrix))
(if org-drill-save-buffers-after-drill-sessions-p
(save-some-buffers))
- (message "Drill session finished!")))))
+ (message "Drill session finished!")
+ ))))
(defun org-drill-save-optimal-factor-matrix ()
@@ -2414,14 +2623,14 @@ than starting a new one."
org-drill-optimal-factor-matrix))
-(defun org-drill-cram (&optional scope)
+(defun org-drill-cram (&optional scope drill-match)
"Run an interactive drill session in 'cram mode'. In cram mode,
all drill items are considered to be due for review, unless they
have been reviewed within the last `org-drill-cram-hours'
hours."
(interactive)
(setq *org-drill-cram-mode* t)
- (org-drill scope))
+ (org-drill scope drill-match))
(defun org-drill-tree ()
@@ -2438,7 +2647,7 @@ files in the same directory as the current file."
(org-drill 'directory))
-(defun org-drill-again (&optional scope)
+(defun org-drill-again (&optional scope drill-match)
"Run a new drill session, but try to use leftover due items that
were not reviewed during the last session, rather than scanning for
unreviewed items. If there are no leftover items in memory, a full
@@ -2453,9 +2662,9 @@ scan will be performed."
(setq *org-drill-start-time* (float-time (current-time))
*org-drill-done-entries* nil
*org-drill-current-item* nil)
- (org-drill scope t))
+ (org-drill scope drill-match t))
(t
- (org-drill scope))))
+ (org-drill scope drill-match))))
@@ -2465,7 +2674,7 @@ exiting them with the `edit' or `quit' options."
(interactive)
(cond
((org-drill-entries-pending-p)
- (org-drill nil t))
+ (org-drill nil nil t))
((and (plusp (org-drill-pending-entry-count))
;; Current drill session is finished, but there are still
;; more items which need to be reviewed.
@@ -2478,10 +2687,18 @@ need reviewing. Start a new drill session? "
(message "You have finished the drill session."))))
+(defun org-drill-relearn-item ()
+ "Make the current item due for revision, and set its last interval to 0.
+Makes the item behave as if it has been failed, without actually recording a
+failure. This command can be used to 'reset' repetitions for an item."
+ (interactive)
+ (org-drill-smart-reschedule 4 0))
+
+
(defun org-drill-strip-entry-data ()
(dolist (prop org-drill-scheduling-properties)
(org-delete-property prop))
- (org-schedule t))
+ (org-schedule '(4)))
(defun org-drill-strip-all-data (&optional scope)
@@ -2499,22 +2716,42 @@ values as `org-drill-scope'."
;; `org-delete-property-globally', which is faster.
(dolist (prop org-drill-scheduling-properties)
(org-delete-property-globally prop))
- (org-map-drill-entries (lambda () (org-schedule t)) scope))
+ (org-map-drill-entries (lambda () (org-schedule '(4))) scope))
(t
(org-map-drill-entries 'org-drill-strip-entry-data scope)))
(message "Done.")))
-
(defun org-drill-add-cloze-fontification ()
+ ;; Compute local versions of the regexp for cloze deletions, in case
+ ;; the left and right delimiters are redefined locally.
+ (setq-local org-drill-cloze-regexp (org-drill--compute-cloze-regexp))
+ (setq-local org-drill-cloze-keywords (org-drill--compute-cloze-keywords))
(when org-drill-use-visible-cloze-face-p
- (font-lock-add-keywords 'org-mode
- org-drill-cloze-keywords
- nil)))
-
-(add-hook 'org-mode-hook 'org-drill-add-cloze-fontification)
-
-(org-drill-add-cloze-fontification)
+ (add-to-list 'org-font-lock-extra-keywords
+ (first org-drill-cloze-keywords))))
+
+(add-hook 'org-font-lock-set-keywords-hook 'org-drill-add-cloze-fontification)
+
+;; Can't add to org-mode-hook, because local variables won't have been loaded
+;; yet.
+
+;; (defun org-drill-add-cloze-fontification ()
+;; (when (eql major-mode 'org-mode)
+;; ;; Compute local versions of the regexp for cloze deletions, in case
+;; ;; the left and right delimiters are redefined locally.
+;; (setq-local org-drill-cloze-regexp (org-drill--compute-cloze-regexp))
+;; (setq-local org-drill-cloze-keywords (org-drill--compute-cloze-keywords))
+;; (when org-drill-use-visible-cloze-face-p
+;; (font-lock-add-keywords nil ;'org-mode
+;; org-drill-cloze-keywords
+;; nil))))
+
+;; XXX
+;; (add-hook 'hack-local-variables-hook
+;; 'org-drill-add-cloze-fontification)
+;;
+;; (org-drill-add-cloze-fontification)
;;; Synching card collections =================================================
@@ -2530,18 +2767,18 @@ the tag 'imported'."
(save-excursion
(let ((src (current-buffer))
(m nil))
- (flet ((paste-tree-here (&optional level)
- (org-paste-subtree level)
- (org-drill-strip-entry-data)
- (org-toggle-tag "imported" 'on)
- (org-map-drill-entries
- (lambda ()
- (let ((id (org-id-get)))
- (org-drill-strip-entry-data)
- (unless (gethash id *org-drill-dest-id-table*)
- (puthash id (point-marker)
- *org-drill-dest-id-table*))))
- 'tree)))
+ (cl-flet ((paste-tree-here (&optional level)
+ (org-paste-subtree level)
+ (org-drill-strip-entry-data)
+ (org-toggle-tag "imported" 'on)
+ (org-map-drill-entries
+ (lambda ()
+ (let ((id (org-id-get)))
+ (org-drill-strip-entry-data)
+ (unless (gethash id *org-drill-dest-id-table*)
+ (puthash id (point-marker)
+ *org-drill-dest-id-table*))))
+ 'tree)))
(unless path
(setq path (org-get-outline-path)))
(org-copy-subtree)
@@ -2565,7 +2802,9 @@ the tag 'imported'."
(outline-next-heading)
(newline)
(forward-line -1)
- (paste-tree-here (1+ (or (org-current-level) 0))))))))
+ (paste-tree-here (1+ (or (org-current-level) 0)))
+ )))))
+
(defun org-drill-merge-buffers (src &optional dest ignore-new-items-p)
@@ -2658,12 +2897,15 @@ copy them across."
(free-marker m))
*org-drill-dest-id-table*))))
+
+
;;; Card types for learning languages =========================================
;;; Get spell-number.el from:
;;; http://www.emacswiki.org/emacs/spell-number.el
(autoload 'spelln-integer-in-words "spell-number")
+
;;; `conjugate' card type =====================================================
;;; See spanish.org for usage
@@ -2726,15 +2968,15 @@ the name of the tense.")
(defun org-drill-present-verb-conjugation ()
"Present a drill entry whose card type is 'conjugate'."
- (flet ((tense-and-mood-to-string
- (tense mood)
- (cond
- ((and tense mood)
- (format "%s tense, %s mood" tense mood))
- (tense
- (format "%s tense" tense))
- (mood
- (format "%s mood" mood)))))
+ (cl-flet ((tense-and-mood-to-string
+ (tense mood)
+ (cond
+ ((and tense mood)
+ (format "%s tense, %s mood" tense mood))
+ (tense
+ (format "%s tense" tense))
+ (mood
+ (format "%s mood" mood)))))
(destructuring-bind (infinitive inf-hint translation tense mood)
(org-drill-get-verb-conjugation-info)
(org-drill-present-card-using-text
@@ -2915,6 +3157,7 @@ returns its return value."
'face highlight-face))
(spelln-integer-in-language drilled-number language))))))))
+
;; (defun org-drill-show-answer-translate-number (reschedule-fn)
;; (let* ((language (read (org-entry-get (point) "DRILL_LANGUAGE" t)))
;; (highlight-face 'font-lock-warning-face)
diff --git a/contrib/lisp/org-ebib.el b/contrib/lisp/org-ebib.el
new file mode 100644
index 0000000..2136a13
--- a/dev/null
+++ b/contrib/lisp/org-ebib.el
@@ -0,0 +1,47 @@
+;;; org-ebib.el - Support for links to Ebib's entries in Org
+;;
+;; Author: Grégoire Jadi <daimrod@gmail.com>
+;;
+;; 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:
+
+(require 'org)
+
+(org-add-link-type "ebib" 'org-ebib-open)
+
+(add-hook 'org-store-link-functions 'org-ebib-store-link)
+
+(defun org-ebib-open (key)
+ "Open Ebib and jump to KEY."
+ (ebib nil key))
+
+(defun org-ebib-store-link ()
+ "Store a key to an Ebib entry."
+ (when (memq major-mode '(ebib-index-mode ebib-entry-mode))
+ ;; This is an Ebib entry
+ (let* ((key (ebib-cur-entry-key))
+ (link (concat "ebib:" key))
+ (description (ignore-errors (ebib-db-get-field-value 'title key ebib-cur-db))))
+ (org-store-link-props
+ :type "ebib"
+ :link link
+ :description description))))
+
+(provide 'org-ebib)
+
+;;; org-ebib.el ends here
diff --git a/contrib/lisp/org-effectiveness.el b/contrib/lisp/org-effectiveness.el
index a872cb2..0d830ab 100644
--- a/contrib/lisp/org-effectiveness.el
+++ b/contrib/lisp/org-effectiveness.el
@@ -33,6 +33,22 @@
(require 'org)
+(defcustom org-effectiveness-max-todo 50
+ "This variable is useful to advice to the user about
+many TODO pending"
+ :type 'integer
+ :group 'org-effectiveness)
+
+(defun org-effectiveness-advice()
+ "Advicing about a possible excess of TODOS"
+ (interactive)
+ (goto-char (point-min))
+ (if (< org-effectiveness-max-todo (count-matches "* TODO"))
+ (message "An excess of TODOS!")))
+
+;; Check advice starting an org file
+(add-hook 'org-mode-hook 'org-effectiveness-advice)
+
(defun org-effectiveness-count-keyword(keyword)
"Print a message with the number of keyword outline in the current buffer"
(interactive "sKeyword: ")
@@ -111,7 +127,7 @@
(concat "0" (number-to-string m))
(number-to-string m)))
-(defun org-effectiveness-plot(startdate enddate)
+(defun org-effectiveness-plot(startdate enddate &optional save)
(interactive "sGive me the start date: \nsGive me the end date: " startdate enddate)
(setq dates (org-effectiveness-check-dates startdate enddate))
(setq syear (cadr (assoc 'startyear dates)))
@@ -140,7 +156,7 @@
(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
@@ -149,10 +165,20 @@
(setq month (+ 1 month))))
(write-region str nil "/tmp/org-effectiveness"))
;; Create the bar graph
+ (if (eq save t)
+ (setq strplot "/usr/bin/gnuplot -e 'set term png; set output \"/tmp/org-effectiveness.png\"; plot \"/tmp/org-effectiveness\" using 2:xticlabels(1) with histograms' -p")
+ (setq strplot "/usr/bin/gnuplot -e 'plot \"/tmp/org-effectiveness\" using 2:xticlabels(1) with histograms' -p"))
(if (file-exists-p "/usr/bin/gnuplot")
- (call-process "/bin/bash" nil t nil "-c" "/usr/bin/gnuplot -e 'plot \"/tmp/org-effectiveness\" using 2:xticlabels(1) with histograms' -p")
+ (call-process "/bin/bash" nil t nil "-c" strplot)
(message "gnuplot is not installed")))
+(defun org-effectiveness-plot-save(startdate enddate &optional save)
+ (interactive "sGive me the start date: \nsGive me the end date: " startdate enddate)
+ (org-effectiveness-plot startdate enddate t))
+
+;; (defun org-effectiveness-plot(startdate enddate)
+
+
(defun org-effectiveness-ascii-bar(n &optional label)
"Print a bar with the percentage from 0 to 100 printed in ascii"
(interactive "nPercentage: \nsLabel: ")
@@ -180,6 +206,18 @@
(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)
@@ -208,21 +246,53 @@
(defun org-effectiveness-plot-ascii (startdate enddate)
(interactive "sGive me the start date: \nsGive me the end date: " startdate enddate)
(setq dates (org-effectiveness-check-dates startdate enddate))
- (setq syear (cadr (assoc 'startyear dates)))
- (setq smonth (cadr (assoc 'startmonth dates)))
- (setq eyear (cadr (assoc 'endyear dates)))
- (setq emonth (cadr (assoc 'endmonth dates)))
-;; (switch-to-buffer "*org-effectiveness*")
- (let ((month smonth)
- (year syear)
+ (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 ""))
- (while (and (>= eyear year) (>= emonth month))
- (org-effectiveness-ascii-bar (string-to-number (org-effectiveness-in-date (concat (number-to-string year) "-" (org-effectiveness-month-to-string month)) 1)) (format "%s-%s" year month))
- (if (= month 12)
+ (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*")
+ (org-effectiveness-ascii-bar (string-to-number str) (format "%s-%s" year month))
+ (switch-to-buffer buffer)
+ (if (eq month 12)
(progn
(setq year (+ 1 year))
(setq month 1))
- (setq month (+ 1 month))))))
+ (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-elisp-symbol.el b/contrib/lisp/org-elisp-symbol.el
index e0bc284..167731e 100644
--- a/contrib/lisp/org-elisp-symbol.el
+++ b/contrib/lisp/org-elisp-symbol.el
@@ -1,6 +1,6 @@
;;; org-elisp-symbol.el --- Org links to emacs-lisp symbols
;;
-;; Copyright 2007-2013 Free Software Foundation, Inc.
+;; Copyright 2007-2014 Free Software Foundation, Inc.
;;
;; Author: Bastien Guerry
;; Version: 0.2
diff --git a/contrib/lisp/org-eval-light.el b/contrib/lisp/org-eval-light.el
index 34a2e99..872f3a4 100644
--- a/contrib/lisp/org-eval-light.el
+++ b/contrib/lisp/org-eval-light.el
@@ -1,6 +1,6 @@
;;; org-eval-light.el --- Display result of evaluating code in various languages (light)
-;; Copyright (C) 2008-2013 Free Software Foundation, Inc.
+;; Copyright (C) 2008-2014 Free Software Foundation, Inc.
;; Author: Carsten Dominik <carsten at orgmode dot org>,
;; Eric Schulte <schulte dot eric at gmail dot com>
diff --git a/contrib/lisp/org-eval.el b/contrib/lisp/org-eval.el
index 6cd7f78..cb5620c 100644
--- a/contrib/lisp/org-eval.el
+++ b/contrib/lisp/org-eval.el
@@ -1,5 +1,5 @@
;;; org-eval.el --- Display result of evaluating code in various languages
-;; Copyright (C) 2008-2013 Free Software Foundation, Inc.
+;; Copyright (C) 2008-2014 Free Software Foundation, Inc.
;;
;; Author: Carsten Dominik <carsten at orgmode dot org>
;; Keywords: outlines, hypermedia, calendar, wp
diff --git a/contrib/lisp/org-eww.el b/contrib/lisp/org-eww.el
new file mode 100644
index 0000000..26a1e09
--- a/dev/null
+++ b/contrib/lisp/org-eww.el
@@ -0,0 +1,157 @@
+;;; org-eww.el --- Store url and kill from Eww mode for Org
+
+;; Copyright (C) 2014 Free Software Foundation, Inc.
+
+;; Author: Marco Wahl <marcowahlsoft>a<gmailcom>
+;; Keywords: link, eww
+;; Homepage: http://orgmode.org
+;;
+;; 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:
+
+;; When this module is active `org-store-link' (often on key C-c l) in
+;; a eww buffer stores a link to the current url of the eww buffer.
+
+;; In an eww buffer function `org-eww-copy-for-org-mode' kills either
+;; a region or the whole buffer if no region is set and transforms the
+;; text on the fly so that it can be pasted into an org-mode buffer
+;; with hot links.
+
+;; C-c C-x C-w (and also C-c C-x M-w) trigger
+;; `org-eww-copy-for-org-mode'.
+
+;; Hint: A lot of code of this module comes from module org-w3m which
+;; has been written by Andy Steward based on the idea of Richard
+;; Riley. Thanks!
+
+;; Potential: Since the code for w3m and eww is so similar one could
+;; try to refactor.
+
+
+;;; Code:
+(require 'org)
+
+
+;; Store Org-link in eww-mode buffer
+(add-hook 'org-store-link-functions 'org-eww-store-link)
+(defun org-eww-store-link ()
+ "Store a link to the url of a eww buffer."
+ (when (eq major-mode 'eww-mode)
+ (org-store-link-props
+ :type "eww"
+ :link eww-current-url
+ :url (url-view-url t)
+ :description (or eww-current-title eww-current-url))))
+
+
+;; Some auxiliary functions concerning links in eww buffers
+(defun org-eww-goto-next-url-property-change ()
+ "Move cursor to the start of next link if exists. Else no
+move. Return point."
+ (goto-char
+ (or (next-single-property-change (point) 'shr-url)
+ (point))))
+
+(defun org-eww-no-next-link-p ()
+ "Whether there is no next link after the cursor.
+Return t if there is no next link; otherwise, return nil."
+ (save-excursion
+ (and (eq (point) (org-eww-goto-next-url-property-change)) t)))
+
+(defun org-eww-url-below-point ()
+ "Return the url below point if there is an url; otherwise, return nil."
+ (get-text-property (point) 'shr-url))
+
+
+(defun org-eww-copy-for-org-mode ()
+ "Copy current buffer content or active region with `org-mode' style links.
+This will encode `link-title' and `link-location' with
+`org-make-link-string', and insert the transformed test into the kill ring,
+so that it can be yanked into an Org-mode buffer with links working correctly."
+ (interactive)
+ (let* ((regionp (org-region-active-p))
+ (transform-start (point-min))
+ (transform-end (point-max))
+ return-content
+ link-location link-title
+ temp-position out-bound)
+ (when regionp
+ (setq transform-start (region-beginning))
+ (setq transform-end (region-end))
+ ;; Deactivate mark if current mark is activate.
+ (if (fboundp 'deactivate-mark) (deactivate-mark)))
+ (message "Transforming links...")
+ (save-excursion
+ (goto-char transform-start)
+ (while (and (not out-bound) ; still inside region to copy
+ (not (org-eww-no-next-link-p))) ; there is a next link
+ ;; store current point before jump next anchor
+ (setq temp-position (point))
+ ;; move to next anchor when current point is not at anchor
+ (or (org-eww-url-below-point)
+ (org-eww-goto-next-url-property-change))
+ (assert (org-eww-url-below-point) t
+ "program logic error: point must have an url below but it hasn't")
+ (if (<= (point) transform-end) ; if point is inside transform bound
+ (progn
+ ;; get content between two links.
+ (if (> (point) temp-position)
+ (setq return-content (concat return-content
+ (buffer-substring
+ temp-position (point)))))
+ ;; get link location at current point.
+ (setq link-location (org-eww-url-below-point))
+ ;; get link title at current point.
+ (setq link-title
+ (buffer-substring
+ (point)
+ (org-eww-goto-next-url-property-change)))
+ ;; concat `org-mode' style url to `return-content'.
+ (setq return-content (concat return-content
+ (org-make-link-string
+ link-location link-title))))
+ (goto-char temp-position) ; reset point before jump next anchor
+ (setq out-bound t) ; for break out `while' loop
+ ))
+ ;; add the rest until end of the region to be copied
+ (if (< (point) transform-end)
+ (setq return-content
+ (concat return-content
+ (buffer-substring (point) transform-end))))
+ (org-kill-new return-content)
+ (message "Transforming links...done, use C-y to insert text into Org-mode file"))))
+
+
+;; Additional keys for eww-mode
+
+(defun org-eww-extend-eww-keymap ()
+ (define-key eww-mode-map "\C-c\C-x\M-w" 'org-eww-copy-for-org-mode)
+ (define-key eww-mode-map "\C-c\C-x\C-w" 'org-eww-copy-for-org-mode))
+
+(when (and (boundp 'eww-mode-map)
+ (keymapp eww-mode-map)) ; eww is already up.
+ (org-eww-extend-eww-keymap))
+
+(add-hook
+ 'eww-mode-hook
+ (lambda () (org-eww-extend-eww-keymap)))
+
+
+(provide 'org-eww)
+
+;;; org-eww.el ends here
diff --git a/contrib/lisp/org-expiry.el b/contrib/lisp/org-expiry.el
index 363bebe..1506c3b 100644
--- a/contrib/lisp/org-expiry.el
+++ b/contrib/lisp/org-expiry.el
@@ -1,6 +1,6 @@
;;; org-expiry.el --- expiry mechanism for Org entries
;;
-;; Copyright 2007-2013 Free Software Foundation, Inc.
+;; Copyright 2007-2014 Free Software Foundation, Inc.
;;
;; Author: Bastien Guerry
;; Version: 0.2
@@ -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 b9e6a4e..ad0ce71 100644
--- a/contrib/lisp/org-git-link.el
+++ b/contrib/lisp/org-git-link.el
@@ -1,6 +1,6 @@
;;; org-git-link.el --- Provide org links to specific file version
-;; Copyright (C) 2009-2013 Reimar Finken
+;; Copyright (C) 2009-2014 Reimar Finken
;; Author: Reimar Finken <reimar.finken@gmx.de>
;; Keywords: files, calendar, hypermedia
@@ -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 a670cd6..64974eb 100644
--- a/contrib/lisp/org-index.el
+++ b/contrib/lisp/org-index.el
@@ -1,1943 +1,2217 @@
-;;; org-index.el --- A personal index for org and beyond
-
-;; Copyright (C) 2011-2013 Free Software Foundation, Inc.
-
-;; Author: Marc Ihm <org-index@2484.de>
-;; Keywords: outlines, hypermedia, matching
-;; Requires: org
-;; Version: 2.3.2.1
-
-;; This file is not part of GNU Emacs.
-
-;;; License:
-
-;; This program is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 3, or (at your option)
-;; any later version.
-;;
-;; This program is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-;;
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; Purpose:
-;;
-;; Mark and find your favorite org-locations and other points of interest
-;; easily; create and update a lookup table of references and links. When
-;; searching, frequently used entries appear at the the top and entering
-;; some keywords narrows down to matching entries only, so that the
-;; right one can be spotted easily.
-;;
-;; References are essentially small numbers (e.g. "R237" or "-455-"),
-;; which are created by this package; they are well suited to be used
-;; outside org. Links are normal org-mode links.
-;;
-;; Setup:
-;;
-;; - Add these lines to your .emacs:
-;;
-;; (require 'org-index)
-;;
-;; ;; Optionally assign a key. Pick your own.
-;; (global-set-key (kbd "C-+") 'org-index)
-;;
-;; - Invoke `org-index', which will assist you to create your
-;; index table.
-;;
-;; - Do not forget to restart emacs to make these lines effective.
-;;
-;;
-;; Further reading:
-;;
-;; See the documentation of `org-index', which can also be read
-;; by invoking `org-index' and and choosing the help-command.
-;;
-;; For more documentation and working examples, see:
-;;
-;; http://orgmode.org/worg/org-contrib/org-index.html
-;;
-
-;;; Change Log:
-
-;; [2013-10-04 Fr] Version 2.3.2:
-;; - Bugfix: index-table created by assistant is found after
-;; restart of emacs instead of invoking assistent again
-;;
-;; [2013-07-20 Sa] Version 2.3.0:
-;; - Renamed from "org-favtable" to "org-index"
-;; - Added an assistent to set up the index table
-;; - occur is now incremental, searching as you type
-;; - simplified the documentation and help-system
-;; - Saving keystrokes, as "+g237" is now valid input
-;; - Many bugfixes
-;;
-;; [2013-02-28 Th] Version 2.2.0:
-;; - Allowed shortcuts like "h237" for command "head" with argument "237"
-;; - Integrated with org-mark-ring-goto
-;;
-;; [2013-01-25 Fr] Version 2.1.0:
-;; - Added full support for links
-;; - New commands "missing" and "statistics"
-;; - Renamed the package from "org-reftable" to "org-favtable"
-;; - Additional columns are required (e.g. "link"). Error messages will
-;; guide you
-;;
-;; [2012-12-07 Fr] Version 2.0.0:
-;; - The format of the table of favorites has changed ! You need to bring
-;; your existing table into the new format by hand (which however is
-;; easy and explained below)
-;; - Reference table can be sorted after usage count or date of last access
-;; - Ask user explicitly, which command to invoke
-;; - Renamed the package from "org-refer-by-number" to "org-reftable"
-
-;; [2012-09-22 Sa] Version 1.5.0:
-;; - New command "sort" to sort a buffer or region by reference number
-;; - New commands "highlight" and "unhighlight" to mark references
-
-;; [2012-07-13 Fr] Version 1.4.0:
-;; - New command "head" to find a headline with a reference number
-
-;; [2012-04-28 Sa] Version 1.3.0:
-;; - New commands occur and multi-occur
-;; - All commands can now be invoked explicitly
-;; - New documentation
-;; - Many bugfixes
-
-;; [2011-12-10 Sa] Version 1.2.0:
-;; - Fixed a bug, which lead to a loss of newly created reference numbers
-;; - Introduced single and double prefix arguments
-;; - Started this Change Log
-
-;;; Code:
-
-(require 'org-table)
-(require 'cl)
-
-(defvar org-index--preferred-command nil)
-
-(defvar org-index--commands
- '(occur head ref link leave enter goto help + reorder fill sort update highlight unhighlight missing statistics)
- "List of commands known to org-index.")
-
-(defvar org-index--commands-some '(occur head ref link leave enter goto help +))
-
-
-(defvar org-index--columns nil)
-
-(defcustom org-index-id nil
- "Id of the Org-mode node, which contains the index table."
- :group 'org
- :group 'org-index)
-
-
-(defvar org-index--text-to-yank nil)
-(defvar org-index--last-action nil)
-(defvar org-index--ref-regex nil)
-(defvar org-index--ref-format nil)
-(defvar org-index--buffer nil "buffer of index table")
-(defvar org-index--point nil "position at start of headline of index table")
-(defvar org-index--below-hline nil "position of first cell in first line below hline")
-(defvar org-index--point-before nil "point in buffer with index table")
-
-
-(defun org-index (&optional ARG)
- "Mark and find your favorite things and org-locations easily:
-Create and update a lookup table of references and links. Often
-used entries bubble to the top; entering some keywords narrows
-down to matching entries only, so that the right one can be
-spotted easily.
-
-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.3.2 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
-its node will be created, when you first invoke org-index.
-
-Each line in the index table contains:
-
- - A reference
-
- - A link
-
- - A number; counting, how often each reference has been
- used. This number is updated automatically and the table can
- be sorted after it, so that most frequently used references
- appear at the top of the table and can be spotted easily.
-
- - The creation date of the line.
-
- - Date and time of last access. This column can alternatively be
- used to sort the table.
-
- - A column for your own comments, which allows lines to be selected by
- keywords.
-
-The index table is found through the id of the containing
-node; this id is stored within `org-index-id'.
-
-
-The function `org-index' is the only interactive function of this
-package and its sole entry point; it offers several commands to
-create, find and look up these favorites (references and links).
-
-Commands known:
-
- occur: Incremental search, that after each keystroke shows
- matching lines from index table. You may enter a list of words
- seperated by 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.
-
- head: If invoked outside the index table, ask for a
- reference number and search for a heading containing it. If
- invoked within index table dont ask; rather use the reference or
- link from the current line.
-
- ref: Create a new reference, copy any previously selected text.
- If already within index table, fill in ref-column.
-
- link: Create a new line in index table with a link to the
- current node. Do not populate the ref column; this can later
- be populated by calling the \"fill\" command from within the
- index table.
-
- leave: Leave the index table. If the last command has
- been \"ref\", the new reference is copied and ready to yank.
- This \"org-mark-ring-goto\" and can be called several times
- in succession. If you invoke org-index with a prefix argument,
- this command \"leave\" is executed without further questions.
-
- enter: Just enter the node with the index table.
-
- goto: Search for a specific reference within the index table.
-
- help: Show this text.
-
- +: Show all commands including the less frequently used ones
- given below. If \"+\" is followd by enough letters of such a
- command (e.g. \"+fi\"), then this command is invoked
- directly.
-
- reorder: Temporarily reorder the index table, e.g. by
- count, reference or last access.
-
- fill: If either ref or link is missing, fill it.
-
- sort: Sort a set of lines (either the active region or the
- whole buffer) by the references found in each line.
-
- update: For the given reference, update the line in the
- index table.
-
- highlight: Highlight references in region or buffer.
-
- unhighlight: Remove highlights.
-
- missing : Search for missing reference numbers (which do not
- appear in the reference table). If requested, add additional
- lines for them, so that the command \"ref\" is able to reuse
- them.
-
- statistics : Show some statistics (e.g. minimum and maximum
- reference) about index table.
-
-
-
-Two ways to save keystrokes:
-
-When prompting for a command, org-index puts the most likely
-one (e.g. \"occur\" or \"ref\") in front of the list, so that
-you may just type RET.
-
-If this command needs additional input (like e.g. \"occur\"), you
-may supply this input right away, although you are still beeing
-prompted for the command. So, to do an occur for the string
-\"foo\", you can just enter \"foo\" RET, without even typing
-\"occur\".
-
-
-Another way to save keystrokes applies if you want to choose a
-command, that requrires a reference number (and would normally
-prompt for it): In that case you may just enter enough characters
-from your command, so that it appears first in the list of
-matches; then immediately enter the number of the reference you
-are searching for. So the input \"h237\" would execute the
-command \"head\" for reference \"237\" right away.
-
-"
-
- (interactive "P")
-
- (org-index-1 (if (equal ARG '(4)) 'leave nil) )
-)
-
-
-(defun org-index-1 (&optional what search search-is-link)
-"Do the actual worg for org-index; its optional arguments are:
-
- search : string to search for
- what : symbol of the command to invoke
- search-is-link : t, if argument search is actually a link
-
-An example would be:
-
- (org-index \"237\" 'head) ;; find heading with ref 237
-"
- (let (within-node ; True, if we are within node of the index table
- active-window-index ; active window with index table (if any)
- below-cursor ; word below cursor
- active-region ; active region (if any)
- link-id ; link of starting node, if required
- guarded-search ; with guard against additional digits
- search-is-ref ; true, if search is a reference
- commands ; currently active set of selectable commands
- what-adjusted ; True, if we had to adjust what
- what-input ; Input on what question (need not necessary be "what")
- trailing-digits ; any digits, that are are appended to what-input
- reorder-once ; Column to use for single time sorting
- parts ; Parts of a typical reference number (which
- ; need not be a plain number); these are:
- head ; Any header before number (e.g. "R")
- maxref ; Maximum number from reference table (e.g. "153")
- tail ; Tail after number (e.g. "}" or "")
- ref-regex ; Regular expression to match a reference
- has-reuse ; True, if table contains a line for reuse
- numcols ; Number of columns in index table
- kill-new-text ; Text that will be appended to kill ring
- message-text ; Text that will be issued as an explanation,
- ; what we have done
- initial-ref-or-link ; Initial position in index table
- )
-
- ;;
- ;; Examine current buffer and location, before turning to index table
- ;;
-
- (unless (boundp 'org-index-id)
- (setq org-index-id nil)
- (org-index--create-new-index
- t
- (format "No index table has been created yet." org-index-id)))
-
- ;; Bail out, if new index has been created
- (catch 'created-new-index
-
- ;; Get the content of the active region or the word under cursor
- (if (and transient-mark-mode
- mark-active)
- (setq active-region (buffer-substring (region-beginning) (region-end))))
- (setq below-cursor (thing-at-point 'symbol))
-
-
- ;; Find out, if we are within favable or not
- (setq within-node (string= (org-id-get) org-index-id))
-
-
- ;;
- ;; Get decoration of references and highest reference from index table
- ;;
-
-
- ;; Save initial ref or link
- (if (and within-node
- (org-at-table-p))
- (setq initial-ref-or-link
- (or (org-index--get-field 'ref)
- (org-index--get-field 'link))))
-
- ;; Find node
- (let ((marker (org-id-find org-index-id 'marker)) initial)
- (if marker
- (progn
- (setq org-index--buffer (marker-buffer marker)
- org-index--point (marker-position marker))
- (move-marker marker nil))
- (org-index--create-new-index
- t
- (format "Cannot find node with id \"%s\"" org-index-id))))
-
- ;; Check and remember, if active window contains buffer with index table
- (if (eq (window-buffer) org-index--buffer)
- (setq active-window-index (selected-window)))
-
- ;; Get configuration of index table; catch errors
- (let ((error-message
- (catch 'content-error
-
- (with-current-buffer org-index--buffer
- (unless org-index--point-before
- (setq org-index--point-before (point)))
-
- (unless (string= (org-id-get) org-index-id)
- (goto-char org-index--point))
-
- ;; parse table while still within buffer
- (setq parts (org-index--parse-and-adjust-table))
-
- ;; go back
- (goto-char org-index--point-before)
-
- nil))))
-
- (when error-message
- (org-pop-to-buffer-same-window org-index--buffer)
- (org-reveal)
- (error error-message)))
-
- ;; Give names to parts of configuration
- (setq head (nth 0 parts))
- (setq maxref (nth 1 parts))
- (setq tail (nth 2 parts))
- (setq numcols (nth 3 parts))
- (setq ref-regex (nth 4 parts))
- (setq has-reuse (nth 5 parts))
- (setq org-index--ref-regex ref-regex)
- (setq org-index--ref-format (concat head "%d" tail))
-
- ;;
- ;; Find out, what we are supposed to do
- ;;
-
- ;; Set preferred action, that will be the default choice
- (setq org-index--preferred-command
- (if within-node
- (if (memq org-index--last-action '(ref link))
- 'leave
- 'goto)
- (if active-region
- 'ref
- (if (and below-cursor (string-match ref-regex below-cursor))
- 'occur
- nil))))
-
- ;; Ask user, what to do
- (unless what
- (setq commands (copy-list org-index--commands-some))
- (while (let (completions starts-with-plus is-only-plus)
-
- (setq what-input
- (org-completing-read
- "Please choose: "
- (mapcar 'symbol-name
- ;; Construct unique list of commands with
- ;; preferred one at front
- (delq nil (delete-dups
- (append
- (list org-index--preferred-command)
- (copy-list commands)))))
- nil nil))
-
- ;; if input ends in digits, save them away and do completions on head of input
- ;; this allows input like "h224" to be accepted
- (when (string-match "^\\([^0-9]+\\)\\([0-9]+\\)\\s *$" what-input)
- ;; remember digits
- (setq trailing-digits (string-to-number (match-string 2 what-input)))
- ;; and use non-digits-part to find match
- (setq what-input (match-string 1 what-input)))
-
- ;; if input starts with "+", any command (not only some) may follow
- ;; this allows input like "+sort" to be accepted
- (when (string= (substring what-input 0 1) "+")
- ;; make all commands available for selection
- (setq commands (copy-list org-index--commands))
- (setq what-input (substring what-input 1))
- (setq starts-with-plus (> (length what-input) 0))
- (setq is-only-plus (not starts-with-plus)))
-
- ;; get list of possible completions for what-input; i.e.
- ;; all commands, that start with what-input
- (setq completions (delq nil (mapcar
- (lambda (x)
- (let ((where (search what-input (symbol-name x))))
- (if (and where
- (= where 0))
- x
- nil))) commands)))
-
- ;; if input starts with "+" and not just "+"
- (when starts-with-plus
- ;; use first completion, if unambigously
- (if (= (length completions) 1)
- (setq what-input (symbol-name (car completions)))
- (if completions
- (error "Input \"+%s\" matches multiple commands: %s"
- what-input
- (mapconcat 'symbol-name completions ", "))
- (error "Input \"+%s\" matches no commands" what-input))))
-
- ;; if input ends in digits, use first completion, even if ambigous
- ;; this allows input like "h224" to be accepted
- (when (and trailing-digits completions)
- ;; use first match as input, even if ambigously
- (setq org-index--preferred-command (first completions))
- (setq what-input (number-to-string trailing-digits)))
-
- ;; convert to symbol
- (setq what (intern what-input))
- (if is-only-plus (setq what '+))
-
- ;; user is not required to input one of the commands; if
- ;; not, take the first one and use the original input for
- ;; next question
- (if (memq what commands)
- ;; input matched one element of list, dont need original
- ;; input any more
- (setq what-input nil)
- ;; what-input will be used for next question, use first
- ;; command for what
- (setq what (or org-index--preferred-command
- (first commands)))
- ;; remove any trailing dot, that user might have added to
- ;; disambiguate his input
- (if (and (> (length what-input) 0)
- (equal (substring what-input -1) "."))
- ;; but do this only, if dot was really necessary to
- ;; disambiguate
- (let ((shortened-what-input (substring what-input 0 -1)))
- (unless (test-completion shortened-what-input
- (mapcar 'symbol-name
- commands))
- (setq what-input shortened-what-input)))))
-
- ;; ask for reorder in loop, because we have to ask for
- ;; what right again
- (if (eq what 'reorder)
- (setq reorder-once
- (intern
- (org-icompleting-read
- "Please choose column to reorder index table once: "
- (mapcar 'symbol-name '(ref count last-accessed))
- nil t))))
-
- ;; maybe ask initial question again
- (memq what '(reorder +)))))
-
-
- ;;
- ;; Get search, if required
- ;;
-
- ;; These actions need a search string:
- (when (memq what '(goto occur head update))
-
- ;; Maybe we've got a search string from the arguments
- (unless search
- (let (search-from-table
- search-from-cursor)
-
- ;; Search string can come from several sources:
- ;; From link or ref columns of table
- (when within-node
- (setq search-from-table (org-index--get-field 'link))
- (if search-from-table
- (setq search-is-link t)
- (setq search-from-table (org-index--get-field 'ref))))
-
- ;; From string below cursor
- (when (and (not within-node)
- below-cursor
- (string-match (concat "\\(" ref-regex "\\)")
- below-cursor))
- (setq search-from-cursor (match-string 1 below-cursor)))
-
- ;; Depending on requested action, get search from one of the sources above
- (cond ((eq what 'goto)
- (setq search (or what-input search-from-cursor)))
- ((memq what '(head occur))
- (setq search (or what-input search-from-table search-from-cursor))))))
-
-
- ;; If we still do not have a search string, ask user explicitly
- (unless search
- (unless (eq what 'occur)
-
- (if what-input
- (setq search what-input)
- (setq search (read-from-minibuffer
- (cond ((eq what 'head)
- "Text or reference number to search for: ")
- ((eq what 'goto)
- "Reference number to search for, or enter \".\" for id of current node: ")
- ((eq what 'update)
- "Reference number to update: ")))))
-
- (if (string-match "^\\s *[0-9]+\\s *$" search)
- (setq search (format "%s%s%s" head (org-trim search) tail))))))
-
- ;; Clean up and examine search string
- (when search
- (setq search (org-trim search))
- (if (string= search "") (setq search nil))
- (when search
- (if (string-match "^[0-9]+$" search)
- (setq search (concat head search tail)))
- (setq search-is-ref (string-match ref-regex search))))
-
- ;; Check for special case
- (when (and (memq what '(head goto))
- (string= search "."))
- (setq search (org-id-get))
- (setq search-is-link t))
-
- (when search-is-ref
- (setq guarded-search (org-index--make-guarded-search search)))
-
- ;;
- ;; Do some sanity checking before really starting
- ;;
-
- ;; Correct requested action, if nothing to search
- (when (and (not search)
- (memq what '(search head)))
- (setq what 'enter)
- (setq what-adjusted t))
-
- ;; For a proper reference as input, we do multi-occur
- (if (and search
- (string-match ref-regex search)
- (eq what 'occur))
- (setq what 'multi-occur))
-
- ;; Check for invalid combinations of arguments; try to be helpful
- (when (and (memq what '(head goto))
- (not search-is-link)
- (not search-is-ref))
- (error "Can do '%s' only for a reference or link (not '%s'), try 'occur' to search for text" what search))
-
-
- ;;
- ;; Prepare
- ;;
-
- ;; Get link if required before moving in
- (if (eq what 'link)
- (let ((org-id-link-to-org-use-id t))
- (setq link-id (org-id-get-create))))
-
- ;; Move into table, if outside
-
- ;; These commands enter index table only temporarily
- (when (memq what '(occur multi-occur statistics))
-
- ;; Switch to index table
- (set-buffer org-index--buffer)
- (goto-char org-index--point)
-
- ;; sort index table
- (org-index--sort-table reorder-once))
-
- ;; These commands will leave user in index table after they are finished
- (when (memq what '(enter ref link goto missing))
-
- ;; Support orgmode-standard of going back (buffer and position)
- (org-mark-ring-push)
-
- ;; Switch to index table
- (org-pop-to-buffer-same-window org-index--buffer)
- (goto-char org-index--point)
- (show-subtree)
- (org-show-context)
- (setq org-index--point-before nil) ;; dont want to go back
-
- ;; sort index table
- (org-index--sort-table reorder-once))
-
- ;; Goto back to initial ref, because reformatting of table above might
- ;; have moved point
- (when initial-ref-or-link
- (while (and (org-at-table-p)
- (not (or
- (string= initial-ref-or-link (org-index--get-field 'ref))
- (string= initial-ref-or-link (org-index--get-field 'link)))))
- (forward-line))
- ;; did not find ref, go back to top
- (if (not (org-at-table-p)) (goto-char org-index--point)))
-
-
- ;;
- ;; Actually do, what is requested
- ;;
-
- (cond
-
-
- ((eq what 'help)
-
- ;; bring up help-buffer for this function
- (describe-function 'org-index))
-
-
- ((eq what 'multi-occur)
-
- ;; Conveniently position cursor on number to search for
- (goto-char org-index--below-hline)
- (let (found (initial (point)))
- (while (and (not found)
- (forward-line)
- (org-at-table-p))
- (save-excursion
- (setq found (string= search
- (org-index--get-field 'ref)))))
- (if found
- (org-index--update-line nil)
- (goto-char initial)))
-
- ;; Construct list of all org-buffers
- (let (buff org-buffers)
- (dolist (buff (buffer-list))
- (set-buffer buff)
- (if (string= major-mode "org-mode")
- (setq org-buffers (cons buff org-buffers))))
-
- ;; Do multi-occur
- (multi-occur org-buffers guarded-search)
- (if (get-buffer "*Occur*")
- (progn
- (setq message-text (format "multi-occur for '%s'" search))
- (other-window 1)
- (toggle-truncate-lines 1))
- (setq message-text (format "Did not find '%s'" search)))))
-
-
- ((eq what 'head)
-
- (let (link)
- ;; link either from table or passed in as argument
-
- ;; try to get link
- (if search-is-link
- (setq link (org-trim search))
- (if (and within-node
- (org-at-table-p))
- (setq link (org-index--get-field 'link))))
-
- ;; use link if available
- (if (and link
- (not (string= link "")))
- (progn
- (org-index--update-line search)
- (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' ..." search))
- (org-index--update-line search)
- (let (buffer point)
- (if (catch 'found
- (progn
- ;; loop over all headlines, stop on first match
- (org-map-entries
- (lambda ()
- (when (looking-at (concat ".*" guarded-search))
- ;; If this is not an inlinetask ...
- (when (< (org-element-property :level (org-element-at-point))
- org-inlinetask-min-level)
- ;; ... remember location and bail out
- (setq buffer (current-buffer))
- (setq point (point))
- (throw 'found t))))
- nil 'agenda)
- nil))
-
- (progn
- (if (eq buffer org-index--buffer)
- (setq org-index--point-before nil))
- (setq message-text (format "Found '%s'" search))
- (org-pop-to-buffer-same-window buffer)
- (goto-char point)
- (org-reveal))
- (setq message-text (format "Did not find '%s'" search)))))))
-
-
- ((eq what 'leave)
-
- (setq kill-new-text org-index--text-to-yank)
- (setq org-index--text-to-yank nil)
-
- ;; If "leave" has been called two times in succession, make
- ;; org-mark-ring-goto believe it has been called two times too
- (if (eq org-index--last-action 'leave)
- (let ((this-command nil) (last-command nil))
- (org-mark-ring-goto 1))
- (org-mark-ring-goto)))
-
-
- ((eq what 'goto)
-
- ;; Go downward in table to requested reference
- (let (found (initial (point)))
- (goto-char org-index--below-hline)
- (while (and (not found)
- (forward-line)
- (org-at-table-p))
- (save-excursion
- (setq found
- (string= search
- (org-index--get-field
- (if search-is-link 'link 'ref))))))
- (if found
- (progn
- (setq message-text (format "Found '%s'" search))
- (org-index--update-line nil)
- (org-table-goto-column (org-index--column-num 'ref))
- (if (looking-back " ") (backward-char))
- ;; remember string to copy
- (setq org-index--text-to-yank
- (org-trim (org-table-get-field (org-index--column-num 'copy)))))
- (setq message-text (format "Did not find '%s'" search))
- (goto-char initial)
- (forward-line)
- (setq what 'missed))))
-
-
- ((eq what 'occur)
-
- (org-index--do-occur what-input))
-
-
- ((memq what '(ref link))
-
- ;; add a new row (or reuse existing one)
- (let (new)
-
- (when (eq what 'ref)
- ;; go through table to find first entry to be reused
- (when has-reuse
- (goto-char org-index--below-hline)
- ;; go through table
- (while (and (org-at-table-p)
- (not new))
- (when (string=
- (org-index--get-field 'count)
- ":reuse:")
- (setq new (org-index--get-field 'ref))
- (if new (org-table-kill-row)))
- (forward-line)))
-
- ;; no ref to reuse; construct new reference
- (unless new
- (setq new (format "%s%d%s" head (1+ maxref) tail)))
-
- ;; remember for org-mark-ring-goto
- (setq org-index--text-to-yank new))
-
- ;; insert ref or link as very first row
- (goto-char org-index--below-hline)
- (org-table-insert-row)
-
- ;; fill special columns with standard values
- (when (eq what 'ref)
- (org-table-goto-column (org-index--column-num 'ref))
- (insert new))
- (when (eq what 'link)
- (org-table-goto-column (org-index--column-num 'link))
- (insert link-id))
- (org-table-goto-column (org-index--column-num 'created))
- (org-insert-time-stamp nil nil t)
- (org-table-goto-column (org-index--column-num 'count))
- (insert "1")
-
- ;; goto copy-field or first empty one
- (if (org-index--column-num 'copy)
- (org-table-goto-column (org-index--column-num 'copy))
- (unless (catch 'empty
- (dotimes (col numcols)
- (org-table-goto-column (+ col 1))
- (if (string= (org-trim (org-table-get-field)) "")
- (throw 'empty t))))
- ;; none found, goto first
- (org-table-goto-column 1)))
-
- (org-table-align)
- (if active-region (setq kill-new-text active-region))
- (if (eq what 'ref)
- (setq message-text (format "Adding a new row with ref '%s'" new))
- (setq message-text (format "Adding a new row linked to '%s'" link-id)))))
-
-
- ((eq what 'enter)
-
- ;; simply go into table
- (goto-char org-index--below-hline)
- (show-subtree)
- (recenter)
- (if what-adjusted
- (setq message-text "Nothing to search for; at index table")
- (setq message-text "At index table")))
-
-
- ((eq what 'fill)
-
- ;; check, if within index table
- (unless (and within-node
- (org-at-table-p))
- (error "Not within index table"))
-
- ;; applies to missing refs and missing links alike
- (let ((ref (org-index--get-field 'ref))
- (link (org-index--get-field 'link)))
-
- (if (and (not ref)
- (not link))
- ;; have already checked this during parse, check here anyway
- (error "Columns ref and link are both empty in this line"))
-
- ;; fill in new ref
- (if (not ref)
- (progn
- (setq kill-new-text (format "%s%d%s" head (1+ maxref) tail))
- (org-index--get-field 'ref kill-new-text)
- ;; remember for org-mark-ring-goto
- (setq org-index--text-to-yank kill-new-text)
- (org-id-goto link)
- (setq message-text "Filled field of index table with new reference"))
-
- ;; fill in new link
- (if (not link)
- (progn
- (setq guarded-search (org-index--make-guarded-search ref))
- (message (format "Scanning headlines for '%s' ..." ref))
- (let (link)
- (if (catch 'found
- (org-map-entries
- (lambda ()
- (when (looking-at (concat ".*" guarded-search))
- (setq link (org-id-get-create))
- (throw 'found t)))
- nil 'agenda)
- nil)
-
- (progn
- (org-index--get-field 'link link)
- (setq message-text "Inserted link"))
-
- (setq message-text (format "Did not find reference '%s'" ref)))))
-
- ;; nothing is missing
- (setq message-text "Columns 'ref' and 'link' are already filled; nothing to do")))))
-
-
- ((eq what 'sort)
-
- ;; sort lines according to contained reference
- (let (begin end where)
- (catch 'aborted
- ;; either active region or whole buffer
- (if (and transient-mark-mode
- mark-active)
- ;; sort only region
- (progn
- (setq begin (region-beginning))
- (setq end (region-end))
- (setq where "region"))
- ;; sort whole buffer
- (setq begin (point-min))
- (setq end (point-max))
- (setq where "whole buffer")
- ;; make sure
- (unless (y-or-n-p "Sort whole buffer ")
- (setq message-text "Sort aborted")
- (throw 'aborted nil)))
-
- (save-excursion
- (save-restriction
- (goto-char (point-min))
- (narrow-to-region begin end)
- (sort-subr nil 'forward-line 'end-of-line
- (lambda ()
- (if (looking-at (concat ".*"
- (org-index--make-guarded-search ref-regex 'dont-quote)))
- (string-to-number (match-string 1))
- 0))))
- (highlight-regexp ref-regex 'isearch)
- (setq message-text (format "Sorted %s from character %d to %d, %d lines"
- where begin end
- (count-lines begin end)))))))
-
-
- ((eq what 'update)
-
- ;; simply update line in index table
- (save-excursion
- (let ((ref-or-link (if search-is-link "link" "reference")))
- (beginning-of-line)
- (if (org-index--update-line search)
- (setq message-text (format "Updated %s '%s'" ref-or-link search))
- (setq message-text (format "Did not find %s '%s'" ref-or-link search))))))
-
-
- ((eq what 'parse)
- ;; Just parse the index table, which is already done, so nothing to do
- )
-
-
- ((memq what '(highlight unhighlight))
-
- (let ((where "buffer"))
- (save-excursion
- (save-restriction
- (when (and transient-mark-mode
- mark-active)
- (narrow-to-region (region-beginning) (region-end))
- (setq where "region"))
-
- (if (eq what 'highlight)
- (progn
- (highlight-regexp ref-regex 'isearch)
- (setq message-text (format "Highlighted references in %s" where)))
- (unhighlight-regexp ref-regex)
- (setq message-text (format "Removed highlights for references in %s" where)))))))
-
-
- ((memq what '(missing statistics))
-
- (goto-char org-index--below-hline)
- (let (missing
- ref-field
- ref
- min
- max
- (total 0))
-
- ;; start with list of all references
- (setq missing (mapcar (lambda (x) (format "%s%d%s" head x tail))
- (number-sequence 1 maxref)))
-
- ;; go through table and remove all refs, that we see
- (while (and (forward-line)
- (org-at-table-p))
-
- ;; get ref-field and number
- (setq ref-field (org-index--get-field 'ref))
- (if (and ref-field
- (string-match ref-regex ref-field))
- (setq ref (string-to-number (match-string 1 ref-field))))
-
- ;; remove existing refs from list
- (if ref-field (setq missing (delete ref-field missing)))
-
- ;; record min and max
- (if (or (not min) (< ref min)) (setq min ref))
- (if (or (not max) (> ref max)) (setq max ref))
-
- ;; count
- (setq total (1+ total)))
-
- ;; insert them, if requested
- (forward-line -1)
- (if (eq what 'statistics)
-
- (setq message-text (format "Found %d references from %s to %s. %d references below highest do not appear in table. "
- total
- (format org-index--ref-format min)
- (format org-index--ref-format max)
- (length missing)))
-
- (if (y-or-n-p (format "Found %d missing references; do you wish to append them to the index table"
- (length missing)))
- (let (type)
- (setq type (org-icompleting-read
- "Insert new lines for reuse by command \"new\" or just as missing ? " '("reuse" "missing")))
- (mapc (lambda (x)
- (let (org-table-may-need-update) (org-table-insert-row t))
- (org-index--get-field 'ref x)
- (org-index--get-field 'count (format ":%s:" type)))
- missing)
- (org-table-align)
- (setq message-text (format "Inserted %d new lines for missing refernces" (length missing))))
- (setq message-text (format "%d missing references." (length missing)))))))
-
-
- (t (error "This is a bug: unmatched case '%s'" what)))
-
-
- ;; restore point in buffer or window with index table
- (if org-index--point-before
- ;; buffer displayed in window need to set point there first
- (if (eq (window-buffer active-window-index)
- org-index--buffer)
- (set-window-point active-window-index org-index--point-before)
- ;; 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))))
-
-
- ;; remember what we have done for next time
- (setq org-index--last-action what)
-
- ;; tell, what we have done and what can be yanked
- (if kill-new-text (setq kill-new-text
- (substring-no-properties kill-new-text)))
- (if (string= kill-new-text "") (setq kill-new-text nil))
- (let ((m (concat
- message-text
- (if (and message-text kill-new-text)
- " and r"
- (if kill-new-text "R" ""))
- (if kill-new-text (format "eady to yank '%s'" kill-new-text) ""))))
- (unless (string= m "") (message m)))
- (if kill-new-text (kill-new kill-new-text)))))
-
-
-
-(defun org-index--parse-and-adjust-table ()
-
- (let ((maxref 0)
- top
- bottom
- ref-field
- link-field
- parts
- numcols
- head
- tail
- ref-regex
- has-reuse
- initial-point)
-
- (setq initial-point (point))
- (org-index--go-below-hline)
- (setq org-index--below-hline (point))
- (setq top (point))
-
- ;; count columns
- (org-table-goto-column 100)
- (setq numcols (- (org-table-current-column) 1))
-
- ;; get contents of columns
- (forward-line -2)
- (unless (org-at-table-p)
- (org-index--create-new-index
- nil
- "Index table starts with a hline"))
-
- ;; check for optional line consisting solely of width specifications
- (beginning-of-line)
- (if (looking-at "\\s *|\\(\\(\\s *|\\)\\|\\(\\s *<[0-9]+>\\s *|\\)\\)+\\s *$")
- (forward-line -1))
- (org-table-goto-column 1)
-
- (setq org-index--columns (org-index--parse-headings numcols))
-
- ;; Go beyond end of table
- (while (org-at-table-p) (forward-line 1))
-
- ;; Kill all empty rows at bottom
- (while (progn
- (forward-line -1)
- (org-table-goto-column 1)
- (and
- (not (org-index--get-field 'ref))
- (not (org-index--get-field 'link))))
- (org-table-kill-row))
- (forward-line)
- (setq bottom (point))
- (forward-line -1)
-
- ;; Retrieve any decorations around the number within the first nonempty ref-field
- (goto-char top)
- (while (and (org-at-table-p)
- (not (setq ref-field (org-index--get-field 'ref))))
- (forward-line))
-
- ;; Some Checking
- (unless ref-field
- (org-index--create-new-index
- nil
- "Reference column is empty"))
-
- (unless (string-match "^\\([^0-9]*\\)\\([0-9]+\\)\\([^0-9]*\\)$" ref-field)
- (org-index--create-new-index
- nil
- (format "First reference in index table ('%s') does not contain a number" ref-field)))
-
-
- ;; These are the decorations used within the first ref of index
- (setq head (match-string 1 ref-field))
- (setq tail (match-string 3 ref-field))
- (setq ref-regex (concat (regexp-quote head)
- "\\([0-9]+\\)"
- (regexp-quote tail)))
-
- ;; Go through table to find maximum number and do some checking
- (let ((ref 0))
-
- (while (org-at-table-p)
-
- (setq ref-field (org-index--get-field 'ref))
- (setq link-field (org-index--get-field 'link))
-
- (if (and (not ref-field)
- (not link-field))
- (throw 'content-error "Columns ref and link are both empty in this line"))
-
- (if ref-field
- (if (string-match ref-regex ref-field)
- ;; grab number
- (setq ref (string-to-number (match-string 1 ref-field)))
- (throw 'content-error "Column ref does not contain a number")))
-
- ;; check, if higher ref
- (if (> ref maxref) (setq maxref ref))
-
- ;; check if ref is ment for reuse
- (if (string= (org-index--get-field 'count) ":reuse:")
- (setq has-reuse 1))
-
- (forward-line 1)))
-
- ;; sort used to be here
-
- (setq parts (list head maxref tail numcols ref-regex has-reuse))
-
- ;; go back to top of table
- (goto-char top)
-
- parts))
-
-
-
-(defun org-index--sort-table (sort-column)
-
- (unless sort-column (setq sort-column (org-index--column-num 'sort)))
-
- (let (top
- bottom
- ref-field
- count-field
- count-special)
-
-
- ;; get boundaries of table
- (goto-char org-index--below-hline)
- (forward-line 0)
- (setq top (point))
- (while (org-at-table-p) (forward-line))
- (setq bottom (point))
-
- (save-restriction
- (narrow-to-region top bottom)
- (goto-char top)
- (sort-subr t
- 'forward-line
- 'end-of-line
- (lambda ()
- (let (ref
- (ref-field (or (org-index--get-field 'ref) ""))
- (count-field (or (org-index--get-field 'count) ""))
- (count-special 0))
-
- ;; get reference with leading zeroes, so it can be
- ;; sorted as text
- (string-match org-index--ref-regex ref-field)
- (setq ref (format
- "%06d"
- (string-to-number
- (or (match-string 1 ref-field)
- "0"))))
-
- ;; find out, if special token in count-column
- (setq count-special (format "%d"
- (- 2
- (length (member count-field '(":missing:" ":reuse:"))))))
-
- ;; Construct different sort-keys according to
- ;; requested sort column; prepend count-special to
- ;; sort special entries at bottom of table, append ref
- ;; as a secondary sort key
- (cond
-
- ((eq sort-column 'count)
- (concat count-special
- (format
- "%08d"
- (string-to-number (or (org-index--get-field 'count)
- "")))
- ref))
-
- ((eq sort-column 'last-accessed)
- (concat count-special
- (org-index--get-field 'last-accessed)
- " "
- ref))
-
- ((eq sort-column 'ref)
- (concat count-special
- ref))
-
- (t (error "This is a bug: unmatched case '%s'" sort-column)))))
-
- nil 'string<)))
-
- ;; align table
- (org-table-align))
-
-
-(defun org-index--go-below-hline ()
-
- ;; go to heading of node
- (while (not (org-at-heading-p)) (forward-line -1))
- (forward-line 1)
- ;; go to table within node, but make sure we do not get into another node
- (while (and (not (org-at-heading-p))
- (not (org-at-table-p))
- (not (eq (point) (point-max))))
- (forward-line 1))
-
- ;; check, if there really is a table
- (unless (org-at-table-p)
- (org-index--create-new-index
- t
- (format "Cannot find index table within node %s" org-index-id)))
-
- ;; go to first hline
- (while (and (not (org-at-table-hline-p))
- (org-at-table-p))
- (forward-line 1))
-
- ;; and check
- (unless (org-at-table-hline-p)
- (org-index--create-new-index
- nil
- "Cannot find hline within index table"))
-
- (forward-line 1)
- (org-table-goto-column 1))
-
-
-
-(defun org-index--parse-headings (numcols)
-
- (let (columns)
-
- ;; Associate names of special columns with column-numbers
- (setq columns (copy-tree '((ref . 0) (link . 0) (created . 0) (last-accessed . 0)
- (count . 0) (sort . nil) (copy . nil))))
-
- ;; For each column
- (dotimes (col numcols)
- (let* (field-flags ;; raw heading, consisting of file name and maybe
- ;; flags (seperated by ";")
- field ;; field name only
- field-symbol ;; and as a symbol
- flags ;; flags from field-flags
- found)
-
- ;; parse field-flags into field and flags
- (setq field-flags (org-trim (org-table-get-field (+ col 1))))
- (if (string-match "^\\([^;]*\\);\\([a-z]+\\)$" field-flags)
- (progn
- (setq field (downcase (or (match-string 1 field-flags) "")))
- ;; get flags as list of characters
- (setq flags (mapcar 'string-to-char
- (split-string
- (downcase (match-string 2 field-flags))
- "" t))))
- ;; no flags
- (setq field field-flags))
-
- (unless (string= field "") (setq field-symbol (intern (downcase field))))
-
- ;; Check, that no flags appear twice
- (mapc (lambda (x)
- (when (memq (car x) flags)
- (if (cdr (assoc (cdr x) columns))
- (org-index--create-new-index
- nil
- (format "More than one heading is marked with flag '%c'" (car x))))))
- '((?s . sort)
- (?c . copy)))
-
- ;; Process flags
- (if (memq ?s flags)
- (setcdr (assoc 'sort columns) field-symbol))
- (if (memq ?c flags)
- (setcdr (assoc 'copy columns) (+ col 1)))
-
- ;; Store columns in alist
- (setq found (assoc field-symbol columns))
- (when found
- (if (> (cdr found) 0)
- (org-index--create-new-index
- nil
- (format "'%s' appears two times as column heading" (downcase field))))
- (setcdr found (+ col 1)))))
-
- ;; check if all necessary informations have been specified
- (mapc (lambda (col)
- (unless (> (cdr (assoc col columns)) 0)
- (org-index--create-new-index
- nil
- (format "column '%s' has not been set" col))))
- '(ref link count created last-accessed))
-
- ;; use ref as a default sort-column
- (unless (cdr (assoc 'sort columns))
- (setcdr (assoc 'sort columns) 'ref))
- columns))
-
-
-
-(defun org-index--create-new-index (create-new-index reason)
- "Create a new empty index table with detailed explanation."
- (let (prompt buffer-name title firstref id)
-
- (setq prompt
- (if create-new-index
- (concat "There is this problem with the existing index table:\n\n " reason "\n\nThis assistant will guide you to create a new one.\n\nDo you want to proceed ?")
- (concat "The existing index table contains this error:\n\n " reason "\n\nYou need to correct this error manually before proceeding. However, this assistant will help you to create an new initial index table with detailed comments, so that you may fix the errors in your existing table more easily.\n\nDo you want to proceed ?")))
-
- (unless (y-or-n-p prompt)
- (message "Cannot proceed without a valid index table: %s" reason)
- ;; show existing index
- (when (and org-index--buffer
- org-index--point)
- (org-pop-to-buffer-same-window org-index--buffer)
- (goto-char org-index--point)
- (org-show-context)
- (show-subtree)
- (recenter 1)
- (delete-other-windows))
- (throw 'created-new-index nil))
-
- (setq buffer-name (org-completing-read "Please choose the buffer, where the new node for the index table should be created; the new node will be inserted at its end.\n\nBuffer: " (mapcar 'buffer-name (org-buffer-list)) nil nil))
-
- (setq title (read-from-minibuffer "Please enter the title of the index node: "))
-
- (while (progn
- (setq firstref (read-from-minibuffer "Please enter your first reference-number. This is a number preceeded by some non-digit chars and optionally followed by some more non-digit chars, e.g. 'R1', '-1-' or '#1#' (and your initial number does not need to be '1'). The format of your reference-numbers only needs to make sense for yourself, so that you can spot it easily in your texts or write it on a piece of paper; it should however not already appear to frequently within your existing notes, to avoid too many false hits when searching.\n\nPlease choose: "))
- (if (string-match "^[^0-9]+[0-9]+[^0-9]*$" firstref)
- nil
- (let (desc)
- ;; firstref not okay, report details
- (setq desc
- (cond ((string= firstref "") "is empty")
- ((not (string-match "^[^0-9]+" firstref)) "starts with a digit")
- ((not (string-match "^[^0-9]+[0-9]+" firstref)) "does not contain a number")
- ((not (string-match "^[^0-9]+[0-9]+[^0-9]*$" firstref)) "contains more than one sequence of digits")))
- (read-from-minibuffer (format "Your input '%s' does not meet the requirements because it %s. Please hit RET and try again " firstref desc)))
- t)))
-
- (with-current-buffer buffer-name
- (goto-char (point-max))
- (insert (format "\n\n* %s %s\n" firstref title))
- (insert "\n\n Below you find your initial index table, which will grow over time.\n"
- " Following that your may read its detailed explanation, which will help you,\n"
- " to adopt org-index to your needs. This however is optional reading and not\n"
- " required to start using org-index.\n\n")
-
- (setq id (org-id-get-create))
- (insert (format "
-
- | | | | | | comment |
- | ref | link | created | count;s | last-accessed | ;c |
- | | <4> | | | | |
- |-----+------+---------+---------+---------------+---------|
- | %s | %s | %s | | | %s |
-
-"
- firstref
- id
- (with-temp-buffer (org-insert-time-stamp nil nil t))
- "This node"))
-
-
- (insert "
-
- Detailed explanation:
-
-
- The index table above has three lines of headings above the first
- hline:
-
- - The first one is ignored by org-index, and you can use it to
- give meaningful names to columns. In the table above only one
- column has a name (\"comment\"). This line is optional.
-
- - The second line is the most important one, because it
- contains the configuration information for org-index; please
- read further below for its format.
-
- - The third line is again optional; it may only specify the
- widths of the individual columns (e.g. <4>).
-
- The columns get their meaning by the second line of headings;
- specifically by one of the keywords (e.g. \"ref\") or a flag
- seperated by a semicolon (e.g. \";s\").
-
-
-
- The keywords and flags are:
-
-
- - ref: This contains the reference, which consists of a decorated
- number, which is incremented for each new line. References are
- meant to be used in org-mode headlines or outside of org´,
- e.g. within folder names.
-
- - link: org-mode link pointing to the matching location within org.
-
- - created: When has this line been created ?
-
- - count: How many times has this line accessed ? The trailing
- flag \"s\" makes the table beeing sorted after
- this column, so that often used entries appear at the top of
- the table.
-
- - last-accessed: When has this line ben accessed
-
- - The last column above has no keyword, only the flag \"c\",
- which makes its content beeing copied under certain
- conditions. It is typically used for comments.
-
- The sequence of columns does not matter. You may reorder them any
- way you like. Columns are found by their name, which appears in
- the second line of headings.
-
- 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.
-
-")
-
-
- (while (not (org-at-table-p)) (forward-line -1))
- (org-table-align)
- (while (not (org-at-heading-p)) (forward-line -1))
-
- ;; present results to user
- (if (and (not create-new-index)
- org-index--buffer
- org-index--point)
-
- ;; we had an error with the existing table, so present old and new one
- (progn
- ;; show existing index
- (org-pop-to-buffer-same-window org-index--buffer)
- (goto-char org-index--point)
- (org-show-context)
- (show-subtree)
- (recenter 1)
- (delete-other-windows)
- ;; show new index
- (select-window (split-window-vertically))
- (org-pop-to-buffer-same-window buffer-name)
- (org-id-goto id)
- (org-show-context)
- (show-subtree)
- (recenter 1)
- (message "Please compare your existing index (upper window) and a temporary new one (lower window) to correct the previous error (\"%s\"); the explanations following the new index table should help." reason))
-
- ;; Only show the new index
- (org-pop-to-buffer-same-window buffer-name)
- (delete-other-windows)
- (org-id-goto id)
- (org-show-context)
- (show-subtree)
- (recenter 1)
- (setq org-index-id id)
- (if (y-or-n-p "This is your new index table; Do you want to save its id to make it permanent ? ")
- (progn
- (customize-save-variable 'org-index-id id)
- (message "Saved org-index-id '%s' to %s" org-index-id custom-file))
- (let (sq)
- (setq sq (format "(setq org-index-id \"%s\")" org-index-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)))))
- ;; cannot handle this situation in higher code, but do not want to finish with an error
- (throw 'created-new-index nil)))
-
-
-
-
-(defun org-index--update-line (ref-or-link)
-
- (let (initial
- found
- count-field)
-
- (with-current-buffer org-index--buffer
-
- ;; search reference or link, if given (or assume, that we are already positioned right)
- (when ref-or-link
- (setq initial (point))
- (goto-char org-index--below-hline)
- (while (and (org-at-table-p)
- (not (or (string= ref-or-link (org-index--get-field 'ref))
- (string= ref-or-link (org-index--get-field 'link)))))
- (forward-line)))
-
- (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-accessed))
- (org-table-blank-field)
- (org-insert-time-stamp nil t t)
-
- (setq found t))
-
- (if initial (goto-char initial))
-
- found)))
-
-
-
-(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))
-
- field))
-
-
-(defun org-index--column-num (key)
- (cdr (assoc key org-index--columns)))
-
-
-(defun org-index--make-guarded-search (ref &optional dont-quote)
- (concat "\\b" (if dont-quote ref (regexp-quote ref)) "\\b"))
-
-
-(defun org-index-get-ref-regex-format ()
- "return cons-cell with regular expression and format for references"
- (unless org-index--ref-regex
- (org-index-1 'parse))
- (cons (org-index--make-guarded-search org-index--ref-regex 'dont-quote) org-index--ref-format))
-
-
-(defun org-index--do-occur (initial-search)
- (let (
- (occur-buffer-name "*org-index-occur*")
- (word "") ; last word to search for growing and shrinking on keystrokes
- (prompt "Search for: ")
- 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
- left-off-at ; stack of last positions in index table
- after-inserted ; in occur-buffer
- lines-visible ; in occur-buffer
- below-hline-bol ; below-hline and at bol
- exit-gracefully ; true if normal exit
- in-c-backspace ; true while processing C-backspace
- ret from to key)
-
- ;; clear buffer
- (if (get-buffer "*org-index-occur*")
- (kill-buffer occur-buffer-name))
- (setq occur-buffer (get-buffer-create "*org-index-occur*"))
-
- (with-current-buffer org-index--buffer
- (let ((initial (point)))
- (goto-char org-index--below-hline)
- (forward-line 0)
- (setq below-hline-bol (point))
- (goto-char initial)))
-
- (org-pop-to-buffer-same-window occur-buffer)
- (toggle-truncate-lines 1)
-
- (unwind-protect ; to reset cursor-shape even in case of errors
- (progn
-
- ;; fill in header
- (erase-buffer)
- (insert (concat "Incremental search, showing one window of matches.\n"
- "Use DEL and C-DEL to erase, cursor keys to move, RET to find heading.\n\n"))
- (setq start-of-lines (point))
- (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))
- (when (car ret)
- (insert (cdr ret))
- (setq left-off-at (cons (car ret) nil))
- (setq after-inserted (cons (point) nil)))
-
- ;; read keys
- (while
- (progn
- (goto-char start-of-lines)
- (setq lines-visible 0)
-
- ;; use initial-search (if present) to simulate keyboard input
- (if (and initial-search
- (> (length initial-search) 0))
- (progn
- (setq key (string-to-char (substring initial-search 0 1)))
- (if (length initial-search)
- (setq initial-search (substring initial-search 1))))
- (if in-c-backspace
- (setq key 'backspace)
- (setq key (read-event
- (format "%s %s"
- prompt
- (mapconcat 'identity (reverse (cons word words)) ","))))
-
- (setq exit-gracefully (memq key (list 'return 'up 'down 'left 'right)))))
-
- (not exit-gracefully))
-
- (cond
-
- ((eq key 'C-backspace)
-
- (setq in-c-backspace t))
-
- ((eq key 'backspace) ; erase last char
-
- (if (= (length word) 0)
-
- ;; nothing more to delete
- (setq in-c-backspace nil)
-
- ;; unhighlight longer match
- (let ((case-fold-search t))
- (unhighlight-regexp (regexp-quote word)))
-
- ;; chars left shorten word
- (setq word (substring word 0 -1))
- (when (= (length word) 0) ; when nothing left, use next word from list
- (setq word (car words))
- (setq words (cdr words))
- (setq in-c-backspace nil))
-
- ;; remove everything, that has been added for char just deleted
- (when (cdr after-inserted)
- (setq after-inserted (cdr after-inserted))
- (goto-char (car after-inserted))
- (delete-region (point) (point-max)))
-
- ;; back up last position in index table too
- (when (cdr left-off-at)
- (setq left-off-at (cdr left-off-at)))
-
- ;; go through buffer and check, if any invisible line should now be shown
- (goto-char start-of-lines)
- (while (< (point) (point-max))
- (if (outline-invisible-p)
- (progn
- (setq from (line-beginning-position)
- to (line-beginning-position 2))
-
- ;; check for matches
- (when (org-index--test-words (cons word words) (buffer-substring from to))
- (when (<= lines-visible lines-to-show) ; show, if more lines required
- (outline-flag-region from to nil)
- (incf lines-visible))))
-
- ;; already visible, just count
- (incf lines-visible))
-
- (forward-line 1))
-
- ;; highlight shorter word
- (unless (= (length word) 0)
- (let ((case-fold-search t))
- (highlight-regexp (regexp-quote word) 'isearch)))))
-
-
- ((eq key ?,) ; comma: enter an additional search word
-
- ;; push current word and clear, no need to change display
- (setq words (cons word words))
- (setq word ""))
-
-
- ((and (characterp key)
- (aref printable-chars key)) ; any other char: add to current search word
-
-
- ;; unhighlight short word
- (unless (= (length word) 0)
- (let ((case-fold-search t))
- (unhighlight-regexp (regexp-quote word))))
-
- ;; add to word
- (setq word (concat word (downcase (string key))))
-
- ;; hide lines, that do not match longer word any more
- (while (< (point) (point-max))
- (unless (outline-invisible-p)
- (setq from (line-beginning-position)
- to (line-beginning-position 2))
-
- ;; check for matches
- (if (org-index--test-words (list word) (buffer-substring from to))
- (incf lines-visible) ; count as visible
- (outline-flag-region from to t))) ; hide
-
- (forward-line 1))
-
- ;; duplicate top of stacks; eventually overwritten below
- (setq left-off-at (cons (car left-off-at) left-off-at))
- (setq after-inserted (cons (car after-inserted) after-inserted))
-
- ;; get new lines from index table
- (when (< lines-visible lines-to-show)
- (setq ret (org-index--get-matching-lines (cons word words)
- (- lines-to-show lines-visible)
- (car left-off-at)))
-
- (when (car ret)
- (insert (cdr ret))
- (setcar left-off-at (car ret))
- (setcar after-inserted (point))))
-
- ;; highlight longer word
- (let ((case-fold-search t))
- (highlight-regexp (regexp-quote word) 'isearch)))))
-
- ;; search is done collect and brush up results
- ;; remove any lines, that are still invisible
- (goto-char start-of-lines)
- (while (< (point) (point-max))
- (if (outline-invisible-p)
- (delete-region (line-beginning-position) (line-beginning-position 2))
- (forward-line 1)))
-
- ;; get all the rest
- (message "Getting all matches ...")
- (setq ret (org-index--get-matching-lines (cons word words) 0 (car left-off-at)))
- (message "done.")
- (insert (cdr ret)))
-
- ;; postprocessing even for non graceful exit
- (setq cursor-type t)
- ;; replace previous heading
- (let ((numlines (count-lines (point) start-of-lines)))
- (goto-char start-of-lines)
- (forward-line -1)
- (delete-region (point-min) (point))
- (insert (format (concat (if exit-gracefully
- "Search is done; showing all %d matches.\n"
- "Search aborted; showing only some matches.\n")
- "Use cursor keys to move, press RET to find heading.\n")
- numlines)))
- (forward-line))
-
- ;; install keyboard-shortcuts within occur-buffer
- (let ((keymap (make-sparse-keymap))
- fun-on-ret)
- (set-keymap-parent keymap text-mode-map)
-
- (setq fun-on-ret (lambda () (interactive)
- (let ((ref (org-index--get-field 'ref))
- (link (org-index--get-field 'link)))
- (org-index-1 'head
- (or link ref) ;; prefer link
- (if link t nil)))))
-
- (define-key keymap (kbd "RET") fun-on-ret)
- (use-local-map keymap)
-
- ;; perform action according to last char
- (cond
- ((eq key 'return)
- (funcall fun-on-ret))
-
- ((eq key 'up)
- (forward-line -1))
-
- ((eq key 'down)
- (forward-line 1))
-
- ((eq key 'left)
- (forward-char -1))
-
- ((eq key 'right)
- (forward-char 1))))))
-
-
-(defun org-index--get-matching-lines (words numlines start-from)
- (let ((numfound 0)
- pos
- initial line lines)
-
- (with-current-buffer org-index--buffer
-
- ;; remember initial pos and start at requested
- (setq initial (point))
- (goto-char start-from)
-
- ;; loop over buffer until we have found enough lines
- (while (and (or (< numfound numlines)
- (= numlines 0))
- (org-at-table-p))
-
- ;; check each word
- (setq line (buffer-substring (line-beginning-position) (line-beginning-position 2)))
- (when (org-index--test-words words line)
- (setq lines (concat lines line))
- (incf numfound))
- (forward-line 1)
- (setq pos (point)))
-
- ;; return to initial position
- (goto-char initial))
-
- (unless lines (setq lines ""))
- (cons pos lines)))
-
-
-(defun org-index--test-words (words line)
- (let ((found-all t))
- (setq line (downcase line))
- (catch 'not-found
- (dolist (w words)
- (or (search w line)
- (throw 'not-found nil)))
- t)))
-
-
-(defadvice org-mark-ring-goto (after org-index--advice-text-to-yank activate)
- "Make text from org-index available for yank."
- (when org-index--text-to-yank
- (kill-new org-index--text-to-yank)
- (message (format "Ready to yank '%s'" org-index--text-to-yank))
- (setq org-index--text-to-yank nil)))
-
-
-(provide 'org-index)
-
-;; Local Variables:
-;; fill-column: 75
-;; comment-column: 50
-;; End:
-
-;;; org-index.el ends here
+;;; org-index.el --- A personal index for org and beyond
+
+;; Copyright (C) 2011-2014 Free Software Foundation, Inc.
+
+;; Author: Marc Ihm <org-index@2484.de>
+;; Keywords: outlines, hypermedia, matching
+;; Requires: org
+;; Version: 2.4.3
+
+;; This file is not part of GNU Emacs.
+
+;;; License:
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 3, or (at your option)
+;; any later version.
+;;
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Purpose:
+;;
+;; Mark and find your favorite org-locations and other points of interest
+;; easily; create and update a lookup table of references and links. When
+;; searching, frequently used entries appear at the the top and entering
+;; some keywords narrows down to matching entries only, so that the
+;; right one can be spotted easily.
+;;
+;; References are essentially small numbers (e.g. "R237" or "-455-"),
+;; which are created by this package; they are well suited to be used
+;; outside org. Links are normal org-mode links.
+;;
+;;
+;; Setup:
+;;
+;; - Add these lines to your .emacs:
+;;
+;; ;; use the real path from your org-installation
+;; (add-to-list 'load-path "~/path/to/orgdir/contrib/lisp" t)
+;; (require 'org-index)
+;;
+;; - Restart your emacs to make these lines effective
+;;
+;; - Invoke `org-index', which will assist in creating your index
+;; table. The variable org-index-id will be persisted within your
+;; customization file (typically .emacs).
+;;
+;;
+;; Further reading:
+;;
+;; See the documentation of `org-index', which can also be read
+;; by invoking `org-index' and and choosing the help-command.
+;;
+;; For more documentation and working examples, see:
+;;
+;; http://orgmode.org/worg/org-contrib/org-index.html
+;;
+;;
+;; Updates:
+;;
+;; The latest tested version of this file can always be found at:
+;;
+;; http://orgmode.org/w/org-mode.git?p=org-mode.git;a=blob_plain;f=contrib/lisp/org-index.el;hb=HEAD
+
+;;; 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
+;;
+;; [2014-01-02 Th] Version 2.4.0:
+;; - New command "put" to store a nodes reference in a property
+;; - New functions org-index-new-line and org-index-get-line
+;; offer access to org-index from other lisp programs
+;; - New flag p, new columns x1,x2 and x3
+;; - Major Code refactoring
+;; - Regression tests with ert
+;; - Lots of bugfixes
+;;
+;; [2013-10-04 Fr] Version 2.3.2:
+;; - Bugfix: index-table created by assistant is found after
+;; restart of emacs instead of invoking assistent again
+;;
+;; [2013-07-20 Sa] Version 2.3.0:
+;; - Renamed from "org-favtable" to "org-index"
+;; - Added an assistent to set up the index table
+;; - occur is now incremental, searching as you type
+;; - simplified the documentation and help-system
+;; - Saving keystrokes, as "+g237" is now valid input
+;; - Many bugfixes
+;;
+;; [2013-02-28 Th] Version 2.2.0:
+;; - Allowed shortcuts like "h237" for command "head" with argument "237"
+;; - Integrated with org-mark-ring-goto
+;;
+;; [2013-01-25 Fr] Version 2.1.0:
+;; - Added full support for links
+;; - New commands "missing" and "statistics"
+;; - Renamed the package from "org-reftable" to "org-favtable"
+;; - Additional columns are required (e.g. "link"). Error messages will
+;; guide you
+;;
+;; [2012-12-07 Fr] Version 2.0.0:
+;; - The format of the table of favorites has changed ! You need to bring
+;; your existing table into the new format by hand (which however is
+;; easy and explained below)
+;; - Reference table can be sorted after usage count or date of last access
+;; - Ask user explicitly, which command to invoke
+;; - Renamed the package from "org-refer-by-number" to "org-reftable"
+;;
+;; [2012-09-22 Sa] Version 1.5.0:
+;; - New command "sort" to sort a buffer or region by reference number
+;; - New commands "highlight" and "unhighlight" to mark references
+;;
+;; [2012-07-13 Fr] Version 1.4.0:
+;; - New command "head" to find a headline with a reference number
+;;
+;; [2012-04-28 Sa] Version 1.3.0:
+;; - New commands occur and multi-occur
+;; - All commands can now be invoked explicitly
+;; - New documentation
+;; - Many bugfixes
+;;
+;; [2011-12-10 Sa] Version 1.2.0:
+;; - Fixed a bug, which lead to a loss of newly created reference numbers
+;; - Introduced single and double prefix arguments
+;; - Started this Change Log
+
+;;; Code:
+
+(require 'org-table)
+(require 'cl)
+
+(defcustom org-index-id nil
+ "Id of the Org-mode node, which contains the index table."
+ :group 'org
+ :group 'org-index)
+
+;; Variables to hold the configuration of the index table
+(defvar org-index--maxref) ; Maximum number from reference table (e.g. "153")
+(defvar org-index--head) ; Any header before number (e.g. "R")
+(defvar org-index--tail) ; Tail after number (e.g. "}" or "")
+(defvar org-index--numcols) ; Number of columns in index table
+(defvar org-index--ref-regex) ; Regular expression to match a reference
+(defvar org-index--has-reuse nil) ; True, if table contains a line for reuse
+(defvar org-index--ref-format) ; Format, that can print a reference
+(defvar org-index--columns nil) ; Columns of index-table
+(defvar org-index--special-columns nil) ; Columns with flags
+(defvar org-index--buffer) ; Buffer of index table
+(defvar org-index--point) ; Position at start of headline of index table
+(defvar org-index--below-hline) ; Position of first cell in first line below hline
+(defvar org-index--headings) ; Headlines of index-table as a string
+
+;; Variables to hold context and state
+(defvar org-index--last-action nil) ; Last action performed by org-index
+(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
+(defvar org-index--below-cursor) ; Word below cursor
+(defvar org-index--within-node) ; True, if we are within node of the index table
+(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 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:
+Create and update a lookup table of references and links. Often
+used entries bubble to the top; entering some keywords narrows
+down to matching entries only, so that the right one can be
+spotted easily.
+
+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.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
+its node will be created, when you first invoke org-index.
+
+Each line in the index table contains:
+
+ - A reference (e.g. \"R237\")
+
+ - An optional link to another location in org
+
+ - A number, counting, how often each reference has been
+ used. This number is updated automatically and the table can
+ be sorted after it, so that most frequently used references
+ appear at the top of the table and can be spotted easily.
+
+ - The creation date of the line
+
+ - Date and time of last access. This column can alternatively be
+ used to sort the table.
+
+ - A column for your own comments
+
+The index table is found through the id of the containing
+node; this id is stored within the variable `org-index-id'.
+
+
+The function `org-index' is the only interactive function of this
+package and its main entry point; it offers several commands to
+create, find and look up line within the index table.
+
+Commands known:
+
+ occur: Incremental search, that shows matching lines from the
+ index table, updated after every keystroke. You may enter a
+ list of words seperated by space or comma (\",\"), to select
+ lines that contain all of the given words.
+
+ You may also read the note at the end of this help on saving
+ the keystroke RET with this frequent default command.
+
+ head: If invoked outside the index table, ask for a reference
+ number and search for an entry, which either has this
+ reference contained in its heading or within its property
+ org-index-ref. If invoked from within the index table dont
+ ask; rather use the reference or link from the current line.
+
+ ref: Create a new reference, copy any previously selected text.
+ If already within index table, fill in ref-column.
+
+ link: Create a new line in index table with a link to the
+ current node. Do not populate the ref column; this can later
+ be populated by calling the \"fill\" command from within the
+ index table.
+
+ leave: Leave the index table. If the last command has been
+ \"ref\", the new reference is copied and ready to yank. This
+ \"org-mark-ring-goto\" and can be called several times in
+ succession. If you invoke org-index with a prefix argument,
+ this command \"leave\" is executed without further questions.
+
+ put: Put the reference, that was created last, as the value of
+ property org-index-ref into the current node. That way it can
+ be found by a later call to \"head\".
+
+ enter: Just enter the node with the index table.
+
+ goto: Enter index table and go to a specific reference.
+
+ help: Show this text.
+
+ +: Show all commands including the less frequently used ones
+ given below. If \"+\" is followd by enough letters of such a
+ command (e.g. \"+fi\"), then this command (e.g. \"fill\") is
+ invoked directly.
+
+ reorder: Temporarily reorder the index table, e.g. by count,
+ reference or last access.
+
+ fill: If either ref or link is missing in current line of index
+ table, fill in the missing value.
+
+ sort: Sort a set of lines (either from the active region or the
+ whole buffer) by references found in each line.
+
+ 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.
+
+ missing : Search for missing reference numbers (which do not
+ appear in the reference table). If requested, add additional
+ lines for them, so that the command \"ref\" is able to reuse
+ them.
+
+ statistics : Show some statistics (e.g. minimum and maximum
+ reference) about index table.
+
+
+
+Two ways to save keystrokes:
+
+When prompting for a command, org-index puts the most likely
+one (e.g. \"occur\" or \"ref\") in front of the list, so that
+you may just type RET.
+
+If this first command in the list of commands needs additional
+input (like e.g. \"occur\"), you may supply this input right
+away, although you are still beeing prompted for the command. So,
+to do an occur for the string \"foo\", you can just enter \"foo\"
+RET, without even typing \"occur\".
+
+
+Another way to save keystrokes applies if you want to choose a
+command, that requrires a reference number and would normally
+prompt for it: In that case you may just enter enough characters
+from your command, so that it appears first in the list of
+matches; then immediately enter the number of the reference you
+are searching for. So the input \"h237\" would execute the
+command \"head\" for reference \"237\".
+
+"
+
+ (interactive "P")
+
+ (let ((org-index--silent nil) ; t, if user can be asked
+ link-id ; link of starting node, if required
+ what ; what to do
+ search ; what to search for
+ guarded-search ; with guard against additional digits
+ search-ref ; search, if search is a reference
+ search-link ; search, if search is a link
+ what-adjusted ; true, if we had to adjust what
+ what-input ; Input on what question (need not necessary be "what")
+ reorder-once ; column to use for single time sorting
+ kill-new-text ; text that will be appended to kill ring
+ message-text ; text that will be issued as an explanation
+ initial-ref-or-link ; initial position in index table
+ )
+
+
+ ;;
+ ;; Initialize and parse
+ ;;
+
+ ;; creates index table, if necessary
+ (org-index--verify-id)
+
+ ;; store context information
+ (org-index--retrieve-context)
+
+ ;; Get configuration of index table
+ (org-index--parse-table)
+
+
+ ;;
+ ;; Find out, what we are supposed to do
+ ;;
+
+ (if ARG
+ (if (equal ARG '(4))
+ (setq what 'leave)
+ (if (and (symbolp ARG)
+ (memq ARG org-index--commands))
+ (setq what ARG)
+ (error "Unknown command '%s' passed as argument, valid choices are a prefix argument or any of these symbols: %s"
+ ARG (mapconcat 'symbol-name org-index--commands ","))))
+
+ (let ((r (org-index--read-what what))) ; query user if not from argument
+ (setq what (nth 0 r))
+ (setq what-input (nth 1 r))
+ (setq reorder-once (nth 2 r))))
+
+
+ ;;
+ ;; Get search, if required
+ ;;
+
+ ;; These actions need a search string:
+ (when (memq what '(goto occur head update))
+ ;; Maybe we've got a search string from the arguments
+ (setq search (org-index--get-or-read-search search what what-input))
+
+ (when search
+ (when (string-match org-index--ref-regex search)
+ (setq search-ref search)
+ (setq guarded-search (org-index--make-guarded-search search)))
+ (when (string-match "^[a-fA-F0-9]\\{8\\}-[a-fA-F0-9]\\{4\\}-[a-fA-F0-9]\\{4\\}-[a-fA-F0-9]\\{4\\}-[a-fA-F0-9]\\{12\\}$" search)
+ (setq search-link search))))
+
+
+ ;;
+ ;; Do some sanity checking before really starting
+ ;;
+
+ ;; Correct requested action, if nothing to search
+ (when (and (not search)
+ (memq what '(search head)))
+ (setq what 'enter)
+ (setq what-adjusted t))
+
+ ;; Check for invalid combinations of arguments; try to be helpful
+ (when (and (memq what '(head goto))
+ (not search-ref)
+ (not search-link))
+ (error "Can do '%s' only for a reference or link (not '%s'), try 'occur' to search for text" what search))
+
+
+ ;;
+ ;; Sort and enter table
+ ;;
+
+ ;; Get link if required before moving in
+ (if (eq what 'link)
+ (let ((org-id-link-to-org-use-id t))
+ (setq link-id (org-id-get-create))))
+
+ ;; Save initial ref or link for later return
+ (if (and org-index--within-node
+ (org-at-table-p))
+ (setq initial-ref-or-link
+ (or (org-index--get-field :ref)
+ (org-index--get-field :link))))
+
+ ;; These commands enter index table only temporarily
+ (when (memq what '(occur multi-occur statistics))
+
+ (set-buffer org-index--buffer)
+ (goto-char org-index--point)
+
+ ;; Sort and align
+ (org-index--sort reorder-once)
+ (org-index--align))
+
+ ;; These commands will leave user in index table after they are finished
+ (when (memq what '(enter ref link goto missing))
+
+ ;; Support orgmode-standard of going back (buffer and position)
+ (org-mark-ring-push)
+
+ (org-pop-to-buffer-same-window org-index--buffer)
+ (goto-char org-index--point)
+ (show-subtree)
+ (org-show-context)
+
+ ;; Sort and align
+ (org-index--sort reorder-once)
+ (org-index--align)
+
+ ;; Remember position for leave
+ (if org-index--point-before
+ (setq org-index--point-saved org-index--point-before)))
+
+ ;; prepare to return to initial position in index table
+ (when initial-ref-or-link
+ (while (and (org-at-table-p)
+ (not (or
+ (string= initial-ref-or-link (org-index--get-field :ref))
+ (string= initial-ref-or-link (org-index--get-field :link)))))
+ (forward-line))
+ ;; did not find ref, go back to top
+ (if (not (org-at-table-p)) (goto-char org-index--point)))
+
+
+ ;;
+ ;; Actually do, what is requested
+ ;;
+
+ (cond
+
+
+ ((eq what 'help)
+
+ ;; bring up help-buffer for this function
+ (describe-function 'org-index))
+
+
+ ((eq what 'multi-occur)
+
+ ;; Position point in index buffer on reference to search for
+ (goto-char org-index--below-hline)
+ (let (found (initial (point)))
+ (while (and (not found)
+ (forward-line)
+ (org-at-table-p))
+ (save-excursion
+ (setq found (string= search
+ (org-index--get-field :ref)))))
+ (if found
+ (org-index--update-line nil)
+ (goto-char initial)))
+
+ ;; Construct list of all org-buffers
+ (let (buff org-buffers)
+ (dolist (buff (buffer-list))
+ (set-buffer buff)
+ (if (string= major-mode "org-mode")
+ (setq org-buffers (cons buff org-buffers))))
+
+ ;; Do multi-occur
+ (multi-occur org-buffers guarded-search)
+
+ ;; Present results
+ (if (get-buffer "*Occur*")
+ (progn
+ (setq message-text (format "multi-occur for '%s'" search))
+ (other-window 1)
+ (toggle-truncate-lines 1))
+ (setq message-text (format "Did not find '%s'" search)))))
+
+
+ ((eq what 'head)
+
+ (let (link)
+ (if (and org-index--within-node
+ (org-at-table-p))
+ (setq link (org-index--get-field :link))))
+
+ (setq message-text (org-index--do-head search-ref search-link)))
+
+
+ ((eq what 'leave)
+
+ (setq kill-new-text org-index--text-to-yank)
+ (setq org-index--text-to-yank nil)
+
+ ;; If "leave" has been called two times in succession, make
+ ;; org-mark-ring-goto believe it has been called two times too
+ (if (eq org-index--last-action 'leave)
+ (let ((this-command nil) (last-command nil))
+ (org-mark-ring-goto 1))
+ (org-mark-ring-goto))
+
+ ;; Return to saved position in index buffer
+ (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 (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-saved)))
+ (setq org-index--point-saved nil))
+
+
+ ((eq what 'goto)
+
+ ;; Go downward in table to requested reference
+ (let (found (initial (point)))
+ (goto-char org-index--below-hline)
+ (while (and (not found)
+ (forward-line)
+ (org-at-table-p))
+ (save-excursion
+ (setq found
+ (string= search
+ (org-index--get-field
+ (if search-link :link :ref))))))
+ (if found
+ (progn
+ (setq message-text (format "Found '%s'" search))
+ (org-index--update-line nil)
+ (org-table-goto-column (org-index--column-num :ref))
+ (if (looking-back " ") (backward-char))
+ ;; remember string to copy
+ (setq org-index--text-to-yank
+ (org-trim (org-table-get-field (org-index--column-num :copy)))))
+ (setq message-text (format "Did not find '%s'" search))
+ (goto-char initial)
+ (forward-line)
+ (setq what 'missed))))
+
+
+ ((eq what 'occur)
+
+ (org-index--do-occur what-input))
+
+
+ ((memq what '(ref link))
+
+ (let (new)
+
+ ;; add a new row (or reuse existing one)
+ (setq new (org-index--do-new-line (eq what 'ref)))
+
+ ;; fill special columns with standard values
+ (when (eq what 'ref)
+ (org-table-goto-column (org-index--column-num :ref))
+ (insert new)
+ (setq org-index--last-ref new))
+ (when (eq what 'link)
+ (org-table-goto-column (org-index--column-num :link))
+ (insert link-id))
+
+ (org-index--align)
+
+ ;; goto point-field or copy-field or first empty one or first field
+ (if (org-index--special-column :point)
+ (org-table-goto-column (org-index--column-num (org-index--special-column :point)))
+ (if (org-index--special-column :copy)
+ (org-table-goto-column (org-index--column-num (org-index--special-column :copy)))
+ (unless (catch 'empty
+ (dotimes (col org-index--numcols)
+ (org-table-goto-column (+ col 1))
+ (if (string= (org-trim (org-table-get-field)) "")
+ (throw 'empty t))))
+ ;; none found, goto first
+ (org-table-goto-column 1))))
+
+ (if org-index--active-region (setq kill-new-text org-index--active-region))
+ (if (eq what 'ref)
+ (setq message-text (format "Adding a new row with ref '%s'" new))
+ (setq message-text (format "Adding a new row linked to '%s'" link-id)))))
+
+
+ ((eq what 'put)
+
+ ;; put latest reference into property
+
+
+ (if org-index--last-ref
+ (progn
+ (org-entry-put (point) "org-index-ref" org-index--last-ref)
+ (message "Reference '%s' has been stored in property org-index-ref" org-index--last-ref))
+ (setq org-index--last-ref
+ (read-from-minibuffer "Reference to be stored in this node: "))
+ (unless org-index--last-ref
+ (message "No reference has been given."))
+ ))
+
+
+ ((eq what 'enter)
+
+ ;; simply go into table
+ (goto-char org-index--below-hline)
+ (show-subtree)
+ (recenter)
+ (if what-adjusted
+ (setq message-text "Nothing to search for; at index table")
+ (setq message-text "At index table")))
+
+
+ ((eq what 'fill)
+
+ ;; check, if within index table
+ (unless (and org-index--within-node
+ (org-at-table-p))
+ (error "Not within index table"))
+
+ ;; applies to missing refs and missing links alike
+ (let ((ref (org-index--get-field :ref))
+ (link (org-index--get-field :link)))
+
+ (if (and (not ref)
+ (not link))
+ ;; have already checked this during parse, check here anyway
+ (error "Columns ref and link are both empty in this line"))
+
+ ;; fill in new ref
+ (if (not ref)
+ (progn
+ (setq kill-new-text (format "%s%d%s" org-index--head (1+ org-index--maxref) org-index--tail))
+ (org-index--get-field :ref kill-new-text)
+ ;; remember for org-mark-ring-goto
+ (setq org-index--text-to-yank kill-new-text)
+ (org-id-goto link)
+ (setq message-text "Filled field of index table with new reference"))
+
+ ;; fill in new link
+ (if (not link)
+ (progn
+ (setq guarded-search (org-index--make-guarded-search ref))
+ (message (format "Scanning headlines for '%s' ..." ref))
+ (let ((search (concat ".*" guarded-search))
+ link)
+ (if (catch 'found
+ (org-map-entries
+ (lambda ()
+ (when (looking-at search)
+ (setq link (org-id-get-create))
+ (throw 'found t)))
+ nil 'agenda)
+ nil)
+
+ (progn
+ (org-index--get-field :link link)
+ (setq message-text "Inserted link"))
+
+ (setq message-text (format "Did not find reference '%s'" ref)))))
+
+ ;; nothing is missing
+ (setq message-text "Columns ref and link are already filled; nothing to do")))))
+
+
+ ((eq what 'sort)
+
+ ;; sort lines according to contained reference
+ (let (begin end where)
+ (catch 'aborted
+ ;; either active region or whole buffer
+ (if (and transient-mark-mode
+ mark-active)
+ ;; sort only region
+ (progn
+ (setq begin (region-beginning))
+ (setq end (region-end))
+ (setq where "region"))
+ ;; sort whole buffer
+ (setq begin (point-min))
+ (setq end (point-max))
+ (setq where "whole buffer")
+ ;; make sure
+ (unless (y-or-n-p "Sort whole buffer ")
+ (setq message-text "Sort aborted")
+ (throw 'aborted nil)))
+
+ (save-excursion
+ (save-restriction
+ (goto-char (point-min))
+ (narrow-to-region begin end)
+ (sort-subr nil 'forward-line 'end-of-line
+ (lambda ()
+ (if (looking-at (concat ".*"
+ (org-index--make-guarded-search org-index--ref-regex 'dont-quote)))
+ (string-to-number (match-string 1))
+ 0))))
+ (highlight-regexp org-index--ref-regex 'isearch)
+ (setq message-text (format "Sorted %s from character %d to %d, %d lines"
+ where begin end
+ (count-lines begin end)))))))
+
+
+ ((eq what 'update)
+
+ ;; simply update line in index table
+ (save-excursion
+ (let ((ref-or-link (if search-link "link" "reference")))
+ (beginning-of-line)
+ (if (org-index--update-line search)
+ (setq message-text (format "Updated %s '%s'" ref-or-link search))
+ (setq message-text (format "Did not find %s '%s'" ref-or-link search))))))
+
+
+ ((memq what '(highlight unhighlight))
+
+ (let ((where "buffer"))
+ (save-excursion
+ (save-restriction
+ (when (and transient-mark-mode
+ mark-active)
+ (narrow-to-region (region-beginning) (region-end))
+ (setq where "region"))
+
+ (if (eq what 'highlight)
+ (progn
+ (highlight-regexp org-index--ref-regex 'isearch)
+ (setq message-text (format "Highlighted references in %s" where)))
+ (unhighlight-regexp org-index--ref-regex)
+ (setq message-text (format "Removed highlights for references in %s" where)))))))
+
+
+ ((memq what '(missing statistics))
+
+ (setq message-text (org-index--do-statistics what)))
+
+
+ (t (error "This is a bug: unmatched case '%s'" what)))
+
+
+ ;; remember what we have done for next time
+ (setq org-index--last-action what)
+
+ ;; tell, what we have done and what can be yanked
+ (if kill-new-text (setq kill-new-text
+ (substring-no-properties kill-new-text)))
+ (if (string= kill-new-text "") (setq kill-new-text nil))
+ (let ((m (concat
+ message-text
+ (if (and message-text kill-new-text)
+ " and r"
+ (if kill-new-text "R" ""))
+ (if kill-new-text (format "eady to yank '%s'" kill-new-text) ""))))
+ (unless (string= m "") (message m)))
+ (if kill-new-text (kill-new kill-new-text))))
+
+
+(defun org-index-new-line (&rest keys-values)
+ "Create a new line within the index table, returning its reference.
+
+The function takes a varying number of arguments pairs; each pair
+is a symbol for an existing column heading followed by its value.
+their values.
+
+Example:
+
+ (org-index-new-line :ref t :x1 \"foo\" :link \"7f480c3e\")
+
+Passing \":ref t\" will make the function create a new reference within the new line.
+
+"
+
+ (let ((org-index--silent t))
+
+ (save-excursion
+ (org-index--retrieve-context)
+ (with-current-buffer org-index--buffer
+ (goto-char org-index--point)
+ (org-index--parse-table)
+
+ ;; check arguments early
+ (let ((kvs keys-values)
+ k v)
+ (while kvs
+ (setq k (car kvs))
+ (setq v (cadr kvs))
+ (if (eq k :ref)
+ (unless (memq v '(t nil))
+ (error "Argument :ref accepts only t or nil"))
+ (if (or (not (symbolp k))
+ (symbolp v))
+ (error "Arguments must be alternation of key and value")))
+ (unless (> (org-index--column-num k) 0)
+ (error "Unknown column or column not defined in table: '%s'" (symbol-name k)))
+ (setq kvs (cddr kvs))))
+
+ (if (and (not (plist-get keys-values :ref))
+ (not (stringp (plist-get keys-values :link))))
+ (error "Need a link when not creating a ref"))
+
+ (let (new)
+ ;; create new line
+ (setq new (org-index--do-new-line (plist-get keys-values :ref)))
+ (plist-put keys-values :ref (or new ""))
+
+ ;; fill columns
+ (let ((kvs keys-values)
+ k v n)
+ (while kvs
+ (setq k (car kvs))
+ (setq v (cadr kvs))
+ (setq n (org-index--column-num k))
+ (org-table-goto-column n)
+ (insert v)
+ (setq kvs (cddr kvs))))
+
+ (org-index--sort)
+ new)))))
+
+
+(defun org-index-get-line (what value)
+ "Retrieve an existing line within the index table by ref or
+link and return its contents as a property list.
+
+The function `plist-get' may be used to retrieve specific values.
+
+Example:
+
+ (plist-get (org-index-get-line \"12\") :count)
+
+retrieves the value of the count-column for reference 12.
+
+"
+ (interactive)
+ (let ((org-index--silent t)
+ found)
+
+ ;; check arguments
+ (unless (memq what '(:ref :link))
+ (error "Argument what can only be :ref or :link"))
+
+ (save-excursion
+ (org-index--retrieve-context)
+ (with-current-buffer org-index--buffer
+ (goto-char org-index--point)
+ (org-index--parse-table)
+
+ (goto-char org-index--below-hline)
+ (while (and (not found)
+ (org-at-table-p))
+ (when (string= (org-index--get-field what)
+ value)
+ (mapc (lambda (x)
+ (if (and (numberp (cdr x))
+ (> (cdr x) 0))
+ (setq found (cons (car x) (cons (or (org-index--get-field (car x)) "") found)))
+ )) (reverse org-index--columns)))
+ (forward-line))
+ found))))
+
+
+(defun org-index--read-what (what)
+ "Find out, what we are supposed to do"
+
+ (let (commands ; currently active set of selectable commands
+ trailing-digits ; any digits, that are are appended to what-input
+ reorder-once ; Column to use for single time sorting
+ what-input) ; Input on what question (need not necessary be "what")
+
+ ;; Set preferred action, that will be the default choice
+ (setq org-index--preferred-command
+ (if org-index--within-node
+ (if (memq org-index--last-action '(ref link))
+ 'leave
+ 'goto)
+ (if org-index--active-region
+ 'ref
+ (if (and org-index--below-cursor (string-match org-index--ref-regex org-index--below-cursor))
+ 'occur
+ nil))))
+
+ ;; Ask user, what to do
+ (if what
+ (setq what-input (symbol-name what))
+ ;; subset of most common commands for initial selection, ie. up to first plus
+ (setq commands (copy-list org-index--commands))
+ (let ((c commands))
+ (while (and c (not (eq (car c) '+)))
+ (setq c (cdr c)))
+ (setcdr c nil))
+
+ (while (let (completions starts-with-plus is-only-plus)
+
+ (setq what-input
+ (org-completing-read
+ "Please choose: "
+ (mapcar 'symbol-name
+ ;; Construct unique list of commands with
+ ;; preferred one at front
+ (delq nil (delete-dups
+ (append
+ (list org-index--preferred-command)
+ (copy-list commands)))))
+ nil nil))
+
+ ;; if input ends in digits, save them away and do completions on head of input
+ ;; this allows input like "h224" to be accepted
+ (when (string-match "^\\([^0-9]+\\)\\([0-9]+\\)\\s *$" what-input)
+ ;; remember digits
+ (setq trailing-digits (string-to-number (match-string 2 what-input)))
+ ;; and use non-digits-part to find match
+ (setq what-input (match-string 1 what-input)))
+
+ ;; if input starts with "+", any command (not only some) may follow
+ ;; this allows input like "+sort" to be accepted
+ (when (and (> (length what-input) 0)
+ (string= (substring what-input 0 1) "+"))
+ ;; make all commands available for selection
+ (setq commands (copy-list org-index--commands))
+ (setq what-input (substring what-input 1))
+ (setq starts-with-plus (> (length what-input) 0))
+ (setq is-only-plus (not starts-with-plus)))
+
+ ;; get list of possible completions for what-input; i.e.
+ ;; all commands, that start with what-input
+ (setq completions (delq nil (mapcar
+ (lambda (x)
+ (let ((where (search what-input (symbol-name x))))
+ (if (and where
+ (= where 0))
+ x
+ nil))) commands)))
+
+ ;; if input starts with "+" and not just "+"
+ (when starts-with-plus
+ ;; use first completion, if unambigously
+ (if (= (length completions) 1)
+ (setq what-input (symbol-name (car completions)))
+ (if completions
+ (error "Input \"+%s\" matches multiple commands: %s"
+ what-input
+ (mapconcat 'symbol-name completions ", "))
+ (error "Input \"+%s\" matches no commands" what-input))))
+
+ ;; if input ends in digits, use first completion, even if ambigous
+ ;; this allows input like "h224" to be accepted
+ (when (and trailing-digits completions)
+ ;; use first match as input, even if ambigously
+ (setq org-index--preferred-command (first completions))
+ (setq what-input (number-to-string trailing-digits)))
+
+ ;; convert to symbol
+ (setq what (intern what-input))
+ (if is-only-plus (setq what '+))
+
+ ;; user is not required to input one of the commands; if
+ ;; not, take the first one and use the original input for
+ ;; next question
+ (if (memq what commands)
+ ;; input matched one element of list, dont need original
+ ;; input any more
+ (setq what-input nil)
+ ;; what-input will be used for next question, use first
+ ;; command for what
+ (setq what (or org-index--preferred-command
+ (first commands)))
+ ;; remove any trailing dot, that user might have added to
+ ;; disambiguate his input
+ (if (and (> (length what-input) 0)
+ (equal (substring what-input -1) "."))
+ ;; but do this only, if dot was really necessary to
+ ;; disambiguate
+ (let ((shortened-what-input (substring what-input 0 -1)))
+ (unless (test-completion shortened-what-input
+ (mapcar 'symbol-name
+ commands))
+ (setq what-input shortened-what-input)))))
+
+ ;; ask for reorder in loop, because we have to ask for
+ ;; what right again
+ (if (eq what 'reorder)
+ (setq reorder-once
+ (intern
+ (org-icompleting-read
+ "Please choose column to reorder index table once: "
+ (mapcar 'symbol-name
+ (append '(:ref :count :first :last)
+ (delq nil (mapcar (lambda (x) (if (> (cdr (assoc x org-index--columns)) 0) x nil))
+ '(:x1 :x2 :x3)))))
+ nil t))))
+
+ ;; maybe ask initial question again
+ (memq what '(reorder +)))))
+ (list what what-input reorder-once)))
+
+
+(defun org-index--get-or-read-search (search what what-input)
+ "Get search string, maybe read from user"
+
+ (let (search-from-table
+ search-from-cursor)
+
+ (unless search
+ ;; Search string can come from several sources:
+ ;; From link or ref columns of table
+ (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))))
+
+ ;; From string below cursor
+ (when (and (not org-index--within-node)
+ org-index--below-cursor
+ (string-match (concat "\\(" org-index--ref-regex "\\)")
+ org-index--below-cursor))
+ (setq search-from-cursor (match-string 1 org-index--below-cursor)))
+
+ ;; Depending on requested action, get search from one of the sources above
+ (cond ((eq what 'goto)
+ (setq search (or what-input search-from-cursor)))
+ ((memq what '(head occur))
+ (setq search (or what-input search-from-table search-from-cursor)))))
+
+
+ ;; If we still do not have a search string, ask user explicitly
+ (unless search
+
+ (if org-index--silent (error "Need to specify search, if silence is required"))
+
+ (unless (eq what 'occur)
+
+ (if what-input
+ (setq search what-input)
+ (setq search (read-from-minibuffer
+ (cond ((eq what 'head)
+ "Text or reference number to search for: ")
+ ((eq what 'goto)
+ "Reference number to search for, or enter \".\" for id of current node: ")
+ ((eq what 'update)
+ "Reference number to update: ")))))
+
+ (if (string-match "^\\s *[0-9]+\\s *$" search)
+ (setq search (format "%s%s%s" org-index--head search org-index--tail)))))
+
+
+ ;; Clean up and examine search string
+ (when search
+ (setq search (org-trim search))
+ (if (string= search "") (setq search nil))
+ (when search
+ (if (string-match "^[0-9]+$" search)
+ (setq search (concat org-index--head search org-index--tail)))))
+
+ ;; Check for special case
+ (when (and (memq what '(head goto))
+ (string= search "."))
+ (setq search (org-id-get)))
+
+ search))
+
+
+(defun org-index--verify-id ()
+
+ ;; Check id
+ (unless 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 (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"))
+ (setq org-index--buffer (marker-buffer marker)
+ org-index--point (marker-position marker))
+ (move-marker marker nil)))
+
+
+(defun org-index--retrieve-context ()
+
+ ;; Get the content of the active region or the word under cursor
+ (setq org-index--active-region
+ (if (and transient-mark-mode mark-active)
+ (buffer-substring (region-beginning) (region-end))
+ nil))
+ (setq org-index--below-cursor (thing-at-point 'symbol))
+
+ ;; Find out, if we are within favable or not
+ (setq org-index--within-node (string= (org-id-get) org-index-id))
+
+ ;; Check and remember, if active window contains buffer with index table
+ (if (eq (window-buffer) org-index--buffer)
+ (setq org-index--active-window-index (selected-window)))
+
+ ;; get current position in index-buffer
+ (with-current-buffer org-index--buffer
+ (setq org-index--point-before
+ (if (string= (org-id-get) org-index-id)
+ nil
+ (point-marker)))))
+
+
+(defun org-index--parse-table ()
+
+ (let (ref-field
+ link-field
+ initial-point
+ end-of-heading)
+
+ (with-current-buffer org-index--buffer
+
+ (setq org-index--maxref 0)
+ (setq initial-point (point))
+ (org-index--go-below-hline)
+ (setq org-index--below-hline (point))
+ (beginning-of-line)
+ (setq end-of-heading (point))
+ (while (org-at-table-p) (forward-line -1))
+ (forward-line)
+ (setq org-index--headings (buffer-substring (point) end-of-heading))
+ (goto-char org-index--below-hline)
+
+
+ ;; count columns
+ (org-table-goto-column 100)
+ (setq org-index--numcols (- (org-table-current-column) 1))
+
+ ;; get contents of columns
+ (forward-line -2)
+ (unless (org-at-table-p)
+ (org-index--create-new-index
+ nil
+ "Index table starts with a hline"))
+
+ ;; check for optional line consisting solely of width specifications
+ (beginning-of-line)
+ (if (looking-at "\\s *|\\(\\(\\s *|\\)\\|\\(\\s *<[0-9]+>\\s *|\\)\\)+\\s *$")
+ (forward-line -1))
+ (org-table-goto-column 1)
+
+ (org-index--parse-headings)
+
+ ;; Go beyond end of table
+ (while (org-at-table-p) (forward-line 1))
+
+ ;; Retrieve any decorations around the number within the first nonempty ref-field
+ (goto-char org-index--below-hline)
+ (while (and (org-at-table-p)
+ (not (setq ref-field (org-index--get-field :ref))))
+ (forward-line))
+
+ ;; Some Checking
+ (unless ref-field
+ (org-index--create-new-index
+ nil
+ "Reference column is empty"))
+
+ (unless (string-match "^\\([^0-9]*\\)\\([0-9]+\\)\\([^0-9]*\\)$" ref-field)
+ (org-index--create-new-index
+ nil
+ (format "First reference in index table ('%s') does not contain a number" ref-field)))
+
+
+ ;; These are the decorations used within the first ref of index
+ (setq org-index--head (match-string 1 ref-field))
+ (setq org-index--tail (match-string 3 ref-field))
+ (setq org-index--ref-regex (concat (regexp-quote org-index--head)
+ "\\([0-9]+\\)"
+ (regexp-quote org-index--tail)))
+ (setq org-index--ref-format (concat org-index--head "%d" org-index--tail))
+
+
+ ;; Go through table to find maximum number and do some checking
+ (let ((ref 0))
+
+ (while (org-at-table-p)
+
+ (setq ref-field (org-index--get-field :ref))
+ (setq link-field (org-index--get-field :link))
+
+ (when (and (not ref-field)
+ (not link-field))
+ (org-pop-to-buffer-same-window org-index--buffer)
+ (org-reveal)
+ (error "Columns ref and link are both empty in this line"))
+
+ (if ref-field
+ (if (string-match org-index--ref-regex ref-field)
+ ;; grab number
+ (setq ref (string-to-number (match-string 1 ref-field)))
+ (org-pop-to-buffer-same-window org-index--buffer)
+ (org-reveal)
+ (error "Column ref does not contain a number")))
+
+ ;; check, if higher ref
+ (if (> ref org-index--maxref) (setq org-index--maxref ref))
+
+ ;; check if ref is ment for reuse
+ (if (string= (org-index--get-field :count) ":reuse:")
+ (setq org-index--has-reuse t))
+
+ (forward-line 1)))
+
+ ;; go back to initial position
+ (goto-char initial-point))))
+
+
+(defun org-index--sort (&optional sort-column)
+
+ (unless sort-column (setq sort-column (org-index--special-column :sort)))
+
+ (let (top
+ bottom
+ ref-field
+ count-field
+ count-special)
+
+ (unless buffer-read-only
+
+ ;; get boundaries of table
+ (goto-char org-index--below-hline)
+ (forward-line 0)
+ (setq top (point))
+ (while (org-at-table-p) (forward-line))
+
+ ;; Kill all empty rows at bottom
+ (while (progn
+ (forward-line -1)
+ (org-table-goto-column 1)
+ (and
+ (not (org-index--get-field :ref))
+ (not (org-index--get-field :link))))
+ (org-table-kill-row))
+ (forward-line 1)
+ (setq bottom (point))
+
+ (save-restriction
+ (narrow-to-region top bottom)
+ (goto-char top)
+ (sort-subr t
+ 'forward-line
+ 'end-of-line
+ (lambda ()
+ (let (ref
+ (ref-field (or (org-index--get-field :ref) ""))
+ (count-field (or (org-index--get-field :count) ""))
+ (count-special 0))
+
+ ;; get reference with leading zeroes, so it can be
+ ;; sorted as text
+ (string-match org-index--ref-regex ref-field)
+ (setq ref (format
+ "%06d"
+ (string-to-number
+ (or (match-string 1 ref-field)
+ "0"))))
+
+ ;; find out, if special token in count-column
+ (setq count-special (format "%d"
+ (- 2
+ (length (member count-field '(":missing:" ":reuse:"))))))
+
+ ;; Construct different sort-keys according to
+ ;; requested sort column; prepend count-special to
+ ;; sort special entries at bottom of table, append ref
+ ;; as a secondary sort key
+ (cond
+
+ ((eq sort-column :count)
+ (concat count-special
+ (format
+ "%08d"
+ (string-to-number (or (org-index--get-field :count)
+ "")))
+ ref))
+
+ ((eq sort-column :ref)
+ (concat count-special
+ ref))
+
+ ((memq sort-column '(:last :x1 :x2 :x3))
+ (concat count-special
+ (org-index--get-field sort-column)
+ " "
+ ref))
+
+ (t (error "This is a bug: unmatched case '%s'" sort-column)))))
+
+ nil 'string<))
+
+ ;; sorting has moved point below hline
+ (org-index--go-below-hline)
+ (setq org-index--below-hline (point)))))
+
+
+(defun org-index--go-below-hline ()
+
+ (goto-char org-index--point)
+ ;; go to heading of node
+ (while (not (org-at-heading-p)) (forward-line -1))
+ (forward-line 1)
+ ;; go to table within node, but make sure we do not get into another node
+ (while (and (not (org-at-heading-p))
+ (not (org-at-table-p))
+ (not (eq (point) (point-max))))
+ (forward-line 1))
+
+ ;; check, if there really is a table
+ (unless (org-at-table-p)
+ (org-index--create-new-index
+ t
+ (format "Cannot find index table within node %s" org-index-id)))
+
+ ;; go to first hline
+ (while (and (not (org-at-table-hline-p))
+ (org-at-table-p))
+ (forward-line 1))
+
+ ;; and check
+ (unless (org-at-table-hline-p)
+ (org-index--create-new-index
+ nil
+ "Cannot find hline within index table"))
+
+ (forward-line 1)
+ (org-table-goto-column 1))
+
+
+(defun org-index--align ()
+ (unless buffer-read-only (org-table-align))
+ (org-index--go-below-hline)
+ (setq org-index--below-hline (point)))
+
+
+(defun org-index--parse-headings ()
+
+ ;; Associate names of special columns with column-numbers
+ (setq org-index--columns (copy-tree '((:ref . 0) (:link . 0) (:first . 0) (:last . 0)
+ (:count . 0) (:x1 . 0) (:x2 . 0) (:x3 . 0))))
+
+ ;; Associate names of special columns with names of columns
+ (setq org-index--special-columns (copy-tree '((:sort . nil) (:copy . nil) (:point . nil))))
+
+ ;; For each column
+ (dotimes (col org-index--numcols)
+ (let* (field-flags ;; raw heading, consisting of file name and maybe
+ ;; flags (seperated by ";")
+ field ;; field name only
+ field-symbol ;; and as a symbol
+ flags ;; flags from field-flags
+ found)
+
+ ;; parse field-flags into field and flags
+ (setq field-flags (org-trim (org-table-get-field (+ col 1))))
+ (if (string-match "^\\([^;]*\\);\\([a-z]+\\)$" field-flags)
+ (progn
+ (setq field (downcase (or (match-string 1 field-flags) "")))
+ ;; get flags as list of characters
+ (setq flags (mapcar 'string-to-char
+ (split-string
+ (downcase (match-string 2 field-flags))
+ "" t))))
+ ;; no flags
+ (setq field field-flags))
+
+ (unless (string= field "") (setq field-symbol (intern (concat ":" (downcase field)))))
+ ;; aliases for backward compatability
+ (if (eq field-symbol :last-accessed) (setq field-symbol :last))
+ (if (eq field-symbol :created) (setq field-symbol :first))
+
+ (if (and field-symbol
+ (not (assoc field-symbol org-index--columns)))
+ (error "Column %s is not a valid heading" (symbol-name field-symbol)))
+
+ ;; Check, that no flags appear twice
+ (mapc (lambda (x)
+ (when (memq (car x) flags)
+ (if (cdr (assoc (cdr x) org-index--columns))
+ (org-index--create-new-index
+ nil
+ (format "More than one heading is marked with flag '%c'" (car x))))))
+ '((?s . sort)
+ (?c . copy)))
+
+ ;; Process flags
+ (if (memq ?s flags)
+ (setcdr (assoc :sort org-index--special-columns) (or field-symbol (+ col 1))))
+ (if (memq ?c flags)
+ (setcdr (assoc :copy org-index--special-columns) (or field-symbol (+ col 1))))
+ (if (memq ?p flags)
+ (setcdr (assoc :point org-index--special-columns) (or field-symbol (+ col 1))))
+
+ ;; Store columns in alist
+ (setq found (assoc field-symbol org-index--columns))
+ (when found
+ (if (> (cdr found) 0)
+ (org-index--create-new-index
+ nil
+ (format "'%s' appears two times as column heading" (downcase field))))
+ (setcdr found (+ col 1)))))
+
+ ;; check if all necessary informations have been specified
+ (mapc (lambda (col)
+ (unless (> (cdr (assoc col org-index--columns)) 0)
+ (org-index--create-new-index
+ nil
+ (format "column '%s' has not been set" col))))
+ (list :ref :link :count :first :last))
+
+ ;; use count as a default sort-column
+ (unless (cdr (assoc :sort org-index--special-columns))
+ (setcdr (assoc :sort org-index--special-columns) :count)))
+
+
+(defun org-index--create-new-index (create-new-index reason)
+ "Create a new empty index table with detailed explanation."
+ (let (prompt buffer-name title firstref id)
+
+ ;; cannot proceed without querying user
+ (if org-index--silent (error "No valid index: %s" reason))
+
+ (setq prompt
+ (if create-new-index
+ (concat "There is this problem with the existing index table:\n\n " reason "\n\nThis assistant will guide you to create a new one.\n\nDo you want to proceed ?")
+ (concat "The existing index table contains this error:\n\n " reason "\n\nYou need to correct this error manually before trying again. However, this assistant will help you to create an new initial index table with detailed comments, so that you may fix the errors in your existing table more easily.\n\nDo you want to proceed ?")))
+ (unless (y-or-n-p prompt)
+ (error "Cannot proceed without a valid index table: %s" reason))
+
+ (setq buffer-name (org-completing-read "Please choose the buffer, where the new node for the index table should be created; the new node will be inserted at its end.\n\nBuffer: " (mapcar 'buffer-name (org-buffer-list)) nil nil))
+
+ (setq title (read-from-minibuffer "Please enter the title of the index node: "))
+
+ (while (progn
+ (setq firstref (read-from-minibuffer "Please enter your first reference-number. This is a number preceeded by some non-digit chars and optionally followed by some more non-digit chars, e.g. 'R1', '-1-' or '#1#' (and your initial number does not need to be '1'). The format of your reference-numbers only needs to make sense for yourself, so that you can spot it easily in your texts or write it on a piece of paper; it should however not already appear to frequently within your existing notes, to avoid too many false hits when searching.\n\nPlease choose: "))
+ (let (desc)
+ (unless (equal '(95 119) (sort (delete-dups (mapcar (lambda (x) (char-syntax x)) (concat "-1" firstref))) '<))
+ (setq desc "Contains other characters than those allowed in symbols"))
+ (unless (string-match "^[^0-9]+[0-9]+[^0-9]*$" firstref)
+ ;; firstref not okay, report details
+ (setq desc
+ (cond ((string= firstref "") "is empty")
+ ((not (string-match "^[^0-9]+" firstref)) "starts with a digit")
+ ((not (string-match "^[^0-9]+[0-9]+" firstref)) "does not contain a number")
+ ((not (string-match "^[^0-9]+[0-9]+[^0-9]*$" firstref)) "contains more than one sequence of digits")
+
+ )))
+ (if desc
+ (progn
+ (read-from-minibuffer (format "Your input '%s' does not meet the requirements because it %s. Please hit RET and try again" firstref desc))
+ t)
+ nil))))
+
+ (with-current-buffer buffer-name
+ (goto-char (point-max))
+ (insert (format "\n\n* %s %s\n" firstref title))
+ (insert "\n\n Below you find your initial index table, which will grow over time.\n"
+ " Following that your may read its detailed explanation, which will help you,\n"
+ " to adjust org-index to your needs. This however is optional reading and not\n"
+ " required to start using org-index.\n")
+
+ (setq id (org-id-get-create))
+ (insert (format "
+
+ | | | | | | comment |
+ | ref | link | first | count;s | last | ;c |
+ | | <4> | | | | |
+ |-----+------+-------+---------+------+---------|
+ | %s | %s | %s | | | %s |
+
+"
+ firstref
+ id
+ (with-temp-buffer (org-insert-time-stamp nil nil t))
+ "This node"))
+
+
+ (insert "
+
+ Detailed explanation:
+
+
+ The index table above has three lines of headings above the first
+ hline:
+
+ - The first one is ignored by org-index, and you can use it to
+ give meaningful names to columns. In the table above only one
+ column has a name (\"comment\"). This line is optional.
+
+ - The second line is the most important one, because it
+ contains the configuration information for org-index; please
+ read further below for its format.
+
+ - The third line is again optional; it may only specify the
+ widths of the individual columns (e.g. <4>).
+
+ The columns get their meaning by the second line of headings;
+ specifically by one of the keywords (e.g. \"ref\") or a flag
+ seperated by a semicolon (e.g. \";s\").
+
+
+
+ The keywords and flags are:
+
+
+ - ref: This contains the reference, which consists of a decorated
+ number, which is incremented for each new line. References are
+ meant to be used in org-mode headlines or outside of org,
+ e.g. within folder names.
+
+ - link: org-mode link pointing to the matching location within org.
+
+ - first: When has this line been first accessed (i.e. created) ?
+
+ - count: How many times has this line been accessed ? The
+ trailing flag \"s\" makes the table beeing sorted after this
+ column this column, so that often used entries appear at the
+ top of the table.
+
+ - last: When has this line been accessed last ?
+
+ - The last column above has no keyword, only the flag \"c\",
+ which makes its content beeing copied under certain
+ conditions. It is typically used for comments.
+
+ The sequence of columns does not matter. You may reorder them any
+ way you like. Columns are found by their name, which appears in
+ the second line of headings.
+
+ 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.
+
+")
+
+
+ (while (not (org-at-table-p)) (forward-line -1))
+ (unless buffer-read-only (org-table-align))
+ (while (not (org-at-heading-p)) (forward-line -1))
+
+ ;; present results to user
+ (if create-new-index
+ (progn
+ ;; Only show the new index
+ (org-pop-to-buffer-same-window buffer-name)
+ (delete-other-windows)
+ (org-id-goto id)
+ (org-show-context)
+ (show-subtree)
+ (recenter 1)
+ (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)
+ (error "Saved org-index-id '%s' to %s" id custom-file))
+ (let (sq)
+ (setq sq (format "(setq org-index-id \"%s\")" id))
+ (kill-new sq)
+ (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
+ (org-pop-to-buffer-same-window org-index--buffer)
+ (goto-char org-index--point)
+ (org-show-context)
+ (show-subtree)
+ (recenter 1)
+ (delete-other-windows)
+ ;; show new index
+ (select-window (split-window-vertically))
+ (org-pop-to-buffer-same-window buffer-name)
+ (org-id-goto id)
+ (org-show-context)
+ (show-subtree)
+ (recenter 1)
+ (error "Please compare your existing index (upper window) and a temporary new one (lower window) to correct the previous error (\"%s\"); the explanations following the new index table should help." reason)))))
+
+
+(defun org-index--update-line (ref-or-link)
+
+ (let ((newcount 0)
+ initial)
+
+ (with-current-buffer org-index--buffer
+ (unless buffer-read-only
+
+ ;; search reference or link, if given (or assume, that we are already positioned right)
+ (when ref-or-link
+ (setq initial (point))
+ (goto-char org-index--below-hline)
+ (while (and (org-at-table-p)
+ (not (or (string= ref-or-link (org-index--get-field :ref))
+ (string= ref-or-link (org-index--get-field :link)))))
+ (forward-line)))
+
+ (if (not (org-at-table-p))
+ (error "Did not find reference or link '%s'" ref-or-link)
+ (org-index--update-current-line))
+
+ (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)
+ (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))))
+
+
+(defun org-index--column-num (key)
+ (if (numberp key)
+ key
+ (cdr (assoc key org-index--columns))))
+
+
+(defun org-index--special-column (key)
+ (cdr (assoc key org-index--special-columns)))
+
+
+(defun org-index--make-guarded-search (ref &optional dont-quote)
+ (concat "\\_<" (if dont-quote ref (regexp-quote ref)) "\\_>"))
+
+
+(defun org-index--do-statistics (what)
+ (let ((total 0)
+ missing
+ ref-field
+ ref
+ min
+ max
+ message-text)
+
+
+ ;; start with list of all references
+ (setq missing (mapcar (lambda (x) (format "%s%d%s" org-index--head x org-index--tail))
+ (number-sequence 1 org-index--maxref)))
+
+ ;; go through table and remove all refs, that we see
+ (goto-char org-index--below-hline)
+ (while (org-at-table-p)
+
+ ;; get ref-field and number
+ (setq ref-field (org-index--get-field :ref))
+ (if (and ref-field
+ (string-match org-index--ref-regex ref-field))
+ (setq ref (string-to-number (match-string 1 ref-field))))
+
+ ;; remove existing refs from list
+ (if ref-field (setq missing (delete ref-field missing)))
+
+ ;; record min and max
+ (if (or (not min) (< ref min)) (setq min ref))
+ (if (or (not max) (> ref max)) (setq max ref))
+
+ ;; count
+ (setq total (1+ total))
+
+ (forward-line))
+
+ ;; insert them, if requested
+ (forward-line -1)
+ (if (eq what 'statistics)
+
+ (setq message-text (format "Found %d references from %s to %s. %d references below highest do not appear in table. "
+ total
+ (format org-index--ref-format min)
+ (format org-index--ref-format max)
+ (length missing)))
+
+ (if (y-or-n-p (format "Found %d missing references; do you wish to append them to the index table"
+ (length missing)))
+ (let (type)
+ (setq type (org-icompleting-read
+ "Insert new lines for reuse by command \"new\" or just as missing ? " '("reuse" "missing")))
+ (mapc (lambda (x)
+ (let (org-table-may-need-update) (org-table-insert-row t))
+ (org-index--get-field :ref x)
+ (org-index--get-field :count (format ":%s:" type)))
+ missing)
+ (org-index--align)
+
+ (setq message-text (format "Inserted %d new lines for missing refernces" (length missing))))
+ (setq message-text (format "%d missing references." (length missing)))))
+ message-text))
+
+
+(defun org-index--do-head (ref link &optional other)
+
+ (if ref (setq org-index--last-ref ref))
+
+ (let (message-text)
+ ;; Use link if available
+ (if link
+ (progn
+ (org-index--update-line link)
+ (org-id-goto link)
+ (org-reveal)
+ (setq message-text "Followed link"))
+
+ (message (format "Scanning headlines for '%s' ..." ref))
+ (org-index--update-line ref)
+ (let ((search (concat ".*" (org-index--make-guarded-search ref)))
+ (org-trust-scanner-tags t)
+ buffer point)
+ (if (catch 'found
+ (progn
+ ;; loop over all headlines, stop on first match
+ (org-map-entries
+ (lambda ()
+ (when (or (looking-at search)
+ (eq ref (org-entry-get (point) "org-index-ref")))
+ ;; If this is not an inlinetask ...
+ (when (< (org-element-property :level (org-element-at-point))
+ org-inlinetask-min-level)
+ ;; ... remember location and bail out
+ (setq buffer (current-buffer))
+ (setq point (point))
+ (throw 'found t))))
+ nil 'agenda)
+ nil))
+
+ (progn
+ (setq message-text (format "Found '%s'" (or ref link)))
+ (if other
+ (progn
+ (pop-to-buffer buffer)
+ (goto-char point)
+ (org-reveal t)
+ (recenter)
+ (pop-to-buffer "*org-index-occur*"))
+ (org-pop-to-buffer-same-window buffer)
+ (goto-char point)
+ (org-reveal t)
+ (recenter)))
+ (setq message-text (format "Did not find '%s'" (or ref link))))))
+ message-text))
+
+
+(defun org-index--do-occur (initial-search)
+ (let ((occur-buffer-name "*org-index-occur*")
+ (word "") ; last word to search for growing and shrinking on keystrokes
+ (prompt "Search for: ")
+ (hint "")
+ (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
+ start-of-help ; start of displayed help (if any)
+ left-off-at ; stack of last positions in index table
+ after-inserted ; in occur-buffer
+ at-end ; in occur-buffer
+ lines-visible ; in occur-buffer
+ below-hline-bol ; below-hline and at bol
+ exit-gracefully ; true if normal exit
+ 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)
+
+ ;; clear buffer
+ (if (get-buffer "*org-index-occur*")
+ (kill-buffer occur-buffer-name))
+ (setq occur-buffer (get-buffer-create "*org-index-occur*"))
+
+ ;; install keyboard-shortcuts within occur-buffer
+ (with-current-buffer occur-buffer
+ (let ((keymap (make-sparse-keymap)))
+
+ (set-keymap-parent keymap org-mode-map)
+ (setq fun-on-ret (lambda () (interactive) (org-index--occur-find-heading nil)))
+ (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 [tab] fun-on-tab)
+ (define-key keymap [(control ?i)] fun-on-tab)
+ (define-key keymap [up] (lambda () (interactive)
+ (forward-line -1)
+ (if org-index--occur-follow-mode (org-index--occur-find-heading t))))
+ (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)))
+
+ (with-current-buffer org-index--buffer
+ (let ((initial (point)))
+ (goto-char org-index--below-hline)
+ (forward-line 0)
+ (setq below-hline-bol (point))
+ (goto-char initial)))
+
+ (org-pop-to-buffer-same-window occur-buffer)
+ (toggle-truncate-lines 1)
+
+ (unwind-protect ; to reset cursor-shape even in case of errors
+ (progn
+
+ ;; fill in header
+ (erase-buffer)
+ (insert (concat "Incremental search, showing one window of matches. '?' toggles help.\n\n"))
+ (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))
+ (when (nth 0 ret)
+ (insert (nth 1 ret))
+ (setq left-off-at (cons (nth 0 ret) nil))
+ (setq after-inserted (cons (point) nil)))
+
+ ;; read keys
+ (while
+ (progn
+ (goto-char start-of-lines)
+ (setq lines-visible 0)
+
+ ;; use initial-search (if present) to simulate keyboard input
+ (if (and initial-search
+ (> (length initial-search) 0))
+ (progn
+ (setq key (string-to-char (substring initial-search 0 1)))
+ (if (length initial-search)
+ (setq initial-search (substring initial-search 1))))
+ (if in-c-backspace
+ (setq key 'backspace)
+ (let ((search-text (mapconcat 'identity (reverse (cons word words)) ",")))
+ (setq key (read-key
+ (format "%s%s%s%s"
+ prompt
+ search-text
+ (if (string= search-text "") "" " ")
+ hint))))
+ (setq hint "")
+ (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))
+
+ (cond
+
+ ((eq key 'C-backspace)
+
+ (setq in-c-backspace t))
+
+ ((member key (list 'backspace 'deletechar ?\C-?)) ; erase last char
+
+ (if (= (length word) 0)
+
+ ;; nothing more to delete from current word; try next
+ (progn
+ (setq word (car words))
+ (setq words (cdr words))
+ (setq in-c-backspace nil))
+
+ ;; unhighlight longer match
+ (let ((case-fold-search t))
+ (unhighlight-regexp (regexp-quote word)))
+
+ ;; some chars are left; shorten word
+ (setq word (substring word 0 -1))
+ (when (= (length word) 0) ; when nothing left, use next word from list
+ (setq word (car words))
+ (setq words (cdr words))
+ (setq in-c-backspace nil))
+
+ ;; remove everything, that has been added for char just deleted
+ (when (cdr after-inserted)
+ (setq after-inserted (cdr after-inserted))
+ (goto-char (car after-inserted))
+ (delete-region (point) (point-max)))
+
+ ;; back up last position in index table too
+ (when (cdr left-off-at)
+ (setq left-off-at (cdr left-off-at)))
+
+ ;; go through buffer and check, if any invisible line should now be shown
+ (goto-char start-of-lines)
+ (while (< (point) (point-max))
+ (if (outline-invisible-p)
+ (progn
+ (setq from (line-beginning-position)
+ to (line-beginning-position 2))
+
+ ;; check for matches
+ (when (org-index--test-words (cons word words) (buffer-substring from to))
+ (when (<= lines-visible lines-to-show) ; show, if more lines required
+ (outline-flag-region from to nil)
+ (incf lines-visible))))
+
+ ;; already visible, just count
+ (incf lines-visible))
+
+ (forward-line 1))
+
+ ;; highlight shorter word
+ (unless (= (length word) 0)
+ (let ((case-fold-search t))
+ (highlight-regexp (regexp-quote word) 'isearch)))))
+
+
+ ((member key (list ?\s ?,)) ; space or comma: enter an additional search word
+
+ ;; push current word and clear, no need to change display
+ (setq words (cons word words))
+ (setq word ""))
+
+
+ ((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-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\n"))
+ (setq start-of-lines (point-marker)))
+
+
+ ((and (integerp key)
+ (aref printable-chars key)) ; any printable char: add to current search word
+
+ ;; unhighlight short word
+ (unless (= (length word) 0)
+ (let ((case-fold-search t))
+ (unhighlight-regexp (regexp-quote word))))
+
+ ;; add to word
+ (setq word (concat word (char-to-string key)))
+
+ ;; hide lines, that do not match longer word any more
+ (while (< (point) (point-max))
+ (unless (outline-invisible-p)
+ (setq from (line-beginning-position)
+ to (line-beginning-position 2))
+
+ ;; check for matches
+ (if (org-index--test-words (list word) (buffer-substring from to))
+ (incf lines-visible) ; count as visible
+ (outline-flag-region from to t))) ; hide
+
+ (forward-line 1))
+
+ ;; duplicate top of stacks; eventually overwritten below
+ (setq left-off-at (cons (car left-off-at) left-off-at))
+ (setq after-inserted (cons (car after-inserted) after-inserted))
+
+ ;; get new lines from index table
+ (when (< lines-visible lines-to-show)
+ (setq ret (org-index--get-matching-lines (cons word words)
+ (- lines-to-show lines-visible)
+ (car left-off-at)))
+
+ (when (nth 0 ret)
+ (insert (nth 1 ret))
+ (setq at-end (nth 2 ret))
+ (setcar left-off-at (nth 0 ret))
+ (setcar after-inserted (point))))
+
+ ;; highlight longer word
+ (let ((case-fold-search t))
+ (highlight-regexp (regexp-quote word) 'isearch)))
+
+
+ (t ; non-printable chars
+ (setq hint (format "(cannot search for key '%s', use %s to quit)"
+ (if (symbolp key)
+ key
+ (key-description (char-to-string key)))
+ (substitute-command-keys "\\[keyboard-quit]"))))))
+
+ ;; search is done collect and brush up results
+ ;; remove any lines, that are still invisible
+ (goto-char start-of-lines)
+ (while (< (point) (point-max))
+ (if (outline-invisible-p)
+ (delete-region (line-beginning-position) (line-beginning-position 2))
+ (forward-line 1)))
+
+ ;; get all the rest
+ (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.")
+ (insert (nth 1 ret))))
+
+ ;; postprocessing even for non graceful exit
+ (setq cursor-type t)
+ ;; replace previous heading
+ (let ((numlines (count-lines (point) start-of-lines)))
+ (goto-char start-of-lines)
+ (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. ")
+ 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))
+
+ ;; perform action according to last char
+ (forward-line -1)
+ (cond
+
+ ((member key (list 'RET ?\C-m))
+ (funcall fun-on-ret))
+
+ ((member key (list 'TAB ?\C-i))
+ (funcall fun-on-tab))
+
+ ((eq key 'up)
+ (forward-line -1))
+
+ ((eq key 'down)
+ (forward-line 1))
+
+ ((eq key 'M-return)
+ (funcall fun-on-m-ret))
+
+ ((eq key 'S-return)
+ (funcall fun-on-s-ret)))))
+
+
+(defun org-index--occur-find-heading (x)
+ "helper for keymap of occur"
+ (interactive)
+ (save-excursion
+ (let ((ref (org-index--get-field :ref))
+ (link (org-index--get-field :link)))
+ (message (org-index--do-head ref link x)))))
+
+
+(defun org-index--do-new-line (create-ref)
+ "Do the common work for org-index-new-line and org-index"
+
+ (let (new)
+
+ (when create-ref
+ ;; go through table to find first entry to be reused
+ (when org-index--has-reuse
+ (goto-char org-index--below-hline)
+ ;; go through table
+ (while (and (org-at-table-p)
+ (not new))
+ (when (string=
+ (org-index--get-field :count)
+ ":reuse:")
+ (setq new (org-index--get-field :ref))
+ (if new (org-table-kill-row)))
+ (forward-line)))
+
+ ;; no ref to reuse; construct new reference
+ (unless new
+ (setq new (format "%s%d%s" org-index--head (1+ org-index--maxref) org-index--tail)))
+
+ ;; remember for org-mark-ring-goto
+ (setq org-index--text-to-yank new))
+
+ ;; insert ref or link as very first row
+ (goto-char org-index--below-hline)
+ (org-table-insert-row)
+
+ ;; insert some of the standard values
+ (org-table-goto-column (org-index--column-num :first))
+ (org-insert-time-stamp nil nil t)
+ (org-table-goto-column (org-index--column-num :count))
+ (insert "1")
+
+ new))
+
+
+(defun org-index--get-matching-lines (words numlines start-from)
+ (let ((numfound 0)
+ pos
+ initial line lines at-end)
+
+ (with-current-buffer org-index--buffer
+
+ ;; remember initial pos and start at requested
+ (setq initial (point))
+ (goto-char start-from)
+
+ ;; loop over buffer until we have found enough lines
+ (while (and (or (< numfound numlines)
+ (= numlines 0))
+ (org-at-table-p))
+
+ ;; check each word
+ (setq line (buffer-substring (line-beginning-position) (line-beginning-position 2)))
+ (when (org-index--test-words words line)
+ (setq lines (concat lines line))
+ (incf numfound))
+ (forward-line 1)
+ (setq pos (point)))
+
+ (setq at-end (not (org-at-table-p)))
+
+ ;; return to initial position
+ (goto-char initial))
+
+ (unless lines (setq lines ""))
+ (list pos lines at-end)))
+
+
+(defun org-index--test-words (words line)
+ (let ((found-all t))
+ (setq line (downcase line))
+ (catch 'not-found
+ (dolist (w words)
+ (or (search w line)
+ (throw 'not-found nil)))
+ t)))
+
+
+
+(defadvice org-mark-ring-goto (after org-index--advice-text-to-yank activate)
+ "Make text from org-index available for yank."
+ (when org-index--text-to-yank
+ (kill-new org-index--text-to-yank)
+ (message (format "Ready to yank '%s'" org-index--text-to-yank))
+ (setq org-index--text-to-yank nil)))
+
+
+(provide 'org-index)
+
+;; Local Variables:
+;; fill-column: 75
+;; comment-column: 50
+;; End:
+
+;;; org-index.el ends here
+
diff --git a/contrib/lisp/org-interactive-query.el b/contrib/lisp/org-interactive-query.el
index 57665e2..644132c 100644
--- a/contrib/lisp/org-interactive-query.el
+++ b/contrib/lisp/org-interactive-query.el
@@ -1,6 +1,6 @@
;;; org-interactive-query.el --- Interactive modification of agenda query
;;
-;; Copyright 2007-2013 Free Software Foundation, Inc.
+;; Copyright 2007-2014 Free Software Foundation, Inc.
;;
;; Author: Christopher League <league at contrapunctus dot net>
;; Version: 1.0
diff --git a/contrib/lisp/org-invoice.el b/contrib/lisp/org-invoice.el
index 88ff48f..c1340a7 100644
--- a/contrib/lisp/org-invoice.el
+++ b/contrib/lisp/org-invoice.el
@@ -1,6 +1,6 @@
;;; org-invoice.el --- Help manage client invoices in OrgMode
;;
-;; Copyright (C) 2008-2013 pmade inc. (Peter Jones pjones@pmade.com)
+;; Copyright (C) 2008-2014 pmade inc. (Peter Jones pjones@pmade.com)
;;
;; This file is not part of GNU Emacs.
;;
diff --git a/contrib/lisp/org-jira.el b/contrib/lisp/org-jira.el
index 57128fb..43edd08 100644
--- a/contrib/lisp/org-jira.el
+++ b/contrib/lisp/org-jira.el
@@ -1,6 +1,6 @@
;;; org-jira.el --- add a jira:ticket protocol to Org
(defconst org-jira-version "0.1")
-;; Copyright (C) 2008-2013 Jonathan Arkell.
+;; Copyright (C) 2008-2014 Jonathan Arkell.
;; Author: Jonathan Arkell <jonnay@jonnay.net>
;; This file is not part of GNU Emacs.
diff --git a/contrib/lisp/org-learn.el b/contrib/lisp/org-learn.el
index 1f5e76c..1755e71 100644
--- a/contrib/lisp/org-learn.el
+++ b/contrib/lisp/org-learn.el
@@ -1,6 +1,6 @@
;;; org-learn.el --- Implements SuperMemo's incremental learning algorithm
-;; Copyright (C) 2009-2013 Free Software Foundation, Inc.
+;; Copyright (C) 2009-2014 Free Software Foundation, Inc.
;; Author: John Wiegley <johnw at gnu dot org>
;; Keywords: outlines, hypermedia, calendar, wp
diff --git a/contrib/lisp/org-license.el b/contrib/lisp/org-license.el
index b452706..426b148 100644
--- a/contrib/lisp/org-license.el
+++ b/contrib/lisp/org-license.el
@@ -35,40 +35,25 @@
;;
;; You can download the images from http://www.davidam/img/licenses.tar.gz
;;
-;; TODO: create a function to test all combinations of licenses
+;;; CHANGELOG:
+;; v 0.2 - add public domain functions
+;; v 0.1 - Initial release
-(defvar org-license-images-directory "")
-
-(defun my-org-switch-language ()
-"Switch language if a `#+LANGUAGE:' Org meta-tag is on top 8 lines."
-(save-excursion
- (let (lang
- (license-alist '(("br" . "brazilian")
- ("ca" . "catalan")
- ("de" . "deutsch")
- ("en" . "american")
- ("eo" . "esperanto")
- ("eu" . "euskera")
- ("es" . "spanish"))))
- (when (re-search-backward "#\\+LANGUAGE: +\\([[:alpha:]_]*\\)" 1 t)
- (setq lang (match-string 1))
-;; (message lang)
- (ispell-change-dictionary (cdr (assoc lang dico-alist)))))))
-(add-hook 'org-mode-hook 'my-org-switch-language)
+(defvar org-license-images-directory "")
(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")
@@ -87,7 +72,6 @@ Testua [[" org-license-cc-url "][Aitortu 3.0 Espainia]] lizentziari jarraituz er
(setq org-license-cc-url "http://creativecommons.org/licenses/by/1.0/fi/deed.fi")
(insert (concat "* Lisenssi
Teksti on saatavilla [[" org-license-cc-url "][Nimeä 1.0 Suomi]] lisenssillä\n")))
-;;Nimeä 1.0 Suomi
((equal language "fr")
(setq org-license-cc-url "http://creativecommons.org/licenses/by/3.0/fr/deed.fr")
(insert (concat "* Licence
@@ -112,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"))))
@@ -169,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"))))
@@ -195,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")
@@ -227,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"))))
@@ -286,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"))))
@@ -344,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"))))
@@ -402,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"))))
@@ -414,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;
@@ -431,11 +416,41 @@ Copyright (C) 2013 " user-full-name
(insert "\n[[https://www.gnu.org/copyleft/fdl.html][file:https://upload.wikimedia.org/wikipedia/commons/thumb/4/42/GFDL_Logo.svg/200px-GFDL_Logo.svg.png]]\n")
(insert (concat "\n[[https://www.gnu.org/copyleft/fdl.html][file:" org-license-images-directory "/gfdl/gfdl.png]]\n"))))
+(defun org-license-publicdomain-zero (language)
+ (interactive "MLanguage ( en | es ): " language)
+ (setq org-license-pd-url "http://creativecommons.org/publicdomain/zero/1.0/")
+ (setq org-license-pd-file "zero/1.0/80x15.png")
+ (if (equal language "es")
+ (insert (concat "* Licencia
+Este documento está bajo una licencia [[" org-license-pd-url "][Public Domain Zero]]\n"))
+ (insert (concat "* License
+This documento is under a [[" org-license-pd-url "][Public Domain Zero]] license\n")))
+ (if (string= "" org-license-images-directory)
+ (insert (concat "\n[[" org-license-pd-url "][file:http://i.creativecommons.org/p/zero/1.0/80x15.png]]\n"))
+ (insert (concat "\n[[" org-license-pd-url "][file:" org-license-images-directory org-license-pd-file "]]\n"))))
+
+(defun org-license-publicdomain-mark (language)
+ (interactive "MLanguage ( en | es ): " language)
+ (setq org-license-pd-url "http://creativecommons.org/publicdomain/mark/1.0/")
+ (setq org-license-pd-file "mark/1.0/80x15.png")
+ (if (equal language "es")
+ (insert (concat "* Licencia
+Este documento está bajo una licencia [[" org-license-pd-url "][Etiqueta de Dominio Público 1.0]]\n"))
+ (insert (concat "* License
+This documento is under a [[" org-license-pd-url "][Public Domain Mark]] license\n")))
+ (if (string= "" org-license-images-directory)
+ (insert (concat "\n[[" org-license-pd-url "][file:http://i.creativecommons.org/p/mark/1.0/80x15.png]]\n"))
+ (insert (concat "\n[[" org-license-pd-url "][file:" org-license-images-directory org-license-pd-file "]]\n"))))
+
(defun org-license-print-all ()
"Print all combinations of licenses and languages, it's useful to find bugs"
(interactive)
(org-license-gfdl "es")
(org-license-gfdl "en")
+ (org-license-publicdomain-mark "es")
+ (org-license-publicdomain-mark "en")
+ (org-license-publicdomain-zero "es")
+ (org-license-publicdomain-zero "en")
(org-license-cc-by "br")
(org-license-cc-by "ca")
(org-license-cc-by "de")
@@ -521,3 +536,5 @@ Copyright (C) 2013 " user-full-name
(org-license-cc-by-nc-nd "nl")
(org-license-cc-by-nc-nd "pt")
)
+
+
diff --git a/contrib/lisp/org-mac-iCal.el b/contrib/lisp/org-mac-iCal.el
index afec84b..937b6dd 100644
--- a/contrib/lisp/org-mac-iCal.el
+++ b/contrib/lisp/org-mac-iCal.el
@@ -1,6 +1,6 @@
;;; org-mac-iCal.el --- Imports events from iCal.app to the Emacs diary
-;; Copyright (C) 2009-2013 Christopher Suckling
+;; Copyright (C) 2009-2014 Christopher Suckling
;; Author: Christopher Suckling <suckling at gmail dot com>
;; Version: 0.1057.104
diff --git a/contrib/lisp/org-mac-link.el b/contrib/lisp/org-mac-link.el
index ebcff75..e0636a5 100644
--- a/contrib/lisp/org-mac-link.el
+++ b/contrib/lisp/org-mac-link.el
@@ -1,15 +1,15 @@
-;;; org-mac-link.el --- Grab links and url from various mac
-;; Application and insert them as links into org-mode documents
+;;; org-mac-link.el --- Insert org-mode links to items selected in various Mac apps
;;
-;; Copyright (c) 2010-2013 Free Software Foundation, Inc.
+;; Copyright (c) 2010-2014 Free Software Foundation, Inc.
+;;
+;; 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>
;;
-;; Authors:
-;; Anthony Lander <anthony.lander@gmail.com>
-;; John Wiegley <johnw@gnu.org>
-;; Christopher Suckling <suckling at gmail dot com>
-;; Daniil Frumin <difrumin@gmail.com>
;;
-;;
;; Version: 1.1
;; Keywords: org, mac, hyperlink
;;
@@ -57,6 +57,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 +87,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 [f]irefox 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,23 +154,23 @@ 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)
-(defcustom org-mac-mail-account "customize"
+(defcustom org-mac-mail-account nil
"The Mail.app account in which to search for flagged messages."
:group 'org-mac-flagged-mail
:type 'string)
@@ -185,30 +191,35 @@ 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)) ?:)
-
+
;; Prompt the user, and grab the link
(message menu-string)
(setq input (read-char-exclusive))
@@ -221,12 +232,17 @@ 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>"
- (let* ((link-list
- (mapcar
- (lambda (x) (if (string-match "\\`\"\\(.*\\)\"\\'" x) (setq x (match-string 1 x))) x)
- (split-string as-link-list "[\r\n]+")))
+ "Paste in a list of links from an applescript handler.
+The links are of the form <link>::split::<name>."
+ (let* ((noquote-as-link-list
+ (if (string-prefix-p "\"" as-link-list)
+ (substring as-link-list 1 -1)
+ as-link-list))
+ (link-list
+ (mapcar (lambda (x) (if (string-match "\\`\"\\(.*\\)\"\\'" x)
+ (setq x (match-string 1 x)))
+ x)
+ (split-string noquote-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 +256,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 +272,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 +319,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,27 +365,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 oldClipboard to the clipboard\n"
- "set frontmostApplication to path to frontmost application\n"
- "tell application \"Google Chrome\"\n"
- " activate\n"
- " delay 0.15\n"
- " tell application \"System Events\"\n"
- " keystroke \"l\" 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))))
+ (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)
@@ -392,57 +402,45 @@ 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"))))
- (car (split-string result "[\r\n]+" t))))
+ (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")))
(defun org-mac-safari-get-frontmost-url ()
(interactive)
(message "Applescript: Getting Safari url...")
- (let* ((url-and-title (org-as-mac-safari-get-frontmost-url))
- (split-link (split-string url-and-title "::split::"))
- (URL (car split-link))
- (description (cadr split-link))
- (org-link))
- (when (not (string= URL ""))
- (setq org-link (org-make-link-string URL description)))
- (kill-new org-link)
- org-link))
+ (org-mac-paste-applescript-links
+ (org-as-mac-safari-get-frontmost-url)))
(defun org-mac-safari-insert-frontmost-url ()
(interactive)
(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)
@@ -452,26 +450,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)
@@ -483,30 +477,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)
@@ -517,8 +507,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)
@@ -531,40 +520,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)
@@ -583,12 +571,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)
@@ -597,9 +581,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."
@@ -680,16 +664,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))
@@ -710,17 +696,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) ">")))
@@ -728,67 +775,43 @@ 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."
+ (unless org-mac-mail-account
+ (error "You must set org-mac-mail-account"))
(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
+ ;; 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"
+ "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.
@@ -800,27 +823,11 @@ The Org-syntax text will be pushed to the kill ring, and also returned."
(interactive "sLink to (s)elected or (f)lagged messages: ")
(setq select-or-flag (or select-or-flag "s"))
(message "AppleScript: searching mailboxes...")
- (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\""))))
- (link-list
- (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::"))
- (setq URL (car split-link))
- (setq description (cadr split-link))
- (when (not (string= URL ""))
- (setq orglink (org-make-link-string URL description))
- (push orglink orglink-list)))
- (setq rtn (mapconcat 'identity orglink-list "\n"))
- (kill-new rtn)
- rtn))
+ (org-mac-paste-applescript-links
+ (cond
+ ((string= select-or-flag "s") (org-as-get-selected-mail))
+ ((string= select-or-flag "f") (org-as-get-flagged-mail))
+ (t (error "Please select \"s\" or \"f\"")))))
(defun org-mac-message-insert-selected ()
"Insert a link to the messages currently selected in Mail.app.
@@ -851,11 +858,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-mairix.el b/contrib/lisp/org-mairix.el
index b08897d..a19719e 100644
--- a/contrib/lisp/org-mairix.el
+++ b/contrib/lisp/org-mairix.el
@@ -1,6 +1,6 @@
;;; org-mairix.el - Support for hooking mairix search into Org for different MUAs
;;
-;; Copyright (C) 2007-2013 Georg C. F. Greve
+;; Copyright (C) 2007-2014 Georg C. F. Greve
;; mutt support by Adam Spiers <orgmode at adamspiers dot org>
;;
;; This file is not part of GNU Emacs.
diff --git a/contrib/lisp/org-mew.el b/contrib/lisp/org-mew.el
index ca6a352..4482375 100644
--- a/contrib/lisp/org-mew.el
+++ b/contrib/lisp/org-mew.el
@@ -1,6 +1,6 @@
;;; org-mew.el --- Support for links to Mew messages from within Org-mode
-;; Copyright (C) 2008-2013 Free Software Foundation, Inc.
+;; Copyright (C) 2008-2014 Free Software Foundation, Inc.
;; Author: Tokuya Kameshima <kames at fa2 dot so-net dot ne dot jp>
;; Keywords: outlines, hypermedia, calendar, wp
diff --git a/contrib/lisp/org-mime.el b/contrib/lisp/org-mime.el
index ef2057c..44bf91b 100644
--- a/contrib/lisp/org-mime.el
+++ b/contrib/lisp/org-mime.el
@@ -1,6 +1,6 @@
;;; org-mime.el --- org html export for text/html MIME emails
-;; Copyright (C) 2010-2013 Eric Schulte
+;; Copyright (C) 2010-2014 Eric Schulte
;; Author: Eric Schulte
;; Keywords: mime, mail, email, html
@@ -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 dadcef7..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-2013 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-notify.el b/contrib/lisp/org-notify.el
index 4047448..da2c96f 100644
--- a/contrib/lisp/org-notify.el
+++ b/contrib/lisp/org-notify.el
@@ -1,6 +1,6 @@
;;; org-notify.el --- Notifications for Org-mode
-;; Copyright (C) 2012, 2013 Free Software Foundation, Inc.
+;; Copyright (C) 2012, 2013, 2014 Free Software Foundation, Inc.
;; Author: Peter Münster <pmrb@free.fr>
;; Keywords: notification, todo-list, alarm, reminder, pop-up
diff --git a/contrib/lisp/org-notmuch.el b/contrib/lisp/org-notmuch.el
index c7f92fe..ae9b50b 100644
--- a/contrib/lisp/org-notmuch.el
+++ b/contrib/lisp/org-notmuch.el
@@ -1,6 +1,6 @@
;;; org-notmuch.el --- Support for links to notmuch messages from within Org-mode
-;; Copyright (C) 2010-2013 Matthieu Lemerre
+;; Copyright (C) 2010-2014 Matthieu Lemerre
;; Author: Matthieu Lemerre <racin@free.fr>
;; Keywords: outlines, hypermedia, calendar, wp
@@ -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..4ebd5a6
--- a/dev/null
+++ b/contrib/lisp/org-passwords.el
@@ -0,0 +1,384 @@
+;;; 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. It is part of org/contrib (see http://orgmode.org/). If
+;; you want to contribute with development, or have a problem, do it
+;; here: https://bitbucket.org/alfaromurillo/org-passwords.el
+
+;; 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', `org-passwords-copy-password' and
+;; `org-passwords-open-url' 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)
+;; (kbd "C-c o")
+;; 'org-passwords-open-url)))
+
+;; Finally, to enter new passwords, you can use `org-capture' and a
+;; minimal template like:
+
+;; ("p" "password" entry (file "~/documents/passwords.gpg")
+;; "* %^{Title}\n %^{URL}p %^{USERNAME}p %^{PASSWORD}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)
+
+;;;###autoload
+(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."
+ :type 'string
+ :group 'org-passwords)
+
+(defcustom org-passwords-username-property "USERNAME"
+ "Name of the property for user name entry."
+ :type 'string
+ :group 'org-passwords)
+
+(defcustom org-passwords-url-property "URL"
+ "Name of the property for URL entry."
+ :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-default-password-size "20"
+ "Default number of characters to use in
+org-passwords-generate-password. It has to be a string."
+ :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)
+
+(defcustom org-passwords-default-random-words-number "5"
+ "Default number of words to use in org-passwords-random-words.
+It has to be a string."
+ :type 'str
+ :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)
+ (funcall interprogram-cut-function
+ (org-entry-get (point)
+ org-passwords-password-property)))
+
+(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)
+ (funcall interprogram-cut-function
+ (org-entry-get (point)
+ org-passwords-username-property
+ t)))
+
+(defun org-passwords-open-url ()
+ "Browse the URL associated with the entry at the location of
+the cursor."
+ (interactive)
+ (browse-url (org-entry-get (point)
+ org-passwords-url-property
+ t)))
+
+;;;###autoload
+(defun org-passwords (&optional arg)
+ "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'.
+
+With prefix arg ARG, the command does not set up a timer to kill the buffer.
+
+With a double prefix arg \\[universal-argument] \\[universal-argument], open the file for editing.
+"
+ (interactive "P")
+ (if org-passwords-file
+ (progn
+ (add-to-list 'auto-mode-alist
+ (cons
+ (regexp-quote
+ (expand-file-name org-passwords-file))
+ 'org-passwords-mode))
+ (if (equal arg '(4))
+ (find-file-read-only org-passwords-file)
+ (if (equal arg '(16))
+ (find-file org-passwords-file)
+ (progn
+ (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
+ (read-from-minibuffer
+ (concat "Number of characters (default "
+ org-passwords-default-password-size
+ "): ")
+ nil
+ nil
+ t
+ nil
+ org-passwords-default-password-size)))
+ (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
+ (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
+ (read-from-minibuffer
+ (concat "Number of words (default "
+ org-passwords-default-random-words-number
+ "): ")
+ nil
+ nil
+ t
+ nil
+ org-passwords-default-random-words-number))
+ (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
+ this
+ (cdr list-of-strings)))
+ (car list-of-strings)))
+
+(provide 'org-passwords)
+
+;;; org-passwords.el ends here
diff --git a/contrib/lisp/org-registry.el b/contrib/lisp/org-registry.el
index b0ee208..402ce30 100644
--- a/contrib/lisp/org-registry.el
+++ b/contrib/lisp/org-registry.el
@@ -1,6 +1,6 @@
;;; org-registry.el --- a registry for Org links
;;
-;; Copyright 2007-2013 Bastien Guerry
+;; Copyright 2007-2014 Bastien Guerry
;;
;; Emacs Lisp Archive Entry
;; Filename: org-registry.el
diff --git a/contrib/lisp/org-screen.el b/contrib/lisp/org-screen.el
index 3334a0f..6b870f2 100644
--- a/contrib/lisp/org-screen.el
+++ b/contrib/lisp/org-screen.el
@@ -1,6 +1,6 @@
;;; org-screen.el --- Integreate Org-mode with screen.
-;; Copyright (c) 2008-2013 Andrew Hyatt
+;; Copyright (c) 2008-2014 Andrew Hyatt
;;
;; Author: Andrew Hyatt <ahyatt at gmail dot com>
;; Maintainer: Carsten Dominik <carsten at orgmode dot org>
diff --git a/contrib/lisp/org-screenshot.el b/contrib/lisp/org-screenshot.el
index a54cb8f..6d10783 100644
--- a/contrib/lisp/org-screenshot.el
+++ b/contrib/lisp/org-screenshot.el
@@ -1,6 +1,6 @@
;;; org-screenshot.el --- Take and manage screenshots in Org-mode files
;;
-;; Copyright (C) 2009-2013
+;; Copyright (C) 2009-2014
;; Free Software Foundation, Inc.
;;
;; Author: Max Mikhanosha <max@openchat.com>
diff --git a/contrib/lisp/org-secretary.el b/contrib/lisp/org-secretary.el
index e98eb34..babfb75 100644
--- a/contrib/lisp/org-secretary.el
+++ b/contrib/lisp/org-secretary.el
@@ -1,5 +1,5 @@
;;; org-secretary.el --- Team management with org-mode
-;; Copyright (C) 2010-2013 Juan Reyero
+;; Copyright (C) 2010-2014 Juan Reyero
;;
;; Author: Juan Reyero <juan _at_ juanreyero _dot_ com>
;; Keywords: outlines, tasks, team, management
diff --git a/contrib/lisp/org-sudoku.el b/contrib/lisp/org-sudoku.el
index 2bf24d8..4b4a3ac 100644
--- a/contrib/lisp/org-sudoku.el
+++ b/contrib/lisp/org-sudoku.el
@@ -1,6 +1,6 @@
;;; org-sudoku.el --- Greate and solve SUDOKU games in Org tables
-;; Copyright (C) 2012, 2013 Free Software Foundation, Inc.
+;; Copyright (C) 2012, 2013, 2014 Free Software Foundation, Inc.
;;
;; Author: Carsten Dominik <carsten at orgmode dot org>
;; Keywords: outlines, hypermedia, calendar, wp, games
diff --git a/contrib/lisp/org-toc.el b/contrib/lisp/org-toc.el
index 2d6c846..255b79e 100644
--- a/contrib/lisp/org-toc.el
+++ b/contrib/lisp/org-toc.el
@@ -1,6 +1,6 @@
;;; org-toc.el --- Table of contents for Org-mode buffer
-;; Copyright 2007-2013 Free Software Foundation, Inc.
+;; Copyright 2007-2014 Free Software Foundation, Inc.
;;
;; Author: Bastien Guerry <bzg@gnu.org>
;; Keywords: Org table of contents
diff --git a/contrib/lisp/org-track.el b/contrib/lisp/org-track.el
index 4a9d71d..434060b 100644
--- a/contrib/lisp/org-track.el
+++ b/contrib/lisp/org-track.el
@@ -1,6 +1,6 @@
;;; org-track.el --- Track the most recent Org-mode version available.
;;
-;; Copyright (C) 2009-2013
+;; Copyright (C) 2009-2014
;; Free Software Foundation, Inc.
;;
;; Author: Bastien Guerry <bzg@gnu.org>
diff --git a/contrib/lisp/org-velocity.el b/contrib/lisp/org-velocity.el
index fa41406..e6788c6 100644
--- a/contrib/lisp/org-velocity.el
+++ b/contrib/lisp/org-velocity.el
@@ -1,6 +1,6 @@
;;; org-velocity.el --- something like Notational Velocity for Org.
-;; Copyright (C) 2010-2013 Paul M. Rodriguez
+;; Copyright (C) 2010-2014 Paul M. Rodriguez
;; Author: Paul M. Rodriguez <paulmrodriguez@gmail.com>
;; Created: 2010-05-05
@@ -671,7 +671,7 @@ Stop searching once there are more matches than can be displayed."
;; Truncate the index to the size of the buffer to be
;; displayed.
(with-selected-window match-window
- (if (> (window-height) (length org-velocity-index))
+ (if (< (window-height) (length org-velocity-index))
;; (subseq org-velocity-index 0 (window-height))
(let ((hints (copy-sequence org-velocity-index)))
(setcdr (nthcdr (window-height) hints) nil)
diff --git a/contrib/lisp/org-vm.el b/contrib/lisp/org-vm.el
index f60c5bb..5d30f64 100644
--- a/contrib/lisp/org-vm.el
+++ b/contrib/lisp/org-vm.el
@@ -1,6 +1,6 @@
;;; org-vm.el --- Support for links to VM messages from within Org-mode
-;; Copyright (C) 2004-2013 Free Software Foundation, Inc.
+;; Copyright (C) 2004-2014 Free Software Foundation, Inc.
;; Author: Carsten Dominik <carsten at orgmode dot org>
;; Keywords: outlines, hypermedia, calendar, wp
diff --git a/contrib/lisp/org-wikinodes.el b/contrib/lisp/org-wikinodes.el
index 4efc373..7f3e2e3 100644
--- a/contrib/lisp/org-wikinodes.el
+++ b/contrib/lisp/org-wikinodes.el
@@ -1,6 +1,6 @@
;;; org-wikinodes.el --- Wiki-like CamelCase links to outline nodes
-;; Copyright (C) 2010-2013 Free Software Foundation, Inc.
+;; Copyright (C) 2010-2014 Free Software Foundation, Inc.
;; Author: Carsten Dominik <carsten at orgmode dot org>
;; Keywords: outlines, hypermedia, calendar, wp
@@ -82,8 +82,6 @@ to `directory'."
;; in heading - deactivate flyspell
(org-remove-flyspell-overlays-in (match-beginning 0)
(match-end 0))
- (add-text-properties (match-beginning 0) (match-end 0)
- '(org-no-flyspell t))
t)
;; this is a wiki link
(org-remove-flyspell-overlays-in (match-beginning 0)
@@ -270,7 +268,6 @@ If there is no such wiki target, return nil."
(car org-export-target-aliases))))
(push (caar target-alist) (cdr a)))))
-(defvar org-current-export-file)
(defun org-wikinodes-process-links-for-export ()
"Process Wiki links in the export preprocess buffer.
@@ -296,12 +293,6 @@ with working links."
((eq org-wikinodes-scope 'file)
;; No match in file, and other files are not allowed
(insert (format "%s" link)))
- ((setq file
- (and (org-string-nw-p org-current-export-file)
- (org-wikinodes-which-file
- link (file-name-directory org-current-export-file))))
- ;; Match in another file in the current directory
- (insert (format "[[file:%s::%s][%s]]" file link link)))
(t ;; No match for this link
(insert (format "%s" link)))))))))
diff --git a/contrib/lisp/org-wl.el b/contrib/lisp/org-wl.el
index 1128ef7..632c9e3 100644
--- a/contrib/lisp/org-wl.el
+++ b/contrib/lisp/org-wl.el
@@ -1,6 +1,6 @@
;;; org-wl.el --- Support for links to Wanderlust messages from within Org-mode
-;; Copyright (C) 2004-2013 Free Software Foundation, Inc.
+;; Copyright (C) 2004-2014 Free Software Foundation, Inc.
;; Author: Tokuya Kameshima <kames at fa2 dot so-net dot ne dot jp>
;; David Maus <dmaus at ictsoc dot de>
diff --git a/contrib/lisp/orgtbl-sqlinsert.el b/contrib/lisp/orgtbl-sqlinsert.el
index b00c93d..ed8f915 100644
--- a/contrib/lisp/orgtbl-sqlinsert.el
+++ b/contrib/lisp/orgtbl-sqlinsert.el
@@ -1,6 +1,6 @@
;;; orgtbl-sqlinsert.el --- orgtbl to SQL insert statements.
-;; Copyright (C) 2008-2013 Free Software Foundation
+;; Copyright (C) 2008-2014 Free Software Foundation
;; Author: Jason Riedy <jason@acm.org>
;; Keywords: org, tables, sql
diff --git a/contrib/lisp/ox-bibtex.el b/contrib/lisp/ox-bibtex.el
index 29a97eb..7cb8972 100644
--- a/contrib/lisp/ox-bibtex.el
+++ b/contrib/lisp/ox-bibtex.el
@@ -1,6 +1,6 @@
;;; ox-bibtex.el --- Export bibtex fragments
-;; Copyright (C) 2009-2013 Taru Karttunen
+;; Copyright (C) 2009-2014 Taru Karttunen
;; Author: Taru Karttunen <taruti@taruti.net>
;; Nicolas Goaziou <n dot goaziou at gmail dot com>
@@ -23,21 +23,31 @@
;;; Commentary:
;;
-;; This is an utility to handle BibTeX export to both LaTeX and html
-;; exports. It uses the bibtex2html software from:
+;; This is an utility to handle BibTeX export to LaTeX, html and ascii
+;; exports. For HTML and ascii it uses the bibtex2html software from:
;;
;; http://www.lri.fr/~filliatr/bibtex2html/
;;
+;; For ascii it uses the pandoc software from:
+;;
+;; http://johnmacfarlane.net/pandoc/
+;;
;; It also introduces "cite" syntax for Org links.
;;
;; The usage is as follows:
;;
-;; #+BIBLIOGRAPHY: bibfilebasename stylename optional-options
+;; #+BIBLIOGRAPHY: bibfilename stylename optional-options
;;
;; e.g. given foo.bib and using style plain:
;;
;; #+BIBLIOGRAPHY: foo plain option:-d
;;
+;; "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
@@ -71,14 +81,18 @@
;; 2) creates a foo.html and foo_bib.html,
;; 3) includes the contents of foo.html in the exported HTML file.
;;
+;; For ascii export it:
+;; 1) converts all \cite{foo} and [[cite:foo]] to links to the
+;; bibliography,
+;; 2) creates a foo.txt and foo_bib.html,
+;; 3) includes the contents of foo.txt in the exported ascii file.
+;;
;; For LaTeX export it:
;; 1) converts all [[cite:foo]] to \cite{foo}.
;; Initialization
(eval-when-compile (require 'cl))
-(org-add-link-type "cite" 'ebib)
-
;;; Internal Functions
@@ -103,9 +117,9 @@ return nil instead."
(defun org-bibtex-get-arguments (keyword)
"Return \"bibtex2html\" arguments specified by the user.
KEYWORD is a \"BIBLIOGRAPHY\" keyword. Return value is a plist
-containing `:options' and `:limit' properties. The former
-contains a list of strings to be passed as options ot
-\"bibtex2html\" process. The latter contains a boolean."
+containing `:options' and `:limit' properties. The former
+contains a list of strings to be passed as options to
+\"bibtex2html\" process. The latter contains a boolean."
(let ((value (org-element-property :value keyword)))
(and value
(string-match "\\(\\S-+\\)[ \t]+\\(\\S-+\\)\\(.*\\)" value)
@@ -137,6 +151,196 @@ 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
+
+(defun org-bibtex-process-bib-files (tree backend info)
+ "Send each bibliography in parse tree to \"bibtex2html\" process.
+Return new parse tree."
+ (when (org-export-derived-backend-p backend 'ascii 'html)
+ ;; Initialize dynamically scoped variables. The first one
+ ;; contain an alist between keyword objects and their HTML
+ ;; translation. The second one will contain an alist between
+ ;; citation keys and names in the output (according to style).
+ (setq org-bibtex-html-entries-alist nil
+ org-bibtex-html-keywords-alist nil)
+ (org-element-map tree 'keyword
+ (lambda (keyword)
+ (when (equal (org-element-property :key keyword) "BIBLIOGRAPHY")
+ (let ((arguments (org-bibtex-get-arguments keyword))
+ (file (org-bibtex-get-file keyword))
+ 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.
+ (when (plist-get arguments :limit)
+ (let ((citations
+ (org-element-map tree '(latex-fragment link)
+ (lambda (object)
+ (and (org-bibtex-citation-p object)
+ (org-bibtex-get-citation-key object))))))
+ (with-temp-file (setq temp-file (make-temp-file "ox-bibtex"))
+ (insert (mapconcat 'identity citations "\n")))
+ (setq arguments
+ (plist-put arguments
+ :options
+ (append (plist-get arguments :options)
+ (list "-citefile" temp-file))))))
+ ;; Call "bibtex2html" on specified file.
+ (unless (eq 0 (apply
+ 'call-process
+ (append '("bibtex2html" nil nil nil)
+ '("-a" "-nodoc" "-noheader" "-nofooter")
+ (let ((style
+ (org-not-nil
+ (org-bibtex-get-style keyword))))
+ (and style (list "--style" style)))
+ (plist-get arguments :options)
+ (list (concat file ".bib")))))
+ (error "Executing bibtex2html failed"))
+ (and temp-file (delete-file temp-file))
+ ;; Open produced HTML file, and collect Bibtex key names
+ (with-temp-buffer
+ (insert-file-contents (concat out-file ".html"))
+ ;; Update `org-bibtex-html-entries-alist'.
+ (goto-char (point-min))
+ (while (re-search-forward
+ "a name=\"\\([-_a-zA-Z0-9:]+\\)\">\\(\\w+\\)" nil t)
+ (push (cons (match-string 1) (match-string 2))
+ org-bibtex-html-entries-alist)))
+ ;; Open produced HTML file, wrap references within a block and
+ ;; return it.
+ (with-temp-buffer
+ (cond
+ ((org-export-derived-backend-p backend '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 out-file ".html")
+ "-o"
+ (concat out-file ".txt")))
+ (error "Executing pandoc failed"))
+ (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)
+ (replace-match ""))
+ (goto-char (point-min))
+ (while (re-search-forward "\\( \\]\\| \\]\\| |\\)" nil t)
+ (replace-match ""))
+ (goto-char (point-min))
+ (while (re-search-forward "[\n\r]\\([\n\r][\n\r]\\)" nil t)
+ (replace-match "\\1"))))
+ ;; Update `org-bibtex-html-keywords-alist'.
+ (push (cons keyword (buffer-string))
+ org-bibtex-html-keywords-alist)))))))
+ ;; Return parse tree unchanged.
+ 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 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)
+ (when (org-bibtex-citation-p object)
+ (let ((new-citation (list 'latex-fragment
+ (list :value ""
+ :post-blank (org-element-property
+ :post-blank object))))
+ option)
+ ;; Insert NEW-CITATION right before OBJECT.
+ (org-element-insert-before new-citation object)
+ ;; Remove all subsequent contiguous citations from parse
+ ;; tree, keeping only their citation key.
+ (let ((keys (list (org-bibtex-get-citation-key object)))
+ next)
+ (while (and (setq next (org-export-get-next-element object info))
+ (or (and (stringp next)
+ (not (org-string-match-p "\\S-" next)))
+ (org-bibtex-citation-p next)))
+ (unless (stringp next)
+ (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
+ ;; as the last citation removed.
+ (org-element-put-property
+ new-citation
+ :post-blank (org-element-property :post-blank object))
+ (org-element-put-property
+ new-citation
+ :value (format "\\cite%s{%s}"
+ (or option "")
+ (mapconcat 'identity (nreverse keys) ",")))))))))
+ tree)
+
+(eval-after-load 'ox
+ '(progn (add-to-list 'org-export-filter-parse-tree-functions
+ 'org-bibtex-process-bib-files)
+ (add-to-list 'org-export-filter-parse-tree-functions
+ 'org-bibtex-merge-contiguous-citations)))
+
;;; LaTeX Part
@@ -148,22 +352,13 @@ Fallback to `latex' back-end for other keywords."
(if (not (equal (org-element-property :key keyword) "BIBLIOGRAPHY"))
ad-do-it
(let ((file (org-bibtex-get-file keyword))
- (style (org-bibtex-get-style keyword)))
+ (style (org-not-nil (org-bibtex-get-style keyword))))
(setq ad-return-value
(when file
(concat (and style (format "\\bibliographystyle{%s}\n" style))
(format "\\bibliography{%s}" file))))))))
-(defadvice org-latex-link (around bibtex-link)
- "Translate \"cite\" type links into LaTeX syntax.
-Fallback to `latex' back-end for other keywords."
- (let ((link (ad-get-arg 0)))
- (if (not (org-bibtex-citation-p link)) ad-do-it
- (setq ad-return-value
- (format "\\cite{%s}" (org-bibtex-get-citation-key link))))))
-
(ad-activate 'org-latex-keyword)
-(ad-activate 'org-latex-link)
@@ -190,103 +385,46 @@ Fallback to `html' back-end for other keywords."
(let ((fragment (ad-get-arg 0)))
(if (not (org-bibtex-citation-p fragment)) ad-do-it
(setq ad-return-value
- (mapconcat
- (lambda (key)
- (let ((key (org-trim key)))
- (format "[<a href=\"#%s\">%s</a>]"
- key
- (or (cdr (assoc key org-bibtex-html-entries-alist))
- key))))
- (org-split-string (org-bibtex-get-citation-key fragment) ",")
- "")))))
-
-(defadvice org-html-link (around bibtex-link)
- "Translate \"cite:\" type links into HTML syntax.
-Fallback to `html' back-end for other types."
- (let ((link (ad-get-arg 0)))
- (if (not (org-bibtex-citation-p link)) ad-do-it
- (setq ad-return-value
- (mapconcat
- (lambda (key)
- (format "[<a href=\"#%s\">%s</a>]"
- key
- (or (cdr (assoc key org-bibtex-html-entries-alist))
- key)))
- (org-split-string (org-bibtex-get-citation-key link)
- "[ \t]*,[ \t]*")
- "")))))
+ (format "[%s]"
+ (mapconcat
+ (lambda (key)
+ (format "<a href=\"#%s\">%s</a>"
+ key
+ (or (cdr (assoc key org-bibtex-html-entries-alist))
+ key)))
+ (org-split-string
+ (org-bibtex-get-citation-key fragment) ",") ","))))))
(ad-activate 'org-html-keyword)
(ad-activate 'org-html-latex-fragment)
-(ad-activate 'org-html-link)
-
-
-;;;; Filter
-
-(defun org-bibtex-process-bib-files (tree backend info)
- "Send each bibliography in parse tree to \"bibtex2html\" process.
-Return new parse tree. This function assumes current back-end is HTML."
- ;; Initialize dynamically scoped variables. The first one
- ;; contain an alist between keyword objects and their HTML
- ;; translation. The second one will contain an alist between
- ;; citation keys and names in the output (according to style).
- (setq org-bibtex-html-entries-alist nil
- org-bibtex-html-keywords-alist nil)
- (org-element-map tree 'keyword
- (lambda (keyword)
- (when (equal (org-element-property :key keyword) "BIBLIOGRAPHY")
- (let ((arguments (org-bibtex-get-arguments keyword))
- (file (org-bibtex-get-file keyword))
- temp-file)
- ;; limit is set: collect citations throughout the document
- ;; in TEMP-FILE and pass it to "bibtex2html" as "-citefile"
- ;; argument.
- (when (plist-get arguments :limit)
- (let ((citations
- (org-element-map tree '(latex-fragment link)
- (lambda (object)
- (and (org-bibtex-citation-p object)
- (org-bibtex-get-citation-key object))))))
- (with-temp-file (setq temp-file (make-temp-file "ox-bibtex"))
- (insert (mapconcat 'identity citations "\n")))
- (setq arguments
- (plist-put arguments
- :options
- (append (plist-get arguments :options)
- (list "-citefile" temp-file))))))
- ;; Call "bibtex2html" on specified file.
- (unless (eq 0 (apply 'call-process
- (append '("bibtex2html" nil nil nil)
- '("-a" "-nodoc" "-noheader" "-nofooter")
- (list "--style"
- (org-bibtex-get-style keyword))
- (plist-get arguments :options)
- (list (concat file ".bib")))))
- (error "Executing bibtex2html failed"))
- (and temp-file (delete-file temp-file))
- ;; Open produced HTML file, wrap references within a block and
- ;; return it.
- (with-temp-buffer
- (insert "<div id=\"bibliography\">\n<h2>References</h2>\n")
- (insert-file-contents (concat file ".html"))
- (insert "\n</div>")
- ;; Update `org-bibtex-html-keywords-alist'.
- (push (cons keyword (buffer-string))
- org-bibtex-html-keywords-alist)
- ;; Update `org-bibtex-html-entries-alist'.
- (goto-char (point-min))
- (while (re-search-forward
- "a name=\"\\([-_a-zA-Z0-9:]+\\)\">\\(\\w+\\)" nil t)
- (push (cons (match-string 1) (match-string 2))
- org-bibtex-html-entries-alist)))))))
- ;; Return parse tree unchanged.
- tree)
-(eval-after-load 'ox
- '(add-to-list 'org-export-filter-parse-tree-functions
- 'org-bibtex-process-bib-files))
+
+;;; Ascii Part
+(defadvice org-ascii-keyword (around bibtex-keyword)
+ "Translate \"BIBLIOGRAPHY\" keywords into ascii syntax.
+Fallback to `ascii' back-end for other keywords."
+ (let ((keyword (ad-get-arg 0)))
+ (if (not (equal (org-element-property :key keyword) "BIBLIOGRAPHY"))
+ ad-do-it
+ (setq ad-return-value
+ (cdr (assq keyword org-bibtex-html-keywords-alist))))))
+(defadvice org-ascii-latex-fragment (around bibtex-citation)
+ "Translate \"\\cite\" LaTeX fragments into ascii syntax.
+Fallback to `ascii' back-end for other keywords."
+ (let ((fragment (ad-get-arg 0)))
+ (if (not (org-bibtex-citation-p fragment)) ad-do-it
+ (setq ad-return-value
+ (format "[%s]"
+ (mapconcat
+ (lambda (key)
+ (or (cdr (assoc key org-bibtex-html-entries-alist))
+ key))
+ (org-split-string
+ (org-bibtex-get-citation-key fragment) ",") ","))))))
+(ad-activate 'org-ascii-keyword)
+(ad-activate 'org-ascii-latex-fragment)
(provide 'ox-bibtex)
diff --git a/contrib/lisp/ox-confluence.el b/contrib/lisp/ox-confluence.el
index c87c23e..9b96d5f 100644
--- a/contrib/lisp/ox-confluence.el
+++ b/contrib/lisp/ox-confluence.el
@@ -1,6 +1,6 @@
;;; ox-confluence --- Confluence Wiki Back-End for Org Export Engine
-;; Copyright (C) 2012 Sébastien Delafond
+;; Copyright (C) 2012, 2014 Sébastien Delafond
;; Author: Sébastien Delafond <sdelafond@gmail.com>
;; Keywords: outlines, confluence, wiki
diff --git a/contrib/lisp/ox-deck.el b/contrib/lisp/ox-deck.el
index 847f7af..0ebde41 100644
--- a/contrib/lisp/ox-deck.el
+++ b/contrib/lisp/ox-deck.el
@@ -1,6 +1,6 @@
;;; ox-deck.el --- deck.js Presentation Back-End for Org Export Engine
-;; Copyright (C) 2013 Rick Frankel
+;; Copyright (C) 2013, 2014 Rick Frankel
;; Author: Rick Frankel <emacs at rickster dot com>
;; Keywords: outlines, hypermedia, slideshow
@@ -55,7 +55,7 @@
(:html-link-up "HTML_LINK_UP" nil nil)
(:deck-postamble "DECK_POSTAMBLE" nil org-deck-postamble newline)
(:deck-preamble "DECK_PREAMBLE" nil org-deck-preamble newline)
- (:html-head-include-default-style "HTML_INCLUDE_DEFAULT_STYLE" nil nil)
+ (:html-head-include-default-style "HTML_INCLUDE_DEFAULT_STYLE" "html-style" nil)
(:html-head-include-scripts "HTML_INCLUDE_SCRIPTS" nil nil)
(:deck-base-url "DECK_BASE_URL" nil org-deck-base-url)
(:deck-theme "DECK_THEME" nil org-deck-theme)
@@ -319,7 +319,7 @@ and have the id \"title-slide\"."
(include (plist-get info :deck-include-extensions))
(exclude (plist-get info :deck-exclude-extensions))
(scripts '()) (sheets '()) (snippets '()))
- (add-to-list 'scripts (concat prefix "jquery-1.7.2.min.js"))
+ (add-to-list 'scripts (concat prefix "jquery.min.js"))
(add-to-list 'scripts (concat prefix "core/deck.core.js"))
(add-to-list 'scripts (concat prefix "modernizr.custom.js"))
(add-to-list 'sheets (concat prefix "core/deck.core.css"))
@@ -368,7 +368,7 @@ holding export options."
"Transcode an ITEM element from Org to HTML.
CONTENTS holds the contents of the item. INFO is a plist holding
contextual information.
-If the containing headline has the property :slide, then
+If the containing headline has the property :STEP, then
the \"slide\" class will be added to the to the list element,
which will make the list into a \"build\"."
(let ((text (org-html-item item contents info)))
@@ -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-freemind.el b/contrib/lisp/ox-freemind.el
index 801bda1..39fb1cc 100644
--- a/contrib/lisp/ox-freemind.el
+++ b/contrib/lisp/ox-freemind.el
@@ -1,6 +1,6 @@
;;; ox-freemind.el --- Freemind Mindmap Back-End for Org Export Engine
-;; Copyright (C) 2013 Free Software Foundation, Inc.
+;; Copyright (C) 2013, 2014 Free Software Foundation, Inc.
;; Author: Jambunathan K <kjambunathan at gmail dot com>
;; Keywords: outlines, hypermedia, calendar, wp
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 245b67d..d8baf39 100644
--- a/contrib/lisp/ox-groff.el
+++ b/contrib/lisp/ox-groff.el
@@ -1,6 +1,6 @@
;;; ox-groff.el --- Groff Back-End for Org Export Engine
-;; Copyright (C) 2011-2013 Free Software Foundation, Inc.
+;; Copyright (C) 2011-2014 Free Software Foundation, Inc.
;; Author: Nicolas Goaziou <n.goaziou at gmail dot com>
;; Author: Luis R Anaya <papoanaya aroba hot mail punto com>
@@ -77,7 +77,6 @@
(planning . org-groff-planning)
(property-drawer . org-groff-property-drawer)
(quote-block . org-groff-quote-block)
- (quote-section . org-groff-quote-section)
(radio-target . org-groff-radio-target)
(section . org-groff-section)
(special-block . org-groff-special-block)
@@ -1254,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
@@ -1273,9 +1268,10 @@ 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 path)))))
+ (org-export-solidify-link-text
+ (org-element-property :value destination))))))
;; Links pointing to a headline: find destination and build
;; appropriate referencing command.
@@ -1457,15 +1453,6 @@ holding contextual information."
quote-block
(format ".DS I\n.I\n%s\n.R\n.DE" contents)))
-;;; Quote Section
-
-(defun org-groff-quote-section (quote-section contents info)
- "Transcode a QUOTE-SECTION element from Org to Groff.
-CONTENTS is nil. INFO is a plist holding contextual information."
- (let ((value (org-remove-indentation
- (org-element-property :value quote-section))))
- (when value (format ".DS L\n\\fI%s\\fP\n.DE\n" value))))
-
;;; Radio Target
(defun org-groff-radio-target (radio-target text info)
@@ -1491,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 240de29..23c4c39 100644
--- a/contrib/lisp/ox-koma-letter.el
+++ b/contrib/lisp/ox-koma-letter.el
@@ -1,6 +1,6 @@
;;; ox-koma-letter.el --- KOMA Scrlttr2 Back-End for Org Export Engine
-;; Copyright (C) 2007-2012 Free Software Foundation, Inc.
+;; Copyright (C) 2007-2012, 2014 Free Software Foundation, Inc.
;; Author: Nicolas Goaziou <n.goaziou AT gmail DOT com>
;; Alan Schmitt <alan.schmitt AT polytechnique DOT org>
@@ -34,14 +34,14 @@
;; On top of buffer keywords supported by `latex' back-end (see
;; `org-latex-options-alist'), this back-end introduces the following
;; keywords:
-;; - "CLOSING" (see `org-koma-letter-closing'),
-;; - "FROM_ADDRESS" (see `org-koma-letter-from-address'),
-;; - "LCO" (see `org-koma-letter-class-option-file'),
-;; - "OPENING" (see `org-koma-letter-opening'),
-;; - "PHONE_NUMBER" (see `org-koma-letter-phone-number'),
-;; - "SIGNATURE" (see `org-koma-letter-signature')
-;; - "PLACE" (see `org-koma-letter-place')
-;; - and "TO_ADDRESS". If unspecified this is set to "\mbox{}".
+;; - CLOSING: see `org-koma-letter-closing',
+;; - FROM_ADDRESS: see `org-koma-letter-from-address',
+;; - LCO: see `org-koma-letter-class-option-file',
+;; - OPENING: see `org-koma-letter-opening',
+;; - PHONE_NUMBER: see `org-koma-letter-phone-number',
+;; - SIGNATURE: see `org-koma-letter-signature',
+;; - PLACE: see `org-koma-letter-place',
+;; - TO_ADDRESS: If unspecified this is set to "\mbox{}".
;;
;; TO_ADDRESS and FROM_ADDRESS can also be specified using heading
;; with the special tags specified in
@@ -67,8 +67,9 @@
;; (see `org-koma-letter-special-tags-after-letter').
;;
;; The following variables works differently from the main LaTeX class
-;; - "AUTHOR": default to user-full-name but may be disabled. (see org-koma-letter-author),
-;; - "EMAIL": same as AUTHOR, (see org-koma-letter-email),
+;; - AUTHOR: Default to user-full-name but may be disabled.
+;; (See also `org-koma-letter-author'),
+;; - EMAIL: Same as AUTHOR. (see also `org-koma-letter-email'),
;;
;; Headlines are in general ignored. However, headlines with special
;; tags can be used for specified contents like postscript (ps),
@@ -84,16 +85,10 @@
;; with information is present precedence is determined by
;; `org-koma-letter-prefer-special-headings'.
;;
-;; You will need to add an appropriate association in
-;; `org-latex-classes' in order to use the KOMA Scrlttr2 class.
-;; The easiest way to do this is by adding
-;;
-;; (eval-after-load "ox-koma-letter"
-;; '(org-koma-letter-plug-into-ox))
-;;
-;; to your init file. This will add a sparse scrlttr2 class and
-;; set it as the default `org-koma-latex-default-class'. You can also
-;; add you own letter class. For instace:
+;; You need an appropriate association in `org-latex-classes' in order
+;; to use the KOMA Scrlttr2 class. By default, a sparse scrlttr2
+;; class is provided: "default-koma-letter". You can also add you own
+;; letter class. For instance:
;;
;; (add-to-list 'org-latex-classes
;; '("my-letter"
@@ -111,16 +106,26 @@
;; \[EXTRA]"))
;;
;; Then, in your Org document, be sure to require the proper class
-;; with :
+;; with:
;;
;; #+LATEX_CLASS: my-letter
;;
;; Or by setting `org-koma-letter-default-class'.
+;;
+;; You may have to load (LaTeX) Babel as well, e.g., by adding
+;; it to `org-latex-packages-alist',
+;;
+;; (add-to-list 'org-latex-packages-alist '("AUTO" "babel" nil))
;;; Code:
(require 'ox-latex)
+;; Install a default letter class.
+(unless (assoc "default-koma-letter" org-latex-classes)
+ (add-to-list 'org-latex-classes
+ '("default-koma-letter" "\\documentclass[11pt]{scrlttr2}")))
+
;;; User-Configurable Variables
@@ -130,17 +135,20 @@
:group 'org-export)
(defcustom org-koma-letter-class-option-file "NF"
- "Letter Class Option File."
+ "Letter Class Option File.
+This option can also be set with the LCO keyword."
:group 'org-export-koma-letter
:type 'string)
(defcustom org-koma-letter-author 'user-full-name
- "The sender's name.
+ "Sender's name.
This variable defaults to calling the function `user-full-name'
-which just returns the current function `user-full-name'. Alternatively a
-string, nil or a function may be given. Functions must return a
-string."
+which just returns the current function `user-full-name'.
+Alternatively a string, nil or a function may be given.
+Functions must return a string.
+
+This option can also be set with the AUTHOR keyword."
:group 'org-export-koma-letter
:type '(radio (function-item user-full-name)
(string)
@@ -148,134 +156,219 @@ string."
(const :tag "Do not export author" nil)))
(defcustom org-koma-letter-email 'org-koma-letter-email
- "The sender's email address.
+ "Sender's email address.
This variable defaults to the value `org-koma-letter-email' which
-returns `user-mail-address'. Alternatively a string, nil or a
-function may be given. Functions must return a string."
+returns `user-mail-address'. Alternatively a string, nil or
+a function may be given. Functions must return a string.
+
+This option can also be set with the EMAIL keyword."
:group 'org-export-koma-letter
:type '(radio (function-item org-koma-letter-email)
(string)
(function)
(const :tag "Do not export email" nil)))
-(defcustom org-koma-letter-from-address nil
- "Sender's address, as a string."
+(defcustom org-koma-letter-from-address ""
+ "Sender's address, as a string.
+This option can also be set with one or more FROM_ADDRESS
+keywords."
:group 'org-export-koma-letter
:type 'string)
-(defcustom org-koma-letter-phone-number nil
- "Sender's phone number, as a string."
+(defcustom org-koma-letter-phone-number ""
+ "Sender's phone number, as a string.
+This option can also be set with the PHONE_NUMBER keyword."
:group 'org-export-koma-letter
:type 'string)
-(defcustom org-koma-letter-place nil
- "Place from which the letter is sent."
+(defcustom org-koma-letter-place ""
+ "Place from which the letter is sent, as a string.
+This option can also be set with the PLACE keyword."
:group 'org-export-koma-letter
:type 'string)
-(defcustom org-koma-letter-opening nil
+(defcustom org-koma-letter-opening ""
"Letter's opening, as a string.
-If (1) this value is nil; (2) the letter is started with a
-headline; and (3) `org-koma-letter-headline-is-opening-maybe' is
-t the value opening will be implicit set as the headline title."
+This option can also be set with the OPENING keyword. Moreover,
+when:
+ (1) this value is the empty string;
+ (2) there's no OPENING keyword or it is empty;
+ (3) `org-koma-letter-headline-is-opening-maybe' is non-nil;
+ (4) the letter contains a headline without a special
+ tag (e.g. \"to\" or \"ps\");
+then the opening will be implicitly set as the headline title."
:group 'org-export-koma-letter
:type 'string)
-(defcustom org-koma-letter-closing nil
- "Koma-Letter's closing, as a string."
+(defcustom org-koma-letter-closing ""
+ "Letter's closing, as a string.
+This option can also be set with the CLOSING keyword."
:group 'org-export-koma-letter
:type 'string)
-(defcustom org-koma-letter-prefer-special-headings nil
- "If TO and/or FROM is specified using both a heading and a keyword the heading value will be preferred if the variable is t."
+(defcustom org-koma-letter-signature ""
+ "Signature, as a string.
+This option can also be set with the SIGNATURE keyword."
:group 'org-export-koma-letter
- :type 'boolean)
+ :type 'string)
-(defcustom org-koma-letter-signature nil
- "String used as the signature."
+(defcustom org-koma-letter-prefer-special-headings nil
+ "Non-nil means prefer headlines over keywords for TO and FROM.
+This option can also be set with the OPTIONS keyword, e.g.:
+\"special-headings:t\"."
:group 'org-export-koma-letter
- :type 'string)
+ :type 'boolean)
(defcustom org-koma-letter-subject-format t
- "Use the title as the subject of the letter.
+ "When non-nil include subject. Supports formatting options.
-At this time the following values are allowed:
+When t, insert a subject using default options. When nil, do not
+insert a subject at all. It can also be a list of symbols among
+the following ones:
- - afteropening: subject after opening.
- - beforeopening: subject before opening.
- - centered: subject centered.
- - left:subject left-justified.
- - right: subject right-justified.
- - titled: add title/description to subject.
- - underlined: set subject underlined.
- - untitled: do not add title/description to subject.
- - No-export: do no insert a subject even if present.
+ `afteropening' Subject after opening
+ `beforeopening' Subject before opening
+ `centered' Subject centered
+ `left' Subject left-justified
+ `right' Subject right-justified
+ `titled' Add title/description to subject
+ `underlined' Set subject underlined
+ `untitled' Do not add title/description to subject
Please refer to the KOMA-script manual (Table 4.16. in the
-English manual of 2012-07-22)."
- :type '(radio
- (const :tag "No export" nil)
- (const :tag "Default options" t)
- (set :tag "selection"
- (const 'afteropening)
- (const 'beforeopening)
- (const 'centered)
- (const 'left)
- (const 'right)
- (const 'underlined)
- (const 'titled)
- (const 'untitled))
- (string))
+English manual of 2012-07-22).
+
+This option can also be set with the OPTIONS keyword, e.g.:
+\"subject:(underlined centered)\"."
+ :type
+ '(choice
+ (const :tag "No export" nil)
+ (const :tag "Default options" t)
+ (set :tag "Configure options"
+ (const :tag "Subject after opening" afteropening)
+ (const :tag "Subject before opening" beforeopening)
+ (const :tag "Subject centered" centered)
+ (const :tag "Subject left-justified" left)
+ (const :tag "Subject right-justified" right)
+ (const :tag "Add title or description to subject" underlined)
+ (const :tag "Set subject underlined" titled)
+ (const :tag "Do not add title or description to subject" untitled)))
:group 'org-export-koma-letter)
-
-
(defcustom org-koma-letter-use-backaddress nil
- "Print return address in small line above to address."
+ "Non-nil prints return address in line above to address.
+This option can also be set with the OPTIONS keyword, e.g.:
+\"backaddress:t\"."
:group 'org-export-koma-letter
:type 'boolean)
-(defcustom org-koma-letter-use-foldmarks "true"
- "Configure appearence of fold marks.
+(defcustom org-koma-letter-use-foldmarks t
+ "Configure appearance of folding marks.
+
+When t, activate default folding marks. When nil, do not insert
+folding marks at all. It can also be a list of symbols among the
+following ones:
+
+ `B' Activate upper horizontal mark on left paper edge
+ `b' Deactivate upper horizontal mark on left paper edge
+
+ `H' Activate all horizontal marks on left paper edge
+ `h' Deactivate all horizontal marks on left paper edge
+
+ `L' Activate left vertical mark on upper paper edge
+ `l' Deactivate left vertical mark on upper paper edge
+
+ `M' Activate middle horizontal mark on left paper edge
+ `m' Deactivate middle horizontal mark on left paper edge
+
+ `P' Activate punch or center mark on left paper edge
+ `p' Deactivate punch or center mark on left paper edge
+
+ `T' Activate lower horizontal mark on left paper edge
+ `t' Deactivate lower horizontal mark on left paper edge
-Accepts any valid value for the KOMA-Script `foldmarks' option.
+ `V' Activate all vertical marks on upper paper edge
+ `v' Deactivate all vertical marks on upper paper edge
-Use `foldmarks:true' to activate default fold marks or
-`foldmarks:nil' to deactivate fold marks."
+This option can also be set with the OPTIONS keyword, e.g.:
+\"foldmarks:(b l m t)\"."
:group 'org-export-koma-letter
- :type 'string)
+ :type '(choice
+ (const :tag "Activate default folding marks" t)
+ (const :tag "Deactivate folding marks" nil)
+ (set
+ :tag "Configure folding marks"
+ (const :tag "Activate upper horizontal mark on left paper edge" B)
+ (const :tag "Deactivate upper horizontal mark on left paper edge" b)
+ (const :tag "Activate all horizontal marks on left paper edge" H)
+ (const :tag "Deactivate all horizontal marks on left paper edge" h)
+ (const :tag "Activate left vertical mark on upper paper edge" L)
+ (const :tag "Deactivate left vertical mark on upper paper edge" l)
+ (const :tag "Activate middle horizontal mark on left paper edge" M)
+ (const :tag "Deactivate middle horizontal mark on left paper edge" m)
+ (const :tag "Activate punch or center mark on left paper edge" P)
+ (const :tag "Deactivate punch or center mark on left paper edge" p)
+ (const :tag "Activate lower horizontal mark on left paper edge" T)
+ (const :tag "Deactivate lower horizontal mark on left paper edge" t)
+ (const :tag "Activate all vertical marks on upper paper edge" V)
+ (const :tag "Deactivate all vertical marks on upper paper edge" v))))
(defcustom org-koma-letter-use-phone nil
- "Print sender's phone number."
+ "Non-nil prints sender's phone number.
+This option can also be set with the OPTIONS keyword, e.g.:
+\"phone:t\"."
:group 'org-export-koma-letter
:type 'boolean)
(defcustom org-koma-letter-use-email nil
- "Print sender's email address."
+ "Non-nil prints sender's email address.
+This option can also be set with the OPTIONS keyword, e.g.:
+\"email:t\"."
:group 'org-export-koma-letter
:type 'boolean)
(defcustom org-koma-letter-use-place t
- "Print the letter's place next to the date."
+ "Non-nil prints the letter's place next to the date.
+This option can also be set with the OPTIONS keyword, e.g.:
+\"place:nil\"."
:group 'org-export-koma-letter
:type 'boolean)
-(defcustom org-koma-letter-default-class nil
- "Default class for `org-koma-letter'.
+(defcustom org-koma-letter-use-title t
+ "Non-nil means use a title in the letter if present.
+This option can also be set with the OPTIONS keyword,
+e.g. \"title:nil\".
+
+See also `org-koma-letter-prefer-subject' for the handling of
+title versus subject."
+ :group 'org-export-koma-letter
+ :type 'boolean)
+(defcustom org-koma-letter-default-class "default-koma-letter"
+ "Default class for `org-koma-letter'.
The value must be a member of `org-latex-classes'."
:group 'org-export-koma-letter
:type 'string)
(defcustom org-koma-letter-headline-is-opening-maybe t
- "Whether a headline may be used as an opening.
+ "Non-nil means a headline may be used as an opening.
A headline is only used if #+OPENING is not set. See also
`org-koma-letter-opening'."
:group 'org-export-koma-letter
:type 'boolean)
+(defcustom org-koma-letter-prefer-subject nil
+ "Non-nil means title should be interpret as subject if subject is missing.
+This option can also be set with the OPTIONS keyword,
+e.g. \"title-subject:t\".
+
+This may be useful for older documents where the SUBJECT keyword
+was not present."
+ :group 'org-export-koma-letter
+ :type 'boolean)
+
(defconst org-koma-letter-special-tags-in-letter '(to from)
"Header tags related to the letter itself.")
@@ -294,41 +387,49 @@ A headline is only used if #+OPENING is not set. See also
(org-export-define-derived-backend 'koma-letter 'latex
:options-alist
- '((:lco "LCO" nil org-koma-letter-class-option-file)
- (:latex-class "LATEX_CLASS" nil (if org-koma-letter-default-class
- org-koma-letter-default-class
- org-latex-default-class) t)
+ '((: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)
(:author-changed-in-buffer-p "AUTHOR" nil nil t)
- (:from-address "FROM_ADDRESS" nil nil newline)
+ (: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)
- (:email-changed-in-buffer-p "EMAIL" nil nil t)
(:to-address "TO_ADDRESS" nil nil newline)
(:place "PLACE" nil org-koma-letter-place)
+ (:subject "SUBJECT" nil nil space)
(:opening "OPENING" nil org-koma-letter-opening)
(:closing "CLOSING" nil org-koma-letter-closing)
(:signature "SIGNATURE" nil org-koma-letter-signature newline)
+ (:special-headings nil "special-headings"
+ org-koma-letter-prefer-special-headings)
(:special-tags nil nil (append
org-koma-letter-special-tags-in-letter
org-koma-letter-special-tags-after-closing
org-koma-letter-special-tags-after-letter))
- (:special-headings nil "special-headings"
- org-koma-letter-prefer-special-headings)
(:with-after-closing nil "after-closing-order"
org-koma-letter-special-tags-after-closing)
(:with-after-letter nil "after-letter-order"
org-koma-letter-special-tags-after-letter)
(:with-backaddress nil "backaddress" org-koma-letter-use-backaddress)
- (:with-backaddress-changed-in-buffer-p nil "backaddress" nil)
+ (:with-email nil "email" org-koma-letter-use-email)
(:with-foldmarks nil "foldmarks" org-koma-letter-use-foldmarks)
- (:with-foldmarks-changed-in-buffer-p nil "foldmarks" "foldmarks-not-set")
(:with-phone nil "phone" org-koma-letter-use-phone)
- (:with-phone-changed-in-buffer-p nil "phone" nil)
- (:with-email nil "email" org-koma-letter-use-email)
- (:with-email-changed-in-buffer-p nil "email" nil)
(:with-place nil "place" org-koma-letter-use-place)
- (:with-subject nil "subject" org-koma-letter-subject-format))
+ (:with-subject nil "subject" org-koma-letter-subject-format)
+ (:with-title nil "title" org-koma-letter-use-title)
+ (:with-title-as-subject nil "title-subject" org-koma-letter-prefer-subject)
+ ;; Special properties non-nil when a setting happened in buffer.
+ ;; They are used to prioritize in-buffer settings over "lco"
+ ;; files. See `org-koma-letter-template'.
+ (:inbuffer-author "AUTHOR" nil 'koma-letter:empty)
+ (:inbuffer-email "EMAIL" nil 'koma-letter:empty)
+ (:inbuffer-phone-number "PHONE_NUMBER" nil 'koma-letter:empty)
+ (:inbuffer-place "PLACE" nil 'koma-letter:empty)
+ (:inbuffer-signature "SIGNATURE" nil 'koma-letter:empty)
+ (:inbuffer-with-backaddress nil "backaddress" 'koma-letter:empty)
+ (:inbuffer-with-email nil "email" 'koma-letter:empty)
+ (:inbuffer-with-foldmarks nil "foldmarks" 'koma-letter:empty)
+ (:inbuffer-with-phone nil "phone" 'koma-letter:empty))
:translate-alist '((export-block . org-koma-letter-export-block)
(export-snippet . org-koma-letter-export-snippet)
(headline . org-koma-letter-headline)
@@ -344,19 +445,8 @@ A headline is only used if #+OPENING is not set. See also
(if a (org-koma-letter-export-to-pdf t s v b)
(org-open-file (org-koma-letter-export-to-pdf nil s v b))))))))
-
-;;; Initialize class function
-
-(defun org-koma-letter-plug-into-ox ()
- "Add a sparse `default-koma-letter' to `org-latex-classes' and set `org-koma-letter-default-class' to `default-koma-letter'."
- (let ((class "default-koma-letter"))
- (eval-after-load "ox-latex"
- `(unless (member ,class 'org-latex-classes)
- (add-to-list 'org-latex-classes
- `(,class
- "\\documentclass[11pt]{scrlttr2}") ())
- (setq org-koma-letter-default-class class)))))
+
;;; Helper functions
(defun org-koma-letter-email ()
@@ -368,83 +458,63 @@ A headline is only used if #+OPENING is not set. See also
(defun org-koma-letter--get-tagged-contents (key)
"Get contents from a headline tagged with KEY.
-Technically, the contents is stored in `org-koma-letter-special-contents'."
+The contents is stored in `org-koma-letter-special-contents'."
(cdr (assoc (org-koma-letter--get-value key)
org-koma-letter-special-contents)))
(defun org-koma-letter--get-value (value)
- "Determines if VALUE is nil, a string, a function or a symbol and return a string or nil."
+ "Turn value into a string whenever possible.
+Determines if VALUE is nil, a string, a function or a symbol and
+return a string or nil."
(when value
(cond ((stringp value) value)
((functionp value) (funcall value))
((symbolp value) (symbol-name value))
(t value))))
+(defun org-koma-letter--special-contents-as-macro
+ (keywords &optional keep-newlines no-tag)
+ "Process KEYWORDS members of `org-koma-letter-special-contents'.
+KEYWORDS is a list of symbols. Return them as a string to be
+formatted.
-(defun org-koma-letter--special-contents-as-macro (a-list &optional keep-newlines no-tag)
- "Find members of `org-koma-letter-special-contents' corresponding to A-LIST.
-Return them as a string to be formatted.
-
-The function is used for inserting content of speciall headings
+The function is used for inserting content of special headings
such as PS.
If KEEP-NEWLINES is t newlines will not be removed. If NO-TAG is
-is t the content in `org-koma-letter-special-contents' will not
-be wrapped in a macro named whatever the members of A-LIST are
+t the content in `org-koma-letter-special-contents' will not be
+wrapped in a macro named whatever the members of KEYWORDS are
called."
- (let (output)
- (dolist (ac* a-list output)
- (let*
- ((ac (org-koma-letter--get-value ac*))
- (x (org-koma-letter--get-tagged-contents ac)))
- (when x
- (setq output
- (concat
- output "\n"
- ;; sometimes LaTeX complains about newlines
- ;; at the end or beginning of macros. Remove them.
- (org-koma-letter--format-string-as-macro
- (if keep-newlines x (org-koma-letter--normalize-string x))
- (unless no-tag ac)))))))))
-
-(defun org-koma-letter--format-string-as-macro (string &optional macro)
- "Format STRING as \"\\macro{string}\" if MACRO is given else as \"string\"."
- (if macro
- (format "\\%s{%s}" macro string)
- (format "%s" string)))
-
-(defun org-koma-letter--normalize-string (string)
- "Remove new lines in the beginning and end of `STRING'."
- (replace-regexp-in-string "\\`[ \n\t]+\\|[\n\t ]*\\'" "" string))
+ (mapconcat
+ #'(lambda (keyword)
+ (let* ((name (org-koma-letter--get-value keyword))
+ (value (org-koma-letter--get-tagged-contents name)))
+ (when value
+ (if no-tag (if keep-newlines value (org-trim value))
+ (format "\\%s{%s}\n"
+ name
+ (if keep-newlines value (org-trim value)))))))
+ keywords
+ ""))
(defun org-koma-letter--determine-to-and-from (info key)
"Given INFO determine KEY for the letter.
KEY should be `to' or `from'.
-`ox-koma-letter' allows two ways to specify to and from. If both
+`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* ((plist-alist '((from . :from-address)
- (to . :to-address)))
- (default-alist `((from ,org-koma-letter-from-address)
- (to "\\mbox{}")))
- (option-value (plist-get info (cdr-safe (assoc key plist-alist))))
- (head-value (org-koma-letter--get-tagged-contents key))
- (order (append
- (funcall
- (if (plist-get info :special-headings)
- 'reverse 'identity)
- `(,option-value ,head-value))
- (cdr-safe (assoc key default-alist))))
- tmp
- (adr (dolist (x order tmp)
- (when (and (not tmp) x)
- (setq tmp x)))))
- (when adr
+ (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-koma-letter--normalize-string adr)))))
+ (org-trim
+ (if (plist-get info :special-headings) (or headline option "")
+ (or option headline ""))))))
+
+
;;; Transcode Functions
;;;; Export Block
@@ -473,12 +543,11 @@ CONTENTS is nil. INFO is a plist used as a communication
channel."
(let ((key (org-element-property :key keyword))
(value (org-element-property :value keyword)))
- ;; Handle specifically BEAMER and TOC (headlines only) keywords.
- ;; Otherwise, fallback to `latex' back-end.
+ ;; Handle specifically KOMA-LETTER keywords. Otherwise, fallback
+ ;; to `latex' back-end.
(if (equal key "KOMA-LETTER") value
(org-export-with-backend 'latex keyword contents info))))
-
;; Headline
(defun org-koma-letter-headline (headline contents info)
@@ -490,24 +559,19 @@ Note that if a headline is tagged with a tag from
`org-koma-letter-special-tags' it will not be exported, but
stored in `org-koma-letter-special-contents' and included at the
appropriate place."
- (let*
- ((tags (org-export-get-tags headline info))
- (tag* (car tags))
- (tag (when tag*
- (car (member-ignore-case
- tag*
- (mapcar 'symbol-name (plist-get info :special-tags)))))))
- (if tag
- (progn
- (push (cons tag contents)
- org-koma-letter-special-contents)
- nil)
- (unless (or (plist-get info :opening)
- (not org-koma-letter-headline-is-opening-maybe))
- (plist-put info :opening
- (org-export-data (org-element-property :title headline) info)))
- contents)))
-
+ (unless (let ((tag (car (org-export-get-tags headline info))))
+ (and tag
+ (member-ignore-case
+ tag (mapcar #'symbol-name (plist-get info :special-tags)))
+ ;; Store association for later use and bail out.
+ (push (cons tag contents) org-koma-letter-special-contents)))
+ ;; Opening is not defined yet: use headline's title.
+ (when (and org-koma-letter-headline-is-opening-maybe
+ (not (org-string-nw-p (plist-get info :opening))))
+ (plist-put info :opening
+ (org-export-data (org-element-property :title headline) info)))
+ ;; In any case, insert contents in letter's body.
+ contents))
;;;; Template
@@ -515,9 +579,6 @@ appropriate place."
"Return complete document string after KOMA Scrlttr2 conversion.
CONTENTS is the transcoded contents string. INFO is a plist
holding export options."
- ;; FIXME: instead of setq'ing org-koma-letter-special-contents and
- ;; callying varioues stuff it might be nice to put a big let* around the templace
- ;; as in org-groff...
(concat
;; Time-stamp.
(and (plist-get info :time-stamp-file)
@@ -544,94 +605,53 @@ holding export options."
(concat (org-element-normalize-string (plist-get info :latex-header))
(plist-get info :latex-header-extra)))))
info)))
- (let ((lco (plist-get info :lco))
- (author (plist-get info :author))
- (author-set (plist-get info :author-changed-in-buffer-p))
- (from-address (org-koma-letter--determine-to-and-from info 'from))
- (phone-number (plist-get info :phone-number))
- (email (plist-get info :email))
- (email-set (plist-get info :email-changed-in-buffer-p))
- (signature (plist-get info :signature)))
- (concat
- ;; author or email not set in file: may be overridden by lco
- (unless author-set
- (when author (format "\\setkomavar{fromname}{%s}\n"
- (org-export-data author info))))
- (unless email-set
- (when email (format "\\setkomavar{fromemail}{%s}\n" email)))
- ;; Letter Class Option File
- (when lco
- (let ((lco-files (split-string lco " "))
- (lco-def ""))
- (dolist (lco-file lco-files lco-def)
- (setq lco-def (format "%s\\LoadLetterOption{%s}\n" lco-def lco-file)))
- lco-def))
- ;; Define "From" data.
- (when (and author author-set) (format "\\setkomavar{fromname}{%s}\n"
- (org-export-data author info)))
- (when from-address (format "\\setkomavar{fromaddress}{%s}\n" from-address))
- (when phone-number
- (format "\\setkomavar{fromphone}{%s}\n" phone-number))
- (when (and email email-set) (format "\\setkomavar{fromemail}{%s}\n" email))
- (when signature (format "\\setkomavar{signature}{%s}\n" signature))))
+ ;; Settings. They can come from three locations, in increasing
+ ;; order of precedence: global variables, LCO files and in-buffer
+ ;; settings. Thus, we first insert settings coming from global
+ ;; variables, then we insert LCO files, and, eventually, we insert
+ ;; settings coming from buffer keywords.
+ (org-koma-letter--build-settings 'global info)
+ (mapconcat #'(lambda (file) (format "\\LoadLetterOption{%s}\n" file))
+ (org-split-string (or (plist-get info :lco) "") " ")
+ "")
+ (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)
+ (format "\\setkomavar{fromaddress}{%s}\n" from-address)))
;; Date.
(format "\\date{%s}\n" (org-export-data (org-export-get-date info) info))
- ;; Place
- (let ((with-place (plist-get info :with-place))
- (place (plist-get info :place)))
- (when (or place (not with-place))
- (format "\\setkomavar{place}{%s}\n" (if with-place place ""))))
- ;; KOMA options
- (let ((with-backaddress (plist-get info :with-backaddress))
- (with-backaddress-set (plist-get info :with-backaddress-changed-in-buffer-p))
- (with-foldmarks (plist-get info :with-foldmarks))
- (with-foldmarks-set
- (not (string-equal (plist-get info :with-foldmarks-changed-in-buffer-p)
- "foldmarks-not-set")))
- (with-phone (plist-get info :with-phone))
- (with-phone-set (plist-get info :with-phone-changed-in-buffer-p))
- (with-email (plist-get info :with-email))
- (with-email-set (plist-get info :with-email-changed-in-buffer-p)))
- (concat
- (when with-backaddress-set
- (format "\\KOMAoption{backaddress}{%s}\n" (if with-backaddress "true" "false")))
- (when with-foldmarks-set
- (format "\\KOMAoption{foldmarks}{%s}\n" (if with-foldmarks with-foldmarks "false")))
- (when with-phone-set
- (format "\\KOMAoption{fromphone}{%s}\n" (if with-phone "true" "false")))
- (when with-email-set
- (format "\\KOMAoption{fromemail}{%s}\n" (if with-email "true" "false")))))
;; Document start
"\\begin{document}\n\n"
- ;; Subject
- (let* ((with-subject (plist-get info :with-subject))
- (subject-format (cond ((member with-subject '("true" "t" t)) nil)
- ((stringp with-subject) (list with-subject))
- ((symbolp with-subject)
- (list (symbol-name with-subject)))
- (t with-subject)))
- (subject (org-export-data (plist-get info :title) info))
- (l (length subject-format))
- (y ""))
- (concat
- (when (and with-subject subject-format)
- (concat
- "\\KOMAoption{subject}{"
- (apply 'format
- (dotimes (x l y)
- (setq y (concat (if (> x 0) "%s," "%s") y)))
- subject-format) "}\n"))
- (when (and subject with-subject)
- (format "\\setkomavar{subject}{%s}\n\n" subject))))
- ;; Letter start
+ ;; Subject and title
+ (let ((with-subject (plist-get info :with-subject)))
+ (when with-subject
+ (concat
+ (unless (eq with-subject t)
+ (format "\\KOMAoption{subject}{%s}\n"
+ (if (symbolp with-subject) with-subject
+ (mapconcat #'symbol-name with-subject ","))))
+ (let* ((title-as-subject (plist-get info :with-title-as-subject))
+ (subject* (org-string-nw-p
+ (org-export-data (plist-get info :subject) info)))
+ (title* (and (plist-get info :with-title)
+ (org-string-nw-p
+ (org-export-data (plist-get info :title) info))))
+ (subject (if title-as-subject (or subject* title*) subject*))
+ (title (if title-as-subject (and subject* title*) title*)))
+ (concat
+ (and subject (format "\\setkomavar{subject}{%s}\n" subject))
+ (and title (format "\\setkomavar{title}{%s}\n" title))
+ (when (or (org-string-nw-p title) (org-string-nw-p subject)) "\n"))))))
+ ;; Letter start.
(format "\\begin{letter}{%%\n%s}\n\n"
(org-koma-letter--determine-to-and-from info 'to))
;; Opening.
- (format "\\opening{%s}\n\n" (or (plist-get info :opening) ""))
+ (format "\\opening{%s}\n\n" (plist-get info :opening))
;; Letter body.
contents
;; Closing.
- (format "\n\\closing{%s}\n" (or (plist-get info :closing) ""))
+ (format "\n\\closing{%s}\n" (plist-get info :closing))
(org-koma-letter--special-contents-as-macro
(plist-get info :with-after-closing))
;; Letter end.
@@ -639,8 +659,65 @@ holding export options."
(org-koma-letter--special-contents-as-macro
(plist-get info :with-after-letter) t t)
;; Document end.
- "\n\\end{document}"
- ))
+ "\n\\end{document}"))
+
+(defun org-koma-letter--build-settings (scope info)
+ "Build settings string according to type.
+SCOPE is either `global' or `buffer'. INFO is a plist used as
+a communication channel."
+ (let ((check-scope
+ (function
+ ;; Non-nil value when SETTING was defined in SCOPE.
+ (lambda (setting)
+ (let ((property (intern (format ":inbuffer-%s" setting))))
+ (if (eq scope 'global)
+ (eq (plist-get info property) 'koma-letter:empty)
+ (not (eq (plist-get info property) 'koma-letter:empty))))))))
+ (concat
+ ;; Name.
+ (let ((author (plist-get info :author)))
+ (and author
+ (funcall check-scope 'author)
+ (format "\\setkomavar{fromname}{%s}\n"
+ (org-export-data author info))))
+ ;; Email.
+ (let ((email (plist-get info :email)))
+ (and email
+ (funcall check-scope 'email)
+ (format "\\setkomavar{fromemail}{%s}\n" email)))
+ (and (funcall check-scope 'with-email)
+ (format "\\KOMAoption{fromemail}{%s}\n"
+ (if (plist-get info :with-email) "true" "false")))
+ ;; Phone number.
+ (let ((phone-number (plist-get info :phone-number)))
+ (and (org-string-nw-p phone-number)
+ (funcall check-scope 'phone-number)
+ (format "\\setkomavar{fromphone}{%s}\n" phone-number)))
+ (and (funcall check-scope 'with-phone)
+ (format "\\KOMAoption{fromphone}{%s}\n"
+ (if (plist-get info :with-phone) "true" "false")))
+ ;; Signature.
+ (let ((signature (plist-get info :signature)))
+ (and (org-string-nw-p signature)
+ (funcall check-scope 'signature)
+ (format "\\setkomavar{signature}{%s}\n" signature)))
+ ;; Back address.
+ (and (funcall check-scope 'with-backaddress)
+ (format "\\KOMAoption{backaddress}{%s}\n"
+ (if (plist-get info :with-backaddress) "true" "false")))
+ ;; Place.
+ (and (funcall check-scope 'place)
+ (format "\\setkomavar{place}{%s}\n"
+ (if (plist-get info :with-place) (plist-get info :place) "")))
+ ;; Folding marks.
+ (and (funcall check-scope 'with-foldmarks)
+ (let ((foldmarks (plist-get info :with-foldmarks)))
+ (cond ((consp foldmarks)
+ (format "\\KOMAoptions{foldmarks=true,foldmarks=%s}\n"
+ (mapconcat #'symbol-name foldmarks "")))
+ (foldmarks "\\KOMAoptions{foldmarks=true}\n")
+ (t "\\KOMAoptions{foldmarks=false}\n")))))))
+
;;; Commands
diff --git a/contrib/lisp/ox-rss.el b/contrib/lisp/ox-rss.el
index 2de1dbc..fddaa1d 100644
--- a/contrib/lisp/ox-rss.el
+++ b/contrib/lisp/ox-rss.el
@@ -1,6 +1,6 @@
;;; ox-rss.el --- RSS 2.0 Back-End for Org Export Engine
-;; Copyright (C) 2013 Bastien Guerry
+;; Copyright (C) 2013, 2014 Bastien Guerry
;; Author: Bastien Guerry <bzg@gnu.org>
;; Keywords: org, wp, blog, feed, rss
@@ -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,14 +238,17 @@ 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"))))))
- (title (org-element-property :raw-value headline))
+ (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)
+ (match-string 1 m)))
+ (org-element-property :raw-value headline)))
(publink
(or (and hl-perm (concat (or hl-home hl-pdir) hl-perm))
(concat
@@ -261,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."
@@ -326,8 +329,8 @@ as a communication channel."
(ifile (plist-get info :input-file))
(publink
(concat (file-name-as-directory blogurl)
- (file-name-nondirectory
- (file-name-sans-extension ifile))
+ (file-name-nondirectory
+ (file-name-sans-extension ifile))
"." rssext)))
(format
"\n<title>%s</title>
diff --git a/contrib/lisp/ox-s5.el b/contrib/lisp/ox-s5.el
index d97a9b2..b94c38c 100644
--- a/contrib/lisp/ox-s5.el
+++ b/contrib/lisp/ox-s5.el
@@ -1,6 +1,6 @@
;;; ox-s5.el --- S5 Presentation Back-End for Org Export Engine
-;; Copyright (C) 2011-2013 Rick Frankel
+;; Copyright (C) 2011-2014 Rick Frankel
;; Author: Rick Frankel <emacs at rickster dot com>
;; Keywords: outlines, hypermedia, S5, wp
@@ -174,8 +174,8 @@ or an empty string."
(defcustom org-s5-title-slide-template
"<h1>%t</h1>
<h2>%a</h2>
-<h2>%e</h2>
-<h2>%d</h2>"
+<h3>%e</h3>
+<h4>%d</h4>"
"Format template to specify title page section.
See `org-html-postamble-format' for the valid elements which
can be included.
@@ -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 fe88b45..807d702 100644
--- a/contrib/lisp/ox-taskjuggler.el
+++ b/contrib/lisp/ox-taskjuggler.el
@@ -1,6 +1,6 @@
;;; ox-taskjuggler.el --- TaskJuggler Back-End for Org Export Engine
;;
-;; Copyright (C) 2007-2013 Free Software Foundation, Inc.
+;; Copyright (C) 2007-2014 Free Software Foundation, Inc.
;;
;; Emacs Lisp Archive Entry
;; Filename: 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/Makefile b/doc/Makefile
index 234ab7e..2c8a3c5 100644
--- a/doc/Makefile
+++ b/doc/Makefile
@@ -54,8 +54,9 @@ clean-install:
%: %.texi org-version.inc
$(MAKEINFO) --no-split $< -o $@
-%.pdf: LC_ALL=C # work around a bug in texi2dvi
-%.pdf: LANG=C # work around a bug in texi2dvi
+# the following two lines work around a bug in some versions of texi2dvi
+%.pdf: LC_ALL=C
+%.pdf: LANG=C
%.pdf: %.texi org-version.inc
$(TEXI2PDF) $<
%.pdf: %.tex
diff --git a/doc/doclicense.texi b/doc/doclicense.texi
index b0c97cd..aa9288e 100644
--- a/doc/doclicense.texi
+++ b/doc/doclicense.texi
@@ -5,7 +5,7 @@
@c hence no sectioning command or @node.
@display
-Copyright @copyright{} 2000, 2001, 2002, 2007, 2008, 2013 Free Software Foundation, Inc.
+Copyright @copyright{} 2000, 2001, 2002, 2007, 2008, 2013, 2014 Free Software Foundation, Inc.
@uref{http://fsf.org/}
Everyone is permitted to copy and distribute verbatim copies
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 4aeae70..3fcf4b2 100644
--- a/doc/org.texi
+++ b/doc/org.texi
@@ -1,21 +1,17 @@
\input texinfo
@c %**start of header
-@setfilename ../../info/org
+@setfilename ../../info/org.info
@settitle The Org Manual
@include org-version.inc
-@c Use proper quote and backtick for code sections in PDF output
-@c Cf. Texinfo manual 14.2
-@set txicodequoteundirected
-@set txicodequotebacktick
-
@c Version and Contact Info
@set MAINTAINERSITE @uref{http://orgmode.org,maintainers web page}
@set AUTHOR Carsten Dominik
@set MAINTAINER Carsten Dominik
@set MAINTAINEREMAIL @email{carsten at orgmode dot org}
@set MAINTAINERCONTACT @uref{mailto:carsten at orgmode dot org,contact the maintainer}
+@documentencoding UTF-8
@c %**end of header
@finalout
@@ -263,13 +259,13 @@
@copying
This manual is for Org version @value{VERSION}.
-Copyright @copyright{} 2004--2013 Free Software Foundation, Inc.
+Copyright @copyright{} 2004--2014 Free Software Foundation, Inc.
@quotation
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3 or
any later version published by the Free Software Foundation; with no
-Invariant Sections, with the Front-Cover texts being ``A GNU Manual,''
+Invariant Sections, with the Front-Cover Texts being ``A GNU Manual,''
and with the Back-Cover Texts as in (a) below. A copy of the license
is included in the section entitled ``GNU Free Documentation License.''
@@ -370,11 +366,6 @@ Visibility cycling
* Initial visibility:: Setting the initial visibility state
* Catching invisible edits:: Preventing mistakes when editing invisible parts
-Global and local cycling
-
-* Initial visibility:: Setting the initial visibility state
-* Catching invisible edits:: Preventing mistakes when editing invisible parts
-
Tables
* Built-in table editor:: Simple tables
@@ -590,10 +581,12 @@ 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}, a man page, or Org
-* Export in foreign buffers:: Author tables in lists in Org syntax
+* 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
HTML export
@@ -644,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
@@ -871,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,
@@ -995,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
@@ -1273,6 +1282,9 @@ When @kbd{S-@key{TAB}} is called with a numeric prefix argument N, the
CONTENTS view up to headlines of level N will be shown. Note that inside
tables, @kbd{S-@key{TAB}} jumps to the previous field.
+@cindex set startup visibility, command
+@orgcmd{C-u C-u @key{TAB},org-set-startup-visibility}
+Switch back to the startup visibility of the buffer (@pxref{Initial visibility}).
@cindex show all, command
@orgcmd{C-u C-u C-u @key{TAB},show-all}
Show all, including drawers.
@@ -1292,29 +1304,17 @@ 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
-@menu
-* Initial visibility:: Setting the initial visibility state
-* Catching invisible edits:: Preventing mistakes when editing invisible parts
-@end menu
-
@node Initial visibility
@subsection Initial visibility
@@ -1330,7 +1330,7 @@ When Emacs first visits an Org file, the global state is set to OVERVIEW,
i.e., only the top level headlines are visible@footnote{When
@code{org-agenda-inhibit-startup} is non-@code{nil}, Org will not honor the default
visibility state when first opening a file for the agenda (@pxref{Speeding up
-your agendas}).} This can be configured through the variable
+your agendas}).}. This can be configured through the variable
@code{org-startup-folded}, or on a per-file basis by adding one of the
following lines anywhere in the buffer:
@@ -1427,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
@@ -2629,6 +2633,12 @@ table in that entry. REF is an absolute field or range reference as
described above for example @code{@@3$3} or @code{$somename}, valid in the
referenced table.
+Indirection of NAME-OR-ID: When NAME-OR-ID has the format @code{@@ROW$COLUMN}
+it will be substituted with the name or ID found in this field of the current
+table. For example @code{remote($1, @@>$2)} => @code{remote(year_2013,
+@@>$1)}. The format @code{B3} is not supported because it can not be
+distinguished from a plain table name or ID.
+
@node Formula syntax for Calc
@subsection Formula syntax for Calc
@cindex formula syntax, Calc
@@ -2719,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
@@ -3246,11 +3258,17 @@ functions.
@cindex plot tables using Gnuplot
@cindex #+PLOT
-Org-Plot can produce 2D and 3D graphs of information stored in org tables
-using @file{Gnuplot} @uref{http://www.gnuplot.info/} and @file{gnuplot-mode}
+Org-Plot can produce graphs of information stored in org tables, either
+graphically or in ASCII-art.
+
+@subheading Graphical plots using @file{Gnuplot}
+
+Org-Plot produces 2D and 3D graphs using @file{Gnuplot}
+@uref{http://www.gnuplot.info/} and @file{gnuplot-mode}
@uref{http://xafs.org/BruceRavel/GnuplotMode}. To see this in action, ensure
that you have both Gnuplot and Gnuplot mode installed on your system, then
-call @code{org-plot/gnuplot} on the following table.
+call @kbd{C-c " g} or @kbd{M-x org-plot/gnuplot @key{RET}} on the following
+table.
@example
@group
@@ -3268,8 +3286,8 @@ call @code{org-plot/gnuplot} on the following table.
Notice that Org Plot is smart enough to apply the table's headers as labels.
Further control over the labels, type, content, and appearance of plots can
be exercised through the @code{#+PLOT:} lines preceding a table. See below
-for a complete list of Org-plot options. For more information and examples
-see the Org-plot tutorial at
+for a complete list of Org-plot options. The @code{#+PLOT:} lines are
+optional. For more information and examples see the Org-plot tutorial at
@uref{http://orgmode.org/worg/org-tutorials/org-plot.html}.
@subsubheading Plot Options
@@ -3325,6 +3343,47 @@ may still want to specify the plot type, as that can impact the content of
the data file.
@end table
+@subheading ASCII bar plots
+
+While the cursor is on a column, typing @kbd{C-c " a} or
+@kbd{M-x orgtbl-ascii-plot @key{RET}} create a new column containing an
+ASCII-art bars plot. The plot is implemented through a regular column
+formula. When the source column changes, the bar plot may be updated by
+refreshing the table, for example typing @kbd{C-u C-c *}.
+
+@example
+@group
+| Sede | Max cites | |
+|---------------+-----------+--------------|
+| Chile | 257.72 | WWWWWWWWWWWW |
+| Leeds | 165.77 | WWWWWWWh |
+| Sao Paolo | 71.00 | WWW; |
+| Stockholm | 134.19 | WWWWWW: |
+| Morelia | 257.56 | WWWWWWWWWWWH |
+| Rochefourchat | 0.00 | |
+#+TBLFM: $3='(orgtbl-ascii-draw $2 0.0 257.72 12)
+@end group
+@end example
+
+The formula is an elisp call:
+@lisp
+(orgtbl-ascii-draw COLUMN MIN MAX WIDTH)
+@end lisp
+
+@table @code
+@item COLUMN
+ is a reference to the source column.
+
+@item MIN MAX
+ are the minimal and maximal values displayed. Sources values
+ outside this range are displayed as @samp{too small}
+ or @samp{too large}.
+
+@item WIDTH
+ is the width in characters of the bar-plot. It defaults to @samp{12}.
+
+@end table
+
@node Hyperlinks
@chapter Hyperlinks
@cindex hyperlinks
@@ -3872,7 +3931,7 @@ Jump to line 255.
Search for a link target @samp{<<My Target>>}, or do a text search for
@samp{my target}, similar to the search in internal links, see
@ref{Internal links}. In HTML export (@pxref{HTML export}), such a file
-link will become a HTML reference to the corresponding named anchor in
+link will become an HTML reference to the corresponding named anchor in
the linked file.
@item *My Target
In an Org file, restrict search to headlines.
@@ -4185,11 +4244,10 @@ unique keys across both sets of keywords.}
@cindex #+SEQ_TODO
It can be very useful to use different aspects of the TODO mechanism in
-different files. For file-local settings, you need to add special lines
-to the file which set the keywords and interpretation for that file
-only. For example, to set one of the two examples discussed above, you
-need one of the following lines, starting in column zero anywhere in the
-file:
+different files. For file-local settings, you need to add special lines to
+the file which set the keywords and interpretation for that file only. For
+example, to set one of the two examples discussed above, you need one of the
+following lines anywhere in the file:
@example
#+TODO: TODO FEEDBACK VERIFY | DONE CANCELED
@@ -4486,6 +4544,10 @@ actual habit with some history:
@example
** TODO Shave
SCHEDULED: <2009-10-17 Sat .+2d/4d>
+ :PROPERTIES:
+ :STYLE: habit
+ :LAST_REPEAT: [2009-10-19 Mon 00:36]
+ :END:
- State "DONE" from "TODO" [2009-10-15 Thu]
- State "DONE" from "TODO" [2009-10-12 Mon]
- State "DONE" from "TODO" [2009-10-10 Sat]
@@ -4496,10 +4558,6 @@ actual habit with some history:
- State "DONE" from "TODO" [2009-09-19 Sat]
- State "DONE" from "TODO" [2009-09-16 Wed]
- State "DONE" from "TODO" [2009-09-12 Sat]
- :PROPERTIES:
- :STYLE: habit
- :LAST_REPEAT: [2009-10-19 Mon 00:36]
- :END:
@end example
What this habit says is: I want to shave at most every 2 days (given by the
@@ -5148,10 +5206,12 @@ Properties can be conveniently edited and viewed in column view
@cindex drawer, for properties
Properties are key-value pairs. When they are associated with a single entry
-or with a tree they need to be inserted into a special
-drawer (@pxref{Drawers}) with the name @code{PROPERTIES}. Each property
-is specified on a single line, with the key (surrounded by colons)
-first, and the value after it. Here is an example:
+or with a tree they need to be inserted into a special drawer
+(@pxref{Drawers}) with the name @code{PROPERTIES}, which has to be located
+right below a headline, and its planning line (@pxref{Deadlines and
+scheduling}) when applicable. Each property is specified on a single line,
+with the key (surrounded by colons) first, and the value after it. Keys are
+case-insensitives. Here is an example:
@example
* CD collection
@@ -5167,7 +5227,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:}
@@ -5523,6 +5583,9 @@ of 5 to 20 days, representing what to expect if everything goes either
extremely well or extremely poorly. In contrast, @code{est+} estimates the
full job more realistically, at 10--15 days.
+Numbers are right-aligned when a format specifier with an explicit width like
+@code{%5d} or @code{%5.1f} is used.
+
Here is an example for a complete columns definition, along with allowed
values.
@@ -6178,14 +6241,6 @@ keywords @code{logreschedule}, @code{lognotereschedule}, and
@code{nologreschedule}}, a note will be taken when changing an existing
scheduling time.
@c
-@orgcmd{C-c C-x C-k,org-mark-entry-for-agenda-action}
-@kindex k a
-@kindex k s
-Mark the current entry for agenda action. After you have marked the entry
-like this, you can open the agenda or the calendar to find an appropriate
-date. With the cursor on the selected date, press @kbd{k s} or @kbd{k d} to
-schedule the marked item.
-@c
@orgcmd{C-c / d,org-check-deadlines}
@cindex sparse tree, for deadlines
@vindex org-deadline-warning-days
@@ -6534,6 +6589,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,}
@@ -7096,9 +7153,10 @@ narrow it so that you only see the new material.
@item :table-line-pos
Specification of the location in the table where the new line should be
-inserted. It should be a string like @code{"II-3"} meaning that the new
-line should become the third line before the second horizontal separator
-line.
+inserted. It can be a string, a variable holding a string or a function
+returning a string. The string should look like @code{"II-3"} meaning that
+the new line should become the third line before the second horizontal
+separator line.
@item :kill-buffer
If the target file was not yet visited when capture was invoked, kill the
@@ -7737,15 +7795,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
@@ -8051,7 +8111,7 @@ You may also test for properties (@pxref{Properties and columns}) at the same
time as matching tags. The properties may be real properties, or special
properties that represent other metadata (@pxref{Special properties}). For
example, the ``property'' @code{TODO} represents the TODO keyword of the
-entry and the ``propety'' @code{PRIORITY} represents the PRIORITY keyword of
+entry and the ``property'' @code{PRIORITY} represents the PRIORITY keyword of
the entry. The ITEM special property cannot currently be used in tags/property
searches@footnote{But @pxref{x-agenda-skip-entry-regexp,
,skipping entries based on regexp}.}.
@@ -8429,24 +8489,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 +8559,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 +8621,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 +8650,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 +9646,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
@@ -9628,7 +9687,7 @@ or on a per-file basis with a line like
@end example
If you would like to move the table of contents to a different location, you
-should turn off the detault table using @code{org-export-with-toc} or
+should turn off the default table using @code{org-export-with-toc} or
@code{#+OPTIONS} and insert @code{#+TOC: headlines N} at the desired
location(s).
@@ -9725,8 +9784,8 @@ multiple footnotes side by side.
@vindex org-fontify-emphasized-text
@vindex org-emphasis-regexp-components
@vindex org-emphasis-alist
-You can make words @b{*bold*}, @i{/italic/}, _underlined_, @code{=code=}
-and @code{~verbatim~}, and, if you must, @samp{+strike-through+}. Text
+You can make words @b{*bold*}, @i{/italic/}, _underlined_, @code{=verbatim=}
+and @code{~code~}, and, if you must, @samp{+strike-through+}. Text
in the code and verbatim string is not processed for Org mode specific
syntax, it is exported verbatim.
@@ -9751,15 +9810,21 @@ 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.
-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.
+@samp{#} and a whitespace are treated as comments and, as such, are not
+exported.
+
+Likewise, regions surrounded by @samp{#+BEGIN_COMMENT}
+... @samp{#+END_COMMENT} are not exported.
+
+Finally, a @samp{COMMENT} keyword at the beginning of an entry, but after any
+other keyword or priority cookie, comments out the entire subtree. 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 ;
@item C-c ;
-Toggle the COMMENT keyword at the beginning of an entry.
+Toggle the @samp{COMMENT} keyword at the beginning of an entry.
@end table
@@ -9839,6 +9904,7 @@ Here is an example
@end example
@cindex formatting source code, markup rules
+@vindex org-latex-listings
If the example is source code from a programming language, or any other text
that can be marked up by font-lock in Emacs, you can ask for the example to
look like the fontified Emacs buffer@footnote{This works automatically for
@@ -9884,12 +9950,16 @@ Here is an example:
@example
#+BEGIN_SRC emacs-lisp -n -r
(save-excursion (ref:sc)
- (goto-char (point-min)) (ref:jump)
+ (goto-char (point-min))) (ref:jump)
#+END_SRC
In line [[(sc)]] we remember the current position. [[(jump)][Line (jump)]]
jumps to point-min.
@end example
+@cindex indentation, in source blocks
+Finally, you can use @code{-i} to preserve the indentation of a specific code
+block (@pxref{Editing source code}).
+
@vindex org-coderef-label-format
If the syntax for the label format conflicts with the language syntax, use a
@code{-l} switch to change the format, for example @samp{#+BEGIN_SRC pascal
@@ -9940,28 +10010,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 behaviour 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}
@@ -9969,6 +10048,23 @@ obvious defaults.
#+INCLUDE: "~/.emacs" :lines "10-" @r{Include lines from 10 to EOF}
@end example
+Finally, you may use a file-link to extract an object as matched by
+@code{org-link-search}@footnote{Note that
+@code{org-link-search-must-match-exact-headline} is locally bound to non-nil.
+Therefore, @code{org-link-search} only matches headlines and named elements.}
+(@pxref{Search options}). If the @code{:only-contents} property is non-nil,
+only the contents of the requested element will be included, omitting
+properties drawer and planning-line if present. The @code{:lines} keyword
+operates locally with respect to the requested element. Some examples:
+
+@example
+#+INCLUDE: "./paper.org::#theory" :only-contents t
+ @r{Include the body of the heading with the custom id @code{theory}}
+#+INCLUDE: "./paper.org::mytable" @r{Include named element.}
+#+INCLUDE: "./paper.org::*conclusion" :lines 1-20
+ @r{Include the first 20 lines of the headline named conclusion.}
+@end example
+
@table @kbd
@kindex C-c '
@item C-c '
@@ -10004,21 +10100,31 @@ You can define text snippets with
#+MACRO: name replacement text $1, $2 are arguments
@end example
-@noindent which can be referenced in
-paragraphs, verse blocks, table cells and some keywords with
-@code{@{@{@{name(arg1,arg2)@}@}@}}@footnote{Since commas separate arguments,
+@noindent which can be referenced
+@code{@{@{@{name(arg1, arg2)@}@}@}}@footnote{Since commas separate arguments,
commas within arguments have to be escaped with a backslash character.
Conversely, backslash characters before a comma, and only them, need to be
-escaped with another backslash character.}. In addition to defined macros,
-@code{@{@{@{title@}@}@}}, @code{@{@{@{author@}@}@}}, etc., will reference
-information set by the @code{#+TITLE:}, @code{#+AUTHOR:}, and similar lines.
-Also, @code{@{@{@{time(@var{FORMAT})@}@}@}} and
+escaped with another backslash character.}.
+
+These references, called macros, can be inserted anywhere Org markup is
+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
+reference information set by the @code{#+TITLE:}, @code{#+AUTHOR:}, and
+similar lines. Also, @code{@{@{@{time(@var{FORMAT})@}@}@}} and
@code{@{@{@{modification-time(@var{FORMAT})@}@}@}} refer to current date time
and to the modification time of the file being exported, respectively.
@var{FORMAT} should be a format string understood by
@code{format-time-string}.
-Macro expansion takes place during export.
+The surrounding brackets can be made invisible by setting
+@code{org-hide-macro-markers} to @code{t}.
+
+Macro expansion takes place during the very beginning of the export process.
@node Embedded @LaTeX{}
@@ -10067,7 +10173,7 @@ Angles are written as Greek letters \alpha, \beta and \gamma.
@vindex org-entities
During export, these symbols will be transformed into the native format of
the exporter back-end. Strings like @code{\alpha} will be exported as
-@code{&alpha;} in the HTML output, and as @code{$\alpha$} in the @LaTeX{}
+@code{&alpha;} in the HTML output, and as @code{\(\alpha\)} in the @LaTeX{}
output. Similarly, @code{\nbsp} will become @code{&nbsp;} in HTML and
@code{~} in @LaTeX{}. If you need such a symbol inside a word, terminate it
like this: @samp{\Aacute@{@}stor}.
@@ -10130,19 +10236,13 @@ format sub- and superscripts in a WYSIWYM way.
Going beyond symbols and sub- and superscripts, a full formula language is
needed. Org mode can contain @LaTeX{} math fragments, and it supports ways
to process these for several export back-ends. When exporting to @LaTeX{},
-the code is obviously left as it is. When exporting to HTML, Org invokes the
-@uref{http://www.mathjax.org, MathJax library} (@pxref{Math formatting in
+the code is obviously left as it is. When exporting to HTML, Org can invoke
+the @uref{http://www.mathjax.org, MathJax library} (@pxref{Math formatting in
HTML export}) to process and display the math@footnote{If you plan to use
this regularly or on pages with significant page views, you should install
@file{MathJax} on your own server in order to limit the load of our server.}.
-Finally, it can also process the mathematical expressions into
-images@footnote{For this to work you need to be on a system with a working
-@LaTeX{} installation. You also need the @file{dvipng} program or the
-@file{convert}, respectively available at
-@url{http://sourceforge.net/projects/dvipng/} and from the @file{imagemagick}
-suite. The @LaTeX{} header that will be used when processing a fragment can
-be configured with the variable @code{org-format-latex-header}.} that can be
-displayed in a browser.
+It can also process the mathematical expressions into images that can be
+displayed in a browser (see @pxref{Previewing @LaTeX{} fragments}).
@LaTeX{} fragments don't need any special marking at all. The following
snippets will be identified as @LaTeX{} source code:
@@ -10152,8 +10252,8 @@ Environments of any kind@footnote{When @file{MathJax} is used, only the
environments recognized by @file{MathJax} will be processed. When
@file{dvipng} program or @file{imagemagick} suite is used to create images,
any @LaTeX{} environment will be handled.}. The only requirement is that the
-@code{\begin} and @code{\end} statements appear on a new line, at the
-beginning of the line or after whitespaces only.
+@code{\begin} statement appears on a new line, at the beginning of the line
+or after whitespaces only.
@item
Text within the usual @LaTeX{} math delimiters. To avoid conflicts with
currency specifications, single @samp{$} characters are only recognized as
@@ -10200,11 +10300,21 @@ lines:
@cindex @LaTeX{} fragments, preview
@vindex org-latex-create-formula-image-program
-If you have @file{dvipng} or @file{imagemagick} installed@footnote{Choose the
-converter by setting the variable
+If you have a working @LaTeX{} installation and either @file{dvipng} or
+@file{convert} installed@footnote{These are respectively available at
+@url{http://sourceforge.net/projects/dvipng/} and from the @file{imagemagick}
+suite. Choose the converter by setting the variable
@code{org-latex-create-formula-image-program} accordingly.}, @LaTeX{}
-fragments can be processed to produce preview images of the typeset
-expressions:
+fragments can be processed to produce images of the typeset expressions to be
+used for inclusion while exporting to HTML (see @pxref{@LaTeX{} fragments}),
+or for inline previewing within Org mode.
+
+@vindex org-format-latex-options
+@vindex org-format-latex-header
+You can customize the variables @code{org-format-latex-options} and
+@code{org-format-latex-header} to influence some aspects of the preview. In
+particular, the @code{:scale} (and for HTML export, @code{:html-scale})
+property of the former can be used to adjust the size of the preview images.
@table @kbd
@kindex C-c C-x C-l
@@ -10220,12 +10330,6 @@ process the entire buffer.
Remove the overlay preview images.
@end table
-@vindex org-format-latex-options
-You can customize the variable @code{org-format-latex-options} to influence
-some aspects of the preview. In particular, the @code{:scale} (and for HTML
-export, @code{:html-scale}) property can be used to adjust the size of the
-preview images.
-
@vindex org-startup-with-latex-preview
You can turn on the previewing of all @LaTeX{} fragments in a file with
@@ -10308,12 +10412,19 @@ 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}. 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 block were not there. For example, when
-exporting a @samp{#+BEGIN_TEST} block, HTML back-end wraps its contents
-within @samp{<div name="test">} tag. Refer to back-end specific
-documentation for more information.
+Any other block is a @emph{special block}. Its name is case-sensitive.
+
+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{<div name="test">} tag.
+
+Refer to back-end specific documentation for more information.
@node Exporting
@chapter Exporting
@@ -10344,10 +10455,12 @@ 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}, a man page, or Org
-* Export in foreign buffers:: Author tables in lists in Org syntax
+* 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
@@ -10388,13 +10501,13 @@ 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 behaviour the default, customize the variable
+To make this behavior the default, customize the variable
@code{org-export-in-background}.
@item C-b
@@ -10412,14 +10525,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
@@ -10444,6 +10551,7 @@ Built-in back-ends include:
@item man (Man page format)
@item md (Markdown format)
@item odt (OpenDocument Text format)
+@item org (Org format)
@item texinfo (Texinfo format)
@end itemize
@@ -10523,7 +10631,8 @@ clocktable.
The tags that select a tree for export (@code{org-export-select-tags}). The
default value is @code{:export:}. Within a subtree tagged with
@code{:export:}, you can still exclude entries with @code{:noexport:} (see
-below).
+below). When headlines are selectively exported with @code{:export:}
+anywhere in a file, text before the first headline is ignored.
@item EXCLUDE_TAGS
@cindex #+EXCLUDE_TAGS
@@ -10531,12 +10640,12 @@ below).
The tags that exclude a tree from export (@code{org-export-exclude-tags}).
The default value is @code{:noexport:}. Entries with the @code{:noexport:}
tag will be unconditionally excluded from the export, even if they have an
-@code{:export:} tag.
+@code{:export:} tag. Code blocks contained in excluded subtrees will still
+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
@@ -10686,16 +10795,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 overriden locally by special node
+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
@@ -10704,6 +10809,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
@@ -10714,6 +10826,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
@@ -10768,6 +10884,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
@@ -10869,7 +11004,7 @@ recognized. See @ref{@LaTeX{} and PDF export} for more information.
@cindex #+BEAMER_INNER_THEME
@cindex #+BEAMER_OUTER_THEME
Beamer export introduces a number of keywords to insert code in the
-document's header. Four control appearance of the presentantion:
+document's header. Four control appearance of the presentation:
@code{#+BEAMER_THEME}, @code{#+BEAMER_COLOR_THEME},
@code{#+BEAMER_FONT_THEME}, @code{#+BEAMER_INNER_THEME} and
@code{#+BEAMER_OUTER_THEME}. All of them accept optional arguments
@@ -10941,11 +11076,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.
@@ -10953,7 +11083,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
@@ -10962,20 +11092,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:
@@ -10988,7 +11118,7 @@ Here is a simple example Org document that is intended for Beamer export.
@section HTML export
@cindex HTML export
-Org mode contains a HTML (XHTML 1.0 strict) exporter with extensive
+Org mode contains an HTML (XHTML 1.0 strict) exporter with extensive
HTML formatting, in ways similar to John Gruber's @emph{markdown}
language, but with additional support for tables.
@@ -11011,11 +11141,11 @@ language, but with additional support for tables.
@table @kbd
@orgcmd{C-c C-e h h,org-html-export-to-html}
-Export as a HTML file. For an Org file @file{myfile.org},
+Export as an HTML file. For an Org file @file{myfile.org},
the HTML file will be @file{myfile.html}. The file will be overwritten
without warning.
@kbd{C-c C-e h o}
-Export as a HTML file and immediately open it with a browser.
+Export as an HTML file and immediately open it with a browser.
@orgcmd{C-c C-e h H,org-html-export-as-html}
Export to a temporary buffer. Do not create a file.
@end table
@@ -11042,7 +11172,7 @@ Export to a temporary buffer. Do not create a file.
Org can export to various (X)HTML flavors.
Setting the variable @code{org-html-doctype} allows you to export to different
-(X)HTML variants. The exported HTML will be adjusted according to the sytax
+(X)HTML variants. The exported HTML will be adjusted according to the syntax
requirements of that variant. You can either set this variable to a doctype
string directly, in which case the exporter will try to adjust the syntax
automatically, or you can use a ready-made doctype. The ready-made options
@@ -11118,12 +11248,12 @@ Becomes:
@end example
Special blocks that do not correspond to HTML5 elements (see
-@code{org-html-html5-elements}) will revert to the usual behavior,
-i.e. #+BEGIN_LEDERHOSEN will still export to <div class=''lederhosen''>.
+@code{org-html-html5-elements}) will revert to the usual behavior, i.e.,
+@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. <section> or <article> tags, set the @code{HTML_CONTAINER}
-property on the headline itself.
+contents in e.g., @samp{<section>} or @samp{<article>} tags, set the
+@code{HTML_CONTAINER} property on the headline itself.
@node HTML preamble and postamble
@subsection HTML preamble and postamble
@@ -11189,7 +11319,7 @@ includes automatic links created by radio targets (@pxref{Radio
targets}). Links to external files will still work if the target file is on
the same @i{relative} path as the published Org file. Links to other
@file{.org} files will be translated into HTML links under the assumption
-that a HTML version also exists of the linked file, at the same relative
+that an HTML version also exists of the linked file, at the same relative
path. @samp{id:} links can then be used to jump to specific entries across
files. For information related to linking files while publishing them to a
publishing directory see @ref{Publishing links}.
@@ -11222,10 +11352,39 @@ individual tables, place something like the following before the table:
#+ATTR_HTML: :border 2 :rules all :frame border
@end example
+You can also group columns in the HTML output (@pxref{Column groups}).
+
+Below is a list of options for customizing tables HTML export.
+
+@table @code
+@vindex org-html-table-align-individual-fields
+@item org-html-table-align-individual-fields
+Non-nil means attach style attributes for alignment to each table field.
+
+@vindex org-html-table-caption-above
+@item org-html-table-caption-above
+When non-nil, place caption string at the beginning of the table.
+
+@vindex org-html-table-data-tags
+@item org-html-table-data-tags
+The opening and ending tags for table data fields.
+
+@vindex org-html-table-default-attributes
+@item org-html-table-default-attributes
+Default attributes and values which will be used in table tags.
+
+@vindex org-html-table-header-tags
+@item org-html-table-header-tags
+The opening and ending tags for table header fields.
+
@vindex org-html-table-row-tags
-You can also modify the default tags used for each row by setting
-@code{org-html-table-row-tags}. See the docstring for an example on
-how to use this option.
+@item org-html-table-row-tags
+The opening and ending tags for table rows.
+
+@vindex org-html-table-use-header-tags-for-first-column
+@item org-html-table-use-header-tags-for-first-column
+Non-nil means format column one in tables with header tags.
+@end table
@node Images in HTML export
@subsection Images in HTML export
@@ -11640,10 +11799,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
@@ -11746,6 +11908,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
@@ -11765,13 +11932,12 @@ the @LaTeX{} @code{\includegraphics} macro will be commented out.
@cindex plain lists, in @LaTeX{} export
Plain lists accept two optional attributes: @code{:environment} and
-@code{:options}. The first one allows the use of a non-standard
-environment (e.g., @samp{inparaenum}). The second one specifies
-optional arguments for that environment (square brackets may be
-omitted).
+@code{:options}. The first one allows the use of a non-standard environment
+(e.g., @samp{inparaenum}). The second one specifies additional arguments for
+that environment.
@example
-#+ATTR_LATEX: :environment compactitem :options $\circ$
+#+ATTR_LATEX: :environment compactitem :options [$\circ$]
- you need ``paralist'' package to reproduce this example.
@end example
@@ -11779,17 +11945,19 @@ omitted).
@cindex source blocks, in @LaTeX{} export
In addition to syntax defined in @ref{Literal examples}, names and captions
-(@pxref{Images and tables}), source blocks also accept a @code{:float}
-attribute. You may set it to:
+(@pxref{Images and tables}), source blocks also accept two additional
+attributes: @code{:float} and @code{:options}.
+
+You may set the former to
@itemize @minus
@item
@code{t}: if you want to make the source block a float. It is the default
value when a caption is provided.
@item
-@code{mulicolumn}: if you wish to include a source block which spans multiple
-colums in a page.
+@code{multicolumn}: if you wish to include a source block which spans multiple
+columns in a page.
@item
-@code{nil}: if you need to avoid any floating evironment, even when a caption
+@code{nil}: if you need to avoid any floating environment, even when a caption
is provided. It is useful for source code that may not fit in a single page.
@end itemize
@@ -11800,25 +11968,50 @@ Code that may not fit in a single page.
#+END_SRC
@end example
+@vindex org-latex-listings-options
+@vindex org-latex-minted-options
+The latter allows to specify options relative to the package used to
+highlight code in the output (e.g., @code{listings}). This is the local
+counterpart to @code{org-latex-listings-options} and
+@code{org-latex-minted-options} variables, which see.
+
+@example
+#+ATTR_LATEX: :options commentstyle=\bfseries
+#+BEGIN_SRC emacs-lisp
+ (defun Fib (n) ; Count rabbits.
+ (if (< n 2) n (+ (Fib (- n 1)) (Fib (- n 2)))))
+#+END_SRC
+@end example
+
@subsubheading Special blocks in @LaTeX{} export
@cindex special blocks, in @LaTeX{} export
+@cindex abstract, in @LaTeX{} export
+@cindex proof, in @LaTeX{} export
In @LaTeX{} back-end, special blocks become environments of the same name.
Value of @code{:options} attribute will be appended as-is to that
environment's opening string. For example:
@example
+#+BEGIN_abstract
+We demonstrate how to solve the Syracuse problem.
+#+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
becomes
@example
+\begin@{abstract@}
+We demonstrate how to solve the Syracuse problem.
+\end@{abstract@}
+
\begin@{proof@}[Proof of important theorem]
...
Therefore, any even number greater than 2 is the sum of two primes.
@@ -11831,9 +12024,9 @@ example:
@example
#+ATTR_LATEX: :caption \MyCaption@{HeadingA@}
-#+BEGIN_PROOF
+#+BEGIN_proof
...
-#+END_PROOF
+#+END_proof
@end example
@subsubheading Horizontal rules
@@ -11851,7 +12044,7 @@ respectively, @code{:width} and @code{:thickness} attributes:
@section Markdown export
@cindex Markdown export
-@code{md} export back-end generates Markdown syntax@footnote{Vanilla flavour,
+@code{md} export back-end generates Markdown syntax@footnote{Vanilla flavor,
as defined at @url{http://daringfireball.net/projects/markdown/}.} for an Org
mode buffer.
@@ -11883,8 +12076,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
@@ -12215,7 +12408,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:
@@ -12555,13 +12748,13 @@ file. The use of this feature is better illustrated with couple of examples.
@enumerate
@item Embedding ODT tags as part of regular text
-You can include simple OpenDocument tags by prefixing them with
-@samp{@@}. For example, to highlight a region of text do the following:
+You can inline OpenDocument syntax by enclosing it within
+@samp{@@@@odt:...@@@@} markup. For example, to highlight a region of text do
+the following:
@example
-@@<text:span text:style-name="Highlight">This is a
-highlighted text@@</text:span>. But this is a
-regular text.
+@@@@odt:<text:span text:style-name="Highlight">This is a highlighted
+text</text:span>@@@@. But this is a regular text.
@end example
@strong{Hint:} To see the above example in action, edit your
@@ -12797,6 +12990,345 @@ will take care of updating the @code{rng-schema-locating-files} for you.
@c end opendocument
+@node Org export
+@section Org export
+@cindex Org export
+
+@code{org} export back-end creates a normalized version of the Org document
+in current buffer. In particular, it evaluates Babel code (@pxref{Evaluating
+code blocks}) and removes other back-ends specific contents.
+
+@subheading Org export commands
+
+@table @kbd
+@orgcmd{C-c C-e O o,org-org-export-to-org}
+Export as an Org document. For an Org file, @file{myfile.org}, the resulting
+file will be @file{myfile.org.org}. The file will be overwritten without
+warning.
+@orgcmd{C-c C-e O O,org-org-export-as-org}
+Export to a temporary buffer. Do not create a file.
+@item C-c C-e O v
+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. @inforef{GNU Sample Texts,,texinfo} for an
+equivalent Texinfo code.
+
+@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
@@ -12871,17 +13403,15 @@ you are using. The FAQ covers this issue.
@cindex export back-ends, built-in
@vindex org-export-backends
-On top of the aforemetioned back-ends, Org comes with other built-in ones:
+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.
-@item @file{ox-org.el}: export to an Org document.
@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.
@@ -12904,8 +13434,8 @@ Convert the selected region into @code{Texinfo}.
Convert the selected region into @code{MarkDown}.
@end table
-This is particularily useful for converting tables and lists in foreign
-buffers. E.g., in a HTML buffer, you can turn on @code{orgstruct-mode}, then
+This is particularly useful for converting tables and lists in foreign
+buffers. E.g., in an HTML buffer, you can turn on @code{orgstruct-mode}, then
use Org commands for editing a list, and finally select and convert the list
with @code{M-x org-html-convert-region-to-html RET}.
@@ -12955,63 +13485,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
@@ -13099,9 +13629,9 @@ channel."
@end lisp
The @code{my-ascii-src-block} function looks at the attribute above the
-element. If it isn’t true, it gives hand to the @code{ascii} back-end.
+element. If it isn't true, it gives hand to the @code{ascii} back-end.
Otherwise, it creates a box around the code, leaving room for the language.
-A new back-end is then created. It only changes its behaviour when
+A new back-end is then created. It only changes its behavior when
translating @code{src-block} type element. Now, all it takes to use the new
back-end is calling the following from an Org buffer:
@@ -13277,48 +13807,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}
@@ -13342,45 +13851,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-xml-declaration
-@vindex org-html-link-up
-@vindex org-html-link-home
-@vindex org-html-link-org-files-as-html
-@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-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-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-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}
+@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-caption-above} @tab @code{org-latex-caption-above}
+@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-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
@@ -13750,8 +14388,14 @@ can be used to map arbitrary language names to existing major modes.
@item org-src-window-setup
Controls the way Emacs windows are rearranged when the edit buffer is created.
@item org-src-preserve-indentation
-This variable is especially useful for tangling languages such as
-Python, in which whitespace indentation in the output is critical.
+@cindex indentation, in source blocks
+By default, the value is @code{nil}, which means that when code blocks are
+evaluated during export or tangled, they are re-inserted into the code block,
+which may replace sequences of spaces with tab characters. When non-nil,
+whitespace in code blocks will be preserved during export or tangling,
+exactly as it appears. This variable is especially useful for tangling
+languages such as Python, in which whitespace indentation in the output is
+critical.
@item org-src-ask-before-returning-to-edit-buffer
By default, Org will ask before returning to an open edit buffer. Set this
variable to @code{nil} to switch without asking.
@@ -13774,7 +14418,8 @@ results of code block evaluation. For information on exporting code block
bodies, see @ref{Literal examples}.
The @code{:exports} header argument can be used to specify export
-behavior:
+behavior (note that these arguments are only relevant for code blocks, not
+inline code):
@subsubheading Header arguments:
@@ -13801,12 +14446,15 @@ ensure that no code blocks are evaluated as part of the export process. This
can be useful in situations where potentially untrusted Org mode files are
exported in an automated fashion, for example when Org mode is used as the
markup language for a wiki. It is also possible to set this variable to
-@code{‘inline-only}. In that case, only inline code blocks will be
+@code{inline-only}. In that case, only inline code blocks will be
evaluated, in order to insert their results. Non-inline code blocks are
assumed to have their results already inserted in the buffer by manual
evaluation. This setting is useful to avoid expensive recalculations during
export, not to provide security.
+Code blocks in commented subtrees (@pxref{Comment lines}) are never evaluated
+on export. However, code blocks in subtrees excluded from export
+(@pxref{Export settings}) may be evaluated on export.
@node Extracting source code
@section Extracting source code
@@ -13900,13 +14548,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. Live code blocks located in the current
-Org mode buffer or in the ``Library of Babel'' (see @ref{Library of Babel})
-can be executed. Named code blocks can be executed with a separate
-@code{#+CALL:} line or inline within a block of text.
+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'' (@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
@@ -14130,7 +14780,7 @@ looked up with inheritance, regardless of the value of
outermost call or source block.@footnote{The deprecated syntax for default
header argument properties, using the name of the header argument as a
property name directly, evaluates the property as seen by the corresponding
-source block definition. This behaviour has been kept for backwards
+source block definition. This behavior has been kept for backwards
compatibility.}
In the following example the value of
@@ -14266,6 +14916,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
@@ -14700,6 +15352,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
@@ -14774,7 +15449,8 @@ which the link does not point.
@cindex @code{:exports}, src header argument
The @code{:exports} header argument specifies what should be included in HTML
-or @LaTeX{} exports of the Org mode file.
+or @LaTeX{} exports of the Org mode file. Note that the @code{:exports}
+option is only relevant for code blocks, not inline code.
@itemize @bullet
@item @code{code}
@@ -14870,6 +15546,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}
@@ -14945,12 +15624,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
@@ -15472,10 +16151,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:
@@ -15837,7 +16516,7 @@ The corresponding variable is @code{org-archive-location}.
This line sets the category for the agenda file. The category applies
for all subsequent lines until the next @samp{#+CATEGORY} line, or the
end of the file. The first such line also applies to any entries before it.
-@item #+COLUMNS: %25ITEM .....
+@item #+COLUMNS: %25ITEM ...
@cindex property, COLUMNS
Set the default format for columns view. This format applies when
columns view is invoked in locations where no @code{COLUMNS} property
@@ -15852,7 +16531,7 @@ The global version of this variable is
@item #+FILETAGS: :tag1:tag2:tag3:
Set tags that can be inherited by any entry in the file, including the
top-level entries.
-@item #+LINK: linkword replace
+@item #+LINK: linkword replace
@vindex org-link-abbrev-alist
These lines (several are allowed) specify link abbreviations.
@xref{Link abbreviations}. The corresponding variable is
@@ -16868,7 +17547,7 @@ Orgtbl mode how to translate this table and where to install it. For
example:
@cindex #+ORGTBL
@example
-#+ORGTBL: SEND table_name translation_function arguments....
+#+ORGTBL: SEND table_name translation_function arguments...
@end example
@noindent
@@ -16891,10 +17570,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
@@ -17002,14 +17677,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
@@ -17020,14 +17696,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
@@ -17037,54 +17713,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
@@ -17504,7 +18162,7 @@ Get all property keys in the current buffer.
@end defun
@defun org-insert-property-drawer
-Insert a property drawer for the current entry. Also
+Insert a property drawer for the current entry.
@end defun
@defun org-entry-put-multivalued-property pom property &rest values
@@ -17968,7 +18626,7 @@ inspired some of the early development, including HTML export. He also
asked for a way to narrow wide table columns.
@item
@i{Jason Dunsmore} has been maintaining the Org-Mode server at Rackspace for
-several years now. He also sponsered the hosting costs until Rackspace
+several years now. He also sponsored the hosting costs until Rackspace
started to host us for free.
@item
@i{Thomas S. Dye} contributed documentation on Worg and helped integrating
diff --git a/doc/orgcard.tex b/doc/orgcard.tex
index 69bf302..cf1e309 100644
--- a/doc/orgcard.tex
+++ b/doc/orgcard.tex
@@ -1,7 +1,7 @@
% Reference Card for Org Mode
-\def\orgversionnumber{8.0}
-\def\versionyear{2013} % latest update
-\def\year{2013} % latest copyright year
+\def\orgversionnumber{8.2}
+\def\versionyear{2014} % latest update
+\def\year{2014} % latest copyright year
%**start of header
\newcount\columnsperpage
@@ -17,7 +17,7 @@
\pdflayout=(0l)
% Nothing else needs to be changed below this line.
-% Copyright (C) 1987, 1993, 1996-1997, 2001-2013 Free Software
+% Copyright (C) 1987, 1993, 1996-1997, 2001-2014 Free Software
% Foundation, Inc.
% This file is part of GNU Emacs.
diff --git a/doc/orgguide.texi b/doc/orgguide.texi
index da4bbc5..e32fa7c 100644
--- a/doc/orgguide.texi
+++ b/doc/orgguide.texi
@@ -35,17 +35,18 @@
@end macro
@macro seealso{text}
-@noindent @b{Further reading}@*@noindent \text\
+@noindent
+@b{Further reading}@*@noindent \text\
@end macro
@copying
-Copyright @copyright{} 2010--2013 Free Software Foundation
+Copyright @copyright{} 2010--2014 Free Software Foundation
@quotation
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3 or
any later version published by the Free Software Foundation; with no
-Invariant Sections, with the Front-Cover texts being ``A GNU Manual,''
+Invariant Sections, with the Front-Cover Texts being ``A GNU Manual,''
and with the Back-Cover Texts as in (a) below. A copy of the license
is included in the section entitled ``GNU Free Documentation License''
in the full Org manual, which is distributed together with the compact
@@ -211,7 +212,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
@@ -263,7 +264,8 @@ to the Emacs load path. To do this, add the following line to @file{.emacs}:
(setq load-path (cons "~/path/to/orgdir/contrib/lisp" load-path))
@end smallexample
-@noindent If you have been using git or a tar ball to get Org, you need to
+@noindent
+If you have been using git or a tar ball to get Org, you need to
run the following command to generate autoload information.
command:
@@ -343,7 +345,8 @@ of @kbd{C-a} and @kbd{C-e} in headlines.}. For example:
* Another top level headline
@end smallexample
-@noindent Some people find the many stars too noisy and would prefer an
+@noindent
+Some people find the many stars too noisy and would prefer an
outline that has whitespace followed by a single star as headline
starters. @ref{Clean view}, describes a setup to realize this.
@@ -543,7 +546,8 @@ The Org homepage[fn:1] now looks a lot better than it used to.
[fn:1] The link is: http://orgmode.org
@end smallexample
-@noindent The following commands handle footnotes:
+@noindent
+The following commands handle footnotes:
@table @kbd
@item C-c C-x f
@@ -604,7 +608,8 @@ create the above table, you would only type
|-
@end smallexample
-@noindent and then press @key{TAB} to align the table and start filling in
+@noindent
+and then press @key{TAB} to align the table and start filling in
fields. Even faster would be to type @code{|Name|Phone|Age} followed by
@kbd{C-c @key{RET}}.
@@ -1068,7 +1073,8 @@ are checkboxes, toggling one of the children checkboxes will make the
parent checkbox reflect if none, some, or all of the children are
checked.
-@noindent The following commands work with checkboxes:
+@noindent
+The following commands work with checkboxes:
@table @kbd
@item C-c C-c
@@ -1176,7 +1182,8 @@ like:
(setq org-tag-alist '(("@@work" . ?w) ("@@home" . ?h) ("laptop" . ?l)))
@end smalllisp
-@noindent If the tag is only relevant to the file you are working on, then you
+@noindent
+If the tag is only relevant to the file you are working on, then you
can instead set the TAGS option line as:
@smallexample
@@ -1332,7 +1339,8 @@ timestamp can appear anywhere in the headline or body of an Org tree entry.
Its presence causes entries to be shown on specific dates in the agenda
(@pxref{Weekly/daily agenda}). We distinguish:
-@noindent @b{Plain timestamp; Event; Appointment}@*
+@noindent
+@b{Plain timestamp; Event; Appointment}@*
A simple timestamp just assigns a date/time to an item. This is just
like writing down an appointment or event in a paper agenda.
@@ -1343,7 +1351,8 @@ like writing down an appointment or event in a paper agenda.
<2006-11-02 Thu 20:00-22:00>
@end smallexample
-@noindent @b{Timestamp with repeater interval}@*
+@noindent
+@b{Timestamp with repeater interval}@*
A timestamp may contain a @emph{repeater interval}, indicating that it
applies not only on the given date, but again and again after a certain
interval of N days (d), weeks (w), months (m), or years (y). The
@@ -1353,7 +1362,8 @@ following will show up in the agenda every Wednesday:
<2007-05-16 Wed 12:30 +1w>
@end smallexample
-@noindent @b{Diary-style sexp entries}@*
+@noindent
+@b{Diary-style sexp entries}@*
For more complex date specifications, Org mode supports using the
special sexp diary entries implemented in the Emacs calendar/diary
package. For example
@@ -1362,14 +1372,16 @@ package. For example
<%%(diary-float t 4 2)>
@end smallexample
-@noindent @b{Time/Date range}@*
+@noindent
+@b{Time/Date range}@*
Two timestamps connected by @samp{--} denote a range.
@smallexample
** Meeting in Amsterdam
<2004-08-23 Mon>--<2004-08-26 Thu>
@end smallexample
-@noindent @b{Inactive timestamp}@*
+@noindent
+@b{Inactive timestamp}@*
Just like a plain timestamp, but with square brackets instead of
angular ones. These timestamps are inactive in the sense that they do
@emph{not} trigger an entry to show up in the agenda.
@@ -1421,7 +1433,8 @@ information on how exactly the date/time prompt works.
A timestamp may be preceded by special keywords to facilitate planning:
-@noindent @b{DEADLINE}@*
+@noindent
+@b{DEADLINE}@*
Meaning: the task (most likely a TODO item, though not necessarily) is supposed
to be finished on that date.
@table @kbd
@@ -1443,7 +1456,8 @@ until the entry is marked DONE. An example:
@end smallexample
-@noindent @b{SCHEDULED}@*
+@noindent
+@b{SCHEDULED}@*
Meaning: you are @i{planning to start working} on that task on the given
date@footnote{This is quite different from what is normally understood by
@i{scheduling a meeting}, which is done in Org-mode by just inserting a time
@@ -1498,7 +1512,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
@@ -1605,7 +1619,8 @@ use:
"* %?\nEntered on %U\n %i\n %a")))
@end smallexample
-@noindent In these entries, the first string is the key to reach the
+@noindent
+In these entries, the first string is the key to reach the
template, the second is a short description. Then follows the type of the
entry and a definition of the target location for storing the note. Finally,
the template itself, a string with %-escapes to fill in information based on
@@ -2169,10 +2184,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 +2276,16 @@ 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. File-links
+will be interpreted as well:
+@smallexample
+#+INCLUDE: "./otherfile.org::#my_custom_id" :only-contents t
+@end smallexample
+@noindent
+@kbd{C-c '} will visit the included file.
@node Embedded @LaTeX{}, , Include files, Markup
@section Embedded @LaTeX{}
@@ -2281,7 +2305,8 @@ $a=+\sqrt@{2@}$ or $a=-\sqrt@{2@}$.
x=\sqrt@{b@}
\end@{equation@}
@end smallexample
-@noindent With
+@noindent
+With
@uref{http://orgmode.org/manual/LaTeX-fragments.html#LaTeX-fragments,special
setup}, @LaTeX{} snippets will be included as images when exporting to HTML.
@@ -2303,30 +2328,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
@@ -2375,7 +2399,8 @@ the exported file use either
@smallexample
#+HTML: Literal HTML code for export
@end smallexample
-@noindent or
+@noindent
+or
@smallexample
#+BEGIN_HTML
All lines between these markers are exported literally
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: