Bastien Guerry 12 лет назад
Родитель
Сommit
7d5985f4e3
100 измененных файлов с 6512 добавлено и 2680 удалено
  1. 1 1
      .gitmodules
  2. 4 2
      README
  3. 6 2
      README_ELPA
  4. 16 95
      README_maintainer
  5. 21 20
      contrib/README
  6. 6 4
      contrib/lisp/htmlize.el
  7. 2 2
      contrib/lisp/org-bibtex-extras.el
  8. 200 48
      contrib/lisp/org-contacts.el
  9. 6 6
      contrib/lisp/org-git-link.el
  10. 93 10
      contrib/lisp/org-mac-link-grabber.el
  11. 5 4
      contrib/lisp/org-mac-message.el
  12. 2 1
      contrib/lisp/org-man.el
  13. 1 3
      contrib/lisp/org-mime.el
  14. 530 0
      contrib/lisp/org-screenshot.el
  15. 1 1
      contrib/lisp/org-wl.el
  16. 252 0
      contrib/lisp/ox-bibtex.el
  17. 1 1
      contrib/lisp/ox-confluence.el
  18. 16 9
      contrib/lisp/ox-deck.el
  19. 9 11
      contrib/lisp/ox-groff.el
  20. 425 49
      contrib/lisp/ox-koma-letter.el
  21. 1 1
      contrib/lisp/ox-s5.el
  22. 250 79
      contrib/lisp/ox-taskjuggler.el
  23. 302 190
      doc/org.texi
  24. 1 1
      doc/orgcard.tex
  25. 67 25
      doc/orgguide.texi
  26. 815 0
      etc/ORG-NEWS
  27. 6 0
      etc/styles/OrgOdtStyles.xml
  28. 1 1
      lisp/Makefile
  29. 73 25
      lisp/ob-C.el
  30. 35 23
      lisp/ob-R.el
  31. 1 1
      lisp/ob-awk.el
  32. 1 1
      lisp/ob-comint.el
  33. 170 108
      lisp/ob-core.el
  34. 1 0
      lisp/ob-eval.el
  35. 35 28
      lisp/ob-exp.el
  36. 7 0
      lisp/ob-fortran.el
  37. 75 29
      lisp/ob-gnuplot.el
  38. 6 5
      lisp/ob-haskell.el
  39. 26 24
      lisp/ob-js.el
  40. 19 11
      lisp/ob-lob.el
  41. 1 0
      lisp/ob-maxima.el
  42. 21 6
      lisp/ob-ocaml.el
  43. 2 1
      lisp/ob-octave.el
  44. 3 2
      lisp/ob-org.el
  45. 23 16
      lisp/ob-perl.el
  46. 1 1
      lisp/ob-picolisp.el
  47. 25 3
      lisp/ob-python.el
  48. 1 1
      lisp/ob-ref.el
  49. 24 26
      lisp/ob-ruby.el
  50. 25 23
      lisp/ob-scheme.el
  51. 1 1
      lisp/ob-sh.el
  52. 36 36
      lisp/ob-tangle.el
  53. 2 0
      lisp/ob.el
  54. 310 155
      lisp/org-agenda.el
  55. 8 3
      lisp/org-bbdb.el
  56. 4 2
      lisp/org-bibtex.el
  57. 19 5
      lisp/org-capture.el
  58. 65 53
      lisp/org-clock.el
  59. 35 12
      lisp/org-compat.el
  60. 6 6
      lisp/org-crypt.el
  61. 2 5
      lisp/org-ctags.el
  62. 4 1
      lisp/org-datetree.el
  63. 197 59
      lisp/org-element.el
  64. 1 0
      lisp/org-entities.el
  65. 11 4
      lisp/org-faces.el
  66. 6 5
      lisp/org-footnote.el
  67. 9 2
      lisp/org-habit.el
  68. 4 1
      lisp/org-id.el
  69. 5 5
      lisp/org-indent.el
  70. 31 18
      lisp/org-list.el
  71. 41 32
      lisp/org-macro.el
  72. 7 6
      lisp/org-macs.el
  73. 1 0
      lisp/org-mhe.el
  74. 3 5
      lisp/org-mobile.el
  75. 1 1
      lisp/org-mouse.el
  76. 2 1
      lisp/org-pcomplete.el
  77. 1 1
      lisp/org-protocol.el
  78. 24 8
      lisp/org-src.el
  79. 82 94
      lisp/org-table.el
  80. 1 1
      lisp/org-w3m.el
  81. 457 305
      lisp/org.el
  82. 39 32
      lisp/ox-ascii.el
  83. 23 18
      lisp/ox-beamer.el
  84. 345 233
      lisp/ox-html.el
  85. 17 10
      lisp/ox-icalendar.el
  86. 278 345
      lisp/ox-latex.el
  87. 5 6
      lisp/ox-man.el
  88. 15 9
      lisp/ox-md.el
  89. 44 26
      lisp/ox-odt.el
  90. 107 11
      lisp/ox-org.el
  91. 17 8
      lisp/ox-publish.el
  92. 23 10
      lisp/ox-texinfo.el
  93. 422 233
      lisp/ox.el
  94. 1 1
      mk/default.mk
  95. 7 5
      mk/server.mk
  96. 2 4
      testing/examples/babel-dangerous.org
  97. 1 1
      testing/examples/babel.org
  98. 27 1
      testing/examples/ob-C-test.org
  99. 22 0
      testing/examples/ob-fortran-test.org
  100. 126 0
      testing/examples/ob-header-arg-defaults.org

+ 1 - 1
.gitmodules

@@ -1,3 +1,3 @@
 [submodule "testing/jump"]
 [submodule "testing/jump"]
 	path = testing/jump
 	path = testing/jump
-	url = git://github.com/eschulte/jump.el.git
+	url = https://github.com/eschulte/jump.el.git

+ 4 - 2
README

@@ -1,9 +1,11 @@
 The is a distribution of Org, a plain text notes and project planning
 The is a distribution of Org, a plain text notes and project planning
 tool for Emacs.
 tool for Emacs.
 
 
-The version of this release is: 7.9.1
+The homepage of Org is at:
+  http://orgmode.org
 
 
-The homepage of Org is at http://orgmode.org
+The installations instructions are at:
+  http://orgmode.org/org.html#Installation
 
 
 This distribution contains:
 This distribution contains:
 
 

+ 6 - 2
README_ELPA

@@ -1,11 +1,15 @@
 This is the Emacs Org project, an Emacs library for organizing your life.
 This is the Emacs Org project, an Emacs library for organizing your life.
 
 
-The homepage of Org is at http://orgmode.org
+The homepage of Org is at:
+  http://orgmode.org
+
+Installations instructions are at:
+  http://orgmode.org/org.html#Installation
 
 
 This distribution contains an ELPA packaged version of Org.
 This distribution contains an ELPA packaged version of Org.
 "ELPA" stands for the "Emacs Lisp Package Archive".
 "ELPA" stands for the "Emacs Lisp Package Archive".
-The GNU ELPA is here:
 
 
+The GNU ELPA is at:
   http://elpa.gnu.org
   http://elpa.gnu.org
 
 
 It contains the org-*.tar package, containing only the org files
 It contains the org-*.tar package, containing only the org files

+ 16 - 95
README_maintainer

@@ -1,6 +1,6 @@
 # -*- mode:org -*-
 # -*- mode:org -*-
 
 
-#+TITLE: Maintainer tasks
+#+TITLE: Org maintainer tasks
 #+STARTUP: noindent
 #+STARTUP: noindent
 
 
 This document describes the tasks the Org-mode maintainer has to do
 This document describes the tasks the Org-mode maintainer has to do
@@ -37,7 +37,7 @@ branch back into maint to synchronize the two.
 
 
 ** Minor release
 ** Minor release
 
 
-The release number for minor releases look like this:  =7.13.01=
+The release number for minor releases look like this:  =7.13.1=
 
 
 Minor releases are small amends to main releases.  Usually they fix
 Minor releases are small amends to main releases.  Usually they fix
 critical bugs discovered in a main release.  Minor bugs are usually
 critical bugs discovered in a main release.  Minor bugs are usually
@@ -50,15 +50,19 @@ maint then merged in master.
 
 
 ** Tagging the release
 ** Tagging the release
 
 
-When doing a major and a minor release, after all necessary merging
-is done, tag the _maint_ branch for the release with:
+When doing a major and a minor release, after all necessary merging is
+done, tag the _maint_ branch for the release with:
 
 
-  git tag -a "Adding release tag" release_7.9.1
+  git tag -a release_7.9.1 -m "Adding release tag"
 
 
 and push tags with
 and push tags with
 
 
   git push --tags
   git push --tags
 
 
+We also encourage you to sign release tags like this:
+
+  git tag -s release_7.9.1 -m "Adding release tag"
+
 ** Uploading the release files from the orgmode.org server
 ** Uploading the release files from the orgmode.org server
 
 
 Log on the orgmode.org server as the emacs user and cd to
 Log on the orgmode.org server as the emacs user and cd to
@@ -72,92 +76,6 @@ From there do
 to create the .tar.gz and .zip files, the documentation, and to
 to create the .tar.gz and .zip files, the documentation, and to
 upload everything at the right place.
 upload everything at the right place.
 
 
-* Working with patchwork
-
-John Wiegley is running a patchwork server that looks at the
-emacs-orgmode mailing list and extracts patches.  The maintainer and
-his helpers should work through such patches, give feedback on them
-and apply the ones which are good and done.  A task for the maintainer
-is to every now and then try to get old stuff out of that list, by
-asking some helpers to investigate the patch, by rejecting or
-accepting it.
-
-I have found that the best workflow for this is using the pw script by
-Nate Case, with the modifications for Org-mode made by John Wiegley
-and Carsten Dominik.  The correct version of this script that should
-be used with Org mode is distributed in the =mk/= directory of the Org
-mode distribution.  Here is the basic workflow for this.
-
-** Access to the patchwork server
-
-If you want to work on patchwork patches, you need write access at the
-patchwork server.  You need to contact John Wiegley to get this
-access.
-
-There is a web interface to look at the patches and to change the
-status of patches.  This interface is self-explanatory.  There is also
-a command line script which can be very convenient to use.
-
-** Testing patches
-
-To start testing a patch, first assign it to yourself
-
-: pw update -s "Under Review" -d DELEGATE-NAME NNN
-
-where =NNN= is a patch number and =DELEGATE-NAME= is your user name on
-the patchwork server.
-
-The get the patch into a branch:
-
-: pw branch NNN
-
-This will create a local topic branch in your git repository with the
-name =t/patchNNN=.  You will also be switched to the branch so that
-you can immediately start testing it.  Quite often small amends need
-to be made, or documentation has to be added.  Also, many contributors
-do not yet provide the proper ChangeLog-like entries in the commit
-message for the patch.  As a maintainer, you have two options here.
-Either ask the contributor to make the changes and resubmit the patch,
-or fix it yourself.  In principle, asking to contributor to change the
-patch until it is complete is the best route, because it will educate
-the contributor and minimize the work for the maintainer.  However,
-sometimes it can be less hassle to fix things directly and commit the
-changes to the same branch =t/patchNNN=.
-
-If you ask the contributor to make the changes, the patch should be
-marked on the patchwork server as "changes requested".
-
-: pw update -s "Changes Requested" -m "What to change" NNN
-
-This will send an email to the contributor and the mailing list with a
-request for changes.  The =-m= message should not be more than one
-sentence and describe the requested changes.  If you need to explain
-in more detail, write a separate email to the contributor.
-
-When a new version of the patch arrives, you mark the old one as
-superseded
-
-: pw update -s "Superseded" NNN
-
-and start working at the new one.
-
-** Merging a final patch
-
-Once the patch has been iterated and is final (including the
-ChangeLog-like entries in the commit message), it should be merged.
-The assumption here is that the final version of the patch is given by
-the HEAD state in the branch =t/patchNNN=.  To merge, do this:
-
-: pw merge -m "maintainer comment" NNN
-
-This will merge the patch into master, switch back to master and send
-an email to both contributor and mailing list stating that this change
-has been accepted, along with the comment given in the =-m= message.
-
-At some point you might then want to remove the topic branch
-
-: git branch -d t/patchNNN
-
 * Synchonization with Emacs
 * Synchonization with Emacs
 
 
 This is still a significant headache.  Some hand work is needed here.
 This is still a significant headache.  Some hand work is needed here.
@@ -253,16 +171,19 @@ So the way I have been doing things with Emacs is this:
 
 
 * Copyright assignments
 * Copyright assignments
 
 
-  The maintainer needs to keep track of copyright assignments.  Even
-  better, find a volunteer to do this.
+  The maintainer needs to keep track of copyright assignments.
+  Even better, find a volunteer to do this.
+
+  The assignment form is included in the repository as a file that
+  you can send to contributors: =request-assign-future.txt=
 
 
   The list of all contributors from who we have the papers is kept on
   The list of all contributors from who we have the papers is kept on
-  Worg at http://orgmode.org/worg/org-contribute.php, so that
+  Worg at http://orgmode.org/worg/org-contribute.html, so that
   committers can check if a patch can go into the core.
   committers can check if a patch can go into the core.
 
 
   The assignment process does not allways go smoothly, and it has
   The assignment process does not allways go smoothly, and it has
   happened several times that it gets stuck or forgotten at the FSF.
   happened several times that it gets stuck or forgotten at the FSF.
-  The contact at the FSF for this is: copyright-clerk@fsf.org
+  The contact at the FSF for this is: mailto:copyright-clerk@fsf.org
 
 
   Emails from the paper submitter have been ignored in the past, but
   Emails from the paper submitter have been ignored in the past, but
   an email from me (Carsten) as the maintainer of Org mode has usually
   an email from me (Carsten) as the maintainer of Org mode has usually

+ 21 - 20
contrib/README

@@ -19,6 +19,7 @@ org-bullets.el           --- Show bullets in org-mode as UTF-8 characters
 org-checklist.el         --- org functions for checklist handling
 org-checklist.el         --- org functions for checklist handling
 org-choose.el            --- Use TODO keywords to mark decision states
 org-choose.el            --- Use TODO keywords to mark decision states
 org-collector.el         --- Collect properties into tables
 org-collector.el         --- Collect properties into tables
+org-colview-xemacs.el	 --- Column View in Org-mode, XEmacs-specific version
 org-contacts.el          --- Contacts management
 org-contacts.el          --- Contacts management
 org-contribdir.el        --- Dummy file to mark the org contrib Lisp directory
 org-contribdir.el        --- Dummy file to mark the org contrib Lisp directory
 org-depend.el            --- TODO dependencies for Org-mode
 org-depend.el            --- TODO dependencies for Org-mode
@@ -29,6 +30,7 @@ org-eval-light.el        --- Evaluate in-buffer code on demand
 org-eval.el              --- The <lisp> tag, adapted from Muse
 org-eval.el              --- The <lisp> tag, adapted from Muse
 org-expiry.el            --- Expiry mechanism for Org entries
 org-expiry.el            --- Expiry mechanism for Org entries
 org-export-generic.el    --- Export framework for configurable backends
 org-export-generic.el    --- Export framework for configurable backends
+org-favtable.el          --- Lookup table of favorite references and links
 org-git-link.el          --- Provide org links to specific file version
 org-git-link.el          --- Provide org links to specific file version
 org-interactive-query.el --- Interactive modification of tags query
 org-interactive-query.el --- Interactive modification of tags query
 org-invoice.el           --- Help manage client invoices in OrgMode
 org-invoice.el           --- Help manage client invoices in OrgMode
@@ -36,8 +38,10 @@ org-jira.el              --- Add a jira:ticket protocol to Org
 org-learn.el             --- SuperMemo's incremental learning algorithm
 org-learn.el             --- SuperMemo's incremental learning algorithm
 org-mac-iCal.el          --- Imports events from iCal.app to the Emacs diary
 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-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-mairix.el 	         --- Hook mairix search into Org for different MUAs
 org-mairix.el 	         --- Hook mairix search into Org for different MUAs
 org-man.el 	         --- Support for links to manpages in Org-mode
 org-man.el 	         --- Support for links to manpages in Org-mode
+org-mew.el		 --- Support for links to Mew messages
 org-mime.el              --- org html export for text/html MIME emails
 org-mime.el              --- org html export for text/html MIME emails
 org-mtags.el 	         --- Support for some Muse-like tags in Org-mode
 org-mtags.el 	         --- Support for some Muse-like tags in Org-mode
 org-notify.el            --- Notifications for Org-mode
 org-notify.el            --- Notifications for Org-mode
@@ -45,53 +49,50 @@ org-notmuch.el           --- Support for links to notmuch messages
 org-panel.el 	         --- Simple routines for us with bad memory
 org-panel.el 	         --- Simple routines for us with bad memory
 org-registry.el          --- A registry for Org links
 org-registry.el          --- A registry for Org links
 org-screen.el            --- Visit screen sessions through Org-mode links
 org-screen.el            --- Visit screen sessions through Org-mode links
+org-screenshot.el        --- Take and manage screenshots in Org-mode files
 org-secretary.el         --- Team management with org-mode
 org-secretary.el         --- Team management with org-mode
 org-static-mathjax.el    --- Muse-like tags in Org-mode
 org-static-mathjax.el    --- Muse-like tags in Org-mode
 org-sudoku.el            --- Create and solve SUDOKU puzzles in Org tables
 org-sudoku.el            --- Create and solve SUDOKU puzzles in Org tables
 org-toc.el 	         --- Table of contents for Org-mode buffer
 org-toc.el 	         --- Table of contents for Org-mode buffer
 org-track.el             --- Keep up with Org development
 org-track.el             --- Keep up with Org development
 org-velocity.el          --- something like Notational Velocity for Org
 org-velocity.el          --- something like Notational Velocity for Org
-org-wikinodes.el         --- CamelCase wiki-like links for Org
-org2rem.el               --- Convert org appointments into reminders
-orgtbl-sqlinsert.el      --- Convert Org-mode tables to SQL insertions
-org-favtable.el          --- Lookup table of favorite references and links
-org-mew.el		 --- Support for links to Mew messages
 org-vm.el		 --- Support for links to VM messages
 org-vm.el		 --- Support for links to VM messages
-org-wl.el		 --- Support for links to Wanderlust messages
 org-w3m.el		 --- Support link/copy/paste from w3m to Org-mode
 org-w3m.el		 --- Support link/copy/paste from w3m to Org-mode
-org-colview-xemacs.el	 --- Column View in Org-mode, XEmacs-specific version
+org-wikinodes.el         --- CamelCase wiki-like links for Org
+org-wl.el		 --- Support for links to Wanderlust messages
+orgtbl-sqlinsert.el      --- Convert Org-mode tables to SQL insertions
 
 
 Org exporters
 Org exporters
 ~~~~~~~~~~~~~
 ~~~~~~~~~~~~~
-ox-confluence.el         --- Confluence Wiki Back-End for Org Export Engine
-ox-deck.el               --- deck.js Presentation Back-End for Org Export Engine
-ox-groff.el              --- Groff Back-End for Org Export Engine
-ox-koma-letter.el        --- KOMA Scrlttr2 Back-End for Org Export Engine
-ox-s5.el                 --- S5 Presentation Back-End for Org Export Engine
-ox-taskjuggler.el        --- TaskJuggler Back-End for Org Export Engine
-ox-rss.el		 --- RSS 2.0 Back-End for Org Export Engine
+ox-confluence.el         --- Confluence Wiki exporter
+ox-deck.el               --- deck.js presentations exporter
+ox-groff.el              --- Groff exporter
+ox-koma-letter.el        --- KOMA Scrlttr2 exporter
+ox-rss.el		 --- RSS 2.0 exporter
+ox-s5.el                 --- S5 presentations exporter
+ox-taskjuggler.el        --- TaskJuggler exporter
 
 
 Org Babel languages
 Org Babel languages
 ~~~~~~~~~~~~~~~~~~~
 ~~~~~~~~~~~~~~~~~~~
+ob-eukleides.el    	 --- Org-babel functions for eukleides evaluation
 ob-fomus.el        	 --- Org-babel functions for fomus evaluation
 ob-fomus.el        	 --- Org-babel functions for fomus evaluation
-ob-oz.el           	 --- Org-babel functions for Oz evaluation
+ob-julia.el  	 	 --- Org-babel functions for julia evaluation
 ob-mathomatic.el   	 --- Org-babel functions for mathomatic evaluation
 ob-mathomatic.el   	 --- Org-babel functions for mathomatic evaluation
+ob-oz.el           	 --- Org-babel functions for Oz evaluation
 ob-tcl.el 		 --- Org-babel functions for tcl evaluation
 ob-tcl.el 		 --- Org-babel functions for tcl evaluation
-ob-eukleides.el    	 --- Org-babel functions for eukleides evaluation
-ob-julia.el  	 	 --- Org-babel functions for julia evaluation
 
 
 External libraries
 External libraries
 ~~~~~~~~~~~~~~~~~~
 ~~~~~~~~~~~~~~~~~~
 htmlize.el               --- Convert buffer text and decorations to HTML
 htmlize.el               --- Convert buffer text and decorations to HTML
-  
+
 
 
 SCRIPTS (shell, bash, etc.)
 SCRIPTS (shell, bash, etc.)
 ===========================
 ===========================
+StartOzServer.oz     	 --- implements the Oz-side of the Org-babel Oz interface
 dir2org.zsh              --- Org compatible fs structure output
 dir2org.zsh              --- Org compatible fs structure output
 ditaa.jar            	 --- ASCII to PNG converter by Stathis Sideris, GPL
 ditaa.jar            	 --- ASCII to PNG converter by Stathis Sideris, GPL
-org2hpda             	 --- Generate hipster pda style printouts from Org-mode
 org-docco.org        	 --- docco side-by-side annotated code export to HTML
 org-docco.org        	 --- docco side-by-side annotated code export to HTML
-StartOzServer.oz     	 --- implements the Oz-side of the Org-babel Oz interface
+org2hpda             	 --- Generate hipster pda style printouts from Org-mode
 staticmathjax        	 --- XULRunner application to process MathJax statically
 staticmathjax        	 --- XULRunner application to process MathJax statically
 x11idle.c            	 --- get the idle time of your X session
 x11idle.c            	 --- get the idle time of your X session
 
 

+ 6 - 4
contrib/lisp/htmlize.el

@@ -601,10 +601,12 @@ list."
                      (htmlize-attr-escape (file-relative-name file))
                      (htmlize-attr-escape (file-relative-name file))
                      alt-attr)))
                      alt-attr)))
           ((plist-get imgprops :data)
           ((plist-get imgprops :data)
-           (format "<img src=\"data:image/%s;base64,%s\"%s />"
-                   (or (plist-get imgprops :type) "")
-                   (base64-encode-string (plist-get imgprops :data))
-                   alt-attr)))))
+	   (if (equalp (plist-get imgprops :type) 'svg)
+	       (plist-get imgprops :data)
+	     (format "<img src=\"data:image/%s;base64,%s\"%s />"
+		     (or (plist-get imgprops :type) "")
+		     (base64-encode-string (plist-get imgprops :data))
+		     alt-attr))))))
 
 
 (defconst htmlize-ellipsis "...")
 (defconst htmlize-ellipsis "...")
 (put-text-property 0 (length htmlize-ellipsis) 'htmlize-ellipsis t htmlize-ellipsis)
 (put-text-property 0 (length htmlize-ellipsis) 'htmlize-ellipsis t htmlize-ellipsis)

+ 2 - 2
contrib/lisp/org-bibtex-extras.el

@@ -78,7 +78,7 @@ For example, to point to your `obe-bibtex-file' use the following.
 	(find-file obe-bibtex-file)
 	(find-file obe-bibtex-file)
 	(goto-char (point-min))
 	(goto-char (point-min))
 	(while (re-search-forward "  :CUSTOM_ID: \\(.+\\)$" nil t)
 	(while (re-search-forward "  :CUSTOM_ID: \\(.+\\)$" nil t)
-	  (push (org-babel-clean-text-properties (match-string 1))
+	  (push (org-no-properties (match-string 1))
 		obe-citations))
 		obe-citations))
 	obe-citations)))
 	obe-citations)))
 
 
@@ -111,7 +111,7 @@ For example, to point to your `obe-bibtex-file' use the following.
     (when (obe-goto-citation citation)
     (when (obe-goto-citation citation)
       (let ((pt (point)))
       (let ((pt (point)))
 	`((:authors . ,(split-string (org-entry-get pt "AUTHOR") " and " t))
 	`((:authors . ,(split-string (org-entry-get pt "AUTHOR") " and " t))
-	  (:title   . ,(org-babel-clean-text-properties (org-get-heading 1 1)))
+	  (:title   . ,(org-no-properties (org-get-heading 1 1)))
 	  (:journal . ,(org-entry-get pt "JOURNAL")))))))
 	  (:journal . ,(org-entry-get pt "JOURNAL")))))))
 
 
 (defun obe-meta-to-json (meta &optional fields)
 (defun obe-meta-to-json (meta &optional fields)

+ 200 - 48
contrib/lisp/org-contacts.el

@@ -25,7 +25,7 @@
 
 
 ;; This file contains the code for managing your contacts into Org-mode.
 ;; This file contains the code for managing your contacts into Org-mode.
 
 
-;; To enter new contacts, you can use `org-capture' and a template just like
+;; To enter new contacts, you can use `org-capture' and a minimal template just like
 ;; this:
 ;; this:
 
 
 ;;         ("c" "Contacts" entry (file "~/Org/contacts.org")
 ;;         ("c" "Contacts" entry (file "~/Org/contacts.org")
@@ -34,6 +34,22 @@
 ;; :EMAIL: %(org-contacts-template-email)
 ;; :EMAIL: %(org-contacts-template-email)
 ;; :END:")))
 ;; :END:")))
 ;;
 ;;
+;; You can also use a complex template, for example:
+;;
+;;         ("c" "Contacts" entry (file "~/Org/contacts.org")
+;;          "* %(org-contacts-template-name)
+;; :PROPERTIES:
+;; :EMAIL: %(org-contacts-template-email)
+;; :PHONE:
+;; :ALIAS:
+;; :NICKNAME:
+;; :IGNORE:
+;; :ICON:
+;; :NOTE:
+;; :ADDRESS:
+;; :BIRTHDAY:
+;; :END:")))
+;;
 ;;; Code:
 ;;; Code:
 
 
 (eval-when-compile
 (eval-when-compile
@@ -61,6 +77,11 @@ When set to nil, all your Org files will be used."
   :type 'string
   :type 'string
   :group 'org-contacts)
   :group 'org-contacts)
 
 
+(defcustom org-contacts-tel-property "PHONE"
+  "Name of the property for contact phone number."
+  :type 'string
+  :group 'org-contacts)
+
 (defcustom org-contacts-address-property "ADDRESS"
 (defcustom org-contacts-address-property "ADDRESS"
   "Name of the property for contact address."
   "Name of the property for contact address."
   :type 'string
   :type 'string
@@ -71,6 +92,23 @@ When set to nil, all your Org files will be used."
   :type 'string
   :type 'string
   :group 'org-contacts)
   :group 'org-contacts)
 
 
+(defcustom org-contacts-note-property "NOTE"
+  "Name of the property for contact note."
+  :type 'string
+  :group 'org-contacts)
+
+(defcustom org-contacts-alias-property "ALIAS"
+  "Name of the property for contact name alias."
+  :type 'string
+  :group 'org-contacts)
+
+(defcustom org-contacts-ignore-property "IGNORE"
+  "Name of the property, which values will be ignored when
+completing or exporting to vcard."
+  :type 'string
+  :group 'org-contacts)
+
+
 (defcustom org-contacts-birthday-format "Birthday: %l (%Y)"
 (defcustom org-contacts-birthday-format "Birthday: %l (%Y)"
   "Format of the anniversary agenda entry.
   "Format of the anniversary agenda entry.
 The following replacements are available:
 The following replacements are available:
@@ -117,7 +155,13 @@ The following replacements are available:
   :type 'string
   :type 'string
   :group 'org-contacts)
   :group 'org-contacts)
 
 
-(defcustom org-contacts-matcher (concat org-contacts-email-property "<>\"\"")
+(defcustom org-contacts-matcher
+  (mapconcat 'identity (list org-contacts-email-property
+			     org-contacts-alias-property
+			     org-contacts-tel-property
+			     org-contacts-address-property
+			     org-contacts-birthday-property)
+			     "<>\"\"|")
   "Matching rule for finding heading that are contacts.
   "Matching rule for finding heading that are contacts.
 This can be a tag name, or a property check."
 This can be a tag name, or a property check."
   :type 'string
   :type 'string
@@ -141,7 +185,6 @@ This overrides `org-email-link-description-format' if set."
 
 
 ;; Decalre external functions and variables
 ;; Decalre external functions and variables
 (declare-function org-reverse-string "org")
 (declare-function org-reverse-string "org")
-(declare-function org-install-letbind "org-exp")
 (declare-function diary-ordinal-suffix "ext:diary-lib")
 (declare-function diary-ordinal-suffix "ext:diary-lib")
 (declare-function wl-summary-message-number "ext:wl-summary")
 (declare-function wl-summary-message-number "ext:wl-summary")
 (declare-function wl-address-header-extract-address "ext:wl-address")
 (declare-function wl-address-header-extract-address "ext:wl-address")
@@ -153,6 +196,11 @@ This overrides `org-email-link-description-format' if set."
 (declare-function std11-narrow-to-header "ext:std11")
 (declare-function std11-narrow-to-header "ext:std11")
 (declare-function std11-fetch-field "ext:std11")
 (declare-function std11-fetch-field "ext:std11")
 
 
+(defconst org-contacts-property-values-separators "[,; \f\t\n\r\v]+"
+  "The default value of separators for `org-contacts-split-property'.
+
+A regexp matching strings of whitespace, `,' and `;'.")
+
 (defvar org-contacts-keymap
 (defvar org-contacts-keymap
   (let ((map (make-sparse-keymap)))
   (let ((map (make-sparse-keymap)))
     (define-key map "M" 'org-contacts-view-send-email)
     (define-key map "M" 'org-contacts-view-send-email)
@@ -185,28 +233,37 @@ This overrides `org-email-link-description-format' if set."
 	  (cdr (org-make-tags-matcher org-contacts-matcher)))
 	  (cdr (org-make-tags-matcher org-contacts-matcher)))
 	 markers result)
 	 markers result)
     (when (org-contacts-db-need-update-p)
     (when (org-contacts-db-need-update-p)
-      (message "Update Org Contacts Database")
-      (dolist (file (org-contacts-files))
-	(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)))
-      (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)))
+      (let ((progress-reporter
+	     (make-progress-reporter "Updating Org Contacts Database..." 0 (length org-contacts-files)))
+	    (i 0))
+	(dolist (file (org-contacts-files))
+	  (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))
+	  (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)))
     org-contacts-db))
     org-contacts-db))
 
 
-(defun org-contacts-filter (&optional name-match tags-match)
-  "Search for a contact maching NAME-MATCH and TAGS-MATCH.
-If both match values are nil, return all contacts."
+(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.
+
+The optional PROP-MATCH argument is a single (PROP . VALUE) cons
+cell corresponding to the contact properties.
+"
   (if (and (null name-match)
   (if (and (null name-match)
+	   (null prop-match)
 	   (null tags-match))
 	   (null tags-match))
       (org-contacts-db)
       (org-contacts-db)
     (loop for contact in (org-contacts-db)
     (loop for contact in (org-contacts-db)
@@ -214,6 +271,11 @@ If both match values are nil, return all contacts."
 	      (and name-match
 	      (and name-match
 		   (org-string-match-p name-match
 		   (org-string-match-p name-match
 				       (first contact)))
 				       (first contact)))
+	      (and prop-match
+		   (org-find-if (lambda (prop)
+				  (and (string= (car prop-match) (car prop))
+				       (org-string-match-p (cdr prop-match) (cdr prop))))
+				(caddr contact)))
 	      (and tags-match
 	      (and tags-match
 		   (org-find-if (lambda (tag)
 		   (org-find-if (lambda (tag)
 				  (org-string-match-p tags-match tag))
 				  (org-string-match-p tags-match tag))
@@ -390,7 +452,8 @@ prefixes rather than just the beginning of the string."
 
 
 (defun org-contacts-metadata-prefix (string collection predicate)
 (defun org-contacts-metadata-prefix (string collection predicate)
   '(metadata .
   '(metadata .
-	     ((display-sort-function . org-contacts-display-sort-function))))
+	     ((cycle-sort-function . org-contacts-display-sort-function)
+	      (display-sort-function . org-contacts-display-sort-function))))
 
 
 (defun org-contacts-complete-group (start end string)
 (defun org-contacts-complete-group (start end string)
   "Complete text at START from a group.
   "Complete text at START from a group.
@@ -412,7 +475,7 @@ A group FOO is composed of contacts with the tag FOO."
 				    (or (cdr (assoc-string "ALLTAGS" (caddr contact))) "") ":")))))))
 				    (or (cdr (assoc-string "ALLTAGS" (caddr contact))) "") ":")))))))
 	(list start end
 	(list start end
 	      (if (= (length completion-list) 1)
 	      (if (= (length completion-list) 1)
-		  ;; We've foudn the correct group, returns the address
+		  ;; We've found the correct group, returns the address
 		  (lexical-let ((tag (get-text-property 0 'org-contacts-group
 		  (lexical-let ((tag (get-text-property 0 'org-contacts-group
 							(car completion-list))))
 							(car completion-list))))
 		    (lambda (string pred &optional to-ignore)
 		    (lambda (string pred &optional to-ignore)
@@ -424,11 +487,11 @@ A group FOO is composed of contacts with the tag FOO."
 				       ;; returned by `org-contacts-filter'.
 				       ;; returned by `org-contacts-filter'.
 				       for contact-name = (car contact)
 				       for contact-name = (car contact)
 				       ;; Grab the first email of the contact
 				       ;; Grab the first email of the contact
-				       for email = (car (split-string
+				       for email = (org-contacts-strip-link (car (org-contacts-split-property
 							 (or
 							 (or
 							  (cdr (assoc-string org-contacts-email-property
 							  (cdr (assoc-string org-contacts-email-property
 									     (caddr contact)))
 									     (caddr contact)))
-							  "")))
+							  ""))))
 				       ;; If the user has an email address, append USER <EMAIL>.
 				       ;; If the user has an email address, append USER <EMAIL>.
 				       if email collect (org-contacts-format-email contact-name email))
 				       if email collect (org-contacts-format-email contact-name email))
 				 ", ")))
 				 ", ")))
@@ -436,6 +499,16 @@ A group FOO is composed of contacts with the tag FOO."
 		(completion-table-case-fold completion-list
 		(completion-table-case-fold completion-list
 					    (not org-contacts-completion-ignore-case))))))))
 					    (not org-contacts-completion-ignore-case))))))))
 
 
+
+(defun org-contacts-remove-ignored-property-values (ignore-list list)
+  "Remove all ignore-list's elements from list and you can use
+   regular expressions in the ignore list."
+    (remove-if (lambda (el)
+               (find-if (lambda (x)
+                          (string-match-p x el))
+                        ignore-list))
+             list))
+
 (defun org-contacts-complete-name (start end string)
 (defun org-contacts-complete-name (start end string)
   "Complete text at START with a user name and email."
   "Complete text at START with a user name and email."
   (let* ((completion-ignore-case org-contacts-completion-ignore-case)
   (let* ((completion-ignore-case org-contacts-completion-ignore-case)
@@ -444,15 +517,23 @@ A group FOO is composed of contacts with the tag FOO."
 		;; The contact name is always the car of the assoc-list
 		;; The contact name is always the car of the assoc-list
 		;; returned by `org-contacts-filter'.
 		;; returned by `org-contacts-filter'.
 		for contact-name = (car contact)
 		for contact-name = (car contact)
+
+		;; Build the list of the email addresses which has
+		;; been expired
+		for ignore-list = (org-contacts-split-property
+				   (or (cdr (assoc-string org-contacts-ignore-property
+							  (caddr contact))) ""))
 		;; Build the list of the user email addresses.
 		;; Build the list of the user email addresses.
-		for email-list = (split-string (or
-						(cdr (assoc-string org-contacts-email-property
-								   (caddr contact))) ""))
+		for email-list = (org-contacts-remove-ignored-property-values
+				  ignore-list
+				  (org-contacts-split-property
+				   (or (cdr (assoc-string org-contacts-email-property
+							  (caddr contact))) "")))
 		;; If the user has email addresses…
 		;; If the user has email addresses…
 		if email-list
 		if email-list
 		;; … append a list of USER <EMAIL>.
 		;; … append a list of USER <EMAIL>.
 		nconc (loop for email in email-list
 		nconc (loop for email in email-list
-			    collect (org-contacts-format-email contact-name email))))
+			    collect (org-contacts-format-email contact-name (org-contacts-strip-link email)))))
 	 (completion-list (org-contacts-all-completions-prefix
 	 (completion-list (org-contacts-all-completions-prefix
 			   string
 			   string
 			   (org-uniquify completion-list))))
 			   (org-uniquify completion-list))))
@@ -493,7 +574,8 @@ A group FOO is composed of contacts with the tag FOO."
          (email (cadr address)))
          (email (cadr address)))
     (cadar (or (org-contacts-filter
     (cadar (or (org-contacts-filter
                 nil
                 nil
-                (concat org-contacts-email-property "={\\b" (regexp-quote email) "\\b}"))
+		nil
+                (cons org-contacts-email-property (concat "\\b" (regexp-quote email) "\\b")))
                (when name
                (when name
                  (org-contacts-filter
                  (org-contacts-filter
                   (concat "^" name "$")))))))
                   (concat "^" name "$")))))))
@@ -661,12 +743,18 @@ This adds `org-contacts-gnus-check-mail-address' and
   (add-hook 'gnus-article-prepare-hook 'org-contacts-gnus-check-mail-address)
   (add-hook 'gnus-article-prepare-hook 'org-contacts-gnus-check-mail-address)
   (add-hook 'gnus-article-prepare-hook 'org-contacts-gnus-store-last-mail))
   (add-hook 'gnus-article-prepare-hook 'org-contacts-gnus-store-last-mail))
 
 
+(defun org-contacts-setup-completion-at-point ()
+  "Add `org-contacts-message-complete-function' as a new function
+to complete the thing at point."
+  (add-to-list 'completion-at-point-functions
+	       'org-contacts-message-complete-function))
+
+(defun org-contacts-unload-hook ()
+  (remove-hook 'message-mode-hook 'org-contacts-setup-completion-at-point))
+
 (when (and org-contacts-enable-completion
 (when (and org-contacts-enable-completion
 	   (boundp 'completion-at-point-functions))
 	   (boundp 'completion-at-point-functions))
-  (add-hook 'message-mode-hook
-	    (lambda ()
-	      (add-to-list 'completion-at-point-functions
-			   'org-contacts-message-complete-function))))
+  (add-hook 'message-mode-hook 'org-contacts-setup-completion-at-point))
 
 
 (defun org-contacts-wl-get-from-header-content ()
 (defun org-contacts-wl-get-from-header-content ()
   "Retrieve the content of the `From' header of an email.
   "Retrieve the content of the `From' header of an email.
@@ -717,11 +805,12 @@ address."
     (org-with-point-at marker
     (org-with-point-at marker
       (let ((emails (org-entry-get (point) org-contacts-email-property)))
       (let ((emails (org-entry-get (point) org-contacts-email-property)))
         (if emails
         (if emails
-            (let ((email-list (split-string emails)))
+            (let ((email-list (org-contacts-split-property emails)))
               (if (and (= (length email-list) 1) (not ask))
               (if (and (= (length email-list) 1) (not ask))
                   (compose-mail (org-contacts-format-email
                   (compose-mail (org-contacts-format-email
                                  (org-get-heading t) emails))
                                  (org-get-heading t) emails))
                 (let ((email (completing-read "Send mail to which address: " email-list)))
                 (let ((email (completing-read "Send mail to which address: " email-list)))
+		  (setq email (org-contacts-strip-link email))
                   (org-contacts-check-mail-address email)
                   (org-contacts-check-mail-address email)
                   (compose-mail (org-contacts-format-email (org-get-heading t) email)))))
                   (compose-mail (org-contacts-format-email (org-get-heading t) email)))))
           (error (format "This contact has no mail address set (no %s property)."
           (error (format "This contact has no mail address set (no %s property)."
@@ -745,8 +834,8 @@ address."
              (email-list (org-entry-get pom org-contacts-email-property))
              (email-list (org-entry-get pom org-contacts-email-property))
              (gravatar
              (gravatar
               (when email-list
               (when email-list
-                (loop for email in (split-string email-list)
-                      for gravatar = (gravatar-retrieve-synchronously email)
+                (loop for email in (org-contacts-split-property email-list)
+                      for gravatar = (gravatar-retrieve-synchronously (org-contacts-strip-link email))
                       if (and gravatar
                       if (and gravatar
                               (not (eq gravatar 'error)))
                               (not (eq gravatar 'error)))
                       return gravatar))))
                       return gravatar))))
@@ -819,15 +908,34 @@ to do our best."
   (let* ((properties (caddr contact))
   (let* ((properties (caddr contact))
 	 (name (org-contacts-vcard-escape (car contact)))
 	 (name (org-contacts-vcard-escape (car contact)))
 	 (n (org-contacts-vcard-encode-name name))
 	 (n (org-contacts-vcard-encode-name name))
-	 (email (org-contacts-vcard-escape (cdr (assoc-string org-contacts-email-property properties))))
+	 (email (cdr (assoc-string org-contacts-email-property properties)))
+	 (tel (cdr (assoc-string org-contacts-tel-property properties)))
+	 (ignore-list (cdr (assoc-string org-contacts-ignore-property properties)))
+	 (ignore-list (when ignore-list
+			(org-contacts-split-property ignore-list)))
+	 (note (cdr (assoc-string org-contacts-note-property properties)))
 	 (bday (org-contacts-vcard-escape (cdr (assoc-string org-contacts-birthday-property properties))))
 	 (bday (org-contacts-vcard-escape (cdr (assoc-string org-contacts-birthday-property properties))))
 	 (addr (cdr (assoc-string org-contacts-address-property properties)))
 	 (addr (cdr (assoc-string org-contacts-address-property properties)))
 	 (nick (org-contacts-vcard-escape (cdr (assoc-string org-contacts-nickname-property properties))))
 	 (nick (org-contacts-vcard-escape (cdr (assoc-string org-contacts-nickname-property properties))))
-	 (head (format "BEGIN:VCARD\nVERSION:3.0\nN:%s\nFN:%s\n" n name)))
+	 (head (format "BEGIN:VCARD\nVERSION:3.0\nN:%s\nFN:%s\n" n name))
+	 emails-list result phones-list)
     (concat head
     (concat head
-	    (when email (format "EMAIL:%s\n" email))
+	    (when email (progn
+			  (setq emails-list (org-contacts-remove-ignored-property-values ignore-list (org-contacts-split-property email)))
+			  (setq result "")
+			  (while emails-list
+			    (setq result (concat result  "EMAIL:" (org-contacts-strip-link (car emails-list)) "\n"))
+			    (setq emails-list (cdr emails-list)))
+			  result))
 	    (when addr
 	    (when addr
 	      (format "ADR:;;%s\n" (replace-regexp-in-string "\\, ?" ";" addr)))
 	      (format "ADR:;;%s\n" (replace-regexp-in-string "\\, ?" ";" addr)))
+	    (when tel (progn
+			(setq phones-list (org-contacts-remove-ignored-property-values ignore-list (org-contacts-split-property tel)))
+			(setq result "")
+			(while phones-list
+			  (setq result (concat result  "TEL:" (org-contacts-strip-link (car phones-list)) "\n"))
+			  (setq phones-list (cdr phones-list)))
+			result))
 	    (when bday
 	    (when bday
 	      (let ((cal-bday (calendar-gregorian-from-absolute (org-time-string-to-absolute bday))))
 	      (let ((cal-bday (calendar-gregorian-from-absolute (org-time-string-to-absolute bday))))
 		(format "BDAY:%04d-%02d-%02d\n"
 		(format "BDAY:%04d-%02d-%02d\n"
@@ -835,6 +943,7 @@ to do our best."
 			(calendar-extract-month cal-bday)
 			(calendar-extract-month cal-bday)
 			(calendar-extract-day cal-bday))))
 			(calendar-extract-day cal-bday))))
 	    (when nick (format "NICKNAME:%s\n" nick))
 	    (when nick (format "NICKNAME:%s\n" nick))
+	    (when note (format "NOTE:%s\n" note))
 	    "END:VCARD\n\n")))
 	    "END:VCARD\n\n")))
 
 
 (defun org-contacts-export-as-vcard (&optional name file to-buffer)
 (defun org-contacts-export-as-vcard (&optional name file to-buffer)
@@ -847,20 +956,14 @@ is created and the VCard is written into that buffer."
 	 (buffer (if to-buffer
 	 (buffer (if to-buffer
 		     (get-buffer-create to-buffer)
 		     (get-buffer-create to-buffer)
 		   (find-file-noselect filename))))
 		   (find-file-noselect filename))))
-
     (message "Exporting...")
     (message "Exporting...")
-
     (set-buffer buffer)
     (set-buffer buffer)
     (let ((inhibit-read-only t)) (erase-buffer))
     (let ((inhibit-read-only t)) (erase-buffer))
     (fundamental-mode)
     (fundamental-mode)
-    (org-install-letbind)
-
     (when (fboundp 'set-buffer-file-coding-system)
     (when (fboundp 'set-buffer-file-coding-system)
       (set-buffer-file-coding-system coding-system-for-write))
       (set-buffer-file-coding-system coding-system-for-write))
-
     (loop for contact in (org-contacts-filter name)
     (loop for contact in (org-contacts-filter name)
 	  do (insert (org-contacts-vcard-format contact)))
 	  do (insert (org-contacts-vcard-format contact)))
-
     (if to-buffer
     (if to-buffer
 	(current-buffer)
 	(current-buffer)
       (progn (save-buffer) (kill-buffer)))))
       (progn (save-buffer) (kill-buffer)))))
@@ -879,7 +982,56 @@ Requires google-maps-el."
     if addr
     if addr
     collect (cons (list addr) (list :label (string-to-char (car contact)))))))
     collect (cons (list addr) (list :label (string-to-char (car contact)))))))
 
 
-(provide 'org-contacts)
+(defun org-contacts-strip-link (link)
+  "Remove brackets, description, link type and colon from an org
+link string and return the pure link target."
+   (let (startpos colonpos endpos)
+     (setq startpos (string-match (regexp-opt '("[[tel:" "[[mailto:")) link))
+     (if startpos
+         (progn
+            (setq colonpos (string-match ":" link))
+            (setq endpos (string-match "\\]" link))
+            (if endpos (substring link (1+ colonpos) endpos) link))
+         (progn
+            (setq startpos (string-match "mailto:" link))
+            (setq colonpos (string-match ":" link))
+            (if startpos (substring link (1+ colonpos)) link)))))
+
+(defun org-contacts-split-property (string &optional separators omit-nulls)
+  "Custom version of `split-string'.
+Split a property STRING into sub-strings bounded by matches
+for SEPARATORS but keep Org links intact.
+
+The beginning and end of STRING, and each match for SEPARATORS, are
+splitting points.  The substrings matching SEPARATORS are removed, and
+the substrings between the splitting points are collected as a list,
+which is returned.
+
+If SEPARATORS is non-nil, it should be a regular expression
+matching text which separates, but is not part of, the
+substrings.  If nil it defaults to `org-contacts-property-values-separators',
+normally \"[,; \f\t\n\r\v]+\", and OMIT-NULLS is forced to t.
+
+If OMIT-NULLS is t, zero-length substrings are omitted from the list \(so
+that for the default value of SEPARATORS leading and trailing whitespace
+are effectively trimmed).  If nil, all zero-length substrings are retained."
+  (let* ((omit-nulls (if separators omit-nulls t))
+	 (rexp (or separators org-contacts-property-values-separators))
+	 (inputlist (split-string string rexp omit-nulls))
+	 (linkstring "")
+	 (bufferstring "")
+	 (proplist (list "")))
+    (while inputlist
+      (setq bufferstring (pop inputlist))
+      (if (string-match "\\[\\[" bufferstring)
+          (progn
+            (setq linkstring (concat bufferstring " "))
+            (while (not (string-match "\\]\\]" bufferstring))
+              (setq bufferstring (pop inputlist))
+              (setq linkstring (concat  linkstring bufferstring " ")))
+            (setq proplist (cons (org-trim linkstring) proplist)))
+        (setq proplist (cons bufferstring proplist))))
+    (cdr (reverse proplist))))
 
 
 (provide 'org-contacts)
 (provide 'org-contacts)
 
 

+ 6 - 6
contrib/lisp/org-git-link.el

@@ -132,10 +132,11 @@
       (list (expand-file-name ".git" dir) relpath))))
       (list (expand-file-name ".git" dir) relpath))))
 
 
 
 
-(if (featurep 'xemacs)
-    (defalias 'org-git-gitrepos-p 'org-git-find-gitdir)
-  (defalias 'org-git-gitrepos-p 'org-git-find-gitdir
-  "Return non-nil if path is in git repository"))
+(eval-and-compile
+  (if (featurep 'xemacs)
+      (defalias 'org-git-gitrepos-p 'org-git-find-gitdir)
+    (defalias 'org-git-gitrepos-p 'org-git-find-gitdir
+      "Return non-nil if path is in git repository")))
 
 
 ;; splitting the link string
 ;; splitting the link string
 
 
@@ -196,8 +197,7 @@
   (unless
   (unless
       (zerop (call-process org-git-program nil buffer nil
       (zerop (call-process org-git-program nil buffer nil
                            "--no-pager" (concat "--git-dir=" gitdir) "show" object))
                            "--no-pager" (concat "--git-dir=" gitdir) "show" object))
-    (error "git error: %s " (save-excursion (set-buffer buffer)
-                                            (buffer-string)))))
+    (error "git error: %s " (with-current-buffer buffer (buffer-string)))))
 
 
 (defun org-git-blob-sha (gitdir object)
 (defun org-git-blob-sha (gitdir object)
   "Return sha of the referenced object"
   "Return sha of the referenced object"

+ 93 - 10
contrib/lisp/org-mac-link-grabber.el

@@ -128,21 +128,36 @@ applications and inserting them in org documents"
   :group 'org-mac-link-grabber
   :group 'org-mac-link-grabber
   :type 'boolean)
   :type 'boolean)
 
 
+(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"
+  :tag "Grab Skim.app page links"
+  :group 'org-mac-link-grabber
+  :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"
+  :tag "Highlight selection in Skim.app"
+  :group 'org-mac-link-grabber
+  :type 'boolean)
+
 
 
 (defun omlg-grab-link ()
 (defun omlg-grab-link ()
   "Prompt the user for an application to grab a link from, then go grab the link, and insert it at point"
   "Prompt the user for an application to grab a link from, then go grab the link, and insert it at point"
   (interactive)
   (interactive)
   (let* ((descriptors `(("F" "inder" org-mac-finder-insert-selected ,org-mac-grab-Finder-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)
-						("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)))
+			("m" "ail" org-mac-message-insert-selected ,org-mac-grab-Mail-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))
 		 (menu-string (make-string 0 ?x))
 		 input)
 		 input)
-
+    
 	;; Create the menu string for the keymap
 	;; Create the menu string for the keymap
 	(mapc '(lambda (descriptor)
 	(mapc '(lambda (descriptor)
 			(when (elt descriptor 3)
 			(when (elt descriptor 3)
@@ -209,8 +224,9 @@ applications and inserting them in org documents"
 					 "	activate\n"
 					 "	activate\n"
 					 "	delay 0.15\n"
 					 "	delay 0.15\n"
 					 "	tell application \"System Events\"\n"
 					 "	tell application \"System Events\"\n"
-					 "		keystroke \"l\" using command down\n"
-					 "		keystroke \"c\" using command down\n"
+					 "		keystroke \"l\" using {command down}\n"
+					 "		keystroke \"a\" using {command down}\n"
+					 "		keystroke \"c\" using {command down}\n"
 					 "	end tell\n"
 					 "	end tell\n"
 					 "	delay 0.15\n"
 					 "	delay 0.15\n"
 					 "	set theUrl to the clipboard\n"
 					 "	set theUrl to the clipboard\n"
@@ -460,6 +476,73 @@ applications and inserting them in org documents"
   (interactive)
   (interactive)
   (insert (org-mac-addressbook-item-get-selected)))
   (insert (org-mac-addressbook-item-get-selected)))
 
 
+;;
+;;
+;; Handle links from Skim.app
+;;
+;; Original code & idea by Christopher Suckling (org-mac-protocol)
+
+(org-add-link-type "skim" 'org-mac-skim-open)
+
+(defun org-mac-skim-open (uri)
+  "Visit page of pdf in Skim"
+  (let* ((page (when (string-match "::\\(.+\\)\\'" uri)
+		 (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"))))
+
+
+(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
+	  "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)
+  (message "Applescript: Getting Skim page link...")
+  (let* ((link-and-descr (as-get-skim-page-link))
+         (split-link (split-string link-and-descr "::split::"))
+         (link (car split-link))
+         (description (cadr split-link))
+         (org-link))
+    (when (not (string= link ""))
+      (setq org-link (org-make-link-string link description)))
+    (kill-new org-link)
+    org-link))
+
+(defun org-mac-skim-insert-page ()
+  (interactive)
+  (insert (org-mac-skim-get-page)))
+
+
 
 
 (provide 'org-mac-link-grabber)
 (provide 'org-mac-link-grabber)
 
 

+ 5 - 4
lisp/org-mac-message.el → contrib/lisp/org-mac-message.el

@@ -7,7 +7,7 @@
 
 
 ;; Keywords: outlines, hypermedia, calendar, wp
 ;; Keywords: outlines, hypermedia, calendar, wp
 
 
-;; This file is part of GNU Emacs.
+;; This file is not part of GNU Emacs.
 
 
 ;; GNU Emacs is free software: you can redistribute it and/or modify
 ;; 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
 ;; it under the terms of the GNU General Public License as published by
@@ -23,9 +23,10 @@
 ;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
 ;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
 
 
 ;;; Commentary:
 ;;; Commentary:
-;; This file implements links to Apple Mail.app messages from within Org-mode.
-;; Org-mode does not load this module by default - if you would actually like
-;; this to happen then configure the variable `org-modules'.
+;; This file implements links to Apple Mail.app messages from within
+;; Org-mode.  Org-mode does not load this module by default - if you
+;; would actually like this to happen then configure the variable
+;; `org-modules' and add Org's contrib/ directory to your `load-path'.
 
 
 ;; If you would like to create links to all flagged messages in an
 ;; If you would like to create links to all flagged messages in an
 ;; Apple Mail.app account, please customize the variable
 ;; Apple Mail.app account, please customize the variable

+ 2 - 1
contrib/lisp/org-man.el

@@ -63,7 +63,8 @@ PATH should be a topic that can be thrown at the man command."
 	(desc (or description link)))
 	(desc (or description link)))
     (cond
     (cond
      ((eq format 'html) (format "<a target=\"_blank\" href=\"%s\">%s</a>" path desc))
      ((eq format 'html) (format "<a target=\"_blank\" href=\"%s\">%s</a>" path desc))
-     ((eq format 'latex) (format "\href{%s}{%s}" path desc))
+     ((eq format 'latex) (format "\\href{%s}{%s}" path desc))
+     ((eq format 'texinfo) (format "@uref{%s,%s}" path desc))
      ((eq format 'ascii) (format "%s (%s)" desc path))
      ((eq format 'ascii) (format "%s (%s)" desc path))
      (t path))))
      (t path))))
 
 

+ 1 - 3
contrib/lisp/org-mime.el

@@ -212,14 +212,12 @@ export that region, otherwise export the entire body."
          (tmp-file (make-temp-name (expand-file-name
          (tmp-file (make-temp-name (expand-file-name
 				    "mail" temporary-file-directory)))
 				    "mail" temporary-file-directory)))
          (body (org-export-string-as raw-body 'org t))
          (body (org-export-string-as raw-body 'org t))
-         ;; because we probably don't want to skip part of our mail
-         (org-export-skip-text-before-1st-heading nil)
          ;; because we probably don't want to export a huge style file
          ;; because we probably don't want to export a huge style file
          (org-export-htmlize-output-type 'inline-css)
          (org-export-htmlize-output-type 'inline-css)
          ;; makes the replies with ">"s look nicer
          ;; makes the replies with ">"s look nicer
          (org-export-preserve-breaks org-mime-preserve-breaks)
          (org-export-preserve-breaks org-mime-preserve-breaks)
 	 ;; dvipng for inline latex because MathJax doesn't work in mail
 	 ;; dvipng for inline latex because MathJax doesn't work in mail
-	 (org-export-with-LaTeX-fragments 'dvipng)
+	 (org-html-with-latex 'dvipng)
          ;; to hold attachments for inline html images
          ;; to hold attachments for inline html images
          (html-and-images
          (html-and-images
           (org-mime-replace-images
           (org-mime-replace-images

+ 530 - 0
contrib/lisp/org-screenshot.el

@@ -0,0 +1,530 @@
+;;; org-screenshot.el --- Take and manage screenshots in Org-mode files
+;;
+;; Copyright (C) 2009-2013
+;;   Free Software Foundation, Inc.
+;;
+;; Author: Max Mikhanosha <max@openchat.com>
+;; Keywords: outlines, hypermedia, calendar, wp
+;; Homepage: http://orgmode.org
+;; Version: 8.0
+;;
+;; Released under the GNU General Public License version 3
+;; see: http://www.gnu.org/licenses/gpl-3.0.html
+;;
+;; 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:
+;;
+;; NOTE: This library requires external screenshot taking executable "scrot",
+;; which is available as a package from all major Linux distribution. If your
+;; distribution does not have it, source can be found at:
+;; 
+;; http://freecode.com/projects/scrot
+;;
+;; org-screenshot.el have been tested with scrot version 0.8.
+;; 
+;; Usage:
+;;
+;;   (require 'org-screenshot)
+;;
+;;  Available commands with default bindings
+;;
+;;  `org-screenshot-take'              C-c M-s M-t  and   C-c M-s M-s
+;;  
+;;        Take the screenshot, C-u argument delays 1 second, double C-u 2 seconds
+;;        triple C-u 3 seconds, and subsequent C-u add 2 seconds to the delay.
+;;
+;;        Screenshot area is selected with the mouse, or left-click on the window
+;;        for an entire window.
+;;        
+;;  `org-screenshot-rotate-prev'       C-c M-s M-p   and C-c M-s C-p
+;;  
+;;        Rotate screenshot before the point to one before it (sorted by date)
+;;        
+;;  `org-screenshot-rotate-next'       C-c M-s M-n   and C-c M-s C-n
+;;
+;;        Rotate screenshot before the point to one after it
+;;
+;;  `org-screenshot-show-unused'       C-c M-s M-u   and C-c M-s u
+;;
+;;        Open dired buffer with screenshots that are not used in current
+;;        Org buffer marked
+;;
+;; The screenshot take and rotate commands will update the inline images
+;; if they are already shown, if you are inserting first screenshot in the Org
+;; Buffer (and there are no other images shown), you need to manually display
+;; inline images with C-c C-x C-v
+;;
+;; Screenshot take and rotate commands offer user to continue by by using single
+;; keys, in a manner similar to to "repeat-char" of keyboard macros, user can
+;; continue rotating screenshots by pressing just the last key of the binding
+;;
+;; For example: C-c M-s M-t creates the screenshot and then user can
+;; repeatedly press M-p or M-n to rotate it back and forth with
+;; previously taken ones.
+;;
+
+(require 'org)
+(require 'dired)
+
+(defgroup org-screenshot nil
+  "Options for taking and managing screen-shots"
+  :group 'org-link)
+
+(defcustom org-screenshot-image-directory "./images/"
+  "Directory in which screenshot image files will be stored, it
+be automatically created if it does't already exist."
+  :type 'string
+  :group 'org-screenshot)
+
+(defcustom org-screenshot-file-name-format "screenshot-%2.2d.png"
+  "The string used to generate screenshot file name. 
+
+Any %d format string recipe will be expanded with `format'
+function with the argument of a screenshot sequence number.
+
+A sequence like %XXXX will be replaced with string of the same
+length as there are X's, consisting of random characters in the
+range of [A-Za-z]."
+  :type 'string
+  :group 'org-screenshot)
+
+(defcustom org-screenshot-max-tries 200
+  "Number of times we will try to generate generate filename that
+does not exist. With default `org-screenshot-name-format' its the
+limit for number of screenshots, before `org-screenshot-take' is
+unable to come up with a unique name."
+  :type 'integer
+  :group 'org-screenshot)
+
+(defvar org-screenshot-map (make-sparse-keymap)
+  "Map for OrgMode screenshot related commands")
+
+;; prefix
+(org-defkey org-mode-map (kbd "C-c M-s") org-screenshot-map)
+
+;; Mnemonic is Control-C Meta "Screenshot" "Take"
+(org-defkey org-screenshot-map (kbd "M-t") 'org-screenshot-take)
+(org-defkey org-screenshot-map (kbd "M-s") 'org-screenshot-take)
+
+;; No reason to require meta key, since its our own keymap
+(org-defkey org-screenshot-map "s" 'org-screenshot-take)
+(org-defkey org-screenshot-map "t" 'org-screenshot-take)
+
+;; Rotations, the fast rotation user hint, would prefer the modifier
+;; used by the original command that started the rotation
+(org-defkey org-screenshot-map (kbd "M-n") 'org-screenshot-rotate-next)
+(org-defkey org-screenshot-map (kbd "M-p") 'org-screenshot-rotate-prev)
+(org-defkey org-screenshot-map (kbd "C-n") 'org-screenshot-rotate-next)
+(org-defkey org-screenshot-map (kbd "C-p") 'org-screenshot-rotate-prev)
+
+;; Show unused image files in Dired
+(org-defkey org-screenshot-map (kbd "M-u") 'org-screenshot-show-unused)
+(org-defkey org-screenshot-map (kbd "u") 'org-screenshot-show-unused)
+
+
+(random t)
+
+(defun org-screenshot-random-string (length)
+  "Generate a random string of LENGTH consisting of random upper
+case and lower case letters."
+  (let ((name (make-string length ?x)))
+    (dotimes (i length)
+      (let ((n (random 52)))
+        (aset name i (if (< n 26)
+                         (+ ?a n)
+                       (+ ?A n -26))))) 
+    name))
+
+(defvar org-screenshot-process nil
+  "Currently running screenshot process")
+
+(defvar org-screenshot-directory-seq-numbers (make-hash-table :test 'equal))
+
+(defun org-screenshot-update-seq-number (directory &optional reset)
+  "Set `org-screenshot-file-name-format' sequence number for the directory.
+When RESET is NIL, increments the number stored, otherwise sets
+RESET as a new number. Intended to be called if screenshot was
+successful.  Updating of sequence number is done in two steps, so
+aborted/canceled screenshot attempts don't increase the number"
+
+  (setq directory (file-name-as-directory directory))
+  (puthash directory (if reset
+                         (if (numberp reset) reset 1)
+                       (1+ (gethash directory
+                                    org-screenshot-directory-seq-numbers
+                                    0)))
+           org-screenshot-directory-seq-numbers))
+
+(defun org-screenshot-generate-file-name (directory)
+  "Use `org-screenshot-name-format' to generate new screenshot
+file name for a specific directory. Keeps re-generating name if
+it already exists, up to `org-screenshot-max-tries'
+times. Returns just the file, without directory part"
+  (setq directory (file-name-as-directory directory))
+  (when (file-exists-p directory)
+    (let ((tries 0)
+          name
+          had-seq
+          (case-fold-search nil))
+      (while (and (< tries org-screenshot-max-tries)
+                  (not name))
+        (incf tries)
+        (let ((tmp org-screenshot-file-name-format)
+              (seq-re "%[-0-9.]*d")
+              (rand-re "%X+"))
+          (when (string-match seq-re tmp)
+            (let ((seq (gethash
+                        directory
+                        org-screenshot-directory-seq-numbers 1))) 
+              (setq tmp 
+                    (replace-regexp-in-string
+                     seq-re (format (match-string 0 tmp) seq)
+                     tmp)
+                    had-seq t)))
+          (when (string-match rand-re tmp)
+            (setq tmp
+                  (replace-regexp-in-string
+                   rand-re (org-screenshot-random-string
+                            (1- (length (match-string 0 tmp))))
+                   tmp t)))
+          (let ((fullname (concat directory tmp))) 
+            (if (file-exists-p fullname)
+                (when had-seq (org-screenshot-update-seq-number directory))
+              (setq name tmp)))))
+      name)))
+
+(defun org-screenshot-image-directory ()
+  "Return the `org-screenshot-image-directory', ensuring there is
+trailing slash, and that it exists"
+  (let ((dir (file-name-as-directory org-screenshot-image-directory)))
+    (if (file-exists-p dir)
+        dir
+      (make-directory dir t)
+      dir)))
+
+(defvar org-screenshot-last-file nil
+  "File name of the last taken or rotated screenshot file,
+without directory")
+
+(defun org-screenshot-process-done (process event file
+                                            orig-buffer
+                                            orig-delay
+                                            orig-event)
+  "Called when \"scrot\" process exits. PROCESS and EVENT are
+same arguments as in `set-process-sentinel'.  ORIG-BUFFER,
+ORIG-DELAY and ORIG-EVENT are Org Buffer, the screenshot delay
+used, and LAST-INPUT-EVENT values from when screenshot was
+initiated.
+"
+  (setq org-screenshot-process nil)
+  (with-current-buffer (process-buffer process) 
+    (if (not (equal event "finished\n"))
+        (progn 
+          (insert event) 
+          (cond ((save-excursion
+                   (goto-char (point-min))
+                   (re-search-forward "Key was pressed" nil t))
+                 (ding)
+                 (message "Key was pressed, screenshot aborted"))
+                (t 
+                 (display-buffer (process-buffer process))
+                 (message "Error running \"scrot\" program")
+                 (ding))))
+      (with-current-buffer orig-buffer 
+        (let ((link (format "[[file:%s]]" file))) 
+          (setq org-screenshot-last-file (file-name-nondirectory file))
+          (let ((beg (point)))
+            (insert link) 
+            (when org-inline-image-overlays
+              (org-display-inline-images nil t beg (point))))
+          (unless (< orig-delay 3)
+            (ding))
+          (org-screenshot-rotate-continue t orig-event))))))
+
+
+;;;###autoload
+(defun org-screenshot-take (&optional delay)
+  "Take a screenshot and insert link to it at point, if image
+display is already on (see \\[org-toggle-inline-images])
+screenshot will be displayed as an image
+
+Screen area for the screenshot is selected with the mouse, left
+click on a window screenshots that window, while left click and
+drag selects a region. Pressing any key cancels the screen shot
+
+With `C-u' universal argument waits one second after target is
+selected before taking the screenshot. With double `C-u' wait two
+seconds.
+
+With triple `C-u' wait 3 seconds, and also rings the bell when
+screenshot is done, any more `C-u' after that increases delay by
+2 seconds
+"
+  (interactive "P")
+
+  ;; probably easier way to count number of C-u C-u out there
+  (setq delay
+        (cond ((null delay) 0)
+              ((integerp delay) delay)
+              ((and (consp delay)
+                    (integerp (car delay))
+                    (plusp (car delay)))
+               (let ((num 1)
+                     (limit (car delay))
+                     (cnt 0))
+                 (while (< num limit)
+                   (setq num (* num 4)
+                         cnt (+ cnt (if (< cnt 3) 1 2))))
+                 cnt))
+              (t (error "Invald delay"))))
+  (when (and org-screenshot-process
+             (member (process-status org-screenshot-process)
+                     '(run stop)))
+    (error "scrot process is still running"))
+  (let* ((name (org-screenshot-generate-file-name (org-screenshot-image-directory)))
+         (file (format "%s%s" (org-screenshot-image-directory)
+                       name))
+         (path (expand-file-name file)))
+    (when (get-buffer "*scrot*")
+      (with-current-buffer (get-buffer "*scrot*")
+        (erase-buffer)))
+    (setq org-screenshot-process
+          (or 
+           (apply 'start-process
+                  (append
+                   (list "scrot" "*scrot*" "scrot" "-s" path)
+                   (when (plusp delay)
+                     (list "-d" (format "%d" delay)))))
+           (error "Unable to start scrot process")))
+    (when org-screenshot-process 
+      (if (plusp delay) 
+          (message "Click on a window, or select a rectangle (delay is %d sec)..."
+                   delay)
+        (message "Click on a window, or select a rectangle..."))
+      (set-process-sentinel
+       org-screenshot-process
+       `(lambda (process event)
+          (org-screenshot-process-done
+           process event ,file ,(current-buffer) ,delay ',last-input-event))))))
+
+(defvar org-screenshot-file-list nil
+  "List of files in `org-screenshot-image-directory' used by
+`org-screenshot-rotate-prev' and `org-screenshot-rotate-next'")
+
+(defvar org-screenshot-rotation-index -1)
+
+(make-variable-buffer-local 'org-screenshot-file-list)
+(make-variable-buffer-local 'org-screenshot-rotation-index)
+
+(defun org-screenshot-rotation-init (lastfile)
+  "Initialize variable `org-screenshot-file-list' variabel with
+the list of PNG files in `org-screenshot-image-directory' sorted
+by most recent first"
+  (setq
+   org-screenshot-rotation-index -1
+   org-screenshot-file-list
+   (let ((files (directory-files org-screenshot-image-directory
+                                 t (org-image-file-name-regexp) t)))
+     (mapcar 'file-name-nondirectory 
+             (sort files
+                   (lambda (file1 file2)
+                     (let ((mtime1 (nth 5 (file-attributes file1)))
+                           (mtime2 (nth 5 (file-attributes file2))))
+                       (setq mtime1 (+ (ash (first mtime1) 16)
+                                       (second mtime1)))
+                       (setq mtime2 (+ (ash (first mtime2) 16)
+                                       (second mtime2)))
+                       (> mtime1 mtime2)))))))
+  (let ((n -1) (list org-screenshot-file-list))
+    (while (and list (not (equal (pop list) lastfile)))
+      (incf n))
+    (setq org-screenshot-rotation-index n)))
+
+(defun org-screenshot-do-rotate (dir from-continue-rotating)
+  "Rotate last screenshot with one of the previously taken
+screenshots from the same directory. If DIR is negative, in the
+other direction"
+  (setq org-screenshot-last-file nil)
+  (let* ((ourdir (file-name-as-directory (org-screenshot-image-directory)))
+         done
+         (link-re 
+          ;; taken from `org-display-inline-images'
+          (concat "\\[\\[\\(\\(file:\\)\\|\\([./~]\\)\\)\\([^]\n]+?"
+                  (substring (org-image-file-name-regexp) 0 -2)
+                  "\\)\\]"))
+         newfile oldfile)
+    (save-excursion 
+      ;; Search for link to image file in the same directory before the point
+      (while (not done)
+        (if (not (re-search-backward link-re (point-min) t))
+            (error "Unable to find link to image from %S directory before point" ourdir)
+          (let ((file (concat (or (match-string 3) "") (match-string 4))))
+            (when (equal (file-name-directory file)
+                         ourdir)
+              (setq done t
+                    oldfile (file-name-nondirectory file))))))
+      (when (or (null org-screenshot-file-list)
+                (and (not from-continue-rotating) 
+                     (not (member last-command
+                                  '(org-screenshot-rotate-prev
+                                    org-screenshot-rotate-next)))))
+        (org-screenshot-rotation-init oldfile))
+      (unless (> (length org-screenshot-file-list) 1)
+        (error "Can't rotate a single image file"))
+      (replace-match "" nil nil nil 1)
+
+      (setq org-screenshot-rotation-index
+            (mod (+ org-screenshot-rotation-index dir)
+                 (length org-screenshot-file-list)) 
+            newfile (nth org-screenshot-rotation-index
+                         org-screenshot-file-list))
+      ;; in case we started rotating from the file we just inserted,
+      ;; advance one more time
+      (when (equal oldfile newfile)
+        (setq org-screenshot-rotation-index
+              (mod (+ org-screenshot-rotation-index (if (plusp dir) 1 -1))
+                   (length org-screenshot-file-list))
+              newfile (nth org-screenshot-rotation-index
+                           org-screenshot-file-list)))
+      (replace-match (concat "file:" ourdir
+                             newfile)
+                     t t nil 4))
+    ;; out of save-excursion
+    (setq org-screenshot-last-file newfile)
+    (when org-inline-image-overlays
+      (org-display-inline-images nil t (match-beginning 0) (point)))))
+
+;;;###autoload
+(defun org-screenshot-rotate-prev (dir)
+  "Rotate last screenshot with one of the previously taken
+screenshots from the same directory. If DIR is negative, rotate
+in the other direction"
+  (interactive "p")
+  (org-screenshot-do-rotate dir nil)
+  (when org-screenshot-last-file 
+    (org-screenshot-rotate-continue nil nil)))
+
+;;;###autoload
+(defun org-screenshot-rotate-next (dir)
+  "Rotate last screenshot with one of the previously taken
+screenshots from the same directory. If DIR is negative, rotate
+in the other direction"
+  (interactive "p")
+  (org-screenshot-do-rotate (- dir) nil)
+  (when org-screenshot-last-file 
+    (org-screenshot-rotate-continue nil nil)))
+
+(defun org-screenshot-prefer-same-modifiers (list event)
+  (if (not (eventp nil)) (car list) 
+    (let (ret (keys list))
+      (while (and (null ret) keys)
+        (let ((key (car keys))) 
+          (if (and (= 1 (length key)) 
+                   (equal (event-modifiers event)
+                          (event-modifiers (elt key 0))))
+              (setq ret (car keys))
+            (setq keys (cdr keys)))))
+      (or ret (car list)))))
+
+(defun org-screenshot-rotate-continue (from-take-screenshot orig-event)
+  "Display the message with the name of the last changed
+image-file and inform user that they can rotate by pressing keys
+bound to `org-screenshot-rotate-next' and
+`org-screenshot-rotate-prev' in `org-screenshot-map'
+
+This works similarly to `kmacro-end-or-call-macro' so that user
+can press a long key sequence to invoke the first command, and
+then uses single keys to rotate, until unregognized key is
+entered, at which point event will be unread"
+
+  (let* ((event (if from-take-screenshot orig-event
+                  last-input-event))
+         done
+         (prev-key
+          (org-screenshot-prefer-same-modifiers
+           (where-is-internal 'org-screenshot-rotate-prev
+                              org-screenshot-map nil)
+           event))
+         (next-key
+          (org-screenshot-prefer-same-modifiers
+           (where-is-internal 'org-screenshot-rotate-next
+                              org-screenshot-map nil)
+           event))
+         prev-key-str next-key-str)
+    (when (and (= (length prev-key) 1)
+               (= (length next-key) 1)) 
+      (setq
+       prev-key-str (format-kbd-macro prev-key nil)
+       next-key-str (format-kbd-macro next-key nil)
+       prev-key (elt prev-key 0)
+       next-key (elt next-key 0))
+      (while (not done)
+        (message "%S - '%s' and '%s' to rotate"
+                 org-screenshot-last-file prev-key-str next-key-str)
+        (setq event (read-event))
+        (cond ((equal event prev-key)
+               (clear-this-command-keys t)
+               (org-screenshot-do-rotate 1 t)
+               (setq last-input-event nil))
+              ((equal event next-key)
+               (clear-this-command-keys t)
+               (org-screenshot-do-rotate -1 t)
+               (setq last-input-event nil))
+              (t (setq done t)))) 
+      (when last-input-event
+        (clear-this-command-keys t)
+        (setq unread-command-events (list last-input-event))))))
+
+;;;###autoload
+(defun org-screenshot-show-unused ()
+  "Open A Dired buffer with unused screenshots marked"
+  (interactive)
+  (let ((files-in-buffer)
+	dired-buffer
+	had-any
+	(image-re (org-image-file-name-regexp))
+	beg end)
+    (save-excursion
+      (save-restriction
+	(widen)
+	(setq beg (or beg (point-min)) end (or end (point-max)))
+	(goto-char beg)
+	(let ((re (concat "\\[\\[\\(\\(file:\\)\\|\\([./~]\\)\\)\\([^]\n]+?"
+			  (substring (org-image-file-name-regexp) 0 -2)
+			  "\\)\\]"))
+	      (case-fold-search t)
+	      old file ov img type attrwidth width)
+	  (while (re-search-forward re end t)
+	    (setq file (concat (or (match-string 3) "") (match-string 4)))
+	    (when (and (file-exists-p file)
+		       (equal (file-name-directory file)
+			      (org-screenshot-image-directory)))
+	      (push (file-name-nondirectory file)
+		    files-in-buffer))))))
+    (setq dired-buffer (dired-noselect (org-screenshot-image-directory)))
+    (with-current-buffer dired-buffer
+      (dired-unmark-all-files ?\r)
+      (dired-mark-if
+       (let ((file (dired-get-filename 'no-dir t))) 
+	 (and file (string-match image-re file)
+	      (not (member file files-in-buffer))
+	      (setq had-any t)))
+       "Unused screenshot"))
+    (when had-any (pop-to-buffer dired-buffer))))
+
+(provide 'org-screenshot)

+ 1 - 1
contrib/lisp/org-wl.el

@@ -67,7 +67,7 @@ googlegroups otherwise."
 
 
 (defcustom org-wl-namazu-default-index nil
 (defcustom org-wl-namazu-default-index nil
   "Default namazu search index."
   "Default namazu search index."
-  :type 'directory
+  :type '(choice (const nil) (directory))
   :group 'org-wl)
   :group 'org-wl)
 
 
 ;; Declare external functions and variables
 ;; Declare external functions and variables

+ 252 - 0
contrib/lisp/ox-bibtex.el

@@ -0,0 +1,252 @@
+;;; ox-bibtex.el --- Export bibtex fragments
+
+;; Copyright (C) 2009-2013 Taru Karttunen
+
+;; Author: Taru Karttunen <taruti@taruti.net>
+;;      Nicolas Goaziou <n dot goaziou at gmail dot com>
+;; This file is not currently 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 2, 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 ; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Commentary:
+;;
+;; This is an utility to handle BibTeX export to both LaTeX and html
+;; exports.  It uses the bibtex2html software from:
+;;
+;;   http://www.lri.fr/~filliatr/bibtex2html/
+;;
+;; The usage is as follows:
+;;
+;;   #+BIBLIOGRAPHY: bibfilebasename stylename optional-options
+;;
+;; e.g. given foo.bib and using style plain:
+;;
+;;   #+BIBLIOGRAPHY: foo plain option:-d
+;;
+;; Optional options are of the form:
+;;
+;;   option:-foobar pass '-foobar' to bibtex2html
+;;
+;; e.g.,
+;;
+;;   option:-d    sort by date
+;;   option:-a    sort as BibTeX (usually by author) *default*
+;;   option:-u    unsorted i.e. same order as in .bib file
+;;   option:-r    reverse the sort
+;;
+;; See the bibtex2html man page for more.  Multiple options can be
+;; combined like:
+;;
+;;   option:-d option:-r
+;;
+;; Limiting to only the entries cited in the document:
+;;
+;;   limit:t
+;;
+;; For LaTeX export this simply inserts the lines
+;;
+;;   \bibliographystyle{plain}
+;;   \bibliography{foo}
+;;
+;; into the TeX file when exporting.
+;;
+;; For HTML export it:
+;; 1) converts all \cite{foo} to links to the bibliography,
+;; 2) creates a foo.html and foo_bib.html,
+;; 3) includes the contents of foo.html in the exported HTML file.
+
+
+;;; Internal Functions
+
+(defun org-bibtex-get-file (keyword)
+  "Return bibliography file as a string.
+KEYWORD is a \"BIBLIOGRAPHY\" keyword. If no file is found,
+return nil instead."
+  (let ((value (org-element-property :value keyword)))
+    (and value
+         (string-match "\\(\\S-+\\)[ \t]+\\(\\S-+\\)\\(.*\\)" value)
+         (match-string 1 value))))
+
+(defun org-bibtex-get-style (keyword)
+  "Return bibliography style as a string.
+KEYWORD is a \"BIBLIOGRAPHY\" keyword. If no style is found,
+return nil instead."
+  (let ((value (org-element-property :value keyword)))
+    (and value
+         (string-match "\\(\\S-+\\)[ \t]+\\(\\S-+\\)\\(.*\\)" value)
+         (match-string 2 value))))
+
+(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."
+  (let ((value (org-element-property :value keyword)))
+    (and value
+         (string-match "\\(\\S-+\\)[ \t]+\\(\\S-+\\)\\(.*\\)" value)
+         (let (options limit)
+           (dolist (arg (org-split-string (match-string 3 value))
+                        ;; Return value.
+                        (list :options (nreverse options) :limit limit))
+             (let* ((s (split-string arg ":"))
+                    (key (car s))
+                    (value (nth 1 s)))
+               (cond ((equal "limit" key)
+                      (setq limit (not (equal "nil" value))))
+                     ((equal "option" key) (push value options)))))))))
+
+(defun org-bibtex-citation-p (fragment)
+  "Non-nil when a LaTeX macro is a citation.
+FRAGMENT is a `latex-fragment' type object."
+  (string-match "\\`\\\\cite{" (org-element-property :value fragment)))
+
+(defun org-bibtex-get-citation-key (citation)
+  "Return key for a given citation, as a string.
+CITATION is a `latex-fragment' type object satisfying to
+`org-bibtex-citation-p' predicate."
+  (let ((value (org-element-property :value citation)))
+    (and (string-match "\\`\\\\cite{" value)
+         (substring value (match-end 0) -1))))
+
+
+
+;;; LaTeX Part
+
+(defadvice org-latex-keyword (around bibtex-keyword)
+  "Translate \"BIBLIOGRAPHY\" keywords into LaTeX syntax.
+Fallback to `latex' back-end for other keywords."
+  (let ((keyword (ad-get-arg 0)))
+    (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)))
+        (setq ad-return-value
+              (when file
+                (concat (and style (format "\\bibliographystyle{%s}\n" style))
+                        (format "\\bibliography{%s}" file))))))))
+
+(ad-activate 'org-latex-keyword)
+
+
+
+;;; HTML Part
+
+(defvar org-bibtex-html-entries-alist nil)  ; Dynamically scoped.
+(defvar org-bibtex-html-keywords-alist nil) ; Dynamically scoped.
+
+
+;;;; Advices
+
+(defadvice org-html-keyword (around bibtex-keyword)
+  "Translate \"BIBLIOGRAPHY\" keywords into HTML syntax.
+Fallback to `html' 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-html-latex-fragment (around bibtex-citation)
+  "Translate \"\\cite\" LaTeX fragments into HTML syntax.
+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) ",")
+             "")))))
+
+(ad-activate 'org-html-keyword)
+(ad-activate 'org-html-latex-fragment)
+
+
+;;;; 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
+                     (lambda (fragment)
+                       (and (org-bibtex-citation-p fragment)
+                            (org-bibtex-get-citation-key fragment))))))
+              (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))
+
+
+
+(provide 'ox-bibtex)
+
+;;; ox-bibtex.el ends here

+ 1 - 1
contrib/lisp/ox-confluence.el

@@ -59,7 +59,7 @@
 (defun org-confluence-bold (bold contents info)
 (defun org-confluence-bold (bold contents info)
   (format "*%s*" contents))
   (format "*%s*" contents))
 
 
-(defun org-confluence-empty (empy contents info)
+(defun org-confluence-empty (empty contents info)
   "")
   "")
 
 
 (defun org-confluence-example-block (example-block contents info)
 (defun org-confluence-example-block (example-block contents info)

+ 16 - 9
contrib/lisp/ox-deck.el

@@ -68,6 +68,7 @@
   '((headline . org-deck-headline)
   '((headline . org-deck-headline)
     (inner-template . org-deck-inner-template)
     (inner-template . org-deck-inner-template)
     (item . org-deck-item)
     (item . org-deck-item)
+    (link . org-deck-link)
     (template . org-deck-template)))
     (template . org-deck-template)))
 
 
 (defgroup org-export-deck nil
 (defgroup org-export-deck nil
@@ -300,9 +301,11 @@ and have the id \"title-slide\"."
               (format
               (format
                "<a href='#outline-container-%s'>%s</a>"
                "<a href='#outline-container-%s'>%s</a>"
                (or (org-element-property :CUSTOM_ID headline)
                (or (org-element-property :CUSTOM_ID headline)
-                   (mapconcat
-                    'number-to-string
-                    (org-export-get-headline-number headline info) "-"))
+		   (concat
+		    "sec-"
+		    (mapconcat
+		     'number-to-string
+		     (org-export-get-headline-number headline info) "-")))
                title)
                title)
             title)
             title)
           (org-export-get-relative-level headline info))))
           (org-export-get-relative-level headline info))))
@@ -373,19 +376,23 @@ the \"slide\" class will be added to the to the list element,
         (replace-regexp-in-string "^<li>" "<li class='slide'>" text)
         (replace-regexp-in-string "^<li>" "<li class='slide'>" text)
       text)))
       text)))
 
 
+(defun org-deck-link (link desc info)
+  (replace-regexp-in-string "href=\"#" "href=\"#outline-container-"
+			    (org-html-link link desc info)))
+
 (defun org-deck-template (contents info)
 (defun org-deck-template (contents info)
   "Return complete document string after HTML conversion.
   "Return complete document string after HTML conversion.
 CONTENTS is the transcoded contents string.  INFO is a plist
 CONTENTS is the transcoded contents string.  INFO is a plist
 holding export options."
 holding export options."
   (let ((pkg-info (org-deck--get-packages info))
   (let ((pkg-info (org-deck--get-packages info))
-         (org-html--pre/postamble-class "deck-status")
-         (info (plist-put
-                (plist-put info :html-preamble (plist-get info :deck-preamble))
-                :html-postamble (plist-get info :deck-postamble))))
+	(org-html--pre/postamble-class "deck-status")
+	(info (plist-put
+	       (plist-put info :html-preamble (plist-get info :deck-preamble))
+	       :html-postamble (plist-get info :deck-postamble))))
     (mapconcat
     (mapconcat
      'identity
      'identity
      (list
      (list
-      (plist-get info :html-doctype)
+      (org-html-doctype info)
       (let ((lang (plist-get info :language)))
       (let ((lang (plist-get info :language)))
         (mapconcat
         (mapconcat
          (lambda (x)
          (lambda (x)
@@ -463,7 +470,7 @@ INFO is a plist used as a communication channel."
                       (let ((auth (plist-get info :author)))
                       (let ((auth (plist-get info :author)))
                         (and auth (org-export-data auth info)))))
                         (and auth (org-export-data auth info)))))
          (date (and (plist-get info :with-date)
          (date (and (plist-get info :with-date)
-                    (let ((date (plist-get info :date)))
+                    (let ((date (org-export-get-date info)))
                       (and date (org-export-data date info)))))
                       (and date (org-export-data date info)))))
          (description (plist-get info :description))
          (description (plist-get info :description))
          (keywords (plist-get info :keywords)))
          (keywords (plist-get info :keywords)))

+ 9 - 11
contrib/lisp/ox-groff.el

@@ -622,8 +622,8 @@ See `org-groff-text-markup-alist' for details."
 
 
    ;; 5. Date.
    ;; 5. Date.
    (when (plist-get info :with-date)
    (when (plist-get info :with-date)
-     (let ((date (org-export-data (plist-get info :date) info)))
-       (and date (format ".ND \"%s\"\n" date))))
+     (let ((date (org-export-data (org-export-get-date info) info)))
+       (and (org-string-nw-p date) (format ".ND \"%s\"\n" date))))
 
 
    ;;
    ;;
    ;; If Abstract, then Populate Abstract
    ;; If Abstract, then Populate Abstract
@@ -1293,12 +1293,9 @@ INFO is a plist holding contextual information.  See
                    (or desc
                    (or desc
                        (org-export-data
                        (org-export-data
                         (org-element-property :raw-link link) info))))
                         (org-element-property :raw-link link) info))))
-          ;; Fuzzy link points to an invisible target.
-          (keyword nil)
-          ;; LINK points to a headline.  If headlines are numbered
-          ;; and the link has no description, display headline's
-          ;; number.  Otherwise, display description or headline's
-          ;; title.
+          ;; LINK points to a headline.  If headlines are numbered and
+          ;; the link has no description, display headline's number.
+          ;; Otherwise, display description or headline's title.
           (headline
           (headline
            (let ((label ""))
            (let ((label ""))
              (if (and (plist-get info :section-numbers) (not desc))
              (if (and (plist-get info :section-numbers) (not desc))
@@ -1922,9 +1919,10 @@ Return PDF file name or an error if it couldn't be produced."
   (let* ((base-name (file-name-sans-extension (file-name-nondirectory file)))
   (let* ((base-name (file-name-sans-extension (file-name-nondirectory file)))
 	 (full-name (file-truename file))
 	 (full-name (file-truename file))
 	 (out-dir (file-name-directory file))
 	 (out-dir (file-name-directory file))
-	 ;; Make sure `default-directory' is set to FILE directory,
-	 ;; not to whatever value the current buffer may have.
-	 (default-directory (file-name-directory full-name))
+	 ;; Properly set working directory for compilation.
+	 (default-directory (if (file-name-absolute-p file)
+				(file-name-directory full-name)
+			      default-directory))
          errors)
          errors)
     (message (format "Processing Groff file %s ..." file))
     (message (format "Processing Groff file %s ..." file))
     (save-window-excursion
     (save-window-excursion

+ 425 - 49
contrib/lisp/ox-koma-letter.el

@@ -4,6 +4,8 @@
 
 
 ;; Author: Nicolas Goaziou <n.goaziou AT gmail DOT com>
 ;; Author: Nicolas Goaziou <n.goaziou AT gmail DOT com>
 ;;         Alan Schmitt <alan.schmitt AT polytechnique DOT org>
 ;;         Alan Schmitt <alan.schmitt AT polytechnique DOT org>
+;;         Viktor Rosenfeld <listuser36 AT gmail DOT com>
+;;         Rasmus Pank Roulund <emacs AT pank DOT eu>
 ;; Keywords: org, wp, tex
 ;; Keywords: org, wp, tex
 
 
 ;; This program is free software: you can redistribute it and/or modify
 ;; This program is free software: you can redistribute it and/or modify
@@ -31,16 +33,67 @@
 ;;
 ;;
 ;; On top of buffer keywords supported by `latex' back-end (see
 ;; On top of buffer keywords supported by `latex' back-end (see
 ;; `org-latex-options-alist'), this back-end introduces the following
 ;; `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') and "TO_ADDRESS".
+;; 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{}".
+;;
+;; TO_ADDRESS and FROM_ADDRESS can also be specified using heading
+;; with the special tags specified in
+;; `org-koma-letter-special-tags-in-letter', namely "to" and "from".
+;; LaTeX line breaks are not necessary if using these headings.  If
+;; both a headline and a keyword specify a to or from address the
+;; value is determined in accordance with
+;; `org-koma-letter-prefer-special-headings'.
+;;
+;; A number of OPTIONS settings can be set to change which contents is
+;; exported.
+;;   - backaddress (see `org-koma-letter-use-backaddress')
+;;   - foldmarks (see `org-koma-letter-use-foldmarks')
+;;   - phone (see `org-koma-letter-use-phone')
+;;   - email (see `org-koma-letter-use-email')
+;;   - place (see `org-koma-letter-use-place')
+;;   - subject, a list of format options
+;;     (see `org-koma-letter-subject-format')
+;;   - after-closing-order, a list of the ordering of headings with
+;;     special tags after closing (see
+;;     `org-koma-letter-special-tags-after-closing') -
+;;     after-letter-order, as above, but after the end of the letter
+;;     (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),
+;;
+;; Headlines are in general ignored.  However, headlines with special
+;; tags can be used for specified contents like postscript (ps),
+;; carbon copy (cc), enclosures (encl) and code to be inserted after
+;; \end{letter} (after_letter).  Specials tags are defined in
+;; `org-koma-letter-special-tags-after-closing' and
+;; `org-koma-letter-special-tags-after-letter'.  Currently members of
+;; `org-koma-letter-special-tags-after-closing' used as macros and the
+;; content of the headline is the argument.
+;;
+;; Headlines with two and from may also be used rather than the
+;; keyword approach described above.  If both a keyword and a headline
+;; with information is present precedence is determined by
+;; `org-koma-letter-prefer-special-headings'.
 ;;
 ;;
 ;; You will need to add an appropriate association in
 ;; You will need to add an appropriate association in
-;; `org-latex-classes' in order to use the KOMA Scrlttr2 class.  For
-;; example, you can use the following code:
+;; `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 very sparse scrlttr2 class and
+;; set it as the default `org-koma-latex-default-class'.  You can also
+;; add you own letter class.  For instace:
 ;;
 ;;
 ;;   (add-to-list 'org-latex-classes
 ;;   (add-to-list 'org-latex-classes
 ;;                '("my-letter"
 ;;                '("my-letter"
@@ -61,7 +114,8 @@
 ;; with :
 ;; with :
 ;;
 ;;
 ;;    #+LATEX_CLASS: my-letter
 ;;    #+LATEX_CLASS: my-letter
-
+;;
+;; Or by setting `org-koma-letter-default-class'.
 
 
 ;;; Code:
 ;;; Code:
 
 
@@ -80,58 +134,297 @@
   :group 'org-export-koma-letter
   :group 'org-export-koma-letter
   :type 'string)
   :type 'string)
 
 
-(defcustom org-koma-letter-closing "See you soon,"
-  "Koma-Letter's closing, as a string."
+(defcustom org-koma-letter-author 'user-full-name
+  "The sender's name.
+
+This variable defaults to calling the function `user-full-name'
+which just returns the current `user-full-name'.  Alternatively a
+string, nil or a function may be given. Functions must return a
+string."
   :group 'org-export-koma-letter
   :group 'org-export-koma-letter
-  :type 'string)
+  :type '(radio (function-item user-full-name)
+		(string)
+		(function)
+		(const :tag "Do not export author" nil)))
+
+(defcustom org-koma-letter-email 'org-koma-letter-email
+  "The 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."
+  :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 "Somewhere \\ Over the rainbow."
+(defcustom org-koma-letter-from-address nil
   "Sender's address, as a string."
   "Sender's address, as a string."
   :group 'org-export-koma-letter
   :group 'org-export-koma-letter
   :type 'string)
   :type 'string)
 
 
-(defcustom org-koma-letter-opening "Dear Sir,"
+(defcustom org-koma-letter-phone-number nil
+  "Sender's phone number, as a string."
+  :group 'org-export-koma-letter
+  :type 'string)
+
+(defcustom org-koma-letter-place nil
+  "Place from which the letter is sent."
+  :group 'org-export-koma-letter
+  :type 'string)
+
+(defcustom org-koma-letter-opening nil
   "Letter's opening, as a string."
   "Letter's opening, as a string."
   :group 'org-export-koma-letter
   :group 'org-export-koma-letter
   :type 'string)
   :type 'string)
 
 
-(defcustom org-koma-letter-phone-number "00-00-00-00"
-  "Sender's phone number, as a string."
+(defcustom org-koma-letter-closing nil
+  "Koma-Letter's closing, as a string."
   :group 'org-export-koma-letter
   :group 'org-export-koma-letter
   :type 'string)
   :type 'string)
 
 
-(defcustom org-koma-letter-signature "\\usekomavar{fromname}"
+(defcustom org-koma-letter-prefer-special-headings nil
+  "If both a TO or FROM is specified two places should the
+  heading version be preferred?"
+  :group 'org-export-koma-letter
+  :type 'boolean)
+
+(defcustom org-koma-letter-signature nil
   "String used as the signature."
   "String used as the signature."
   :group 'org-export-koma-letter
   :group 'org-export-koma-letter
   :type 'string)
   :type 'string)
 
 
+(defcustom org-koma-letter-subject-format t
+  "Use the title as the subject of the letter.  At the time of
+writing the following values are allowed:
+
+ - 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 (see note in text please)
+ - untitled: do not add title/description to subject.
+ - No-export: do no insert a subject even if present.
+
+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))
+  :group 'org-export-koma-letter)
+
+
+
+(defcustom org-koma-letter-use-backaddress t
+  "Print return address in small line above to address."
+  :group 'org-export-koma-letter
+  :type 'boolean)
+
+(defcustom org-koma-letter-use-foldmarks "true"
+  "Configure appearence of fold marks.
+
+Accepts any valid value for the KOMA-Script `foldmarks' option.
+
+Use `foldmarks:true' to activate default fold marks or
+`foldmarks:nil' to deactivate fold marks."
+  :group 'org-export-koma-letter
+  :type 'string)
+
+(defcustom org-koma-letter-use-phone t
+  "Print sender's phone number."
+  :group 'org-export-koma-letter
+  :type 'boolean)
+
+(defcustom org-koma-letter-use-email t
+  "Print sender's email address."
+  :group 'org-export-koma-letter
+  :type 'boolean)
+
+(defcustom org-koma-letter-use-place t
+  "Print the letter's place next to the date."
+  :group 'org-export-koma-letter
+  :type 'boolean)
+
+(defcustom org-koma-letter-default-class nil
+  "Default class for `org-koma-letter'.  Must be a member of
+  `org-latex-classes'"
+  :group 'org-export-koma-letter
+  :type 'string)
+
+(defconst org-koma-letter-special-tags-in-letter '(to from)
+  "header tags related to the letter itself")
+
+(defconst org-koma-letter-special-tags-after-closing '(ps encl cc)
+  "Header tags to be inserted after closing")
+
+(defconst org-koma-letter-special-tags-after-letter '(after_letter)
+  "Header tags to be inserted after closing")
+
+(defvar org-koma-letter-special-contents nil
+  "holds special content temporarily.")
+
+
 
 
 ;;; Define Back-End
 ;;; Define Back-End
 
 
 (org-export-define-derived-backend 'koma-letter 'latex
 (org-export-define-derived-backend 'koma-letter 'latex
   :options-alist
   :options-alist
-  '((:closing "CLOSING" nil org-koma-letter-closing)
-    (:from-address "FROM_ADDRESS" nil org-koma-letter-from-address newline)
-    (:lco "LCO" nil org-koma-letter-class-option-file)
-    (:opening "OPENING" nil org-koma-letter-opening)
+  '((: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)
+    (:author "AUTHOR" nil (org-koma-letter--get-custom org-koma-letter-author) t)
+    (:from-address "FROM_ADDRESS" nil nil newline)
     (:phone-number "PHONE_NUMBER" nil org-koma-letter-phone-number)
     (:phone-number "PHONE_NUMBER" nil org-koma-letter-phone-number)
-    (:signature "SIGNATURE" nil nil newline)
-    (:to-address "TO_ADDRESS" nil nil newline))
+    (:email "EMAIL" nil (org-koma-letter--get-custom org-koma-letter-email) t)
+    (:to-address "TO_ADDRESS" nil nil newline)
+    (:place "PLACE" nil org-koma-letter-place)
+    (:opening "OPENING" nil org-koma-letter-opening)
+    (:closing "CLOSING" nil org-koma-letter-closing)
+    (:signature "SIGNATURE" nil org-koma-letter-signature newline)
+    (: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-foldmarks nil "foldmarks" org-koma-letter-use-foldmarks)
+    (:with-phone nil "phone" org-koma-letter-use-phone)
+    (:with-email nil "email" org-koma-letter-use-email)
+    (:with-place nil "place" org-koma-letter-use-place)
+    (:with-subject nil "subject" org-koma-letter-subject-format))
   :translate-alist '((export-block . org-koma-letter-export-block)
   :translate-alist '((export-block . org-koma-letter-export-block)
 		     (export-snippet . org-koma-letter-export-snippet)
 		     (export-snippet . org-koma-letter-export-snippet)
+		     (headline . org-koma-letter-headline)
 		     (keyword . org-koma-letter-keyword)
 		     (keyword . org-koma-letter-keyword)
 		     (template . org-koma-letter-template))
 		     (template . org-koma-letter-template))
   :menu-entry
   :menu-entry
   '(?k "Export with KOMA Scrlttr2"
   '(?k "Export with KOMA Scrlttr2"
-       ((?K "As LaTeX buffer" org-koma-letter-export-as-latex)
-	(?k "As LaTeX file" org-koma-letter-export-to-latex)
+       ((?L "As LaTeX buffer" org-koma-letter-export-as-latex)
+	(?l "As LaTeX file" org-koma-letter-export-to-latex)
 	(?p "As PDF file" org-koma-letter-export-to-pdf)
 	(?p "As PDF file" org-koma-letter-export-to-pdf)
-	(?O "As PDF file and open"
+	(?o "As PDF file and open"
 	    (lambda (a s v b)
 	    (lambda (a s v b)
 	      (if a (org-koma-letter-export-to-pdf t s v b)
 	      (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))))))))
 		(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 ()
+  "Return the current `user-mail-address'"
+  user-mail-address)
+
+;; The following is taken from/inspired by ox-grof.el
+;; Thanks, Luis!
+
+(defun org-koma-letter--get-tagged-contents (key)
+  "Get tagged content from `org-koma-letter-special-contents'"
+  (cdr (assoc (org-koma-letter--get-custom key)
+	      org-koma-letter-special-contents)))
+
+(defun org-koma-letter--get-custom (value)
+  "Determines whether a value is nil, a string or a
+function (a symobl).  If it is a function it it evaluates it."
+  (when value
+    (cond ((stringp value) value)
+	  ((functionp value) (funcall value))
+	  ((symbolp value) (symbol-name value))
+	  (t value))))
+
+
+(defun org-koma-letter--prepare-special-contents-as-macro (a-list &optional keep-newlines no-tag)
+  "Finds all the components of `org-koma-letter-special-contents'
+corresponding to members of the `a-list' and return them as a
+string to be formatted.  The function is used for inserting
+content of speciall 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 called.
+"
+  (let (output)
+    (dolist (ac* a-list output)
+      (let*
+	  ((ac (org-koma-letter--get-custom 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--remove-offending-new-lines x))
+		  (unless no-tag  ac)))))))))
+
+(defun org-koma-letter--format-string-as-macro (string &optional macro)
+  "If a macro is given format as string as  \"\\macro{string}\" else as \"string\""
+  (if macro
+      (format "\\%s{%s}" macro string)
+    (format "%s" string)))
+
+(defun org-koma-letter--remove-offending-new-lines (string)
+  "Remove new lines in the begging and end of `string'"
+  (replace-regexp-in-string "\\`[ \n\t]+\\|[\n\t ]*\\'" "" string))
+
+(defun org-koma-letter--determine-special-value (info key)
+  "Determine who the letter is to and whom it is from.
+  oxkoma-letter allows two ways to specify these things.  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
+    (replace-regexp-in-string
+     "\n" "\\\\\\\\\n"
+     (org-koma-letter--remove-offending-new-lines adr)))))
+
 ;;; Transcode Functions
 ;;; Transcode Functions
 
 
 ;;;; Export Block
 ;;;; Export Block
@@ -159,18 +452,48 @@ channel."
 CONTENTS is nil.  INFO is a plist used as a communication
 CONTENTS is nil.  INFO is a plist used as a communication
 channel."
 channel."
   (let ((key (org-element-property :key keyword))
   (let ((key (org-element-property :key keyword))
-        (value (org-element-property :value keyword)))
+	(value (org-element-property :value keyword)))
     ;; Handle specifically BEAMER and TOC (headlines only) keywords.
     ;; Handle specifically BEAMER and TOC (headlines only) keywords.
     ;; Otherwise, fallback to `latex' back-end.
     ;; Otherwise, fallback to `latex' back-end.
     (if (equal key "KOMA-LETTER") value
     (if (equal key "KOMA-LETTER") value
       (org-export-with-backend 'latex keyword contents info))))
       (org-export-with-backend 'latex keyword contents info))))
 
 
+
+;; Headline
+
+(defun org-koma-letter-headline (headline contents info)
+  "Transcode a HEADLINE element from Org to LaTeX.
+CONTENTS holds the contents of the headline.  INFO is a plist
+holding contextual information.
+
+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)
+      contents)))
+
+
 ;;;; Template
 ;;;; Template
 
 
 (defun org-koma-letter-template (contents info)
 (defun org-koma-letter-template (contents info)
   "Return complete document string after KOMA Scrlttr2 conversion.
   "Return complete document string after KOMA Scrlttr2 conversion.
 CONTENTS is the transcoded contents string.  INFO is a plist
 CONTENTS is the transcoded contents string.  INFO is a plist
 holding export options."
 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
   (concat
    ;; Time-stamp.
    ;; Time-stamp.
    (and (plist-get info :time-stamp-file)
    (and (plist-get info :time-stamp-file)
@@ -187,7 +510,7 @@ holding export options."
 		      "^[ \t]*\\\\documentclass\\(\\(\\[[^]]*\\]\\)?\\)"
 		      "^[ \t]*\\\\documentclass\\(\\(\\[[^]]*\\]\\)?\\)"
 		      class-options header t nil 1)))))
 		      class-options header t nil 1)))))
         (if (not document-class-string)
         (if (not document-class-string)
-	    (user-error "Unknown LaTeX class `%s'")
+	    (user-error "Unknown LaTeX class `%s'" class)
           (org-latex-guess-babel-language
           (org-latex-guess-babel-language
            (org-latex-guess-inputenc
            (org-latex-guess-inputenc
             (org-splice-latex-header
             (org-splice-latex-header
@@ -197,33 +520,84 @@ holding export options."
 	     (concat (plist-get info :latex-header)
 	     (concat (plist-get info :latex-header)
 		     (plist-get info :latex-header-extra))))
 		     (plist-get info :latex-header-extra))))
            info)))))
            info)))))
-   ;; Define "From" data.
-   (format "\\setkomavar{fromname}{%s}\n"
-           (org-export-data (plist-get info :author) info))
-   (format "\\setkomavar{fromaddress}{%s}\n" (plist-get info :from-address))
-   (format "\\setkomavar{signature}{%s}\n" (plist-get info :signature))
-   (format "\\setkomavar{fromemail}{%s}\n"
-           (org-export-data (plist-get info :email) info))
-   (format "\\setkomavar{fromphone}{%s}\n" (plist-get info :phone-number))
+   (let ((lco (plist-get info :lco))
+	 (author (plist-get info :author))
+	 (from-address (org-koma-letter--determine-special-value info 'from))
+	 (phone-number (plist-get info :phone-number))
+	 (email (plist-get info :email))
+	 (signature (plist-get info :signature)))
+     (concat
+      ;; 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 author (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 email (format "\\setkomavar{fromemail}{%s}\n" email))
+      (when signature (format "\\setkomavar{signature}{%s}\n" signature))))
    ;; Date.
    ;; Date.
-   (format "\\date{%s}\n" (org-export-data (plist-get info :date) info))
-   ;; Letter Class Option File
-   (format "\\LoadLetterOption{%s}\n" (plist-get info :lco))
-   ;; Letter start.
+   (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-foldmarks (plist-get info :with-foldmarks))
+	 (with-phone (plist-get info :with-phone))
+	 (with-email (plist-get info :with-email)))
+     (concat
+      (format "\\KOMAoption{backaddress}{%s}\n" (if with-backaddress "true" "false"))
+      (format "\\KOMAoption{foldmarks}{%s}\n" (if with-foldmarks with-foldmarks "false"))
+      (format "\\KOMAoption{fromphone}{%s}\n" (if with-phone "true" "false"))
+      (format "\\KOMAoption{fromemail}{%s}\n" (if with-email "true" "false"))))
+   ;; Document start
    "\\begin{document}\n\n"
    "\\begin{document}\n\n"
-   (format "\\setkomavar{subject}{%s}\n\n"
-           (org-export-data (plist-get info :title) info))
+   ;; 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
    (format "\\begin{letter}{%%\n%s}\n\n"
    (format "\\begin{letter}{%%\n%s}\n\n"
-	   (or (plist-get info :to-address) "no address given"))
+	   (org-koma-letter--determine-special-value info 'to))
    ;; Opening.
    ;; Opening.
    (format "\\opening{%s}\n\n" (plist-get info :opening))
    (format "\\opening{%s}\n\n" (plist-get info :opening))
    ;; Letter body.
    ;; Letter body.
    contents
    contents
    ;; Closing.
    ;; Closing.
-   (format "\n\\closing{%s}\n\n" (plist-get info :closing))
+   (format "\n\\closing{%s}\n" (plist-get info :closing))
+   (org-koma-letter--prepare-special-contents-as-macro
+    (plist-get info :with-after-closing))
    ;; Letter end.
    ;; Letter end.
-   "\\end{letter}\n\\end{document}"))
-
+   "\n\\end{letter}\n"
+   (org-koma-letter--prepare-special-contents-as-macro
+    (plist-get info :with-after-letter) t t)
+   ;; Document end.
+   "\n\\end{document}"
+   ))
 
 
 
 
 ;;; Commands
 ;;; Commands
@@ -252,7 +626,7 @@ contents of hidden elements.
 When optional argument BODY-ONLY is non-nil, only write code
 When optional argument BODY-ONLY is non-nil, only write code
 between \"\\begin{letter}\" and \"\\end{letter}\".
 between \"\\begin{letter}\" and \"\\end{letter}\".
 
 
-EXT-PLIST, when provided, is a property list with external
+EXT-PLIST, when provided, is a proeprty list with external
 parameters overriding Org default settings, but still inferior to
 parameters overriding Org default settings, but still inferior to
 file-local settings.
 file-local settings.
 
 
@@ -260,6 +634,7 @@ Export is done in a buffer named \"*Org KOMA-LETTER Export*\".  It
 will be displayed if `org-export-show-temporary-export-buffer' is
 will be displayed if `org-export-show-temporary-export-buffer' is
 non-nil."
 non-nil."
   (interactive)
   (interactive)
+  (let (org-koma-letter-special-contents)
   (if async
   (if async
       (org-export-async-start
       (org-export-async-start
 	  (lambda (output)
 	  (lambda (output)
@@ -276,7 +651,7 @@ non-nil."
 		   subtreep visible-only body-only ext-plist)))
 		   subtreep visible-only body-only ext-plist)))
       (with-current-buffer outbuf (LaTeX-mode))
       (with-current-buffer outbuf (LaTeX-mode))
       (when org-export-show-temporary-export-buffer
       (when org-export-show-temporary-export-buffer
-	(switch-to-buffer-other-window outbuf)))))
+	(switch-to-buffer-other-window outbuf))))))
 
 
 ;;;###autoload
 ;;;###autoload
 (defun org-koma-letter-export-to-latex
 (defun org-koma-letter-export-to-latex
@@ -311,7 +686,8 @@ directory.
 
 
 Return output file's name."
 Return output file's name."
   (interactive)
   (interactive)
-  (let ((outfile (org-export-output-file-name ".tex" subtreep)))
+  (let ((outfile (org-export-output-file-name ".tex" subtreep))
+	org-koma-letter-special-contents)
     (if async
     (if async
 	(org-export-async-start
 	(org-export-async-start
 	    (lambda (f) (org-export-add-to-stack f 'koma-letter))
 	    (lambda (f) (org-export-add-to-stack f 'koma-letter))

+ 1 - 1
contrib/lisp/ox-s5.el

@@ -306,7 +306,7 @@ holding export options."
     (mapconcat
     (mapconcat
      'identity
      'identity
      (list
      (list
-      (plist-get info :html-doctype)
+      (org-html-doctype info)
       (format "<html xmlns=\"http://www.w3.org/1999/xhtml\" lang=\"%s\" xml:lang=\"%s\">"
       (format "<html xmlns=\"http://www.w3.org/1999/xhtml\" lang=\"%s\" xml:lang=\"%s\">"
 	      (plist-get info :language) (plist-get info :language))
 	      (plist-get info :language) (plist-get info :language))
       "<head>"
       "<head>"

+ 250 - 79
contrib/lisp/ox-taskjuggler.el

@@ -28,12 +28,11 @@
 ;;; Commentary:
 ;;; Commentary:
 ;;
 ;;
 ;; This library implements a TaskJuggler exporter for Org mode.
 ;; This library implements a TaskJuggler exporter for Org mode.
-;; TaskJuggler uses a text format to define projects, tasks and
-;; resources, so it is a natural fit for Org mode.  It can produce all
-;; sorts of reports for tasks or resources in either HTML, CSV or PDF.
-;; The current version of TaskJuggler requires KDE but the next
-;; version is implemented in Ruby and should therefore run on any
-;; platform.
+;; TaskJuggler is a project planing tool that uses a text format to
+;; define projects, tasks and resources, so it is a natural fit for
+;; Org mode.  It can produce all sorts of reports for tasks or
+;; resources in either HTML, CSV or PDF.  TaskJuggler is implemented
+;; in Ruby and should therefore run on any platform.
 ;;
 ;;
 ;; The exporter does not export all the nodes of a document or
 ;; The exporter does not export all the nodes of a document or
 ;; strictly follow the order of the nodes in the document.
 ;; strictly follow the order of the nodes in the document.
@@ -142,6 +141,7 @@
 ;;     org-global-properties-fixed
 ;;     org-global-properties-fixed
 ;;   - What about property inheritance and org-property-inherit-p?
 ;;   - What about property inheritance and org-property-inherit-p?
 ;;   - Use TYPE_TODO as an way to assign resources
 ;;   - Use TYPE_TODO as an way to assign resources
+;;   - Add support for org-export-with-planning
 ;;
 ;;
 ;;; Code:
 ;;; Code:
 
 
@@ -185,7 +185,14 @@ the project."
   :type 'string)
   :type 'string)
 
 
 (defcustom org-taskjuggler-target-version 3.0
 (defcustom org-taskjuggler-target-version 3.0
-  "Which version of TaskJuggler the exporter is targeting."
+  "Which version of TaskJuggler the exporter is targeting.
+By default a project plan is exported which conforms to version
+3.x of TaskJuggler.  For a project plan that is compatible with
+versions of TaskJuggler older than 3.0 set this to 2.4.
+
+If you change this variable be sure to also change
+`org-taskjuggler-default-reports' as the format of reports has
+changed considerably between version 2.x and 3.x of TaskJuggler"
   :group 'org-export-taskjuggler
   :group 'org-export-taskjuggler
   :type 'number)
   :type 'number)
 
 
@@ -205,21 +212,67 @@ marked with `org-taskjuggler-project-tag'"
   :type 'integer)
   :type 'integer)
 
 
 (defcustom org-taskjuggler-default-reports
 (defcustom org-taskjuggler-default-reports
-  '("taskreport \"Gantt Chart\" {
+  '("textreport report \"Plan\" {
+  formats html
+  header '== %title =='
+
+  center -8<-
+    [#Plan Plan] | [#Resource_Allocation Resource Allocation]
+    ----
+    === Plan ===
+    <[report id=\"plan\"]>
+    ----
+    === Resource Allocation ===
+    <[report id=\"resourceGraph\"]>
+  ->8-
+}
+
+# A traditional Gantt chart with a project overview.
+taskreport plan \"\" {
+  headline \"Project Plan\"
+  columns bsi, name, start, end, effort, chart
+  loadunit shortauto
+  hideresource 1
+}
+
+# A graph showing resource allocation. It identifies whether each
+# resource is under- or over-allocated for.
+resourcereport resourceGraph \"\" {
+  headline \"Resource Allocation Graph\"
+  columns no, name, effort, weekly
+  loadunit shortauto
+  hidetask ~(isleaf() & isleaf_())
+  sorttasks plan.start.up
+}")
+  "Default reports for the project.
+These are sensible default reports to give a good out-of-the-box
+result when exporting without defining any reports.  \"%title\"
+anywhere in the reports will be replaced with the document title.
+If you want to define your own reports you can change them here
+or simply define the default reports so that they include an
+external report definition as follows:
+
+include reports.tji
+
+These default are made to work with tj3.  If you are targeting
+TaskJuggler 2.4 (see `org-taskjuggler-target-version') please
+change these defaults to something like the following:
+
+taskreport \"Gantt Chart\" {
   headline \"Project Gantt Chart\"
   headline \"Project Gantt Chart\"
   columns hierarchindex, name, start, end, effort, duration, completed, chart
   columns hierarchindex, name, start, end, effort, duration, completed, chart
   timeformat \"%Y-%m-%d\"
   timeformat \"%Y-%m-%d\"
   hideresource 1
   hideresource 1
   loadunit shortauto
   loadunit shortauto
-}"
-    "resourcereport \"Resource Graph\" {
+}
+
+resourcereport \"Resource Graph\" {
   headline \"Resource Allocation Graph\"
   headline \"Resource Allocation Graph\"
   columns no, name, utilization, freeload, chart
   columns no, name, utilization, freeload, chart
   loadunit shortauto
   loadunit shortauto
   sorttasks startup
   sorttasks startup
   hidetask ~isleaf()
   hidetask ~isleaf()
-}")
-  "Default reports for the project."
+}"
   :group 'org-export-taskjuggler
   :group 'org-export-taskjuggler
   :type '(repeat (string :tag "Report")))
   :type '(repeat (string :tag "Report")))
 
 
@@ -273,6 +326,31 @@ If one of these appears as a property for a headline, it will be
 exported with the corresponding report."
 exported with the corresponding report."
   :group 'org-export-taskjuggler)
   :group 'org-export-taskjuggler)
 
 
+(defcustom org-taskjuggler-process-command
+  "tj3 --silent --no-color --output-dir %o %f"
+  "Command to process a Taskjuggler file.
+The command will be given to the shell as a command to process a
+Taskjuggler file.  \"%f\" in the command will be replaced by the
+full file name, \"%o\" by the reports directory (see
+`org-taskjuggler-reports-directory').
+
+If you are targeting Taskjuggler 2.4 (see
+`org-taskjuggler-target-version') this setting is ignored."
+  :group 'org-export-taskjuggler)
+
+(defcustom org-taskjuggler-reports-directory "reports"
+  "Default directory to generate the Taskjuggler reports in.
+The command `org-taskjuggler-process-command' generates the
+reports and associated files such as CSS inside this directory.
+
+If the directory is not an absolute path it is relative to the
+directory of the exported file.  The directory is created if it
+doesn't exist.
+
+If you are targeting Taskjuggler 2.4 (see
+`org-taskjuggler-target-version') this setting is ignored."
+  :group 'org-export-taskjuggler)
+
 (defcustom org-taskjuggler-keep-project-as-task t
 (defcustom org-taskjuggler-keep-project-as-task t
   "Non-nil keeps the project headline as an umbrella task for all tasks.
   "Non-nil keeps the project headline as an umbrella task for all tasks.
 Setting this to nil will allow maintaining completely separated
 Setting this to nil will allow maintaining completely separated
@@ -297,10 +375,14 @@ This hook is run with the name of the file as argument.")
   :menu-entry
   :menu-entry
   '(?J "Export to TaskJuggler"
   '(?J "Export to TaskJuggler"
        ((?j "As TJP file" (lambda (a s v b) (org-taskjuggler-export a s v)))
        ((?j "As TJP file" (lambda (a s v b) (org-taskjuggler-export a s v)))
-	(?o "As TJP file and open"
+	(?p "As TJP file and process"
 	    (lambda (a s v b)
 	    (lambda (a s v b)
 	      (if a (org-taskjuggler-export a s v)
 	      (if a (org-taskjuggler-export a s v)
-		(org-taskjuggler-export-and-open s v))))))
+		(org-taskjuggler-export-and-process s v))))
+	(?o "As TJP file, process and open"
+	    (lambda (a s v b)
+	      (if a (org-taskjuggler-export a s v)
+		(org-taskjuggler-export-process-and-open s v))))))
   ;; This property will be used to store unique ids in communication
   ;; This property will be used to store unique ids in communication
   ;; channel.  Ids will be retrieved with `org-taskjuggler-get-id'.
   ;; channel.  Ids will be retrieved with `org-taskjuggler-get-id'.
   :options-alist '((:taskjuggler-unique-ids nil nil nil)))
   :options-alist '((:taskjuggler-unique-ids nil nil nil)))
@@ -311,10 +393,12 @@ This hook is run with the name of the file as argument.")
 
 
 (defun org-taskjuggler-assign-task-ids (tasks info)
 (defun org-taskjuggler-assign-task-ids (tasks info)
   "Assign a unique ID to each task in TASKS.
   "Assign a unique ID to each task in TASKS.
-TASKS is a list of headlines.  Return value is an alist between
+TASKS is a list of headlines.  INFO is a plist used as a
+communication channel.  Return value is an alist between
 headlines and their associated ID.  IDs are hierarchical, which
 headlines and their associated ID.  IDs are hierarchical, which
 means they only need to be unique among the task siblings."
 means they only need to be unique among the task siblings."
   (let* (alist
   (let* (alist
+	 build-id			; For byte-compiler.
          (build-id
          (build-id
           (lambda (tasks local-ids)
           (lambda (tasks local-ids)
             (org-element-map tasks 'headline
             (org-element-map tasks 'headline
@@ -329,8 +413,9 @@ means they only need to be unique among the task siblings."
 
 
 (defun org-taskjuggler-assign-resource-ids (resources info)
 (defun org-taskjuggler-assign-resource-ids (resources info)
   "Assign a unique ID to each resource within RESOURCES.
   "Assign a unique ID to each resource within RESOURCES.
-RESOURCES is a list of headlines.  Return value is an alist
-between headlines and their associated ID."
+RESOURCES is a list of headlines.  INFO is a plist used as a
+communication channel.  Return value is an alist between
+headlines and their associated ID."
   (let (ids)
   (let (ids)
     (org-element-map resources 'headline
     (org-element-map resources 'headline
       (lambda (resource)
       (lambda (resource)
@@ -349,17 +434,19 @@ INFO is a plist used as a communication channel.  First headline
 in buffer with `org-taskjuggler-project-tag' defines the project.
 in buffer with `org-taskjuggler-project-tag' defines the project.
 If no such task is defined, pick the first headline in buffer.
 If no such task is defined, pick the first headline in buffer.
 If there is no headline at all, return nil."
 If there is no headline at all, return nil."
-  (or (org-element-map (plist-get info :parse-tree) 'headline
-        (lambda (hl)
-          (and (member org-taskjuggler-project-tag
-                       (org-export-get-tags hl info))
-               hl))
-        info t)
-      (org-element-map tree 'headline 'identity info t)))
+  (let ((tree (plist-get info :parse-tree)))
+    (or (org-element-map tree 'headline
+	  (lambda (hl)
+	    (and (member org-taskjuggler-project-tag
+			 (org-export-get-tags hl info))
+		 hl))
+	  info t)
+	(org-element-map tree 'headline 'identity info t))))
 
 
 (defun org-taskjuggler-get-id (item info)
 (defun org-taskjuggler-get-id (item info)
   "Return id for task or resource ITEM.
   "Return id for task or resource ITEM.
-ITEM is a headline.  Return value is a string."
+ITEM is a headline.  INFO is a plist used as a communication
+channel.  Return value is a string."
   (cdr (assq item (plist-get info :taskjuggler-unique-ids))))
   (cdr (assq item (plist-get info :taskjuggler-unique-ids))))
 
 
 (defun org-taskjuggler-get-name (item)
 (defun org-taskjuggler-get-name (item)
@@ -372,14 +459,17 @@ ITEM is a headline.  Return value is a string."
 (defun org-taskjuggler-get-start (item)
 (defun org-taskjuggler-get-start (item)
   "Return start date for task or resource ITEM.
   "Return start date for task or resource ITEM.
 ITEM is a headline.  Return value is a string or nil if ITEM
 ITEM is a headline.  Return value is a string or nil if ITEM
-doesn't have any start date defined.."
+doesn't have any start date defined."
   (let ((scheduled (org-element-property :scheduled item)))
   (let ((scheduled (org-element-property :scheduled item)))
-    (and scheduled (org-timestamp-format scheduled "%Y-%02m-%02d"))))
+    (or
+     (and scheduled (org-timestamp-format scheduled "%Y-%02m-%02d"))
+     (and (memq 'start org-taskjuggler-valid-task-attributes)
+	  (org-element-property :START item)))))
 
 
 (defun org-taskjuggler-get-end (item)
 (defun org-taskjuggler-get-end (item)
   "Return end date for task or resource ITEM.
   "Return end date for task or resource ITEM.
 ITEM is a headline.  Return value is a string or nil if ITEM
 ITEM is a headline.  Return value is a string or nil if ITEM
-doesn't have any end date defined.."
+doesn't have any end date defined."
   (let ((deadline (org-element-property :deadline item)))
   (let ((deadline (org-element-property :deadline item)))
     (and deadline (org-timestamp-format deadline "%Y-%02m-%02d"))))
     (and deadline (org-timestamp-format deadline "%Y-%02m-%02d"))))
 
 
@@ -411,16 +501,19 @@ resource.  Its id is derived from its name and made unique
 against UNIQUE-IDS.  If the (downcased) first token of the
 against UNIQUE-IDS.  If the (downcased) first token of the
 headline is not unique try to add more (downcased) tokens of the
 headline is not unique try to add more (downcased) tokens of the
 headline or finally add more underscore characters (\"_\")."
 headline or finally add more underscore characters (\"_\")."
-  (let* ((parts (org-split-string (org-element-property :raw-value item)))
-	 (id (org-taskjuggler--clean-id (downcase (pop parts)))))
-    ;; Try to add more parts of the headline to make it unique.
-    (while (and (car parts) (member id unique-ids))
-      (setq id (concat id "_"
-                       (org-taskjuggler--clean-id (downcase (pop parts))))))
-    ;; If it's still not unique, add "_".
-    (while (member id unique-ids)
-      (setq id (concat id "_")))
-    id))
+  (let ((id (org-string-nw-p (org-element-property :TASK_ID item))))
+    ;; If an id is specified, use it, as long as it's unique.
+    (if (and id (not (member id unique-ids))) id
+      (let* ((parts (org-split-string (org-element-property :raw-value item)))
+	     (id (org-taskjuggler--clean-id (downcase (pop parts)))))
+	;; Try to add more parts of the headline to make it unique.
+	(while (and (car parts) (member id unique-ids))
+	  (setq id (concat id "_"
+			   (org-taskjuggler--clean-id (downcase (pop parts))))))
+	;; If it's still not unique, add "_".
+	(while (member id unique-ids)
+	  (setq id (concat id "_")))
+	id))))
 
 
 (defun org-taskjuggler--clean-id (id)
 (defun org-taskjuggler--clean-id (id)
   "Clean and return ID to make it acceptable for TaskJuggler.
   "Clean and return ID to make it acceptable for TaskJuggler.
@@ -457,7 +550,8 @@ channel."
         (setq depends
         (setq depends
               (org-element-map tasks 'headline
               (org-element-map tasks 'headline
                 (lambda (task)
                 (lambda (task)
-                  (let ((task-id (org-element-property :TASK_ID task)))
+                  (let ((task-id (or (org-element-property :TASK_ID task)
+				     (org-element-property :ID task))))
                     (and task-id (member task-id deps-ids) task)))
                     (and task-id (member task-id deps-ids) task)))
                 info)))
                 info)))
       ;; Check BLOCKER and DEPENDS properties.  If "previous-sibling"
       ;; Check BLOCKER and DEPENDS properties.  If "previous-sibling"
@@ -481,33 +575,34 @@ DEPENDENCIES is list of dependencies for TASK, as returned by
 `org-taskjuggler-resolve-depedencies'.  TASK is a headline.
 `org-taskjuggler-resolve-depedencies'.  TASK is a headline.
 INFO is a plist used as a communication channel.  Return value
 INFO is a plist used as a communication channel.  Return value
 doesn't include leading \"depends\"."
 doesn't include leading \"depends\"."
-  (let ((dep-str (concat (org-element-property :BLOCKER task)
-                         " "
-                         (org-element-property :DEPENDS task)))
-        (get-path
-         (lambda (dep)
-           ;; Return path to DEP relatively to TASK.
-           (let ((parent (org-export-get-parent dep))
-                 (exclamations 1)
-                 (option
-                  (let ((id (org-element-property :TASK_ID dep)))
-                    (and id
-                         (string-match (concat id " +\\({.*?}\\)") dep-str)
-                         (org-match-string-no-properties 1))))
-                 path)
-             ;; Compute number of exclamation marks.
-             (while (not (org-element-map parent 'headline
-                           (lambda (task) (eq task dep))))
-               (incf exclamations)
-               (setq parent (org-export-get-parent parent)))
-             ;; Build path from DEP to PARENT.
-             (while (not (eq parent dep))
-               (push (org-taskjuggler-get-id dep info) path)
-               (setq dep (org-export-get-parent dep)))
-             ;; Return full path.  Add dependency options, if any.
-             (concat (make-string exclamations ?!)
-                     (mapconcat 'identity path ".")
-                     (and option (concat " " option)))))))
+  (let* ((dep-str (concat (org-element-property :BLOCKER task)
+			  " "
+			  (org-element-property :DEPENDS task)))
+	 (get-path
+	  (lambda (dep)
+	    ;; Return path to DEP relatively to TASK.
+	    (let ((parent (org-export-get-parent task))
+		  (exclamations 1)
+		  (option
+		   (let ((id (org-element-property :TASK_ID dep)))
+		     (and id
+			  (string-match (concat id " +\\({.*?}\\)") dep-str)
+			  (org-match-string-no-properties 1))))
+		  path)
+	      ;; Compute number of exclamation marks by looking for the
+	      ;; common ancestor between TASK and DEP.
+	      (while (not (org-element-map parent 'headline
+			    (lambda (hl) (eq hl dep))))
+		(incf exclamations)
+		(setq parent (org-export-get-parent parent)))
+	      ;; Build path from DEP to PARENT.
+	      (while (not (eq parent dep))
+		(push (org-taskjuggler-get-id dep info) path)
+		(setq dep (org-export-get-parent dep)))
+	      ;; Return full path.  Add dependency options, if any.
+	      (concat (make-string exclamations ?!)
+		      (mapconcat 'identity path ".")
+		      (and option (concat " " option)))))))
     ;; Return dependencies string, without the leading "depends".
     ;; Return dependencies string, without the leading "depends".
     (mapconcat (lambda (dep) (funcall get-path dep)) dependencies ", ")))
     (mapconcat (lambda (dep) (funcall get-path dep)) dependencies ", ")))
 
 
@@ -517,7 +612,7 @@ doesn't include leading \"depends\"."
 
 
 (defun org-taskjuggler-project-plan (contents info)
 (defun org-taskjuggler-project-plan (contents info)
   "Build TaskJuggler project plan.
   "Build TaskJuggler project plan.
-CONTENTS is ignored. INFO is a plist holding export options.
+CONTENTS is ignored.  INFO is a plist holding export options.
 Return complete project plan as a string in TaskJuggler syntax."
 Return complete project plan as a string in TaskJuggler syntax."
   (let* ((tree (plist-get info :parse-tree))
   (let* ((tree (plist-get info :parse-tree))
          (project (or (org-taskjuggler-get-project info)
          (project (or (org-taskjuggler-get-project info)
@@ -601,8 +696,18 @@ Return complete project plan as a string in TaskJuggler syntax."
               (mapconcat
               (mapconcat
                (lambda (report) (org-taskjuggler--build-report report info))
                (lambda (report) (org-taskjuggler--build-report report info))
                main-reports "")
                main-reports "")
-            (mapconcat 'org-element-normalize-string
-                       org-taskjuggler-default-reports ""))))))))
+	    ;; insert title in default reports
+	    (let* ((title (org-export-data (plist-get info :title) info))
+		   (report-title (if (string= title "")
+				     (org-taskjuggler-get-name project)
+				   title)))
+	      (mapconcat
+	       'org-element-normalize-string
+	       (mapcar
+		(function
+		 (lambda (report)
+		   (replace-regexp-in-string "%title" report-title  report t t)))
+		org-taskjuggler-default-reports) "")))))))))
 
 
 (defun org-taskjuggler--build-project (project info)
 (defun org-taskjuggler--build-project (project info)
   "Return a project declaration.
   "Return a project declaration.
@@ -656,7 +761,7 @@ neither is defined a unique id will be associated to it."
    ;; Closing resource.
    ;; Closing resource.
    "}\n"))
    "}\n"))
 
 
-(defun org-taskjuggler--build-report (report)
+(defun org-taskjuggler--build-report (report info)
   "Return a report declaration.
   "Return a report declaration.
 REPORT is a headline.  INFO is a plist used as a communication
 REPORT is a headline.  INFO is a plist used as a communication
 channel."
 channel."
@@ -726,13 +831,13 @@ a unique id will be associated to it."
                   (if (>= org-taskjuggler-target-version 3.0) "allocate"
                   (if (>= org-taskjuggler-target-version 3.0) "allocate"
                     "allocations")
                     "allocations")
                   allocate))
                   allocate))
-     (and complete (format "  complete %s\n" comptete))
+     (and complete (format "  complete %s\n" complete))
      (and effort
      (and effort
           (format "  effort %s\n"
           (format "  effort %s\n"
                   (let* ((minutes (org-duration-string-to-minutes effort))
                   (let* ((minutes (org-duration-string-to-minutes effort))
                          (hours (/ minutes 60.0)))
                          (hours (/ minutes 60.0)))
                     (format "%.1fh" hours))))
                     (format "%.1fh" hours))))
-     (and priority (format "  priority %s\n" complete))
+     (and priority (format "  priority %s\n" priority))
      (and milestone "  milestone\n")
      (and milestone "  milestone\n")
      ;; Add other valid attributes.
      ;; Add other valid attributes.
      (org-taskjuggler--indent-string
      (org-taskjuggler--indent-string
@@ -801,8 +906,8 @@ Return output file's name."
       outfile)))
       outfile)))
 
 
 ;;;###autoload
 ;;;###autoload
-(defun org-taskjuggler-export-and-open (&optional subtreep visible-only)
-  "Export current buffer to a TaskJuggler file and open it.
+(defun org-taskjuggler-export-and-process (&optional subtreep visible-only)
+  "Export current buffer to a TaskJuggler file and process it.
 
 
 The exporter looks for a tree with tag that matches
 The exporter looks for a tree with tag that matches
 `org-taskjuggler-project-tag' and takes this as the tasks for
 `org-taskjuggler-project-tag' and takes this as the tasks for
@@ -829,12 +934,78 @@ first.
 When optional argument VISIBLE-ONLY is non-nil, don't export
 When optional argument VISIBLE-ONLY is non-nil, don't export
 contents of hidden elements.
 contents of hidden elements.
 
 
-Open file with the TaskJuggler GUI."
+Return a list of reports."
+  (interactive)
+  (let ((file (org-taskjuggler-export nil subtreep visible-only)))
+    (org-taskjuggler-compile file)))
+
+;;;###autoload
+(defun org-taskjuggler-export-process-and-open (&optional subtreep visible-only)
+  "Export current buffer to a TaskJuggler file, process and open it.
+
+Export and process the file using
+`org-taskjuggler-export-and-process' and open the generated
+reports with a browser.
+
+If you are targeting TaskJuggler 2.4 (see
+`org-taskjuggler-target-version') the processing and display of
+the reports is done using the TaskJuggler GUI."
   (interactive)
   (interactive)
-  (let* ((file (org-taskjuggler-export nil subtreep visible-only))
-	 (process-name "TaskJugglerUI")
-	 (command (concat process-name " " file)))
-    (start-process-shell-command process-name nil command)))
+  (if (< org-taskjuggler-target-version 3.0)
+      (let* ((process-name "TaskJugglerUI")
+	     (command
+	      (concat process-name " "
+		      (org-taskjuggler-export nil subtreep visible-only))))
+	(start-process-shell-command process-name nil command))
+    (dolist (report (org-taskjuggler-export-and-process subtreep visible-only))
+      (org-open-file report))))
+
+(defun org-taskjuggler-compile (file)
+  "Compile a TaskJuggler file.
+
+FILE is the name of the file being compiled.  Processing is done
+through the command given in `org-taskjuggler-process-command'.
+
+Return a list of reports."
+  (let* ((full-name (file-truename file))
+	 (out-dir
+	  (expand-file-name
+	   org-taskjuggler-reports-directory (file-name-directory file)))
+	 errors)
+    (message (format "Processing TaskJuggler file %s..." file))
+    (save-window-excursion
+      (let ((outbuf (get-buffer-create "*Org Taskjuggler Output*")))
+	(unless (file-directory-p out-dir)
+	  (make-directory out-dir t))
+	(with-current-buffer outbuf (erase-buffer))
+	(shell-command
+	 (replace-regexp-in-string
+	  "%f" (shell-quote-argument full-name)
+	  (replace-regexp-in-string
+	   "%o" (shell-quote-argument out-dir)
+	   org-taskjuggler-process-command t t) t t) outbuf)
+	;; Collect standard errors from output buffer.
+	(setq errors (org-taskjuggler--collect-errors outbuf)))
+      (if (not errors)
+	  (message "Process completed.")
+	(error (format "TaskJuggler failed with errors: %s" errors))))
+    (file-expand-wildcards (format "%s/*.html" out-dir))))
+
+(defun org-taskjuggler--collect-errors (buffer)
+  "Collect some kind of errors from \"tj3\" command output.
+
+BUFFER is the buffer containing output.
+
+Return collected error types as a string, or nil if there was
+none."
+  (with-current-buffer buffer
+    (save-excursion
+      (goto-char (point-min))
+      (let ((case-fold-search t)
+	    (errors ""))
+	(while (re-search-forward "^.+:[0-9]+: \\(.*\\)$" nil t)
+	  (setq errors (concat errors " " (match-string 1))))
+	(and (org-string-nw-p errors) (org-trim errors))))))
 
 
 
 
 (provide 'ox-taskjuggler)
 (provide 'ox-taskjuggler)

Разница между файлами не показана из-за своего большого размера
+ 302 - 190
doc/org.texi


+ 1 - 1
doc/orgcard.tex

@@ -1,5 +1,5 @@
 % Reference Card for Org Mode
 % Reference Card for Org Mode
-\def\orgversionnumber{7.9.3}
+\def\orgversionnumber{8.0}
 \def\versionyear{2013}          % latest update
 \def\versionyear{2013}          % latest update
 \def\year{2013}                 % latest copyright year
 \def\year{2013}                 % latest copyright year
 
 

+ 67 - 25
doc/orgguide.texi

@@ -13,9 +13,9 @@
 @c Version and Contact Info
 @c Version and Contact Info
 @set MAINTAINERSITE @uref{http://orgmode.org,maintainers webpage}
 @set MAINTAINERSITE @uref{http://orgmode.org,maintainers webpage}
 @set AUTHOR Carsten Dominik
 @set AUTHOR Carsten Dominik
-@set MAINTAINER Bastien Guerry
-@set MAINTAINEREMAIL @email{bzg at gnu dot org}
-@set MAINTAINERCONTACT @uref{mailto:bzg at gnu dot org,contact the maintainer}
+@set MAINTAINER Carsten Dominik
+@set MAINTAINEREMAIL @email{carsten at orgmode dot org}
+@set MAINTAINERCONTACT @uref{mailto:carsten at orgmode dot org,contact the maintainer}
 @c %**end of header
 @c %**end of header
 @finalout
 @finalout
 
 
@@ -98,7 +98,7 @@ modify this GNU manual.''
 * Working With Source Code::	Source code snippets embedded in Org
 * Working With Source Code::	Source code snippets embedded in Org
 * Miscellaneous::		All the rest which did not fit elsewhere
 * Miscellaneous::		All the rest which did not fit elsewhere
 
 
-* GNU Free Documentation License:: This manual license.
+* GNU Free Documentation License::  This manual license.
 
 
 @detailmenu
 @detailmenu
  --- The Detailed Node Listing ---
  --- The Detailed Node Listing ---
@@ -147,6 +147,7 @@ Tags
 
 
 * Tag inheritance::		Tags use the tree structure of the outline
 * Tag inheritance::		Tags use the tree structure of the outline
 * Setting tags::		How to assign tags to a headline
 * Setting tags::		How to assign tags to a headline
+* Tag groups::			Use one tag to search for several tags
 * Tag searches::		Searching for combinations of tags
 * Tag searches::		Searching for combinations of tags
 
 
 Dates and Times
 Dates and Times
@@ -158,7 +159,7 @@ Dates and Times
 
 
 Capture - Refile - Archive
 Capture - Refile - Archive
 
 
-* Capture::			
+* Capture::			Capturing new stuff
 * Refile and copy::		Moving a tree from one place to another
 * Refile and copy::		Moving a tree from one place to another
 * Archiving::			What to do with finished projects
 * Archiving::			What to do with finished projects
 
 
@@ -187,7 +188,7 @@ The built-in agenda views
 Markup for rich export
 Markup for rich export
 
 
 * Structural markup elements::	The basic structure as seen by the exporter
 * Structural markup elements::	The basic structure as seen by the exporter
-* Images and tables::		Tables and Images will be included
+* Images and tables::		Images, tables and caption mechanism
 * Literal examples::		Source code examples with special formatting
 * Literal examples::		Source code examples with special formatting
 * Include files::		Include additional files into a document
 * Include files::		Include additional files into a document
 * Embedded @LaTeX{}::		@LaTeX{} can be freely used inside Org documents
 * Embedded @LaTeX{}::		@LaTeX{} can be freely used inside Org documents
@@ -729,6 +730,9 @@ Links such as @samp{[[My Target]]} or @samp{[[My Target][Find my target]]}
 lead to a text search in the current file for the corresponding target which
 lead to a text search in the current file for the corresponding target which
 looks like @samp{<<My Target>>}.
 looks like @samp{<<My Target>>}.
 
 
+Internal links will be used to reference their destination, through links or
+numbers, when possible.
+
 @node External links, Handling links, Internal links, Hyperlinks
 @node External links, Handling links, Internal links, Hyperlinks
 @section External links
 @section External links
 
 
@@ -1109,6 +1113,7 @@ Tags will by default be in bold face with the same color as the headline.
 @menu
 @menu
 * Tag inheritance::		Tags use the tree structure of the outline
 * Tag inheritance::		Tags use the tree structure of the outline
 * Setting tags::		How to assign tags to a headline
 * Setting tags::		How to assign tags to a headline
+* Tag groups::			Use one tag to search for several tags
 * Tag searches::		Searching for combinations of tags
 * Tag searches::		Searching for combinations of tags
 @end menu
 @end menu
 
 
@@ -1138,7 +1143,7 @@ changes in the line.}:
 #+FILETAGS: :Peter:Boss:Secret:
 #+FILETAGS: :Peter:Boss:Secret:
 @end smallexample
 @end smallexample
 
 
-@node Setting tags, Tag searches, Tag inheritance, Tags
+@node Setting tags, Tag groups, Tag inheritance, Tags
 @section Setting tags
 @section Setting tags
 
 
 Tags can simply be typed into the buffer at the end of a headline.
 Tags can simply be typed into the buffer at the end of a headline.
@@ -1189,7 +1194,46 @@ can instead set the TAGS option line as:
 #+TAGS: @@work(w)  @@home(h)  @@tennisclub(t)  laptop(l)  pc(p)
 #+TAGS: @@work(w)  @@home(h)  @@tennisclub(t)  laptop(l)  pc(p)
 @end smallexample
 @end smallexample
 
 
-@node Tag searches,  , Setting tags, Tags
+@node Tag groups, Tag searches, Setting tags, Tags
+@section Tag groups
+
+@cindex group tags
+@cindex tags, groups
+In a set of mutually exclusive tags, the first tag can be defined as a
+@emph{group tag}.  When you search for a group tag, it will return matches
+for all members in the group.  In an agenda view, filtering by a group tag
+will display headlines tagged with at least one of the members of the
+group.  This makes tag searches and filters even more flexible.
+
+You can set group tags by inserting a colon between the group tag and other
+tags, like this:
+
+@example
+#+TAGS: @{ @@read : @@read_book  @@read_ebook @}
+@end example
+
+In this example, @samp{@@read} is a @emph{group tag} for a set of three
+tags: @samp{@@read}, @samp{@@read_book} and @samp{@@read_ebook}.
+
+You can also use the @code{:grouptags} keyword directly when setting
+@var{org-tag-alist}:
+
+@lisp
+(setq org-tag-alist '((:startgroup . nil) 
+                      ("@@read" . nil)
+                      (:grouptags . nil)
+                      ("@@read_book" . nil)
+                      ("@@read_ebook" . nil)
+                      (:endgroup . nil)))
+@end lisp
+
+@kindex C-c C-x q
+@vindex org-group-tags
+If you want to ignore group tags temporarily, toggle group tags support
+with @command{org-toggle-tags-groups}, bound to @kbd{C-c C-x q}.  If you
+want to disable tag groups completely, set @var{org-group-tags} to nil.
+
+@node Tag searches,  , Tag groups, Tags
 @section Tag searches
 @section Tag searches
 
 
 Once a system of tags has been set up, it can be used to collect related
 Once a system of tags has been set up, it can be used to collect related
@@ -1518,8 +1562,8 @@ projects need to be moved around.  Moving completed project trees to an
 archive file keeps the system compact and fast.
 archive file keeps the system compact and fast.
 
 
 @menu
 @menu
-* Capture::
-* Refiling notes::		Moving a tree from one place to another
+* Capture::			Capturing new stuff
+* Refile and copy::		Moving a tree from one place to another
 * Archiving::			What to do with finished projects
 * Archiving::			What to do with finished projects
 @end menu
 @end menu
 
 
@@ -2046,7 +2090,7 @@ summarizes the markup rules used in an Org-mode buffer.
 
 
 @menu
 @menu
 * Structural markup elements::	The basic structure as seen by the exporter
 * Structural markup elements::	The basic structure as seen by the exporter
-* Images and tables::		Tables and Images will be included
+* Images and tables::		Images, tables and caption mechanism
 * Literal examples::		Source code examples with special formatting
 * Literal examples::		Source code examples with special formatting
 * Include files::		Include additional files into a document
 * Include files::		Include additional files into a document
 * Embedded @LaTeX{}::		@LaTeX{} can be freely used inside Org documents
 * Embedded @LaTeX{}::		@LaTeX{} can be freely used inside Org documents
@@ -2167,32 +2211,30 @@ Toggle the COMMENT keyword at the beginning of an entry.
 For Org mode tables, the lines before the first horizontal separator line
 For Org mode tables, the lines before the first horizontal separator line
 will become table header lines.  You can use the following lines somewhere
 will become table header lines.  You can use the following lines somewhere
 before the table to assign a caption and a label for cross references, and in
 before the table to assign a caption and a label for cross references, and in
-the text you can refer to the object with @code{\ref@{tab:basic-data@}}:
+the text you can refer to the object with @code{[[tab:basic-data]]}:
 
 
 @smallexample
 @smallexample
 #+CAPTION: This is the caption for the next table (or link)
 #+CAPTION: This is the caption for the next table (or link)
-#+LABEL:   tbl:basic-data
+#+NAME:   tbl:basic-data
    | ... | ...|
    | ... | ...|
    |-----|----|
    |-----|----|
 @end smallexample
 @end smallexample
 
 
-Some backends (HTML, @LaTeX{}, and DocBook) allow you to directly include
-images into the exported document.  Org does this, if a link to an image
-files does not have a description part, for example @code{[[./img/a.jpg]]}.
-If you wish to define a caption for the image and maybe a label for internal
-cross references, you sure that the link is on a line by itself precede it
-with:
+Some backends allow you to directly include images into the exported
+document.  Org does this, if a link to an image files does not have
+a description part, for example @code{[[./img/a.jpg]]}.  If you wish to
+define a caption for the image and maybe a label for internal cross
+references, you sure that the link is on a line by itself precede it with:
 
 
 @smallexample
 @smallexample
 #+CAPTION: This is the caption for the next figure link (or table)
 #+CAPTION: This is the caption for the next figure link (or table)
-#+LABEL:   fig:SED-HR4049
+#+NAME:   fig:SED-HR4049
 [[./img/a.jpg]]
 [[./img/a.jpg]]
 @end smallexample
 @end smallexample
 
 
-You may also define additional attributes for the figure.  As this is
-backend-specific, see the sections about the individual backends for more
-information.
-
+The same caption mechanism applies to other structures than images and tables
+(e.g., @LaTeX{} equations, source code blocks), provided the chosen export
+back-end supports them.
 
 
 @node Literal examples, Include files, Images and tables, Markup
 @node Literal examples, Include files, Images and tables, Markup
 @section Literal examples
 @section Literal examples
@@ -2252,7 +2294,7 @@ processed normally. @kbd{C-c '} will visit the included file.
 
 
 For scientific notes which need to be able to contain mathematical symbols
 For scientific notes which need to be able to contain mathematical symbols
 and the occasional formula, Org-mode supports embedding @LaTeX{} code into
 and the occasional formula, Org-mode supports embedding @LaTeX{} code into
-its files.  You can directly use TeX-like macros for special symbols, enter
+its files.  You can directly use TeX-like syntax for special symbols, enter
 formulas and entire @LaTeX{} environments.
 formulas and entire @LaTeX{} environments.
 
 
 @smallexample
 @smallexample

+ 815 - 0
etc/ORG-NEWS

@@ -1,12 +1,827 @@
 ORG NEWS -- history of user-visible changes.           -*- org -*-
 ORG NEWS -- history of user-visible changes.           -*- org -*-
 
 
 #+LINK: doc http://orgmode.org/worg/doc.html#%s
 #+LINK: doc http://orgmode.org/worg/doc.html#%s
+#+LINK: git http://orgmode.org/w/?p=org-mode.git;a=commit;h=%s
 
 
 Copyright (C) 2012-2013 Free Software Foundation, Inc.
 Copyright (C) 2012-2013 Free Software Foundation, Inc.
 See the end of the file for license conditions.
 See the end of the file for license conditions.
 
 
 Please send Org bug reports to emacs-orgmode@gnu.org.
 Please send Org bug reports to emacs-orgmode@gnu.org.
 
 
+* Version 8.0.1
+
+** Installation
+
+Installation instructions have been updated and simplified.
+
+If you have troubles installing or updating Org, focus on these
+instructions:
+
+- when updating via a =.zip/.tar.gz= file, you only need to set the
+  =load-path= in your =.emacs=.  Set it before any other Org
+  customization that would call autoloaded Org functions.
+
+- when updating by pulling Org's Git repository, make sure to create the
+  correct autoloads.  You can do this by running =~$ make autoloads= (to
+  only create the autoloads) or by running =~$ make= (to also compile
+  the Emacs lisp files.)  =~$ make help= and =~$ make helpall= gives you
+  detailed explanations.
+
+- when updating through ELPA (either from GNU ELPA or from Org ELPA),
+  you have to install Org's ELPA package in a session where no Org
+  function has been called already.
+  
+When in doubt, run =M-x org-version RET= and see if you have a mixed-up
+installation.
+
+See http://orgmode.org/org.html#Installation for details.
+
+** Incompatible changes
+
+Org 8.0 is the most disruptive major version of Org.
+
+If you configured export options, you will have to update some of them.
+
+If you used =#+ATTR_*= keywords, the syntax of the attributes changed and
+you will have to update them.
+
+Below is a list of changes for which you need to take action.
+
+See http://orgmode.org/worg/org-8.0.html for the most recent version of
+this list and for detailed instructions on how to migrate.
+
+**** New export engine
+
+Org 8.0 comes with a new export engine written by Nicolas Goaziou.  This
+export engine relies on ~org-element.el~ (Org's syntax parser), which was
+already in Org's core.  This new export engine triggered the rewriting of
+/all/ export back-ends.
+
+The most visible change is the export dispatcher, accessible through the
+keybinding =C-c C-e=.  By default, this menu only shows some of the
+built-in export formats, but you can add more formats by loading them
+directly (e.g., =(require 'ox-texinfo)= or by configuring the option
+[[doc:org-export-backends][org-export-backends]].
+
+More contributed back-ends are available from the =contrib/= directory, the
+corresponding files start with the =ox-= prefix.
+
+If you customized an export back-end (like HTML or LaTeX), you will need to
+rename some options so that your customization is not lost.  Typically, an
+option starting with =org-export-html-= is now named =org-html-=.  See the
+manual for details and check [[http://orgmode.org/worg/org-8.0.html][this Worg page]] for directions.
+
+**** New syntax for #+ATTR_HTML/LaTeX/... options
+
+     : #+ATTR_HTML width="200px"
+
+     should now be written
+
+     : #+ATTR_HTML :width 200px
+
+     Keywords like =#+ATTR_HTML= and =#+ATTR_LaTeX= are defined in their
+     respective back-ends, and the list of supported parameters depends on
+     each backend.  See Org's manual for details.
+
+**** ~org-remember.el~ has been removed
+
+     You cannot use =remember.el= anymore to capture notes.
+
+     Support for remember templates has been obsoleted since long, it is
+     now fully removed.
+
+     Use =M-x org-capture-import-remember-templates RET= to import your
+     remember templates into capture templates.
+
+**** ~org-jsinfo.el~ has been merged into ~ox-html.el~
+
+     If you were requiring ~ox-jsinfo.el~ in your ~.emacs.el~ file, you
+     will have to remove this requirement from your initialization file.
+
+**** Note for third-party developers
+
+     The name of the files for export back-end have changed: we now use the
+     prefix =ox-= for those files (like we use the =ob-= prefix for Babel
+     files.)  For example ~org-html.el~ is now ~ox-html.el~.
+
+     If your code relies on these files, please update the names in your
+     code.
+
+**** Packages moved from core to contrib
+
+     Since packages in Org's core are meant to be part of GNU Emacs, we try
+     to be minimalist when it comes to adding files into core.  For 8.0, we
+     moved some contributions into the =contrib/= directory.
+
+     The rationale for deciding that these files should live in =contrib/=
+     is either because they rely on third-part softwares that are not
+     included in Emacs, or because they are not targetting a significant
+     user-base.
+
+     - org-colview-xemacs.el
+     - org-mac-message.el
+     - org-mew.el
+     - org-wl.el
+     - ox-freedmind.el
+     - ox-taskjuggler.el
+
+     Note that ~ox-freedmind.el~ has been rewritten by Jambunathan,
+     ~org-mew.el~ has been enhanced by Tokuya Kameshima and
+     ~ox-taskjuggler.el~ by Nicolas Goaziou and others.
+
+     Also, the Taskjuggler exporter now uses TJ3 by default.  John Hendy
+     wrote [[http://orgmode.org/worg/org-tutorials/org-taskjuggler3.html][a tutorial on Worg]] for the TJ3 export.
+
+** New packages in core
+
+*** ~ob-makefile.el~ by Eric Schulte and Thomas S. Dye
+
+    =ob-makefile.el= implements Org Babel support for Makefile tangling.
+
+*** ~ox-man.el~ by Luis Anaya
+
+    =ox-man.el= allows you to export Org files to =man= pages.
+
+*** ~ox-md.el~ by Nicolas Goaziou
+
+    =ox-md.el= allows you to export Org files to Markdown files, using the
+    vanilla [[http://daringfireball.net/projects/markdown/][Markdown syntax]].
+
+*** ~ox-texinfo.el~ by Jonathan Leech-Pepin
+
+    =ox-texinfo.el= allows you to export Org files to [[http://www.gnu.org/software/texinfo/][Texinfo]] files.
+
+** New packages in contrib
+
+*** ~ob-julia.el~ by G. Jay Kerns
+
+    [[http://julialang.org/][Julia]] is a new programming language.
+
+    =ob-julia.el= provides Org Babel support for evaluating Julia source
+    code.
+
+*** ~ob-mathomatic.el~ by Luis Anaya
+
+    [[http://www.mathomatic.org/][mathomatic]] a portable, command-line, educational CAS and calculator
+    software, written entirely in the C programming language.
+
+    ~ob-mathomatic.el~ provides Org Babel support for evaluating mathomatic
+    entries.
+
+*** ~ob-tcl.el~ by Luis Anaya
+
+    ~ob-tcl.el~ provides Org Babel support for evaluating [[http://www.tcl.tk/][Tcl]] source code.
+
+*** ~org-bullets.el~ by Evgeni Sabof
+
+    Display bullets instead of stars for headlines.
+
+    Also see [[http://orgmode.org/worg/org-faq.html#sec-8-12][this updated FAQ]] on how to display another character than "*"
+    for starting headlines.
+
+*** ~org-favtable.el~ by Marc-Oliver Ihm
+
+    ~org-favtable.el~ helps you to create and update a table of favorite
+    locations in org, keeping the most frequently visited lines right at
+    the top.  This table is called "favtable".  See the documentation on
+    [[http://orgmode.org/worg/org-contrib/org-favtable.html][Worg]].
+
+*** ~ox-confluence.el~ by Sébastien Delafond
+
+    ~ox-confluence.el~ lets you convert Org files to [[https://confluence.atlassian.com/display/DOC/Confluence%2BWiki%2BMarkup][Confluence Wiki]] files.
+
+*** ~ox-deck.el~ and ~ox-s5.el~ by Rick Frankel
+
+    [[http://imakewebthings.com/deck.js/][deck.js]] is a javascript library for displaying HTML ages as
+    presentations.  ~ox-deck.el~ exports Org files to HTML presentations
+    using =deck.js=.
+
+    [[http://meyerweb.com/eric/tools/s5/][s5]] is a set of scripts which also allows to display HTML pages as
+    presentations.  ~ox-s5.el~ exports Org files to HTML presentations
+    using =s5=.
+
+*** ~ox-groff.el~ by Luis Anaya and Nicolas Goaziou
+
+    The [[http://www.gnu.org/software/groff/][groff]] (GNU troff) software is a typesetting package which reads
+    plain text mixed with formatting commands and produces formatted
+    output.
+
+    Luis Anaya and Nicolas Goaziou implemented ~ox-groff.el~ to allow
+    conversion from Org files to groff.
+
+*** ~ox-koma-letter.el~ by Nicolas Goaziou and Alan Schmitt
+
+    This back-end allow to export Org pages to the =KOMA Scrlttr2= format.
+
+*** ~ox-rss.el~ by Bastien
+
+    This back-end lets you export Org pages to RSS 2.0 feeds.  Combined
+    with the HTML publishing feature, this allows you to build a blog
+    entirely with Org.
+
+** New features
+
+*** Export
+
+**** New export generic options
+
+If you use Org exporter, we advise you to re-read [[http://orgmode.org/org.html#Exporting][the manual section about
+it]].  It has been updated and includes new options.
+
+Among the new/updated export options, three are of particular importance:
+
+- [[doc:org-export-allow-bind-keywords][org-export-allow-bind-keywords]] :: This option replaces the old option
+     =org-export-allow-BIND= and the default value is =nil=, not =confirm=.
+     You will need to explicitely set this to =t= in your initialization
+     file if you want to allow =#+BIND= keywords.
+
+- [[doc:org-export-with-planning][org-export-with-planning]] :: This new option controls the export of
+     =SCHEDULED:, DEADLINE:, CLOSED:= lines, and planning information is
+     now skipped by default during export.  This use to be the job of
+     [[doc:org-export-with-timestamps][org-export-with-timestamps]], but this latter option has been given a
+     new role: it controls the export of /standalone time-stamps/.  When
+     set to =nil=, Org will not export active and inactive time-stamps
+     standing on a line by themselves or within a paragraph that only
+     contains time-stamps.
+
+To check if an option has been introduced or its default value changed in
+Org 8.0, do =C-h v [option] RET= and check if the documentation says that
+the variable has been introduced (or changed) in version 24.4 of Emacs.
+
+**** Enhanced default stylesheet for the HTML exporter
+
+See the new default value of [[doc:org-html-style-default][org-html-style-default]].
+
+**** New tags, classes and ids for the HTML exporter
+
+See the new default value of [[doc:org-html-divs][org-html-divs]].
+
+**** Support for tikz pictures in LaTeX export
+**** ~org-man.el~: New export function for "man" links
+**** ~org-docview.el~: New export function for docview links
+*** Structure editing
+
+**** =C-u C-u M-RET= inserts a heading at the end of the parent subtree
+**** Cycling to the =CONTENTS= view keeps inline tasks folded
+
+[[doc:org-cycle-hook][org-cycle-hook]] as a new function [[doc:org-cycle-hide-inline-tasks][org-cycle-hide-inline-tasks]] which
+prevents the display of inline tasks when showing the content of a subtree.
+
+**** =C-c -= in a region makes a list item for each line
+
+This is the opposite of the previous behavior, where =C-c -= on a region
+would create one item for the whole region, and where =C-u C-c -= would
+create an item for each line.  Now =C-c -= on the selected region creates
+an item per line, and =C-u C-c -= creates a single item for the whole
+region.
+
+**** When transposing words, markup characters are now part of the words
+
+In Emacs, you can transpose words with =M-t=.  Transposing =*these*
+_words__= will preserve markup.
+
+**** New command [[doc:org-set-property-and-value][org-set-property-and-value]] bound to =C-c C-x P=
+
+This command allows you to quickly add both the property and its value.  It
+is useful in buffers where there are many properties and where =C-c C-x p=
+can slow down the flow of editing too much.
+
+**** New commands [[doc:org-next-block][org-next-block]] and [[doc:org-previous-block][org-previous-block]]
+
+These commands allow you to go to the previous block (=C-c M-b= or the
+speedy key =B=) or to the next block (=C-c M-f= or the speedy key =F=.)
+
+**** New commands [[doc:org-drag-line-forward][org-drag-line-forward]] and [[doc:org-drag-line-backward][org-drag-line-backward]]
+
+These commands emulate the old behavior of =M-<down>= and =M-<up>= but are
+now bound to =S-M-<down>= and =S-M-<up>= respectively, since =M-<down>= and
+=M-<up>= now drag the whole element at point (a paragraph, a table, etc.)
+forward and backward.
+
+**** When a list item has a checkbox, inserting a new item uses a checkbox too
+**** When sorting entries/items, only the description of links is considered
+
+Now Org will sort this list
+
+: - [[http://abc.org][B]]
+: - [[http://def.org][A]]
+
+like this:
+
+: - [[http://def.org][A]]
+: - [[http://abc.org][B]]
+
+by comparing the descriptions, not the links.
+Same when sorting headlines instead of list items.
+**** New option =orgstruct-heading-prefix-regexp=
+
+For example, setting this option to "^;;; " in Emacs lisp files and using
+=orgstruct-mode= in those files will allow you to cycle through visibility
+states as if lines starting with ";;; *..." where headlines.
+
+In general, you want to set =orgstruct-heading-prefix-regexp= as a file
+local variable.
+
+**** New behavior of [[doc:org-clone-subtree-with-time-shift][org-clone-subtree-with-time-shift]]
+
+The default is now to ask for a time-shift only when there is a time-stamp.
+When called with a universal prefix argument =C-u=, it will not ask for a
+time-shift even if there is a time-stamp.
+
+**** New option [[doc:org-agenda-restriction-lock-highlight-subtree][org-agenda-restriction-lock-highlight-subtree]]
+
+This defaults to =t= so that the whole subtree is highlighted when you
+restrict the agenda view to it with =C-c C-x <= (or the speed command =<=).
+The default setting helps ensuring that you are not adding tasks after the
+restricted region.  If you find this highlighting too intrusive, set this
+option to =nil=.
+**** New option [[doc:org-closed-keep-when-no-todo][org-closed-keep-when-no-todo]]
+
+When switching back from a =DONE= keyword to a =TODO= keyword, Org now
+removes the =CLOSED= planning information, if any.  It also removes this
+information when going back to a non-TODO state (e.g., with =C-c C-t SPC=).
+If you want to keep the =CLOSED= planning information when removing the
+TODO keyword, set [[doc:org-closed-keep-when-no-todo][org-closed-keep-when-no-todo]] to =t=.
+
+**** New option [[doc:org-image-actual-width][org-image-actual-width]]
+
+This option allows you to change the width of in-buffer displayed images.
+The default is to use the actual width of the image, but you can use a
+fixed value for all images, or fall back on an attribute like
+
+: #+attr_html: :width 300px
+*** Scheduled/deadline
+
+**** Implement "delay" cookies for scheduled items
+
+If you want to delay the display of a scheduled task in the agenda, you can
+now use a delay cookie like this: =SCHEDULED: <2004-12-25 Sat -2d>=.  The
+task is still scheduled on the 25th but will appear in your agenda starting
+from two days later (i.e. from March 27th.)
+
+Imagine for example that your co-workers are not done in due time and tell
+you "we need two more days".  In that case, you may want to delay the
+display of the task in your agenda by two days, but you still want the task
+to appear as scheduled on March 25th.
+
+In case the task contains a repeater, the delay is considered to affect all
+occurrences; if you want the delay to only affect the first scheduled
+occurrence of the task, use =--2d= instead.  See [[doc:org-scheduled-delay-days][org-scheduled-delay-days]]
+and [[doc:org-agenda-skip-scheduled-delay-if-deadline][org-agenda-skip-scheduled-delay-if-deadline]] for details on how to
+control this globally or per agenda.
+
+**** Use =C-u C-u C-c C-s= will insert a delay cookie for scheduled tasks
+
+See the previous section for why delay cookies may be useful.
+
+**** Use =C-u C-u C-c C-d= will insert a warning delay for deadline tasks
+
+=C-u C-u C-c C-d= now inserts a warning delay to deadlines.
+*** Calendar, diary and appts
+
+**** New variable [[doc:org-read-date-minibuffer-local-map][org-read-date-minibuffer-local-map]]
+
+By default, this new local map uses "." to go to today's date, like in the
+normal =M-x calendar RET=.  If you want to deactivate this and to reassign
+the "@" key to =calendar-goto-today=, use this:
+
+#+BEGIN_SRC emacs-lisp
+  ;; Unbind "." in Org's calendar:
+  (define-key org-read-date-minibuffer-local-map (kbd ".") nil)
+
+  ;; Bind "@" to `calendar-goto-today':
+  (define-key org-read-date-minibuffer-local-map
+              (kbd "@")
+              (lambda () (interactive) (org-eval-in-calendar '(calendar-goto-today))))
+#+END_SRC
+
+**** In Org's calendar, =!= displays diary entries of the date at point
+
+This is useful when you want to check if you don't already have an
+appointment when setting new ones with =C-c .= or =C-c s=.  =!= will
+call =diary-view-entries= and display the diary in a separate buffer.
+
+**** [[doc:org-diary][org-diary]]: only keep the descriptions of links
+
+[[doc:org-diary][org-diary]] returns diary information from Org files, but it returns it
+in a diary buffer, not in an Org mode buffer.  When links are displayed,
+only show their description, not the full links.
+*** Agenda
+
+**** New agenda type =agenda*= and entry types =:scheduled* :deadline*=
+
+When defining agenda custom commands, you can now use =agenda*=: this will
+list entries that have both a date and a time.  This is useful when you
+want to build a list of appointments.
+
+You can also set [[doc:org-agenda-entry-types][org-agenda-entry-types]] either globally or locally in
+each agenda custom command and use =:timestamp*= and/or =:deadline*= there.
+
+Another place where this is useful is your =.diary= file:
+
+: %%(org-diary :scheduled*) ~/org/rdv.org
+
+This will list only entries from =~/org/rdv.org= that are scheduled with a
+time value (i.e. appointments).
+
+**** New agenda sorting strategies
+
+[[doc:org-agenda-sorting-strategy][org-agenda-sorting-strategy]] allows these new sorting strategies:
+
+| Strategy       | Explanations                             |
+|----------------+------------------------------------------|
+| timestamp-up   | Sort by any timestamp, early first       |
+| timestamp-down | Sort by any timestamp, late first        |
+| scheduled-up   | Sort by scheduled timestamp, early first |
+| scheduled-down | Sort by scheduled timestamp, late first  |
+| deadline-up    | Sort by deadline timestamp, early first  |
+| deadline-down  | Sort by deadline timestamp, late first   |
+| ts-up          | Sort by active timestamp, early first    |
+| ts-down        | Sort by active timestamp, late first     |
+| tsia-up        | Sort by inactive timestamp, early first  |
+| tsia-down      | Sort by inactive timestamp, late first   |
+
+**** New options to limit the number of agenda entries
+
+You can now limit the number of entries in an agenda view.  This is
+different from filters: filters only /hide/ the entries in the agenda,
+while limits are set while generating the list of agenda entries.
+
+These new options are available:
+
+- [[doc:org-agenda-max-entries][org-agenda-max-entries]] :: limit by number of entries.
+- [[doc:org-agenda-max-todos][org-agenda-max-todos]] :: limit by number of TODOs.
+- [[doc:org-agenda-max-tags][org-agenda-max-tags]] :: limit by number of tagged entries.
+- [[doc:org-agenda-max-effort][org-agenda-max-effort]] :: limit by effort (minutes).
+
+For example, if you locally set [[doc:org-agenda-max-todos][org-agenda-max-todos]] to 3 in an agenda
+view, the agenda will be limited to the first three todos.  Other entries
+without a TODO keyword or beyond the third TODO headline will be ignored.
+
+When setting a limit (e.g. about an effort's sum), the default behavior is
+to exclude entries that cannot be checked against (e.g. entries that have
+no effort property.)  To include other entries too, you can set the limit
+to a negative number.  For example =(setq org-agenda-max-tags -3)= will not
+show the fourth tagged headline (and beyond), but it will also show
+non-tagged headlines.
+
+**** =~= in agenda view sets temporary limits
+
+You can hit =~= in the agenda to temporarily set limits: this will
+regenerate the agenda as if the limits were set.  This is useful for
+example when you want to only see a list of =N= tasks, or a list of tasks
+that take only =N= minutes.
+
+**** "=" in agenda view filters by regular expressions
+
+You can now filter agenda entries by regular expressions using ~=~.  =C-u
+== will filter entries out.  Regexp filters are cumulative.  You can set
+[[doc:org-agenda-regexp-filter-preset][org-agenda-regexp-filter-preset]] to suit your needs in each agenda view.
+
+**** =|= in agenda view resets all filters
+
+Since it's common to combine tag filters, category filters, and now regexp
+filters, there is a new command =|= to reset all filters at once.
+
+**** Allow writing an agenda to an =.org= file
+
+You can now write an agenda view to an =.org= file.  It copies the
+headlines and their content (but not subheadings) into the new file.
+
+This is useful when you want to quickly share an agenda containing the full
+list of notes.
+
+**** New commands to drag an agenda line forward (=M-<down>=) or backard (=M-<up>=)
+
+It sometimes handy to move agenda lines around, just to quickly reorganize
+your tasks, or maybe before saving the agenda to a file.  Now you can use
+=M-<down>= and =M-<up>= to move the line forward or backward.
+
+This does not persist after a refresh of the agenda, and this does not
+change the =.org= files who contribute to the agenda.
+
+**** Use =%b= for displaying "breadcrumbs" in the agenda view
+
+[[doc:org-agenda-prefix-format][org-agenda-prefix-format]] now allows to use a =%b= formatter to tell Org
+to display "breadcrumbs" in the agenda view.
+
+This is useful when you want to display the task hierarchy in your agenda.
+
+**** Use =%l= for displaying the headline's level in the agenda view
+
+[[doc:org-agenda-prefix-format][org-agenda-prefix-format]] allows to use a =%l= formatter to tell Org to
+display entries with additional spaces corresponding to their level in the
+outline tree.
+
+**** [[doc:org-agenda-write][org-agenda-write]] will ask before overwriting an existing file
+
+=M-x org-agenda-write RET= (or =C-c C-w= from an agenda buffer) used to
+overwrite preexisting file with the same name without confirmation.  It now
+asks for a confirmation.
+
+**** New commands =M-m= and =M-*= to toggle (all) mark(s) for bulk action
+
+- [[doc:org-agenda-bulk-toggle][org-agenda-bulk-toggle]] :: this command is bound to =M-m= and toggles
+     the mark of the entry at point.
+
+- [[doc:org-agenda-bulk-toggle-all][org-agenda-bulk-toggle-all]] :: this command is bound to =M-*= and
+     toggles all the marks in the current agenda.
+
+**** New option [[doc:org-agenda-search-view-max-outline-level][org-agenda-search-view-max-outline-level]]
+
+This option sets the maximum outline level to display in search view.
+E.g. when this is set to 1, the search view will only show headlines of
+level 1.
+
+**** New option [[doc:org-agenda-todo-ignore-time-comparison-use-seconds][org-agenda-todo-ignore-time-comparison-use-seconds]]
+
+This allows to compare times using seconds instead of days when honoring
+options like =org-agenda-todo-ignore-*= in the agenda display.
+
+**** New option [[doc:org-agenda-entry-text-leaders][org-agenda-entry-text-leaders]]
+
+This allows you to get rid of the ">" character that gets added in front of
+entries excerpts when hitting =E= in the agenda view.
+
+**** New formatting string for past deadlines in [[doc:org-agenda-deadline-leaders][org-agenda-deadline-leaders]]
+
+The default formatting for past deadlines is ="%2d d. ago: "=, which makes
+it explicit that the deadline is in the past.  You can configure this via
+[[doc:org-agenda-deadline-leaders][org-agenda-deadline-leaders]].  Note that the width of the formatting
+string is important to keep the agenda alignment clean.
+
+**** New allowed value =repeated-after-deadline= for [[doc:org-agenda-skip-scheduled-if-deadline-is-shown][org-agenda-skip-scheduled-if-deadline-is-shown]]
+
+When [[doc:org-agenda-skip-scheduled-if-deadline-is-shown][org-agenda-skip-scheduled-if-deadline-is-shown]] is set to
+=repeated-after-deadline=, the agenda will skip scheduled items if they are
+repeated beyond the current dealine.
+
+**** New option for [[doc:org-agenda-skip-deadline-prewarning-if-scheduled][org-agenda-skip-deadline-prewarning-if-scheduled]]
+
+This variable may be set to nil, t, the symbol `pre-scheduled', or a number
+which will then give the number of days before the actual deadline when the
+prewarnings should resume.  The symbol `pre-scheduled' eliminates the
+deadline prewarning only prior to the scheduled date.
+
+Read the full docstring for details.
+
+**** [[doc:org-class][org-class]] now supports holiday strings in the skip-weeks parameter
+
+For example, this task will now be skipped only on new year's day:
+
+    : * Task
+    :   <%%(org-class 2012 1 1 2013 12 12 2 "New Year's Day")>
+*** Capture
+
+**** Allow =C-1= as a prefix for [[doc:org-agenda-capture][org-agenda-capture]] and [[doc:org-capture][org-capture]]
+
+With a =C-1= prefix, the capture mechanism will use the =HH:MM= value at
+point (if any) or the current =HH:MM= time as the default time for the
+capture template.
+
+**** Expand keywords within %(sexp) placeholder in capture templates
+
+If you use a =%:keyword= construct within a =%(sexp)= construct, Org will
+expand the keywords before expanding the =%(sexp)=.
+
+**** Allow to contextualize capture (and agenda) commands by checking the name of the buffer
+
+[[doc:org-capture-templates-contexts][org-capture-templates-contexts]] and [[doc:org-agenda-custom-commands-contexts][org-agenda-custom-commands-contexts]]
+allow you to define what capture templates and what agenda commands should
+be available in various contexts.  It is now possible for the context to
+check against the name of the buffer.
+*** Tag groups
+
+Using =#+TAGS: { Tag1 : Tag2 Tag3 }= will define =Tag1= as a /group tag/
+(note the colon after =Tag1=).  If you search for =Tag1=, it will return
+headlines containing either =Tag1=, =Tag2= or =Tag3= (or any combinaison
+of those tags.)
+
+You can use group tags for sparse tree in an Org buffer, for creating
+agenda views, and for filtering.
+
+See http://orgmode.org/org.html#Tag-groups for details.
+
+*** Links
+
+**** =C-u C-u M-x org-store-link RET= will ignore non-core link functions
+
+Org knows how to store links from Org buffers, from info files and from
+other Emacs buffers.  Org can be taught how to store links from any buffer
+through new link protocols (see [[http://orgmode.org/org.html#Adding-hyperlink-types]["Adding hyperlink types"]] in the manual.)
+
+Sometimes you want Org to ignore added link protocols and store the link
+as if the protocol was not known.
+
+You can now do this with =C-u C-u M-x org-store-link RET=.
+
+**** =C-u C-u C-u M-x org-store-link RET= on an active region will store links for each lines
+
+Imagine for example that you want to store a link for every message in a
+Gnus summary buffer.  In that case =C-x h C-u C-u C-u M-x org-store-link
+RET= will store a link for every line (i.e. message) if the region is
+active.
+
+**** =C-c C-M-l= will add a default description for links which don't have one
+
+=C-c C-M-l= inserts all stored links.  If a link does not have a
+description, this command now adds a default one, so that we are not mixing
+with-description and without-description links when inserting them.
+
+**** No curly braces to bracket links within internal links
+
+When storing a link to a headline like
+
+: * See [[http://orgmode.org][Org website]]
+
+[[doc:org-store-link][org-store-link]] used to convert the square brackets into curly brackets.
+It does not anymore, taking the link description or the link path, when
+there is no description.
+*** Table
+
+**** Switching between #+TBLFM lines
+
+If you have several =#+TBLFM= lines below a table, =C-c C-c= on a line will
+apply the formulas from this line, and =C-c C-c= on another line will apply
+those other formulas.
+
+**** You now use "nan" for empty fields in Calc formulas
+
+If empty fields are of interest, it is recommended to reread the section
+[[http://orgmode.org/org.html#Formula-syntax-for-Calc][3.5.2 Formula syntax for Calc]] of the manual because the description for the
+mode strings has been clarified and new examples have been added towards
+the end.
+
+**** Handle localized time-stamps in formulas evaluation
+
+If your =LOCALE= is set so that Org time-stamps use another language than
+english, and if you make time computations in Org's table, it now works by
+internally converting the time-stamps with a temporary =LOCALE=C= before
+doing computation.
+
+**** New lookup functions
+
+There are now three lookup functions:
+
+- [[doc:org-loopup-first][org-loopup-first]]
+- [[doc:org-loopup-last][org-loopup-last]]
+- [[doc:org-loopup-all][org-loopup-all]]
+
+See [[http://orgmode.org/org.html#Lookup-functions][the manual]] for details.
+*** Startup keywords
+
+These new startup keywords are now available:
+
+| Startup keyword                  | Option                                      |
+|----------------------------------+---------------------------------------------|
+| =#+STARTUP: logdrawer=           | =(setq org-log-into-drawer t)=              |
+| =#+STARTUP: nologdrawer=         | =(setq org-log-into-drawer nil)=            |
+|----------------------------------+---------------------------------------------|
+| =#+STARTUP: logstatesreversed=   | =(setq org-log-states-order-reversed t)=    |
+| =#+STARTUP: nologstatesreversed= | =(setq org-log-states-order-reversed nil)=  |
+|----------------------------------+---------------------------------------------|
+| =#+STARTUP: latexpreview=        | =(setq org-startup-with-latex-preview t)=   |
+| =#+STARTUP: nolatexpreview=      | =(setq org-startup-with-latex-preview nil)= |
+
+*** Clocking
+
+**** New option [[doc:org-clock-rounding-minutes][org-clock-rounding-minutes]]
+
+E.g. if [[doc:org-clock-rounding-minutes][org-clock-rounding-minutes]] is set to 5, time is 14:47 and you
+clock in: then the clock starts at 14:45.  If you clock out within the next
+5 minutes, the clock line will be removed; if you clock out 8 minutes after
+your clocked in, the clock out time will be 14:50.
+
+**** New option [[doc:org-time-clocksum-use-effort-durations][org-time-clocksum-use-effort-durations]]
+
+When non-nil, =C-c C-x C-d= uses effort durations.  E.g., by default, one
+day is considered to be a 8 hours effort, so a task that has been clocked
+for 16 hours will be displayed as during 2 days in the clock display or in
+the clocktable.
+
+See [[doc:org-effort-durations][org-effort-durations]] on how to set effort durations and
+[[doc:org-time-clocksum-format][org-time-clocksum-format]] for more on time clock formats.
+
+**** New option [[doc:org-clock-x11idle-program-name][org-clock-x11idle-program-name]]
+
+This allows to set the name of the program which prints X11 idle time in
+milliseconds.  The default is to use =x11idle=.
+
+**** New option [[doc:org-use-last-clock-out-time-as-effective-time][org-use-last-clock-out-time-as-effective-time]]
+
+When non-nil, use the last clock out time for [[doc:org-todo][org-todo]].  Note that this
+option has precedence over the combined use of [[doc:org-use-effective-time][org-use-effective-time]] and
+[[doc:org-extend-today-until][org-extend-today-until]].
+
+**** =S-<left/right>= on a clocksum column will update the sum by updating the last clock
+**** =C-u 3 C-S-<up/down>= will update clock timestamps synchronously by 3 units
+**** New parameter =:wstart= for clocktables to define the week start day
+**** New parameter =:mstart= to state the starting day of the month
+**** Allow relative times in clocktable tstart and tend options
+**** The clocktable summary is now a caption
+**** =:tstart= and =:tend= and friends allow relative times like "<-1w>" or "<now>"
+*** Babel
+
+**** You can now use =C-c C-k= for [[doc:org-edit-src-abort][org-edit-src-abort]]
+
+This allows you to quickly cancel editing a source block.
+
+**** =C-u C-u M-x org-babel-tangle RET= tangles by the target file of the block at point
+
+This is handy if you want to tangle all source code blocks that have the
+same target than the block at point.
+
+**** New options for auto-saving the base buffer or the source block editing buffer
+
+When [[doc:org-edit-src-turn-on-auto-save][org-edit-src-turn-on-auto-save]] is set to =t=, editing a source block
+in a new window will turn on =auto-save-mode= and save the code in a new
+file under the same directory than the base Org file.
+
+When [[doc:org-edit-src-auto-save-idle-delay][org-edit-src-auto-save-idle-delay]] is set to a number of minutes =N=,
+the base Org buffer will be saved after this number of minutes of idle
+time.
+
+**** New =:post= header argument post-processes results
+
+     This header argument may be used to pass the results of the current
+     code block through another code block for post-processing.  See the
+     manual for a usage example.
+
+**** Commented out heading are ignored when collecting blocks for tangling
+
+If you comment out a heading (with =C-c ;= anywhere on the heading or in
+the subtree), code blocks from within this heading are now ignored when
+collecting blocks for tangling.
+
+**** New option [[doc:org-babel-hash-show-time][org-babel-hash-show-time]] to show a time-stamp in the result hash
+**** Do not ask for confirmation if cached value is current
+
+Do not run [[doc:org-babel-confirm-evaluate][org-babel-confirm-evaluate]] if source block has a cache and the
+cache value is current as there is no evaluation involved in this case.
+**** =ob-sql.el= and =ob-python.el= have been improved.
+**** New Babel files only need to =(require 'ob)=
+
+When writing a new Babel file, you now only need to use =(require 'ob)=
+instead of requiring each Babel library one by one.
+*** Faces
+
+- Org now fontifies radio link targets by default
+- In the agenda, use [[doc:org-todo-keyword-faces][org-todo-keyword-faces]] to highlight selected TODO keywords
+- New face [[doc:org-priority][org-priority]], enhanced fontification of priority cookies in agenda
+- New face [[doc:org-tag-group][org-tag-group]] for group tags
+
+** Miscellaneous
+
+- New speedy key =s= pour [[doc:org-narrow-to-subtree][org-narrow-to-subtree]]
+- Handling of [[doc:org-html-table-row][org-html-table-row]] has been updated (incompatible change)
+- [[doc:org-export-html-table-tag][org-export-html-table-tag]] is replaced by [[doc:org-html-table-default-attributes][org-html-table-default-attributes]]
+- Support using =git-annex= with Org attachments
+- org-protocol: Pass optional value using query in url to capture from protocol
+- When the refile history is empty, use the current filename as default
+- When you cannot change the TODO state of a task, Org displays the blocking task
+- New option [[doc:org-mobile-allpriorities][org-mobile-allpriorities]]
+- org-bibtex.el now use =visual-line-mode= instead of the deprecated =longlines-mode=
+- [[doc:org-format-latex-options][org-format-latex-options]] allows to set the foreground/background colors automatically
+- New option [[doc:org-archive-file-header-format][org-archive-file-header-format]]
+- New "neg" entity in [[doc:org-entities][org-entities]]
+- New function [[doc:org-docview-export][org-docview-export]] to export docview links
+- New =:eps= header argument for ditaa code blocks
+- New option [[doc:org-gnus-no-server][org-gnus-no-server]] to start Gnus with =gnus-no-server=
+- Org is now distributed with =htmlize.el= version 1.43
+- ~org-drill.el~ has been updated to version 2.3.7
+- ~org-mac-iCal.el~ now supports MacOSX version up to 10.8
+- Various improvements to ~org-contacts.el~ and =orgpan.el=
+
+** Outside Org
+
+*** Spanish translation of the Org guide by David Arroyo Menéndez
+
+David (and others) translated the Org compact guide in spanish:
+
+You can read the [[http://orgmode.org/worg/orgguide/orgguide.es.pdf][PDF guide]].
+
+*** ~poporg.el~ and ~outorg.el~
+
+Two new libraries (~poporg.el~ by François Pinard and ~outorg.el~ by
+Thorsten Jolitz) now enable editing of comment-sections from source-code
+buffers in temporary Org-mode buffers, making the full editing power of
+Org-mode available.  ~outorg.el~ comes together with ~outshine.el~ and
+~navi-mode.el~, two more libraries by Thorsten Jolitz with the goal to give
+source-code buffers the /look & feel/ of Org-mode buffers while greatly
+improving navigation and structure editing.  A detailed description can be
+found here: http://orgmode.org/worg/org-tutorials/org-outside-org.html
+
+Here are two screencasts demonstrating Thorsten's tools:
+
+- [[http://youtu.be/nqE6YxlY0rw]["Modern conventions for Emacs Lisp files"]]
+- [[http://www.youtube.com/watch?v%3DII-xYw5VGFM][Exploring Bernt Hansen's Org-mode tutorial with 'navi-mode']]
+
+*** MobileOrg for iOS
+
+MobileOrg for iOS back in the App Store The 1.6.0 release was focused on
+the new Dropbox API and minor bug fixes but also includes a new ability to
+launch in Capture mode.  Track development and contribute [[https://github.com/MobileOrg/mobileorg/issues][on github]].
+
 * Version 7.9.3
 * Version 7.9.3
 
 
 ** New option [[doc::org-agenda-use-tag-inheritance][org-agenda-use-tag-inheritance]]
 ** New option [[doc::org-agenda-use-tag-inheritance][org-agenda-use-tag-inheritance]]

+ 6 - 0
etc/styles/OrgOdtStyles.xml

@@ -256,6 +256,9 @@
   <style:style style:name="Quotations" style:family="paragraph" style:parent-style-name="Standard" style:class="html">
   <style:style style:name="Quotations" style:family="paragraph" style:parent-style-name="Standard" style:class="html">
    <style:paragraph-properties fo:margin-left="1cm" fo:margin-right="1cm" fo:margin-top="0cm" fo:margin-bottom="0.499cm" fo:text-indent="0cm" style:auto-text-indent="false"/>
    <style:paragraph-properties fo:margin-left="1cm" fo:margin-right="1cm" fo:margin-top="0cm" fo:margin-bottom="0.499cm" fo:text-indent="0cm" style:auto-text-indent="false"/>
   </style:style>
   </style:style>
+  <style:style style:name="OrgFootnoteQuotations" style:family="paragraph" style:parent-style-name="Footnote" style:class="html">
+   <style:paragraph-properties fo:margin-left="1cm" fo:margin-right="1cm" fo:margin-top="0cm" fo:margin-bottom="0.499cm" fo:text-indent="0cm" style:auto-text-indent="false"/>
+  </style:style>
   <style:style style:name="Preformatted_20_Text" style:display-name="Preformatted Text" style:family="paragraph" style:parent-style-name="Standard" style:class="html">
   <style:style style:name="Preformatted_20_Text" style:display-name="Preformatted Text" style:family="paragraph" style:parent-style-name="Standard" style:class="html">
    <style:paragraph-properties fo:margin-top="0cm" fo:margin-bottom="0cm"/>
    <style:paragraph-properties fo:margin-top="0cm" fo:margin-bottom="0cm"/>
    <style:text-properties style:font-name="Courier New" fo:font-size="10pt" style:font-name-asian="NSimSun" style:font-size-asian="10pt" style:font-name-complex="Courier New" style:font-size-complex="10pt"/>
    <style:text-properties style:font-name="Courier New" fo:font-size="10pt" style:font-name-asian="NSimSun" style:font-size-asian="10pt" style:font-name-complex="Courier New" style:font-size-complex="10pt"/>
@@ -298,6 +301,9 @@
   <style:style style:name="OrgCenter" style:family="paragraph" style:parent-style-name="Text_20_body">
   <style:style style:name="OrgCenter" style:family="paragraph" style:parent-style-name="Text_20_body">
    <style:paragraph-properties fo:text-align="center" style:justify-single-word="false"/>
    <style:paragraph-properties fo:text-align="center" style:justify-single-word="false"/>
   </style:style>
   </style:style>
+  <style:style style:name="OrgFootnoteCenter" style:family="paragraph" style:parent-style-name="Footnote">
+   <style:paragraph-properties fo:text-align="center" style:justify-single-word="false"/>
+  </style:style>
   <style:style style:name="OrgTableContents" style:family="paragraph" style:parent-style-name="Text_20_body"/>
   <style:style style:name="OrgTableContents" style:family="paragraph" style:parent-style-name="Text_20_body"/>
   <style:style style:name="OrgTableHeading" style:family="paragraph" style:parent-style-name="OrgTableContents" style:class="extra">
   <style:style style:name="OrgTableHeading" style:family="paragraph" style:parent-style-name="OrgTableContents" style:class="extra">
     <style:paragraph-properties fo:text-align="center" style:justify-single-word="false" text:number-lines="false" text:line-number="0"/>
     <style:paragraph-properties fo:text-align="center" style:justify-single-word="false" text:number-lines="false" text:line-number="0"/>

+ 1 - 1
lisp/Makefile

@@ -89,5 +89,5 @@ clean cleanall cleanelc::
 
 
 clean-install:
 clean-install:
 	if [ -d $(DESTDIR)$(lispdir) ] ; then \
 	if [ -d $(DESTDIR)$(lispdir) ] ; then \
-	  $(RM) $(DESTDIR)$(lispdir)/org*.el* $(DESTDIR)$(lispdir)/ob*.el* ; \
+	  $(RM) $(DESTDIR)$(lispdir)/org*.el* $(DESTDIR)$(lispdir)/ob*.el* $(DESTDIR)$(lispdir)/ox*.el* ; \
 	fi ;
 	fi ;

+ 73 - 25
lisp/ob-C.el

@@ -44,24 +44,24 @@
 
 
 (defvar org-babel-C-compiler "gcc"
 (defvar org-babel-C-compiler "gcc"
   "Command used to compile a C source code file into an
   "Command used to compile a C source code file into an
-  executable.")
+executable.")
 
 
 (defvar org-babel-C++-compiler "g++"
 (defvar org-babel-C++-compiler "g++"
   "Command used to compile a C++ source code file into an
   "Command used to compile a C++ source code file into an
-  executable.")
+executable.")
 
 
 (defvar org-babel-c-variant nil
 (defvar org-babel-c-variant nil
   "Internal variable used to hold which type of C (e.g. C or C++)
   "Internal variable used to hold which type of C (e.g. C or C++)
 is currently being evaluated.")
 is currently being evaluated.")
 
 
 (defun org-babel-execute:cpp (body params)
 (defun org-babel-execute:cpp (body params)
-  "Execute BODY according to PARAMS.  This function calls
-`org-babel-execute:C++'."
+  "Execute BODY according to PARAMS.
+This function calls `org-babel-execute:C++'."
   (org-babel-execute:C++ body params))
   (org-babel-execute:C++ body params))
 
 
 (defun org-babel-execute:C++ (body params)
 (defun org-babel-execute:C++ (body params)
-  "Execute a block of C++ code with org-babel.  This function is
-called by `org-babel-execute-src-block'."
+  "Execute a block of C++ code with org-babel.
+This function is called by `org-babel-execute-src-block'."
   (let ((org-babel-c-variant 'cpp)) (org-babel-C-execute body params)))
   (let ((org-babel-c-variant 'cpp)) (org-babel-C-execute body params)))
 
 
 (defun org-babel-expand-body:C++ (body params)
 (defun org-babel-expand-body:C++ (body params)
@@ -70,8 +70,8 @@ header arguments (calls `org-babel-C-expand')."
   (let ((org-babel-c-variant 'cpp)) (org-babel-C-expand body params)))
   (let ((org-babel-c-variant 'cpp)) (org-babel-C-expand body params)))
 
 
 (defun org-babel-execute:C (body params)
 (defun org-babel-execute:C (body params)
-  "Execute a block of C code with org-babel.  This function is
-called by `org-babel-execute-src-block'."
+  "Execute a block of C code with org-babel.
+This function is called by `org-babel-execute-src-block'."
   (let ((org-babel-c-variant 'c)) (org-babel-C-execute body params)))
   (let ((org-babel-c-variant 'c)) (org-babel-C-execute body params)))
 
 
 (defun org-babel-expand-body:c (body params)
 (defun org-babel-expand-body:c (body params)
@@ -146,10 +146,10 @@ it's header arguments."
 		  body) "\n") "\n")))
 		  body) "\n") "\n")))
 
 
 (defun org-babel-C-ensure-main-wrap (body)
 (defun org-babel-C-ensure-main-wrap (body)
-  "Wrap body in a \"main\" function call if none exists."
+  "Wrap BODY in a \"main\" function call if none exists."
   (if (string-match "^[ \t]*[intvod]+[ \t\n\r]*main[ \t]*(.*)" body)
   (if (string-match "^[ \t]*[intvod]+[ \t\n\r]*main[ \t]*(.*)" body)
       body
       body
-    (format "int main() {\n%s\nreturn(0);\n}\n" body)))
+    (format "int main() {\n%s\nreturn 0;\n}\n" body)))
 
 
 (defun org-babel-prep-session:C (session params)
 (defun org-babel-prep-session:C (session params)
   "This function does nothing as C is a compiled language with no
   "This function does nothing as C is a compiled language with no
@@ -163,6 +163,59 @@ support for sessions"
 
 
 ;; helper functions
 ;; helper functions
 
 
+(defun org-babel-C-format-val (type val)
+  "Handle the FORMAT part of TYPE with the data from VAL."
+  (let ((format-data (cadr type)))
+    (if (stringp format-data)
+	(cons "" (format format-data val))
+      (funcall format-data val))))
+
+(defun org-babel-C-val-to-C-type (val)
+  "Determine the type of VAL.
+Return a list (TYPE-NAME FORMAT).  TYPE-NAME should be the name of the type.
+FORMAT can be either a format string or a function which is called with VAL."
+  (cond
+   ((integerp val) '("int" "%d"))
+   ((floatp val) '("double" "%f"))
+   ((or (listp val) (vectorp val))
+    (lexical-let ((type (org-babel-C-val-to-C-list-type val)))
+      (list (car type)
+	    (lambda (val)
+	      (cons
+	       (format "[%d]%s"
+		       (length val)
+		       (car (org-babel-C-format-val type (elt val 0))))
+	       (concat "{ "
+		       (mapconcat (lambda (v)
+				    (cdr (org-babel-C-format-val type v)))
+				  val
+				  ", ")
+		       " }"))))))
+   (t ;; treat unknown types as string
+    '("char" (lambda (val)
+	       (let ((s (format "%s" val))) ;; convert to string for unknown types
+		 (cons (format "[%d]" (1+ (length s)))
+		       (concat "\"" s "\""))))))))
+
+(defun org-babel-C-val-to-C-list-type (val)
+  "Determine the C array type of a VAL."
+  (let (type)
+    (mapc
+     #'(lambda (i)
+	 (let* ((tmp-type (org-babel-C-val-to-C-type i))
+		(type-name (car type))
+		(tmp-type-name (car tmp-type)))
+	   (when (and type (not (string= type-name tmp-type-name)))
+	     (if (and (member type-name '("int" "double" "int32_t"))
+		      (member tmp-type-name '("int" "double" "int32_t")))
+		 (setq tmp-type '("double" "" "%f"))
+	       (error "Only homogeneous lists are supported by C.  You can not mix %s and %s"
+		      type-name
+		      tmp-type-name)))
+	   (setq type tmp-type)))
+     val)
+    type))
+
 (defun org-babel-C-var-to-C (pair)
 (defun org-babel-C-var-to-C (pair)
   "Convert an elisp val into a string of C code specifying a var
   "Convert an elisp val into a string of C code specifying a var
 of the same value."
 of the same value."
@@ -173,22 +226,17 @@ of the same value."
       (setq val (symbol-name val))
       (setq val (symbol-name val))
       (when (= (length val) 1)
       (when (= (length val) 1)
         (setq val (string-to-char val))))
         (setq val (string-to-char val))))
-    (cond
-     ((integerp val)
-      (format "int %S = %S;" var val))
-     ((floatp val)
-      (format "double %S = %S;" var val))
-     ((or (integerp val))
-      (format "char %S = '%S';" var val))
-     ((stringp val)
-      (format "char %S[%d] = \"%s\";"
-              var (+ 1 (length val)) val))
-     (t
-      (format "u32 %S = %S;" var val)))))
-
+    (let* ((type-data (org-babel-C-val-to-C-type val))
+	   (type (car type-data))
+	   (formated (org-babel-C-format-val type-data val))
+	   (suffix (car formated))
+	   (data (cdr formated)))
+      (format "%s %s%s = %s;"
+	      type
+	      var
+	      suffix
+	      data))))
 
 
 (provide 'ob-C)
 (provide 'ob-C)
 
 
-
-
 ;;; ob-C.el ends here
 ;;; ob-C.el ends here

+ 35 - 23
lisp/ob-R.el

@@ -209,6 +209,9 @@ This function is called by `org-babel-execute-src-block'."
       (if (org-babel-comint-buffer-livep session)
       (if (org-babel-comint-buffer-livep session)
 	  session
 	  session
 	(save-window-excursion
 	(save-window-excursion
+	  (when (get-buffer session)
+	    ;; Session buffer exists, but with dead process
+	    (set-buffer session))
 	  (require 'ess) (R)
 	  (require 'ess) (R)
 	  (rename-buffer
 	  (rename-buffer
 	   (if (bufferp session)
 	   (if (bufferp session)
@@ -231,31 +234,40 @@ current code buffer."
   (and (member "graphics" (cdr (assq :result-params params)))
   (and (member "graphics" (cdr (assq :result-params params)))
        (cdr (assq :file params))))
        (cdr (assq :file params))))
 
 
+(defvar org-babel-R-graphics-devices
+  '((:bmp "bmp" "filename")
+    (:jpg "jpeg" "filename")
+    (:jpeg "jpeg" "filename")
+    (:tikz "tikz" "file")
+    (:tiff "tiff" "filename")
+    (:png "png" "filename")
+    (:svg "svg" "file")
+    (:pdf "pdf" "file")
+    (:ps "postscript" "file")
+    (:postscript "postscript" "file"))
+  "An alist mapping graphics file types to R functions.
+
+Each member of this list is a list with three members:
+1. the file extension of the graphics file, as an elisp :keyword
+2. the R graphics device function to call to generate such a file
+3. the name of the argument to this function which specifies the
+   file to write to (typically \"file\" or \"filename\")")
+
 (defun org-babel-R-construct-graphics-device-call (out-file params)
 (defun org-babel-R-construct-graphics-device-call (out-file params)
   "Construct the call to the graphics device."
   "Construct the call to the graphics device."
-  (let ((devices
-	 '((:bmp . "bmp")
-	   (:jpg . "jpeg")
-	   (:jpeg . "jpeg")
-	   (:tikz . "tikz")
-	   (:tiff . "tiff")
-	   (:png . "png")
-	   (:svg . "svg")
-	   (:pdf . "pdf")
-	   (:ps . "postscript")
-	   (:postscript . "postscript")))
-	(allowed-args '(:width :height :bg :units :pointsize
-			       :antialias :quality :compression :res
-			       :type :family :title :fonts :version
-			       :paper :encoding :pagecentre :colormodel
-			       :useDingbats :horizontal))
-	(device (and (string-match ".+\\.\\([^.]+\\)" out-file)
-		     (match-string 1 out-file)))
-	(extra-args (cdr (assq :R-dev-args params))) filearg args)
-    (setq device (or (and device (cdr (assq (intern (concat ":" device))
-					    devices))) "png"))
-    (setq filearg
-	  (if (member device '("pdf" "postscript" "svg" "tikz")) "file" "filename"))
+  (let* ((allowed-args '(:width :height :bg :units :pointsize
+				:antialias :quality :compression :res
+				:type :family :title :fonts :version
+				:paper :encoding :pagecentre :colormodel
+				:useDingbats :horizontal))
+	 (device (and (string-match ".+\\.\\([^.]+\\)" out-file)
+		      (match-string 1 out-file)))
+	 (device-info (or (assq (intern (concat ":" device))
+				org-babel-R-graphics-devices)
+                          (assq :png org-babel-R-graphics-devices)))
+        (extra-args (cdr (assq :R-dev-args params))) filearg args)
+    (setq device (nth 1 device-info))
+    (setq filearg (nth 2 device-info))
     (setq args (mapconcat
     (setq args (mapconcat
 		(lambda (pair)
 		(lambda (pair)
 		  (if (member (car pair) allowed-args)
 		  (if (member (car pair) allowed-args)

+ 1 - 1
lisp/ob-awk.el

@@ -44,7 +44,7 @@
 (defvar org-babel-awk-command "awk"
 (defvar org-babel-awk-command "awk"
   "Name of the awk executable command.")
   "Name of the awk executable command.")
 
 
-(defun org-babel-expand-body:awk (body params &optional processed-params)
+(defun org-babel-expand-body:awk (body params)
   "Expand BODY according to PARAMS, return the expanded body."
   "Expand BODY according to PARAMS, return the expanded body."
   (dolist (pair (mapcar #'cdr (org-babel-get-header params :var)))
   (dolist (pair (mapcar #'cdr (org-babel-get-header params :var)))
     (setf body (replace-regexp-in-string
     (setf body (replace-regexp-in-string

+ 1 - 1
lisp/ob-comint.el

@@ -117,7 +117,7 @@ or user `keyboard-quit' during execution of body."
 		   string-buffer))
 		   string-buffer))
 	     (setq raw (substring string-buffer (match-end 0))))
 	     (setq raw (substring string-buffer (match-end 0))))
 	 (split-string string-buffer comint-prompt-regexp)))))
 	 (split-string string-buffer comint-prompt-regexp)))))
-(def-edebug-spec org-babel-comint-with-output (form body))
+(def-edebug-spec org-babel-comint-with-output (sexp body))
 
 
 (defun org-babel-comint-input-command (buffer cmd)
 (defun org-babel-comint-input-command (buffer cmd)
   "Pass CMD to BUFFER.
   "Pass CMD to BUFFER.

+ 170 - 108
lisp/ob-core.el

@@ -1,6 +1,6 @@
 ;;; ob-core.el --- working with code blocks in org-mode
 ;;; ob-core.el --- working with code blocks in org-mode
 
 
-;; Copyright (C) 2009-2012  Free Software Foundation, Inc.
+;; Copyright (C) 2009-2013  Free Software Foundation, Inc.
 
 
 ;; Authors: Eric Schulte
 ;; Authors: Eric Schulte
 ;;	Dan Davison
 ;;	Dan Davison
@@ -152,6 +152,12 @@ See also `org-babel-noweb-wrap-start'."
   :group 'org-babel
   :group 'org-babel
   :type 'string)
   :type 'string)
 
 
+(defcustom org-babel-inline-result-wrap "=%s="
+  "Format string used to wrap inline results.
+This string must include a \"%s\" which will be replaced by the results."
+  :group 'org-babel
+  :type 'string)
+
 (defun org-babel-noweb-wrap (&optional regexp)
 (defun org-babel-noweb-wrap (&optional regexp)
   (concat org-babel-noweb-wrap-start
   (concat org-babel-noweb-wrap-start
 	  (or regexp "\\([^ \t\n].+?[^ \t]\\|[^ \t\n]\\)")
 	  (or regexp "\\([^ \t\n].+?[^ \t]\\|[^ \t\n]\\)")
@@ -170,7 +176,7 @@ See also `org-babel-noweb-wrap-start'."
 	  "\\("
 	  "\\("
 	  org-babel-multi-line-header-regexp
 	  org-babel-multi-line-header-regexp
 	  "\\)*"
 	  "\\)*"
-	  "\\([^ ()\f\t\n\r\v]+\\)\\(\(\\(.*\\)\)\\|\\)")
+	  "\\([^ ()\f\t\n\r\v]+\\)")
   "Regular expression matching source name lines with a name.")
   "Regular expression matching source name lines with a name.")
 
 
 (defvar org-babel-src-block-regexp
 (defvar org-babel-src-block-regexp
@@ -245,14 +251,14 @@ references; a process which could likely result in the execution
 of other code blocks.
 of other code blocks.
 
 
 Returns a list
 Returns a list
- (language body header-arguments-alist switches name indent)."
+ (language body header-arguments-alist switches name indent block-head)."
   (let ((case-fold-search t) head info name indent)
   (let ((case-fold-search t) head info name indent)
     ;; full code block
     ;; full code block
     (if (setq head (org-babel-where-is-src-block-head))
     (if (setq head (org-babel-where-is-src-block-head))
 	(save-excursion
 	(save-excursion
 	  (goto-char head)
 	  (goto-char head)
 	  (setq info (org-babel-parse-src-block-match))
 	  (setq info (org-babel-parse-src-block-match))
-	  (setq indent (car (last info)))
+	  (setq indent (nth 5 info))
 	  (setq info (butlast info))
 	  (setq info (butlast info))
 	  (while (and (forward-line -1)
 	  (while (and (forward-line -1)
 		      (looking-at org-babel-multi-line-header-regexp))
 		      (looking-at org-babel-multi-line-header-regexp))
@@ -261,28 +267,14 @@ Returns a list
 		   (nth 2 info)
 		   (nth 2 info)
 		   (org-babel-parse-header-arguments (match-string 1)))))
 		   (org-babel-parse-header-arguments (match-string 1)))))
 	  (when (looking-at org-babel-src-name-w-name-regexp)
 	  (when (looking-at org-babel-src-name-w-name-regexp)
-	    (setq name (org-no-properties (match-string 3)))
-	    (when (and (match-string 5) (> (length (match-string 5)) 0))
-	      (setf (nth 2 info) ;; merge functional-syntax vars and header-args
-		    (org-babel-merge-params
-		     (mapcar
-		      (lambda (ref) (cons :var ref))
-		      (mapcar
-		       (lambda (var) ;; check that each variable is initialized
-			 (if (string-match ".+=.+" var)
-			     var
-			   (error
-			    "variable \"%s\"%s must be assigned a default value"
-			    var (if name (format " in block \"%s\"" name) ""))))
-		       (org-babel-ref-split-args (match-string 5))))
-		     (nth 2 info))))))
+	    (setq name (org-no-properties (match-string 3)))))
       ;; inline source block
       ;; inline source block
       (when (org-babel-get-inline-src-block-matches)
       (when (org-babel-get-inline-src-block-matches)
 	(setq info (org-babel-parse-inline-src-block-match))))
 	(setq info (org-babel-parse-inline-src-block-match))))
     ;; resolve variable references and add summary parameters
     ;; resolve variable references and add summary parameters
     (when (and info (not light))
     (when (and info (not light))
       (setf (nth 2 info) (org-babel-process-params (nth 2 info))))
       (setf (nth 2 info) (org-babel-process-params (nth 2 info))))
-    (when info (append info (list name indent)))))
+    (when info (append info (list name indent head)))))
 
 
 (defvar org-current-export-file) ; dynamically bound
 (defvar org-current-export-file) ; dynamically bound
 (defmacro org-babel-check-confirm-evaluate (info &rest body)
 (defmacro org-babel-check-confirm-evaluate (info &rest body)
@@ -331,7 +323,7 @@ Do not query the user."
 (defsubst org-babel-confirm-evaluate (info)
 (defsubst org-babel-confirm-evaluate (info)
   "Confirm evaluation of the code block INFO.
   "Confirm evaluation of the code block INFO.
 
 
-If the variable `org-babel-confirm-evaluate-answer-no´ is bound
+If the variable `org-babel-confirm-evaluate-answer-no' is bound
 to a non-nil value, auto-answer with \"no\".
 to a non-nil value, auto-answer with \"no\".
 
 
 This query can also be suppressed by setting the value of
 This query can also be suppressed by setting the value of
@@ -365,15 +357,25 @@ of potentially harmful code."
   (or (org-babel-execute-src-block-maybe)
   (or (org-babel-execute-src-block-maybe)
       (org-babel-lob-execute-maybe)))
       (org-babel-lob-execute-maybe)))
 
 
+(defmacro org-babel-when-in-src-block (&rest body)
+  "Execute BODY if point is in a source block and return t.
+
+Otherwise do nothing and return nil."
+  `(if (or (org-babel-where-is-src-block-head)
+           (org-babel-get-inline-src-block-matches))
+       (progn
+	 ,@body
+	 t)
+     nil))
+
 (defun org-babel-execute-src-block-maybe ()
 (defun org-babel-execute-src-block-maybe ()
   "Conditionally execute a source block.
   "Conditionally execute a source block.
 Detect if this is context for a Babel src-block and if so
 Detect if this is context for a Babel src-block and if so
 then run `org-babel-execute-src-block'."
 then run `org-babel-execute-src-block'."
   (interactive)
   (interactive)
-  (let ((info (org-babel-get-src-block-info)))
-    (if info
-	(progn (org-babel-eval-wipe-error-buffer)
-	       (org-babel-execute-src-block current-prefix-arg info) t) nil)))
+  (org-babel-when-in-src-block
+   (org-babel-eval-wipe-error-buffer)
+   (org-babel-execute-src-block current-prefix-arg)))
 
 
 ;;;###autoload
 ;;;###autoload
 (defun org-babel-view-src-block-info ()
 (defun org-babel-view-src-block-info ()
@@ -409,10 +411,8 @@ a window into the `org-babel-get-src-block-info' function."
 Detect if this is context for a org-babel src-block and if so
 Detect if this is context for a org-babel src-block and if so
 then run `org-babel-expand-src-block'."
 then run `org-babel-expand-src-block'."
   (interactive)
   (interactive)
-  (let ((info (org-babel-get-src-block-info)))
-    (if info
-	(progn (org-babel-expand-src-block current-prefix-arg info) t)
-      nil)))
+  (org-babel-when-in-src-block
+   (org-babel-expand-src-block current-prefix-arg)))
 
 
 ;;;###autoload
 ;;;###autoload
 (defun org-babel-load-in-session-maybe ()
 (defun org-babel-load-in-session-maybe ()
@@ -420,10 +420,8 @@ then run `org-babel-expand-src-block'."
 Detect if this is context for a org-babel src-block and if so
 Detect if this is context for a org-babel src-block and if so
 then run `org-babel-load-in-session'."
 then run `org-babel-load-in-session'."
   (interactive)
   (interactive)
-  (let ((info (org-babel-get-src-block-info)))
-    (if info
-	(progn (org-babel-load-in-session current-prefix-arg info) t)
-      nil)))
+  (org-babel-when-in-src-block
+   (org-babel-load-in-session current-prefix-arg)))
 
 
 (add-hook 'org-metaup-hook 'org-babel-load-in-session-maybe)
 (add-hook 'org-metaup-hook 'org-babel-load-in-session-maybe)
 
 
@@ -431,10 +429,10 @@ then run `org-babel-load-in-session'."
 (defun org-babel-pop-to-session-maybe ()
 (defun org-babel-pop-to-session-maybe ()
   "Conditionally pop to a session.
   "Conditionally pop to a session.
 Detect if this is context for a org-babel src-block and if so
 Detect if this is context for a org-babel src-block and if so
-then run `org-babel-pop-to-session'."
+then run `org-babel-switch-to-session'."
   (interactive)
   (interactive)
-  (let ((info (org-babel-get-src-block-info)))
-    (if info (progn (org-babel-pop-to-session current-prefix-arg info) t) nil)))
+  (org-babel-when-in-src-block
+   (org-babel-switch-to-session current-prefix-arg)))
 
 
 (add-hook 'org-metadown-hook 'org-babel-pop-to-session-maybe)
 (add-hook 'org-metadown-hook 'org-babel-pop-to-session-maybe)
 
 
@@ -446,6 +444,7 @@ then run `org-babel-pop-to-session'."
     (dir	. :any)
     (dir	. :any)
     (eval	. ((never query)))
     (eval	. ((never query)))
     (exports	. ((code results both none)))
     (exports	. ((code results both none)))
+    (epilogue   . :any)
     (file	. :any)
     (file	. :any)
     (file-desc  . :any)
     (file-desc  . :any)
     (hlines	. ((no yes)))
     (hlines	. ((no yes)))
@@ -456,6 +455,8 @@ then run `org-babel-pop-to-session'."
     (noweb-ref	. :any)
     (noweb-ref	. :any)
     (noweb-sep  . :any)
     (noweb-sep  . :any)
     (padline	. ((yes no)))
     (padline	. ((yes no)))
+    (post       . :any)
+    (prologue   . :any)
     (results	. ((file list vector table scalar verbatim)
     (results	. ((file list vector table scalar verbatim)
 		   (raw html latex org code pp drawer)
 		   (raw html latex org code pp drawer)
 		   (replace silent none append prepend)
 		   (replace silent none append prepend)
@@ -465,6 +466,7 @@ then run `org-babel-pop-to-session'."
     (session	. :any)
     (session	. :any)
     (shebang	. :any)
     (shebang	. :any)
     (tangle	. ((tangle yes no :any)))
     (tangle	. ((tangle yes no :any)))
+    (tangle-mode . ((#o755 #o555 #o444 :any)))
     (var	. :any)
     (var	. :any)
     (wrap       . :any)))
     (wrap       . :any)))
 
 
@@ -519,7 +521,7 @@ can not be resolved.")
   "Number of initial characters to show of a hidden results hash.")
   "Number of initial characters to show of a hidden results hash.")
 
 
 (defvar org-babel-hash-show-time nil
 (defvar org-babel-hash-show-time nil
-  "When not nil show the time the code block was evaluated in the result hash.")
+  "Non-nil means show the time the code block was evaluated in the result hash.")
 
 
 (defvar org-babel-after-execute-hook nil
 (defvar org-babel-after-execute-hook nil
   "Hook for functions to be called after `org-babel-execute-src-block'")
   "Hook for functions to be called after `org-babel-execute-src-block'")
@@ -536,6 +538,12 @@ can not be resolved.")
 
 
 ;;; functions
 ;;; functions
 (defvar call-process-region)
 (defvar call-process-region)
+(defvar org-babel-current-src-block-location nil
+  "Marker pointing to the src block currently being executed.
+This may also point to a call line or an inline code block.  If
+multiple blocks are being executed (e.g., in chained execution
+through use of the :var header argument) this marker points to
+the outer-most code block.")
 
 
 ;;;###autoload
 ;;;###autoload
 (defun org-babel-execute-src-block (&optional arg info params)
 (defun org-babel-execute-src-block (&optional arg info params)
@@ -554,13 +562,17 @@ Optionally supply a value for PARAMS which will be merged with
 the header arguments specified at the front of the source code
 the header arguments specified at the front of the source code
 block."
 block."
   (interactive)
   (interactive)
-  (let* ((info (or info (org-babel-get-src-block-info)))
+  (let* ((info (if info
+		   (copy-tree info)
+		 (org-babel-get-src-block-info)))
 	 (merged-params (org-babel-merge-params (nth 2 info) params)))
 	 (merged-params (org-babel-merge-params (nth 2 info) params)))
     (when (org-babel-check-evaluate
     (when (org-babel-check-evaluate
 	   (let ((i info)) (setf (nth 2 i) merged-params) i))
 	   (let ((i info)) (setf (nth 2 i) merged-params) i))
       (let* ((params (if params
       (let* ((params (if params
 			 (org-babel-process-params merged-params)
 			 (org-babel-process-params merged-params)
 		       (nth 2 info)))
 		       (nth 2 info)))
+	     (org-babel-current-src-block-location
+	      (or org-babel-current-src-block-location (nth 6 info)))
 	     (cachep (and (not arg) (cdr (assoc :cache params))
 	     (cachep (and (not arg) (cdr (assoc :cache params))
 			   (string= "yes" (cdr (assoc :cache params)))))
 			   (string= "yes" (cdr (assoc :cache params)))))
 	     (new-hash (when cachep (org-babel-sha1-hash info)))
 	     (new-hash (when cachep (org-babel-sha1-hash info)))
@@ -591,7 +603,7 @@ block."
 		  (or (org-bound-and-true-p
 		  (or (org-bound-and-true-p
 		       org-babel-call-process-region-original)
 		       org-babel-call-process-region-original)
 		      (symbol-function 'call-process-region)))
 		      (symbol-function 'call-process-region)))
-		 (indent (car (last info)))
+		 (indent (nth 5 info))
 		 result cmd)
 		 result cmd)
 	    (unwind-protect
 	    (unwind-protect
 		(let ((call-process-region
 		(let ((call-process-region
@@ -615,7 +627,8 @@ block."
 		  (if (member "none" result-params)
 		  (if (member "none" result-params)
 		      (progn
 		      (progn
 			(funcall cmd body params)
 			(funcall cmd body params)
-			(message "result silenced"))
+			(message "result silenced")
+			(setq result nil))
 		    (setq result
 		    (setq result
 			  ((lambda (result)
 			  ((lambda (result)
 			     (if (and (eq (cdr (assoc :result-type params))
 			     (if (and (eq (cdr (assoc :result-type params))
@@ -633,10 +646,24 @@ block."
 			   (org-babel-format-result
 			   (org-babel-format-result
 			    result (cdr (assoc :sep (nth 2 info)))))))
 			    result (cdr (assoc :sep (nth 2 info)))))))
 		      (setq result (cdr (assoc :file params))))
 		      (setq result (cdr (assoc :file params))))
+		    ;; possibly perform post process provided its appropriate
+		    (when (cdr (assoc :post params))
+		      (let ((*this* (if (cdr (assoc :file params))
+					(org-babel-result-to-file
+					 (cdr (assoc :file params))
+					 (when (assoc :file-desc params)
+					   (or (cdr (assoc :file-desc params))
+					       result)))
+				      result)))
+			(setq result (org-babel-ref-resolve
+				      (cdr (assoc :post params))))
+			(when (cdr (assoc :file params))
+			  (setq result-params
+				(remove "file" result-params)))))
 		    (org-babel-insert-result
 		    (org-babel-insert-result
-		     result result-params info new-hash indent lang)
-		    (run-hooks 'org-babel-after-execute-hook)
-		    result))
+		     result result-params info new-hash indent lang))
+                  (run-hooks 'org-babel-after-execute-hook)
+		  result)
 	      (setq call-process-region
 	      (setq call-process-region
 		    'org-babel-call-process-region-original)))))))))
 		    'org-babel-call-process-region-original)))))))))
 
 
@@ -646,7 +673,14 @@ Expand a block of code with org-babel according to its header
 arguments.  This generic implementation of body expansion is
 arguments.  This generic implementation of body expansion is
 called for languages which have not defined their own specific
 called for languages which have not defined their own specific
 org-babel-expand-body:lang function."
 org-babel-expand-body:lang function."
-  (mapconcat #'identity (append var-lines (list body)) "\n"))
+  (let ((pro (cdr (assoc :prologue params)))
+	(epi (cdr (assoc :epilogue params))))
+    (mapconcat #'identity
+	       (append (when pro (list pro))
+		       var-lines
+		       (list body)
+		       (when epi (list epi)))
+	       "\n")))
 
 
 ;;;###autoload
 ;;;###autoload
 (defun org-babel-expand-src-block (&optional arg info params)
 (defun org-babel-expand-src-block (&optional arg info params)
@@ -671,7 +705,7 @@ arguments and pop open the results in a preview buffer."
 	    (org-babel-expand-body:generic
 	    (org-babel-expand-body:generic
 	     body params (and (fboundp assignments-cmd)
 	     body params (and (fboundp assignments-cmd)
 			      (funcall assignments-cmd params))))))
 			      (funcall assignments-cmd params))))))
-    (if (called-interactively-p 'any)
+    (if (org-called-interactively-p 'any)
 	(org-edit-src-code
 	(org-edit-src-code
 	 nil expanded
 	 nil expanded
 	 (concat "*Org-Babel Preview " (buffer-name) "[ " lang " ]*"))
 	 (concat "*Org-Babel Preview " (buffer-name) "[ " lang " ]*"))
@@ -741,7 +775,7 @@ arguments and pop open the results in a preview buffer."
 	 (lang-headers (intern (concat "org-babel-header-args:" lang)))
 	 (lang-headers (intern (concat "org-babel-header-args:" lang)))
 	 (headers (org-babel-combine-header-arg-lists
 	 (headers (org-babel-combine-header-arg-lists
 		   org-babel-common-header-args-w-values
 		   org-babel-common-header-args-w-values
-		   (if (boundp lang-headers) (eval lang-headers) nil)))
+		   (when (boundp lang-headers) (eval lang-headers))))
 	 (arg (org-icompleting-read
 	 (arg (org-icompleting-read
 	       "Header Arg: "
 	       "Header Arg: "
 	       (mapcar
 	       (mapcar
@@ -909,7 +943,7 @@ source code block, otherwise return nil.  With optional prefix
 argument RE-RUN the source-code block is evaluated even if
 argument RE-RUN the source-code block is evaluated even if
 results already exist."
 results already exist."
   (interactive "P")
   (interactive "P")
-  (let ((info (org-babel-get-src-block-info)))
+  (let ((info (org-babel-get-src-block-info 'light)))
     (when info
     (when info
       (save-excursion
       (save-excursion
 	;; go to the results, if there aren't any then run the block
 	;; go to the results, if there aren't any then run the block
@@ -1266,26 +1300,38 @@ portions of results lines."
 (defvar org-file-properties)
 (defvar org-file-properties)
 (defun org-babel-params-from-properties (&optional lang)
 (defun org-babel-params-from-properties (&optional lang)
   "Retrieve parameters specified as properties.
   "Retrieve parameters specified as properties.
-Return an association list of any source block params which
-may be specified in the properties of the current outline entry."
+Return a list of association lists of source block params
+specified in the properties of the current outline entry."
   (save-match-data
   (save-match-data
-    (let (val sym)
-      (org-babel-parse-multiple-vars
-       (delq nil
-	     (mapcar
-	      (lambda (header-arg)
-		(and (setq val (org-entry-get (point) header-arg t))
-		     (cons (intern (concat ":" header-arg))
-			   (org-babel-read val))))
+    (list
+     ;; DEPRECATED header arguments specified as separate property at
+     ;; point of definition
+     (let (val sym)
+       (org-babel-parse-multiple-vars
+	(delq nil
 	      (mapcar
 	      (mapcar
-	       #'symbol-name
+	       (lambda (header-arg)
+		 (and (setq val (org-entry-get (point) header-arg t))
+		      (cons (intern (concat ":" header-arg))
+			    (org-babel-read val))))
 	       (mapcar
 	       (mapcar
-		#'car
-		(org-babel-combine-header-arg-lists
-		 org-babel-common-header-args-w-values
-		 (progn
-		   (setq sym (intern (concat "org-babel-header-args:" lang)))
-		   (and (boundp sym) (eval sym))))))))))))
+		#'symbol-name
+		(mapcar
+		 #'car
+		 (org-babel-combine-header-arg-lists
+		  org-babel-common-header-args-w-values
+		  (progn
+		    (setq sym (intern (concat "org-babel-header-args:" lang)))
+		    (and (boundp sym) (eval sym))))))))))
+     ;; header arguments specified with the header-args property at
+     ;; point of call
+     (org-babel-parse-header-arguments
+      (org-entry-get org-babel-current-src-block-location
+		     "header-args" 'inherit))
+     (when lang ;; language-specific header arguments at point of call
+	 (org-babel-parse-header-arguments
+	  (org-entry-get org-babel-current-src-block-location
+			 (concat "header-args:" lang) 'inherit))))))
 
 
 (defvar org-src-preserve-indentation)
 (defvar org-src-preserve-indentation)
 (defun org-babel-parse-src-block-match ()
 (defun org-babel-parse-src-block-match ()
@@ -1311,12 +1357,13 @@ may be specified in the properties of the current outline entry."
               (insert (org-unescape-code-in-string body))
               (insert (org-unescape-code-in-string body))
 	      (unless preserve-indentation (org-do-remove-indentation))
 	      (unless preserve-indentation (org-do-remove-indentation))
               (buffer-string)))
               (buffer-string)))
-	  (org-babel-merge-params
-	   org-babel-default-header-args
-           (org-babel-params-from-properties lang)
-	   (if (boundp lang-headers) (eval lang-headers) nil)
-	   (org-babel-parse-header-arguments
-            (org-no-properties (or (match-string 4) ""))))
+	  (apply #'org-babel-merge-params
+		 org-babel-default-header-args
+		 (when (boundp lang-headers) (eval lang-headers))
+		 (append
+		  (org-babel-params-from-properties lang)
+		  (list (org-babel-parse-header-arguments
+			 (org-no-properties (or (match-string 4) ""))))))
 	  switches
 	  switches
 	  block-indentation)))
 	  block-indentation)))
 
 
@@ -1326,12 +1373,13 @@ may be specified in the properties of the current outline entry."
          (lang-headers (intern (concat "org-babel-default-header-args:" lang))))
          (lang-headers (intern (concat "org-babel-default-header-args:" lang))))
     (list lang
     (list lang
           (org-unescape-code-in-string (org-no-properties (match-string 5)))
           (org-unescape-code-in-string (org-no-properties (match-string 5)))
-          (org-babel-merge-params
-           org-babel-default-inline-header-args
-           (org-babel-params-from-properties lang)
-           (if (boundp lang-headers) (eval lang-headers) nil)
-           (org-babel-parse-header-arguments
-            (org-no-properties (or (match-string 4) "")))))))
+          (apply #'org-babel-merge-params
+		 org-babel-default-inline-header-args
+		 (if (boundp lang-headers) (eval lang-headers) nil)
+		 (append
+		  (org-babel-params-from-properties lang)
+		  (list (org-babel-parse-header-arguments
+			 (org-no-properties (or (match-string 4) "")))))))))
 
 
 (defun org-babel-balanced-split (string alts)
 (defun org-babel-balanced-split (string alts)
   "Split STRING on instances of ALTS.
   "Split STRING on instances of ALTS.
@@ -1576,7 +1624,7 @@ If the point is not on a source block then return nil."
         (< top initial) (< initial bottom)
         (< top initial) (< initial bottom)
         (progn (goto-char top) (beginning-of-line 1)
         (progn (goto-char top) (beginning-of-line 1)
 	       (looking-at org-babel-src-block-regexp))
 	       (looking-at org-babel-src-block-regexp))
-        (point))))))
+        (point-marker))))))
 
 
 ;;;###autoload
 ;;;###autoload
 (defun org-babel-goto-src-block-head ()
 (defun org-babel-goto-src-block-head ()
@@ -1855,14 +1903,14 @@ following the source block."
      ((org-at-item-p) (org-babel-read-list))
      ((org-at-item-p) (org-babel-read-list))
      ((looking-at org-bracket-link-regexp) (org-babel-read-link))
      ((looking-at org-bracket-link-regexp) (org-babel-read-link))
      ((looking-at org-block-regexp) (org-babel-trim (match-string 4)))
      ((looking-at org-block-regexp) (org-babel-trim (match-string 4)))
-     ((looking-at "^[ \t]*: ")
+     ((or (looking-at "^[ \t]*: ") (looking-at "^[ \t]*:$"))
       (setq result-string
       (setq result-string
 	    (org-babel-trim
 	    (org-babel-trim
 	     (mapconcat (lambda (line)
 	     (mapconcat (lambda (line)
-                          (if (and (> (length line) 1)
-                                   (string-match "^[ \t]*: \\(.+\\)" line))
-                              (match-string 1 line)
-                            line))
+                          (or (and (> (length line) 1)
+				   (string-match "^[ \t]*: ?\\(.+\\)" line)
+				   (match-string 1 line))
+			      ""))
 			(split-string
 			(split-string
 			 (buffer-substring
 			 (buffer-substring
                           (point) (org-babel-result-end)) "[\r\n]+")
                           (point) (org-babel-result-end)) "[\r\n]+")
@@ -2036,7 +2084,7 @@ code ---- the results are extracted in the syntax of the source
 		     (cons 'unordered
 		     (cons 'unordered
 			   (mapcar
 			   (mapcar
 			    (lambda (el) (list nil (if (stringp el) el (format "%S" el))))
 			    (lambda (el) (list nil (if (stringp el) el (format "%S" el))))
-			    (if (listp result) result (list result))))
+			    (if (listp result) result (split-string result "\n" t))))
 		     '(:splicep nil :istart "- " :iend "\n")))
 		     '(:splicep nil :istart "- " :iend "\n")))
 		   "\n"))
 		   "\n"))
 		 ;; assume the result is a table if it's not a string
 		 ;; assume the result is a table if it's not a string
@@ -2068,6 +2116,7 @@ code ---- the results are extracted in the syntax of the source
 		 ((member "latex" result-params)
 		 ((member "latex" result-params)
 		  (funcall wrap "#+BEGIN_LaTeX" "#+END_LaTeX"))
 		  (funcall wrap "#+BEGIN_LaTeX" "#+END_LaTeX"))
 		 ((member "org" result-params)
 		 ((member "org" result-params)
+		  (goto-char beg) (if (org-at-table-p) (org-cycle))
 		  (funcall wrap "#+BEGIN_SRC org" "#+END_SRC"))
 		  (funcall wrap "#+BEGIN_SRC org" "#+END_SRC"))
 		 ((member "code" result-params)
 		 ((member "code" result-params)
 		  (funcall wrap (format "#+BEGIN_SRC %s%s" (or lang "none") results-switches)
 		  (funcall wrap (format "#+BEGIN_SRC %s%s" (or lang "none") results-switches)
@@ -2077,6 +2126,7 @@ code ---- the results are extracted in the syntax of the source
 		 ((or (member "drawer" result-params)
 		 ((or (member "drawer" result-params)
 		      ;; Stay backward compatible with <7.9.2
 		      ;; Stay backward compatible with <7.9.2
 		      (member "wrap" result-params))
 		      (member "wrap" result-params))
+		  (goto-char beg) (if (org-at-table-p) (org-cycle))
 		  (funcall wrap ":RESULTS:" ":END:" 'no-escape))
 		  (funcall wrap ":RESULTS:" ":END:" 'no-escape))
 		 ((and (not (funcall proper-list-p result))
 		 ((and (not (funcall proper-list-p result))
 		       (not (member "file" result-params)))
 		       (not (member "file" result-params)))
@@ -2124,7 +2174,7 @@ code ---- the results are extracted in the syntax of the source
 	    (progn (re-search-forward (concat "[ \t]*#\\+end_" (match-string 1))
 	    (progn (re-search-forward (concat "[ \t]*#\\+end_" (match-string 1))
 				      nil t)
 				      nil t)
 		   (forward-char 1))
 		   (forward-char 1))
-	  (while (looking-at "[ \t]*\\(: \\|\\[\\[\\)")
+	  (while (looking-at "[ \t]*\\(: \\|:$\\|\\[\\[\\)")
 	    (forward-line 1))))
 	    (forward-line 1))))
       (point)))))
       (point)))))
 
 
@@ -2157,8 +2207,9 @@ file's directory then expand relative links."
 	    (funcall chars-between end (save-excursion (goto-char end) (point-at-eol))))
 	    (funcall chars-between end (save-excursion (goto-char end) (point-at-eol))))
 	(save-excursion
 	(save-excursion
 	  (goto-char beg)
 	  (goto-char beg)
-	  (insert (format "=%s=" (prog1 (buffer-substring beg end)
-				   (delete-region beg end)))))
+	  (insert (format org-babel-inline-result-wrap
+			  (prog1 (buffer-substring beg end)
+			    (delete-region beg end)))))
       (let ((size (count-lines beg end)))
       (let ((size (count-lines beg end)))
 	(save-excursion
 	(save-excursion
 	  (cond ((= size 0))	      ; do nothing for an empty result
 	  (cond ((= size 0))	      ; do nothing for an empty result
@@ -2353,7 +2404,7 @@ would set the value of argument \"a\" equal to \"9\".  Note that
 these arguments are not evaluated in the current source-code
 these arguments are not evaluated in the current source-code
 block but are passed literally to the \"example-block\"."
 block but are passed literally to the \"example-block\"."
   (let* ((parent-buffer (or parent-buffer (current-buffer)))
   (let* ((parent-buffer (or parent-buffer (current-buffer)))
-         (info (or info (org-babel-get-src-block-info)))
+         (info (or info (org-babel-get-src-block-info 'light)))
          (lang (nth 0 info))
          (lang (nth 0 info))
          (body (nth 1 info))
          (body (nth 1 info))
 	 (ob-nww-start org-babel-noweb-wrap-start)
 	 (ob-nww-start org-babel-noweb-wrap-start)
@@ -2504,14 +2555,15 @@ block but are passed literally to the \"example-block\"."
 (defun org-babel-read (cell &optional inhibit-lisp-eval)
 (defun org-babel-read (cell &optional inhibit-lisp-eval)
   "Convert the string value of CELL to a number if appropriate.
   "Convert the string value of CELL to a number if appropriate.
 Otherwise if cell looks like lisp (meaning it starts with a
 Otherwise if cell looks like lisp (meaning it starts with a
-\"(\", \"'\", \"`\" or a \"[\") then read it as lisp, otherwise
-return it unmodified as a string.  Optional argument NO-LISP-EVAL
-inhibits lisp evaluation for situations in which is it not
-appropriate."
+\"(\", \"'\", \"`\" or a \"[\") then read it as lisp,
+otherwise return it unmodified as a string.  Optional argument
+NO-LISP-EVAL inhibits lisp evaluation for situations in which is
+it not appropriate."
   (if (and (stringp cell) (not (equal cell "")))
   (if (and (stringp cell) (not (equal cell "")))
       (or (org-babel-number-p cell)
       (or (org-babel-number-p cell)
           (if (and (not inhibit-lisp-eval)
           (if (and (not inhibit-lisp-eval)
-		   (member (substring cell 0 1) '("(" "'" "`" "[")))
+		   (or (member (substring cell 0 1) '("(" "'" "`" "["))
+		       (string= cell "*this*")))
               (eval (read cell))
               (eval (read cell))
             (if (string= (substring cell 0 1) "\"")
             (if (string= (substring cell 0 1) "\"")
 		(read cell)
 		(read cell)
@@ -2520,7 +2572,8 @@ appropriate."
 
 
 (defun org-babel-number-p (string)
 (defun org-babel-number-p (string)
   "If STRING represents a number return its value."
   "If STRING represents a number return its value."
-  (if (and (string-match "^-?[0-9]*\\.?[0-9]*$" string)
+  (if (and (string-match "[0-9]+" string)
+	   (string-match "^-?[0-9]*\\.?[0-9]*$" string)
            (= (length (substring string (match-beginning 0)
            (= (length (substring string (match-beginning 0)
 				 (match-end 0)))
 				 (match-end 0)))
 	      (length string)))
 	      (length string)))
@@ -2625,30 +2678,39 @@ Emacs shutdown."))
   "Call the code to parse raw string results according to RESULT-PARAMS."
   "Call the code to parse raw string results according to RESULT-PARAMS."
   (declare (indent 1)
   (declare (indent 1)
 	   (debug (form form &rest form)))
 	   (debug (form form &rest form)))
-  `(unless (member "none" ,result-params)
-     (if (or (member "scalar" ,result-params)
-	     (member "verbatim" ,result-params)
-	     (member "html" ,result-params)
-	     (member "code" ,result-params)
-	     (member "pp" ,result-params)
-	     (and (member "output" ,result-params)
-		  (not (member "table" ,result-params))))
-	 ,scalar-form
-       ,@table-forms)))
+  (org-with-gensyms (params)
+    `(let ((,params ,result-params))
+       (unless (member "none" ,params)
+	 (if (or (member "scalar" ,params)
+		 (member "verbatim" ,params)
+		 (member "html" ,params)
+		 (member "code" ,params)
+		 (member "pp" ,params)
+		 (and (or (member "output" ,params)
+			  (member "raw"    ,params)
+			  (member "org"    ,params)
+			  (member "drawer" ,params))
+		      (not (member "table" ,params))))
+	     ,scalar-form
+	   ,@table-forms)))))
+(def-edebug-spec org-babel-result-cond (form form body))
 
 
 (defun org-babel-temp-file (prefix &optional suffix)
 (defun org-babel-temp-file (prefix &optional suffix)
   "Create a temporary file in the `org-babel-temporary-directory'.
   "Create a temporary file in the `org-babel-temporary-directory'.
 Passes PREFIX and SUFFIX directly to `make-temp-file' with the
 Passes PREFIX and SUFFIX directly to `make-temp-file' with the
 value of `temporary-file-directory' temporarily set to the value
 value of `temporary-file-directory' temporarily set to the value
 of `org-babel-temporary-directory'."
 of `org-babel-temporary-directory'."
-  (let ((temporary-file-directory
-	 (if (file-remote-p default-directory)
-	     (concat (file-remote-p default-directory) "/tmp")
+  (if (file-remote-p default-directory)
+      (let ((prefix
+             (concat (file-remote-p default-directory)
+                     (expand-file-name prefix temporary-file-directory))))
+        (make-temp-file prefix nil suffix))
+    (let ((temporary-file-directory
 	   (or (and (boundp 'org-babel-temporary-directory)
 	   (or (and (boundp 'org-babel-temporary-directory)
 		    (file-exists-p org-babel-temporary-directory)
 		    (file-exists-p org-babel-temporary-directory)
 		    org-babel-temporary-directory)
 		    org-babel-temporary-directory)
-	       temporary-file-directory))))
-      (make-temp-file prefix nil suffix)))
+	       temporary-file-directory)))
+      (make-temp-file prefix nil suffix))))
 
 
 (defun org-babel-remove-temporary-directory ()
 (defun org-babel-remove-temporary-directory ()
   "Remove `org-babel-temporary-directory' on Emacs shutdown."
   "Remove `org-babel-temporary-directory' on Emacs shutdown."

+ 1 - 0
lisp/ob-eval.el

@@ -27,6 +27,7 @@
 ;; shell commands.
 ;; shell commands.
 
 
 ;;; Code:
 ;;; Code:
+(require 'org-macs)
 (eval-when-compile (require 'cl))
 (eval-when-compile (require 'cl))
 
 
 (defvar org-babel-error-buffer-name "*Org-Babel Error Output*")
 (defvar org-babel-error-buffer-name "*Org-Babel Error Output*")

+ 35 - 28
lisp/ob-exp.el

@@ -52,10 +52,13 @@
 (defcustom org-export-babel-evaluate t
 (defcustom org-export-babel-evaluate t
   "Switch controlling code evaluation during export.
   "Switch controlling code evaluation during export.
 When set to nil no code will be evaluated as part of the export
 When set to nil no code will be evaluated as part of the export
-process."
+process.  When set to 'inline-only, only inline code blocks will
+be executed."
   :group 'org-babel
   :group 'org-babel
   :version "24.1"
   :version "24.1"
-  :type 'boolean)
+  :type '(choice (const :tag "Never" nil)
+		 (const :tag "Only inline code" inline-only)
+		 (const :tag "Always" t)))
 (put 'org-export-babel-evaluate 'safe-local-variable (lambda (x) (eq x nil)))
 (put 'org-export-babel-evaluate 'safe-local-variable (lambda (x) (eq x nil)))
 
 
 (defun org-babel-exp-get-export-buffer ()
 (defun org-babel-exp-get-export-buffer ()
@@ -92,8 +95,8 @@ process."
 
 
 (defun org-babel-exp-src-block (&rest headers)
 (defun org-babel-exp-src-block (&rest headers)
   "Process source block for export.
   "Process source block for export.
-Depending on the 'export' headers argument in replace the source
-code block with...
+Depending on the 'export' headers argument, replace the source
+code block like this:
 
 
 both ---- display the code and the results
 both ---- display the code and the results
 
 
@@ -103,7 +106,7 @@ code ---- the default, display the code inside the block but do
 results - just like none only the block is run on export ensuring
 results - just like none only the block is run on export ensuring
           that it's results are present in the org-mode buffer
           that it's results are present in the org-mode buffer
 
 
-none ----- do not display either code or results upon export
+none ---- do not display either code or results upon export
 
 
 Assume point is at the beginning of block's starting line."
 Assume point is at the beginning of block's starting line."
   (interactive)
   (interactive)
@@ -119,11 +122,11 @@ Assume point is at the beginning of block's starting line."
 	  (org-babel-exp-in-export-file lang
 	  (org-babel-exp-in-export-file lang
 	    (setf (nth 2 info)
 	    (setf (nth 2 info)
 		  (org-babel-process-params
 		  (org-babel-process-params
-		   (org-babel-merge-params
-		    org-babel-default-header-args
-		    (org-babel-params-from-properties lang)
-		    (if (boundp lang-headers) (eval lang-headers) nil)
-		    raw-params))))
+		   (apply #'org-babel-merge-params
+			  org-babel-default-header-args
+			  (if (boundp lang-headers) (eval lang-headers) nil)
+			  (append (org-babel-params-from-properties lang)
+				  (list raw-params))))))
 	  (setf hash (org-babel-sha1-hash info)))
 	  (setf hash (org-babel-sha1-hash info)))
 	(org-babel-exp-do-export info 'block hash)))))
 	(org-babel-exp-do-export info 'block hash)))))
 
 
@@ -203,16 +206,19 @@ this template."
 			  (results
 			  (results
 			   (org-babel-exp-do-export
 			   (org-babel-exp-do-export
 			    (list "emacs-lisp" "results"
 			    (list "emacs-lisp" "results"
-				  (org-babel-merge-params
-				   org-babel-default-header-args
-				   org-babel-default-lob-header-args
-				   (org-babel-params-from-properties)
-				   (org-babel-parse-header-arguments
-				    (org-no-properties
-				     (concat ":var results="
-					     (mapconcat 'identity
-							(butlast lob-info)
-							" ")))))
+				  (apply #'org-babel-merge-params
+					 org-babel-default-header-args
+					 org-babel-default-lob-header-args
+					 (append
+					  (org-babel-params-from-properties)
+					  (list
+					   (org-babel-parse-header-arguments
+					    (org-no-properties
+					     (concat
+					      ":var results="
+					      (mapconcat 'identity
+							 (butlast lob-info)
+							 " ")))))))
 				  "" nil (car (last lob-info)))
 				  "" nil (car (last lob-info)))
 			    'lob))
 			    'lob))
 			  (rep (org-fill-template
 			  (rep (org-fill-template
@@ -264,10 +270,7 @@ this template."
 		    (cons
 		    (cons
 		     (org-element-property :language element)
 		     (org-element-property :language element)
 		     (let ((params (org-element-property :parameters element)))
 		     (let ((params (org-element-property :parameters element)))
-		       (and params (org-split-string params "[ \t]+")))))
-                   (preserve-indent
-		    (or org-src-preserve-indentation
-			(org-element-property :preserve-indent element))))
+		       (and params (org-split-string params "[ \t]+"))))))
               ;; Execute all non-block elements between POS and
               ;; Execute all non-block elements between POS and
               ;; current block.
               ;; current block.
               (org-babel-exp-non-block-elements pos begin)
               (org-babel-exp-non-block-elements pos begin)
@@ -288,7 +291,7 @@ this template."
 		       (goto-char match-start)
 		       (goto-char match-start)
 		       (delete-region (point) block-end)
 		       (delete-region (point) block-end)
 		       (insert replacement)
 		       (insert replacement)
-		       (if preserve-indent
+		       (if (org-element-property :preserve-indent element)
 			   ;; Indent only the code block markers.
 			   ;; Indent only the code block markers.
 			   (save-excursion (skip-chars-backward " \r\t\n")
 			   (save-excursion (skip-chars-backward " \r\t\n")
 					   (indent-line-to ind)
 					   (indent-line-to ind)
@@ -378,14 +381,17 @@ Results are prepared in a manner suitable for export by org-mode.
 This function is called by `org-babel-exp-do-export'.  The code
 This function is called by `org-babel-exp-do-export'.  The code
 block will be evaluated.  Optional argument SILENT can be used to
 block will be evaluated.  Optional argument SILENT can be used to
 inhibit insertion of results into the buffer."
 inhibit insertion of results into the buffer."
-  (when (and org-export-babel-evaluate
+  (when (and (or (eq org-export-babel-evaluate t)
+		 (and (eq type 'inline)
+		      (eq org-export-babel-evaluate 'inline-only)))
 	     (not (and hash (equal hash (org-babel-current-result-hash)))))
 	     (not (and hash (equal hash (org-babel-current-result-hash)))))
     (let ((lang (nth 0 info))
     (let ((lang (nth 0 info))
 	  (body (if (org-babel-noweb-p (nth 2 info) :eval)
 	  (body (if (org-babel-noweb-p (nth 2 info) :eval)
 		    (org-babel-expand-noweb-references
 		    (org-babel-expand-noweb-references
 		     info (org-babel-exp-get-export-buffer))
 		     info (org-babel-exp-get-export-buffer))
 		  (nth 1 info)))
 		  (nth 1 info)))
-	  (info (copy-sequence info)))
+	  (info (copy-sequence info))
+	  (org-babel-current-src-block-location (point-marker)))
       ;; skip code blocks which we can't evaluate
       ;; skip code blocks which we can't evaluate
       (when (fboundp (intern (concat "org-babel-execute:" lang)))
       (when (fboundp (intern (concat "org-babel-execute:" lang)))
 	(org-babel-eval-wipe-error-buffer)
 	(org-babel-eval-wipe-error-buffer)
@@ -411,7 +417,8 @@ inhibit insertion of results into the buffer."
 	   ((equal type 'lob)
 	   ((equal type 'lob)
 	    (save-excursion
 	    (save-excursion
 	      (re-search-backward org-babel-lob-one-liner-regexp nil t)
 	      (re-search-backward org-babel-lob-one-liner-regexp nil t)
-	      (org-babel-execute-src-block nil info)))))))))
+	      (let (org-confirm-babel-evaluate)
+		(org-babel-execute-src-block nil info))))))))))
 
 
 
 
 (provide 'ob-exp)
 (provide 'ob-exp)

+ 7 - 0
lisp/ob-fortran.el

@@ -32,6 +32,7 @@
 
 
 (declare-function org-entry-get "org"
 (declare-function org-entry-get "org"
 		  (pom property &optional inherit literal-nil))
 		  (pom property &optional inherit literal-nil))
+(declare-function org-every "org" (pred seq))
 
 
 (defvar org-babel-tangle-lang-exts)
 (defvar org-babel-tangle-lang-exts)
 (add-to-list 'org-babel-tangle-lang-exts '("fortran" . "F90"))
 (add-to-list 'org-babel-tangle-lang-exts '("fortran" . "F90"))
@@ -143,6 +144,12 @@ of the same value."
      ((stringp val)
      ((stringp val)
       (format "character(len=%d), parameter ::  %S = '%s'\n"
       (format "character(len=%d), parameter ::  %S = '%s'\n"
               (length val) var val))
               (length val) var val))
+     ;; val is a matrix
+     ((and (listp val) (org-every #'listp val))
+      (format "real, parameter :: %S(%d,%d) = transpose( reshape( %s , (/ %d, %d /) ) )\n"
+	      var (length val) (length (car val)) 
+	      (org-babel-fortran-transform-list val)
+	      (length (car val)) (length val)))
      ((listp val)
      ((listp val)
       (format "real, parameter :: %S(%d) = %s\n"
       (format "real, parameter :: %S(%d) = %s\n"
 	      var (length val) (org-babel-fortran-transform-list val)))
 	      var (length val) (org-babel-fortran-transform-list val)))

+ 75 - 29
lisp/ob-gnuplot.el

@@ -52,77 +52,117 @@
   '((:results . "file") (:exports . "results") (:session . nil))
   '((:results . "file") (:exports . "results") (:session . nil))
   "Default arguments to use when evaluating a gnuplot source block.")
   "Default arguments to use when evaluating a gnuplot source block.")
 
 
+(defvar org-babel-header-args:gnuplot
+  '((title	. :any)
+    (lines	. :any)
+    (sets	. :any)
+    (x-labels	. :any)
+    (y-labels	. :any)
+    (timefmt	. :any)
+    (time-ind	. :any)
+    (missing	. :any)
+    (term       . :any))
+  "Gnuplot specific header args.")
+
 (defvar org-babel-gnuplot-timestamp-fmt nil)
 (defvar org-babel-gnuplot-timestamp-fmt nil)
 
 
+(defvar *org-babel-gnuplot-missing* nil)
+
+(defcustom *org-babel-gnuplot-terms*
+  '((eps . "postscript eps"))
+  "List of file extensions and the associated gnuplot terminal."
+  :group 'org-babel
+  :type '(repeat (cons (symbol :tag "File extension")
+		       (string :tag "Gnuplot terminal"))))
+
 (defun org-babel-gnuplot-process-vars (params)
 (defun org-babel-gnuplot-process-vars (params)
   "Extract variables from PARAMS and process the variables.
   "Extract variables from PARAMS and process the variables.
 Dumps all vectors into files and returns an association list
 Dumps all vectors into files and returns an association list
 of variable names and the related value to be used in the gnuplot
 of variable names and the related value to be used in the gnuplot
 code."
 code."
-  (mapcar
-   (lambda (pair)
-     (cons
-      (car pair) ;; variable name
-      (if (listp (cdr pair)) ;; variable value
-          (org-babel-gnuplot-table-to-data
-           (cdr pair) (org-babel-temp-file "gnuplot-") params)
-        (cdr pair))))
-   (mapcar #'cdr (org-babel-get-header params :var))))
+  (let ((*org-babel-gnuplot-missing* (cdr (assoc :missing params))))
+    (mapcar
+     (lambda (pair)
+       (cons
+	(car pair) ;; variable name
+	(if (listp (cdr pair)) ;; variable value
+	    (org-babel-gnuplot-table-to-data
+	     (cdr pair) (org-babel-temp-file "gnuplot-") params)
+	  (cdr pair))))
+     (mapcar #'cdr (org-babel-get-header params :var)))))
 
 
 (defun org-babel-expand-body:gnuplot (body params)
 (defun org-babel-expand-body:gnuplot (body params)
   "Expand BODY according to PARAMS, return the expanded body."
   "Expand BODY according to PARAMS, return the expanded body."
   (save-window-excursion
   (save-window-excursion
     (let* ((vars (org-babel-gnuplot-process-vars params))
     (let* ((vars (org-babel-gnuplot-process-vars params))
            (out-file (cdr (assoc :file params)))
            (out-file (cdr (assoc :file params)))
-           (term (or (cdr (assoc :term params))
-                     (when out-file (file-name-extension out-file))))
+	   (prologue (cdr (assoc :prologue params)))
+	   (epilogue (cdr (assoc :epilogue params)))
+	   (term (or (cdr (assoc :term params))
+                     (when out-file
+		       (let ((ext (file-name-extension out-file)))
+			 (or (cdr (assoc (intern (downcase ext))
+					 *org-babel-gnuplot-terms*))
+			     ext)))))
            (cmdline (cdr (assoc :cmdline params)))
            (cmdline (cdr (assoc :cmdline params)))
-           (title (plist-get params :title))
-           (lines (plist-get params :line))
-           (sets (plist-get params :set))
-           (x-labels (plist-get params :xlabels))
-           (y-labels (plist-get params :ylabels))
-           (timefmt (plist-get params :timefmt))
-           (time-ind (or (plist-get params :timeind)
+           (title (cdr (assoc :title params)))
+           (lines (cdr (assoc :line params)))
+           (sets (cdr (assoc :set params)))
+           (x-labels (cdr (assoc :xlabels params)))
+           (y-labels (cdr (assoc :ylabels params)))
+           (timefmt (cdr (assoc :timefmt params)))
+           (time-ind (or (cdr (assoc :timeind params))
                          (when timefmt 1)))
                          (when timefmt 1)))
+	   (missing (cdr (assoc :missing params)))
 	   (add-to-body (lambda (text) (setq body (concat text "\n" body))))
 	   (add-to-body (lambda (text) (setq body (concat text "\n" body))))
            output)
            output)
       ;; append header argument settings to body
       ;; append header argument settings to body
-      (when title (funcall add-to-body (format "set title '%s'" title))) ;; title
-      (when lines (mapc (lambda (el) (funcall add-to-body el)) lines)) ;; line
+      (when title (funcall add-to-body (format "set title '%s'" title)))
+      (when lines (mapc (lambda (el) (funcall add-to-body el)) lines))
+      (when missing
+	(funcall add-to-body (format "set datafile missing '%s'" missing)))
       (when sets
       (when sets
 	(mapc (lambda (el) (funcall add-to-body (format "set %s" el))) sets))
 	(mapc (lambda (el) (funcall add-to-body (format "set %s" el))) sets))
       (when x-labels
       (when x-labels
 	(funcall add-to-body
 	(funcall add-to-body
 		 (format "set xtics (%s)"
 		 (format "set xtics (%s)"
 			 (mapconcat (lambda (pair)
 			 (mapconcat (lambda (pair)
-				      (format "\"%s\" %d" (cdr pair) (car pair)))
+				      (format "\"%s\" %d"
+					      (cdr pair) (car pair)))
 				    x-labels ", "))))
 				    x-labels ", "))))
       (when y-labels
       (when y-labels
 	(funcall add-to-body
 	(funcall add-to-body
 		 (format "set ytics (%s)"
 		 (format "set ytics (%s)"
 			 (mapconcat (lambda (pair)
 			 (mapconcat (lambda (pair)
-				      (format "\"%s\" %d" (cdr pair) (car pair)))
+				      (format "\"%s\" %d"
+					      (cdr pair) (car pair)))
 				    y-labels ", "))))
 				    y-labels ", "))))
       (when time-ind
       (when time-ind
 	(funcall add-to-body "set xdata time")
 	(funcall add-to-body "set xdata time")
 	(funcall add-to-body (concat "set timefmt \""
 	(funcall add-to-body (concat "set timefmt \""
 				     (or timefmt
 				     (or timefmt
 					 "%Y-%m-%d-%H:%M:%S") "\"")))
 					 "%Y-%m-%d-%H:%M:%S") "\"")))
-      (when out-file (funcall add-to-body (format "set output \"%s\"" out-file)))
+      (when out-file
+	;; set the terminal at the top of the block
+	(funcall add-to-body (format "set output \"%s\"" out-file))
+	;; and close the terminal at the bottom of the block
+	(setq body (concat body "\nset output\n")))
       (when term (funcall add-to-body (format "set term %s" term)))
       (when term (funcall add-to-body (format "set term %s" term)))
       ;; insert variables into code body: this should happen last
       ;; insert variables into code body: this should happen last
       ;; placing the variables at the *top* of the code in case their
       ;; placing the variables at the *top* of the code in case their
       ;; values are used later
       ;; values are used later
-      (funcall add-to-body (mapconcat #'identity
-				      (org-babel-variable-assignments:gnuplot params)
-				      "\n"))
+      (funcall add-to-body
+	       (mapconcat #'identity
+			  (org-babel-variable-assignments:gnuplot params)
+			  "\n"))
       ;; replace any variable names preceded by '$' with the actual
       ;; replace any variable names preceded by '$' with the actual
       ;; value of the variable
       ;; value of the variable
       (mapc (lambda (pair)
       (mapc (lambda (pair)
 	      (setq body (replace-regexp-in-string
 	      (setq body (replace-regexp-in-string
 			  (format "\\$%s" (car pair)) (cdr pair) body)))
 			  (format "\\$%s" (car pair)) (cdr pair) body)))
-	    vars))
+	    vars)
+      (when prologue (funcall add-to-body prologue))
+      (when epilogue (setq body (concat body "\n" epilogue))))
     body))
     body))
 
 
 (defun org-babel-execute:gnuplot (body params)
 (defun org-babel-execute:gnuplot (body params)
@@ -199,7 +239,8 @@ then create one.  Return the initialized session.  The current
 
 
 (defun org-babel-gnuplot-quote-timestamp-field (s)
 (defun org-babel-gnuplot-quote-timestamp-field (s)
   "Convert S from timestamp to Unix time and export to gnuplot."
   "Convert S from timestamp to Unix time and export to gnuplot."
-  (format-time-string org-babel-gnuplot-timestamp-fmt (org-time-string-to-time s)))
+  (format-time-string org-babel-gnuplot-timestamp-fmt
+		      (org-time-string-to-time s)))
 
 
 (defvar org-table-number-regexp)
 (defvar org-table-number-regexp)
 (defvar org-ts-regexp3)
 (defvar org-ts-regexp3)
@@ -210,7 +251,12 @@ then create one.  Return the initialized session.  The current
   (if (string-match org-table-number-regexp s) s
   (if (string-match org-table-number-regexp s) s
     (if (string-match org-ts-regexp3 s)
     (if (string-match org-ts-regexp3 s)
 	(org-babel-gnuplot-quote-timestamp-field s)
 	(org-babel-gnuplot-quote-timestamp-field s)
-      (concat "\"" (mapconcat 'identity (split-string s "\"") "\"\"") "\""))))
+      (if (zerop (length s))
+	  (or *org-babel-gnuplot-missing* s)
+	(if (string-match "[ \"]" "?")
+	    (concat "\"" (mapconcat 'identity (split-string s "\"") "\"\"")
+		    "\"")
+	  s)))))
 
 
 (defun org-babel-gnuplot-table-to-data (table data-file params)
 (defun org-babel-gnuplot-table-to-data (table data-file params)
   "Export TABLE to DATA-FILE in a format readable by gnuplot.
   "Export TABLE to DATA-FILE in a format readable by gnuplot.

+ 6 - 5
lisp/ob-haskell.el

@@ -78,11 +78,12 @@
                    (cdr (member org-babel-haskell-eoe
                    (cdr (member org-babel-haskell-eoe
                                 (reverse (mapcar #'org-babel-trim raw)))))))
                                 (reverse (mapcar #'org-babel-trim raw)))))))
     (org-babel-reassemble-table
     (org-babel-reassemble-table
-     (cond
-      ((equal result-type 'output)
-       (mapconcat #'identity (reverse (cdr results)) "\n"))
-      ((equal result-type 'value)
-       (org-babel-haskell-table-or-string (car results))))
+     ((lambda (result)
+	(org-babel-result-cond (cdr (assoc :result-params params))
+	  result (org-babel-haskell-table-or-string result)))
+      (case result-type
+	('output (mapconcat #'identity (reverse (cdr results)) "\n"))
+	('value (car results))))
      (org-babel-pick-name (cdr (assoc :colname-names params))
      (org-babel-pick-name (cdr (assoc :colname-names params))
 			  (cdr (assoc :colname-names params)))
 			  (cdr (assoc :colname-names params)))
      (org-babel-pick-name (cdr (assoc :rowname-names params))
      (org-babel-pick-name (cdr (assoc :rowname-names params))

+ 26 - 24
lisp/ob-js.el

@@ -65,30 +65,32 @@ This function is called by `org-babel-execute-src-block'"
   (let* ((org-babel-js-cmd (or (cdr (assoc :cmd params)) org-babel-js-cmd))
   (let* ((org-babel-js-cmd (or (cdr (assoc :cmd params)) org-babel-js-cmd))
          (result-type (cdr (assoc :result-type params)))
          (result-type (cdr (assoc :result-type params)))
          (full-body (org-babel-expand-body:generic
          (full-body (org-babel-expand-body:generic
-		     body params (org-babel-variable-assignments:js params))))
-    (org-babel-js-read
-     (if (not (string= (cdr (assoc :session params)) "none"))
-	 ;; session evaluation
-         (let ((session (org-babel-prep-session:js
-			 (cdr (assoc :session params)) params)))
-	   (nth 1
-		(org-babel-comint-with-output
-		    (session (format "%S" org-babel-js-eoe) t body)
-		  (mapc
-		   (lambda (line)
-		     (insert (org-babel-chomp line)) (comint-send-input nil t))
-		   (list body (format "%S" org-babel-js-eoe))))))
-       ;; external evaluation
-       (let ((script-file (org-babel-temp-file "js-script-")))
-         (with-temp-file script-file
-           (insert
-            ;; return the value or the output
-            (if (string= result-type "value")
-                (format org-babel-js-function-wrapper full-body)
-              full-body)))
-         (org-babel-eval
-	  (format "%s %s" org-babel-js-cmd
-		  (org-babel-process-file-name script-file)) ""))))))
+		     body params (org-babel-variable-assignments:js params)))
+	 (result (if (not (string= (cdr (assoc :session params)) "none"))
+		     ;; session evaluation
+		     (let ((session (org-babel-prep-session:js
+				     (cdr (assoc :session params)) params)))
+		       (nth 1
+			    (org-babel-comint-with-output
+				(session (format "%S" org-babel-js-eoe) t body)
+			      (mapc
+			       (lambda (line)
+				 (insert (org-babel-chomp line))
+				 (comint-send-input nil t))
+			       (list body (format "%S" org-babel-js-eoe))))))
+		   ;; external evaluation
+		   (let ((script-file (org-babel-temp-file "js-script-")))
+		     (with-temp-file script-file
+		       (insert
+			;; return the value or the output
+			(if (string= result-type "value")
+			    (format org-babel-js-function-wrapper full-body)
+			  full-body)))
+		     (org-babel-eval
+		      (format "%s %s" org-babel-js-cmd
+			      (org-babel-process-file-name script-file)) "")))))
+    (org-babel-result-cond (cdr (assoc :result-params params))
+      result (org-babel-js-read result))))
 
 
 (defun org-babel-js-read (results)
 (defun org-babel-js-read (results)
   "Convert RESULTS into an appropriate elisp value.
   "Convert RESULTS into an appropriate elisp value.

+ 19 - 11
lisp/ob-lob.el

@@ -35,7 +35,7 @@
 This is an association list.  Populate the library by adding
 This is an association list.  Populate the library by adding
 files to `org-babel-lob-files'.")
 files to `org-babel-lob-files'.")
 
 
-(defcustom org-babel-lob-files '()
+(defcustom org-babel-lob-files nil
   "Files used to populate the `org-babel-library-of-babel'.
   "Files used to populate the `org-babel-library-of-babel'.
 To add files to this list use the `org-babel-lob-ingest' command."
 To add files to this list use the `org-babel-lob-ingest' command."
   :group 'org-babel
   :group 'org-babel
@@ -116,27 +116,35 @@ if so then run the appropriate source block from the Library."
 	 (list (length (if (= (length (match-string 12)) 0)
 	 (list (length (if (= (length (match-string 12)) 0)
 			   (match-string 2) (match-string 11)))))))))
 			   (match-string 2) (match-string 11)))))))))
 
 
+(defvar org-babel-default-header-args:emacs-lisp) ; Defined in ob-emacs-lisp.el
 (defun org-babel-lob-execute (info)
 (defun org-babel-lob-execute (info)
   "Execute the lob call specified by INFO."
   "Execute the lob call specified by INFO."
   (let* ((mkinfo (lambda (p) (list "emacs-lisp" "results" p nil nil (nth 2 info))))
   (let* ((mkinfo (lambda (p) (list "emacs-lisp" "results" p nil nil (nth 2 info))))
-	 (pre-params (org-babel-merge-params
-		      org-babel-default-header-args
-		      (org-babel-params-from-properties)
-		      (org-babel-parse-header-arguments
-		       (org-no-properties
-			(concat ":var results="
-				(mapconcat #'identity (butlast info) " "))))))
+	 (pre-params (apply #'org-babel-merge-params
+			    org-babel-default-header-args
+			    org-babel-default-header-args:emacs-lisp
+			    (append
+			     (org-babel-params-from-properties)
+			     (list
+			      (org-babel-parse-header-arguments
+			       (org-no-properties
+				(concat
+				 ":var results="
+				 (mapconcat #'identity (butlast info)
+					    " "))))))))
 	 (pre-info (funcall mkinfo pre-params))
 	 (pre-info (funcall mkinfo pre-params))
 	 (cache-p (and (cdr (assoc :cache pre-params))
 	 (cache-p (and (cdr (assoc :cache pre-params))
 		       (string= "yes" (cdr (assoc :cache pre-params)))))
 		       (string= "yes" (cdr (assoc :cache pre-params)))))
 	 (new-hash (when cache-p (org-babel-sha1-hash pre-info)))
 	 (new-hash (when cache-p (org-babel-sha1-hash pre-info)))
-	 (old-hash (when cache-p (org-babel-current-result-hash))))
+	 (old-hash (when cache-p (org-babel-current-result-hash)))
+	 (org-babel-current-src-block-location (point-marker)))
     (if (and cache-p (equal new-hash old-hash))
     (if (and cache-p (equal new-hash old-hash))
 	(save-excursion (goto-char (org-babel-where-is-src-block-result))
 	(save-excursion (goto-char (org-babel-where-is-src-block-result))
 			(forward-line 1)
 			(forward-line 1)
 			(message "%S" (org-babel-read-result)))
 			(message "%S" (org-babel-read-result)))
-      (prog1 (org-babel-execute-src-block
-	      nil (funcall mkinfo (org-babel-process-params pre-params)))
+      (prog1 (let* ((proc-params (org-babel-process-params pre-params))
+		     org-confirm-babel-evaluate)
+	       (org-babel-execute-src-block nil (funcall mkinfo proc-params)))
 	;; update the hash
 	;; update the hash
 	(when new-hash (org-babel-set-current-result-hash new-hash))))))
 	(when new-hash (org-babel-set-current-result-hash new-hash))))))
 
 

+ 1 - 0
lisp/ob-maxima.el

@@ -83,6 +83,7 @@ called by `org-babel-execute-src-block'."
 		     (mapcar (lambda (line)
 		     (mapcar (lambda (line)
 			       (unless (or (string-match "batch" line)
 			       (unless (or (string-match "batch" line)
 					   (string-match "^rat: replaced .*$" line)
 					   (string-match "^rat: replaced .*$" line)
+					   (string-match "^;;; Loading #P" line)
 					   (= 0 (length line)))
 					   (= 0 (length line)))
 				 line))
 				 line))
 			     (split-string raw "[\r\n]"))) "\n"))
 			     (split-string raw "[\r\n]"))) "\n"))

+ 21 - 6
lisp/ob-ocaml.el

@@ -51,6 +51,13 @@
 (defvar org-babel-ocaml-eoe-indicator "\"org-babel-ocaml-eoe\";;")
 (defvar org-babel-ocaml-eoe-indicator "\"org-babel-ocaml-eoe\";;")
 (defvar org-babel-ocaml-eoe-output "org-babel-ocaml-eoe")
 (defvar org-babel-ocaml-eoe-output "org-babel-ocaml-eoe")
 
 
+(defcustom org-babel-ocaml-command "ocaml"
+  "Name of the command for executing Ocaml code."
+  :version "24.4"
+  :package-version '(Org . "8.0")
+  :group 'org-babel
+  :type 'string)
+
 (defun org-babel-execute:ocaml (body params)
 (defun org-babel-execute:ocaml (body params)
   "Execute a block of Ocaml code with Babel."
   "Execute a block of Ocaml code with Babel."
   (let* ((vars (mapcar #'cdr (org-babel-get-header params :var)))
   (let* ((vars (mapcar #'cdr (org-babel-get-header params :var)))
@@ -63,7 +70,7 @@
 		  (session org-babel-ocaml-eoe-output t full-body)
 		  (session org-babel-ocaml-eoe-output t full-body)
 		(insert
 		(insert
 		 (concat
 		 (concat
-		  (org-babel-chomp full-body)"\n"org-babel-ocaml-eoe-indicator))
+		  (org-babel-chomp full-body)";;\n"org-babel-ocaml-eoe-indicator))
 		(tuareg-interactive-send-input)))
 		(tuareg-interactive-send-input)))
 	 (clean
 	 (clean
 	  (car (let ((re (regexp-quote org-babel-ocaml-eoe-output)) out)
 	  (car (let ((re (regexp-quote org-babel-ocaml-eoe-output)) out)
@@ -74,7 +81,14 @@
 					 (progn (setq out t) nil))))
 					 (progn (setq out t) nil))))
 				   (mapcar #'org-babel-trim (reverse raw))))))))
 				   (mapcar #'org-babel-trim (reverse raw))))))))
     (org-babel-reassemble-table
     (org-babel-reassemble-table
-     (org-babel-ocaml-parse-output (org-babel-trim clean))
+     (let ((raw (org-babel-trim clean))
+	   (result-params (cdr (assoc :result-params params))))
+       (org-babel-result-cond result-params
+	 ;; strip type information from output unless verbatim is specified
+	 (if (and (not (member "verbatim" result-params))
+		  (string-match "= \\(.+\\)$" raw))
+	     (match-string 1 raw) raw)
+	 (org-babel-ocaml-parse-output raw)))
      (org-babel-pick-name
      (org-babel-pick-name
       (cdr (assoc :colname-names params)) (cdr (assoc :colnames params)))
       (cdr (assoc :colname-names params)) (cdr (assoc :colnames params)))
      (org-babel-pick-name
      (org-babel-pick-name
@@ -89,9 +103,10 @@
                                                  (stringp session))
                                                  (stringp session))
                                             session
                                             session
                                           tuareg-interactive-buffer-name)))
                                           tuareg-interactive-buffer-name)))
-    (save-window-excursion
-      (if (fboundp 'tuareg-run-caml) (tuareg-run-caml) (tuareg-run-ocaml))
-      (get-buffer tuareg-interactive-buffer-name))))
+    (save-window-excursion (if (fboundp 'tuareg-run-process-if-needed)
+	 (tuareg-run-process-if-needed org-babel-ocaml-command)
+       (tuareg-run-caml)))
+    (get-buffer tuareg-interactive-buffer-name)))
 
 
 (defun org-babel-variable-assignments:ocaml (params)
 (defun org-babel-variable-assignments:ocaml (params)
   "Return list of ocaml statements assigning the block's variables."
   "Return list of ocaml statements assigning the block's variables."
@@ -109,7 +124,7 @@
 (defun org-babel-ocaml-parse-output (output)
 (defun org-babel-ocaml-parse-output (output)
   "Parse OUTPUT.
   "Parse OUTPUT.
 OUTPUT is string output from an ocaml process."
 OUTPUT is string output from an ocaml process."
-  (let ((regexp "%s = \\(.+\\)$"))
+  (let ((regexp "[^:]+ : %s = \\(.+\\)$"))
     (cond
     (cond
      ((string-match (format regexp "string") output)
      ((string-match (format regexp "string") output)
       (org-babel-read (match-string 1 output)))
       (org-babel-read (match-string 1 output)))

+ 2 - 1
lisp/ob-octave.el

@@ -151,7 +151,8 @@ create.  Return the initialized session."
   "Create an octave inferior process buffer.
   "Create an octave inferior process buffer.
 If there is not a current inferior-process-buffer in SESSION then
 If there is not a current inferior-process-buffer in SESSION then
 create.  Return the initialized session."
 create.  Return the initialized session."
-  (if matlabp (require 'matlab) (require 'octave-inf))
+  (if matlabp (require 'matlab) (or (require 'octave-inf nil 'noerror)
+				    (require 'octave)))
   (unless (string= session "none")
   (unless (string= session "none")
     (let ((session (or session
     (let ((session (or session
 		       (if matlabp "*Inferior Matlab*" "*Inferior Octave*"))))
 		       (if matlabp "*Inferior Matlab*" "*Inferior Octave*"))))

+ 3 - 2
lisp/ob-org.el

@@ -43,8 +43,9 @@
 (defun org-babel-expand-body:org (body params)
 (defun org-babel-expand-body:org (body params)
   (dolist (var (mapcar #'cdr (org-babel-get-header params :var)))
   (dolist (var (mapcar #'cdr (org-babel-get-header params :var)))
     (setq body (replace-regexp-in-string
     (setq body (replace-regexp-in-string
-		(regexp-quote (format "$%s" (car var)))  (cdr var) body
-		nil 'literal)))
+		(regexp-quote (format "$%s" (car var)))
+		(format "%s" (cdr var))
+		body nil 'literal)))
   body)
   body)
 
 
 (defun org-babel-execute:org (body params)
 (defun org-babel-execute:org (body params)

+ 23 - 16
lisp/ob-perl.el

@@ -87,7 +87,7 @@ specifying a var of the same value."
 		    (concat "[\n"
 		    (concat "[\n"
 			    (mapconcat #'org-babel-perl--var-to-perl var "")
 			    (mapconcat #'org-babel-perl--var-to-perl var "")
 			    prefix "]"))
 			    prefix "]"))
-		(concat "q(" (princ var) ")"))
+		(format "q(%s)" var))
 	      (unless (zerop org-babel-perl--lvl) ",\n")))))
 	      (unless (zerop org-babel-perl--lvl) ",\n")))))
 
 
 (defvar org-babel-perl-buffers '(:default . nil))
 (defvar org-babel-perl-buffers '(:default . nil))
@@ -101,15 +101,16 @@ specifying a var of the same value."
         %s
         %s
     };
     };
     open my $BOH, qq(>%s) or die qq(Perl: Could not open output file.$/);
     open my $BOH, qq(>%s) or die qq(Perl: Could not open output file.$/);
-    select $BOH;
     my $rv = &$babel_sub();
     my $rv = &$babel_sub();
     my $rt = ref $rv;
     my $rt = ref $rv;
+    select $BOH;
     if (qq(ARRAY) eq $rt) {
     if (qq(ARRAY) eq $rt) {
         local $\\=$/;
         local $\\=$/;
+        local $,=qq(\t);
 	foreach my $rv ( @$rv ) {
 	foreach my $rv ( @$rv ) {
 	    my $rt = ref $rv;
 	    my $rt = ref $rv;
 	    if (qq(ARRAY) eq $rt) {
 	    if (qq(ARRAY) eq $rt) {
-		print join q(|), @$rv;
+		print @$rv;
 	    } else {
 	    } else {
 		print $rv;
 		print $rv;
 	    }
 	    }
@@ -130,19 +131,25 @@ If RESULT-TYPE equals 'output then return a list of the outputs
 of the statements in BODY, if RESULT-TYPE equals 'value then
 of the statements in BODY, if RESULT-TYPE equals 'value then
 return the value of the last statement in BODY, as elisp."
 return the value of the last statement in BODY, as elisp."
   (when session (error "Sessions are not supported for Perl"))
   (when session (error "Sessions are not supported for Perl"))
-  (let ((body (concat org-babel-perl-preface ibody)))
-    (case result-type
-      (output (org-babel-eval org-babel-perl-command body))
-      (value (let ((tmp-file (org-babel-temp-file "perl-")))
-	       (org-babel-eval
-		org-babel-perl-command
-		(format org-babel-perl-wrapper-method body
-			(org-babel-process-file-name tmp-file 'noquote)))
-	       	(org-babel-result-cond result-params
-		  (with-temp-buffer
-		    (insert-file-contents tmp-file)
-		    (buffer-string))
-		  (org-babel-import-elisp-from-file tmp-file '(16))))))))
+  (let* ((body (concat org-babel-perl-preface ibody))
+	 (tmp-file (org-babel-temp-file "perl-"))
+	 (tmp-babel-file (org-babel-process-file-name
+			  tmp-file 'noquote)))
+    ((lambda (results)
+       (when results
+	 (org-babel-result-cond result-params
+	   (org-babel-eval-read-file tmp-file)
+	   (org-babel-import-elisp-from-file tmp-file '(16)))))
+     (case result-type
+       (output
+	(with-temp-file tmp-file
+	  (insert
+	   (org-babel-eval org-babel-perl-command body))
+	  (buffer-string)))
+       (value
+	(org-babel-eval org-babel-perl-command
+			(format org-babel-perl-wrapper-method
+				body tmp-babel-file)))))))
 
 
 (provide 'ob-perl)
 (provide 'ob-perl)
 
 

+ 1 - 1
lisp/ob-picolisp.el

@@ -78,7 +78,7 @@
   :version "24.1"
   :version "24.1"
   :type 'string)
   :type 'string)
 
 
-(defun org-babel-expand-body:picolisp (body params &optional processed-params)
+(defun org-babel-expand-body:picolisp (body params)
   "Expand BODY according to PARAMS, return the expanded body."
   "Expand BODY according to PARAMS, return the expanded body."
   (let ((vars (mapcar #'cdr (org-babel-get-header params :var)))
   (let ((vars (mapcar #'cdr (org-babel-get-header params :var)))
         (result-params (cdr (assoc :result-params params)))
         (result-params (cdr (assoc :result-params params)))

+ 25 - 3
lisp/ob-python.el

@@ -151,12 +151,26 @@ Emacs-lisp table, otherwise return the results as a string."
        res))
        res))
    (org-babel-script-escape results)))
    (org-babel-script-escape results)))
 
 
-(defvar org-babel-python-buffers '((:default . nil)))
+(defvar org-babel-python-buffers '((:default . "*Python*")))
 
 
 (defun org-babel-python-session-buffer (session)
 (defun org-babel-python-session-buffer (session)
   "Return the buffer associated with SESSION."
   "Return the buffer associated with SESSION."
   (cdr (assoc session org-babel-python-buffers)))
   (cdr (assoc session org-babel-python-buffers)))
 
 
+(defun org-babel-python-with-earmufs (session)
+  (let ((name (if (stringp session) session (format "%s" session))))
+    (if (and (string= "*" (substring name 0 1))
+	     (string= "*" (substring name (- (length name) 1))))
+	name
+      (format "*%s*" name))))
+
+(defun org-babel-python-without-earmufs (session)
+  (let ((name (if (stringp session) session (format "%s" session))))
+    (if (and (string= "*" (substring name 0 1))
+	     (string= "*" (substring name (- (length name) 1))))
+	(substring name 1 (- (length name) 1))
+      name)))
+
 (defvar py-default-interpreter)
 (defvar py-default-interpreter)
 (defun org-babel-python-initiate-session-by-key (&optional session)
 (defun org-babel-python-initiate-session-by-key (&optional session)
   "Initiate a python session.
   "Initiate a python session.
@@ -170,7 +184,15 @@ then create.  Return the initialized session."
        ((and (eq 'python org-babel-python-mode)
        ((and (eq 'python org-babel-python-mode)
 	     (fboundp 'run-python)) ; python.el
 	     (fboundp 'run-python)) ; python.el
 	(if (version< "24.1" emacs-version)
 	(if (version< "24.1" emacs-version)
-	    (run-python org-babel-python-command)
+	    (progn
+	      (unless python-buffer
+		(setq python-buffer (org-babel-python-with-earmufs session)))
+	      (let ((python-shell-buffer-name
+		     (org-babel-python-without-earmufs python-buffer)))
+		(run-python
+		 (if (member system-type '(cygwin windows-nt ms-dos))
+		     (concat org-babel-python-command " -i")
+		   org-babel-python-command))))
 	  (run-python)))
 	  (run-python)))
        ((and (eq 'python-mode org-babel-python-mode)
        ((and (eq 'python-mode org-babel-python-mode)
 	     (fboundp 'py-shell)) ; python-mode.el
 	     (fboundp 'py-shell)) ; python-mode.el
@@ -186,7 +208,7 @@ then create.  Return the initialized session."
 			  (concat "Python-" (symbol-name session))))
 			  (concat "Python-" (symbol-name session))))
 	       (py-which-bufname bufname))
 	       (py-which-bufname bufname))
 	  (py-shell)
 	  (py-shell)
-	  (setq python-buffer (concat "*" bufname "*"))))
+	  (setq python-buffer (org-babel-python-with-earmufs bufname))))
        (t
        (t
 	(error "No function available for running an inferior Python")))
 	(error "No function available for running an inferior Python")))
       (setq org-babel-python-buffers
       (setq org-babel-python-buffers

+ 1 - 1
lisp/ob-ref.el

@@ -40,7 +40,7 @@
 ;; So an example of a simple src block referencing table data in the
 ;; So an example of a simple src block referencing table data in the
 ;; same file would be
 ;; same file would be
 
 
-;;  #+TBLNAME: sandbox
+;;  #+NAME: sandbox
 ;;  | 1 |         2 | 3 |
 ;;  | 1 |         2 | 3 |
 ;;  | 4 | org-babel | 6 |
 ;;  | 4 | org-babel | 6 |
 ;;
 ;;

+ 24 - 26
lisp/ob-ruby.el

@@ -68,7 +68,9 @@ This function is called by `org-babel-execute-src-block'."
 		   (org-babel-ruby-evaluate
 		   (org-babel-ruby-evaluate
 		    session full-body result-type result-params))))
 		    session full-body result-type result-params))))
     (org-babel-reassemble-table
     (org-babel-reassemble-table
-     result
+     (org-babel-result-cond result-params
+       result
+       (org-babel-ruby-table-or-string result))
      (org-babel-pick-name (cdr (assoc :colname-names params))
      (org-babel-pick-name (cdr (assoc :colname-names params))
 			  (cdr (assoc :colnames params)))
 			  (cdr (assoc :colnames params)))
      (org-babel-pick-name (cdr (assoc :rowname-names params))
      (org-babel-pick-name (cdr (assoc :rowname-names params))
@@ -203,31 +205,27 @@ return the value of the last statement in BODY, as elisp."
 	      (comint-send-input nil t)) 2)
 	      (comint-send-input nil t)) 2)
 	   "\n") "[\r\n]")) "\n"))
 	   "\n") "[\r\n]")) "\n"))
       (value
       (value
-       ((lambda (results)
-	  (if (or (member "code" result-params) (member "pp" result-params))
-	      results
-	    (org-babel-ruby-table-or-string results)))
-	(let* ((tmp-file (org-babel-temp-file "ruby-"))
-	       (ppp (or (member "code" result-params)
-			(member "pp" result-params))))
-	  (org-babel-comint-with-output
-	      (buffer org-babel-ruby-eoe-indicator t body)
-	    (when ppp (insert "require 'pp';") (comint-send-input nil t))
-	    (mapc
-	     (lambda (line)
-	       (insert (org-babel-chomp line)) (comint-send-input nil t))
-	     (append
-	      (list body)
-	      (if (not ppp)
-		  (list (format org-babel-ruby-f-write
-				(org-babel-process-file-name tmp-file 'noquote)))
-		(list
-		 "results=_" "require 'pp'" "orig_out = $stdout"
-		 (format org-babel-ruby-pp-f-write
-			 (org-babel-process-file-name tmp-file 'noquote))))
-	      (list org-babel-ruby-eoe-indicator)))
-	    (comint-send-input nil t))
-	  (org-babel-eval-read-file tmp-file)))))))
+       (let* ((tmp-file (org-babel-temp-file "ruby-"))
+	      (ppp (or (member "code" result-params)
+		       (member "pp" result-params))))
+	 (org-babel-comint-with-output
+	     (buffer org-babel-ruby-eoe-indicator t body)
+	   (when ppp (insert "require 'pp';") (comint-send-input nil t))
+	   (mapc
+	    (lambda (line)
+	      (insert (org-babel-chomp line)) (comint-send-input nil t))
+	    (append
+	     (list body)
+	     (if (not ppp)
+		 (list (format org-babel-ruby-f-write
+			       (org-babel-process-file-name tmp-file 'noquote)))
+	       (list
+		"results=_" "require 'pp'" "orig_out = $stdout"
+		(format org-babel-ruby-pp-f-write
+			(org-babel-process-file-name tmp-file 'noquote))))
+	     (list org-babel-ruby-eoe-indicator)))
+	   (comint-send-input nil t))
+	 (org-babel-eval-read-file tmp-file))))))
 
 
 (defun org-babel-ruby-read-string (string)
 (defun org-babel-ruby-read-string (string)
   "Strip \\\"s from around a ruby string."
   "Strip \\\"s from around a ruby string."

+ 25 - 23
lisp/ob-scheme.el

@@ -72,29 +72,31 @@ This function is called by `org-babel-execute-src-block'"
   (let* ((result-type (cdr (assoc :result-type params)))
   (let* ((result-type (cdr (assoc :result-type params)))
 	 (org-babel-scheme-cmd (or (cdr (assoc :scheme params))
 	 (org-babel-scheme-cmd (or (cdr (assoc :scheme params))
 				   org-babel-scheme-cmd))
 				   org-babel-scheme-cmd))
-         (full-body (org-babel-expand-body:scheme body params)))
-    (read
-     (if (not (string= (cdr (assoc :session params)) "none"))
-         ;; session evaluation
-	 (let ((session (org-babel-prep-session:scheme
-			 (cdr (assoc :session params)) params)))
-	   (org-babel-comint-with-output
-	       (session (format "%S" org-babel-scheme-eoe) t body)
-	     (mapc
-	      (lambda (line)
-		(insert (org-babel-chomp line)) (comint-send-input nil t))
-	      (list body (format "%S" org-babel-scheme-eoe)))))
-       ;; external evaluation
-       (let ((script-file (org-babel-temp-file "scheme-script-")))
-         (with-temp-file script-file
-           (insert
-            ;; return the value or the output
-            (if (string= result-type "value")
-                (format "(display %s)" full-body)
-              full-body)))
-         (org-babel-eval
-	  (format "%s %s" org-babel-scheme-cmd
-		  (org-babel-process-file-name script-file)) ""))))))
+         (full-body (org-babel-expand-body:scheme body params))
+	 (result (if (not (string= (cdr (assoc :session params)) "none"))
+		     ;; session evaluation
+		     (let ((session (org-babel-prep-session:scheme
+				     (cdr (assoc :session params)) params)))
+		       (org-babel-comint-with-output
+			   (session (format "%S" org-babel-scheme-eoe) t body)
+			 (mapc
+			  (lambda (line)
+			    (insert (org-babel-chomp line))
+			    (comint-send-input nil t))
+			  (list body (format "%S" org-babel-scheme-eoe)))))
+		   ;; external evaluation
+		   (let ((script-file (org-babel-temp-file "scheme-script-")))
+		     (with-temp-file script-file
+		       (insert
+			;; return the value or the output
+			(if (string= result-type "value")
+			    (format "(display %s)" full-body)
+			  full-body)))
+		     (org-babel-eval
+		      (format "%s %s" org-babel-scheme-cmd
+			      (org-babel-process-file-name script-file)) "")))))
+    (org-babel-result-cond (cdr (assoc :result-params params))
+      result (read result))))
 
 
 (defun org-babel-prep-session:scheme (session params)
 (defun org-babel-prep-session:scheme (session params)
   "Prepare SESSION according to the header arguments specified in PARAMS."
   "Prepare SESSION according to the header arguments specified in PARAMS."

+ 1 - 1
lisp/ob-sh.el

@@ -106,7 +106,7 @@ var of the same value."
   "Convert an elisp value to a string."
   "Convert an elisp value to a string."
   (let ((echo-var (lambda (v) (if (stringp v) v (format "%S" v)))))
   (let ((echo-var (lambda (v) (if (stringp v) v (format "%S" v)))))
     (cond
     (cond
-     ((and (listp var) (listp (car var)))
+     ((and (listp var) (or (listp (car var)) 'hline))
       (orgtbl-to-generic var  (list :sep (or sep "\t") :fmt echo-var)))
       (orgtbl-to-generic var  (list :sep (or sep "\t") :fmt echo-var)))
      ((listp var)
      ((listp var)
       (mapconcat echo-var var "\n"))
       (mapconcat echo-var var "\n"))

+ 36 - 36
lisp/ob-tangle.el

@@ -30,7 +30,10 @@
 (eval-when-compile
 (eval-when-compile
   (require 'cl))
   (require 'cl))
 
 
+(declare-function org-edit-special "org" (&optional arg))
 (declare-function org-link-escape "org" (text &optional table))
 (declare-function org-link-escape "org" (text &optional table))
+(declare-function org-store-link "org" (arg))
+(declare-function org-open-link-from-string "org" (s &optional arg reference-buffer))
 (declare-function org-heading-components "org" ())
 (declare-function org-heading-components "org" ())
 (declare-function org-back-to-heading "org" (invisible-ok))
 (declare-function org-back-to-heading "org" (invisible-ok))
 (declare-function org-fill-template "org" (template alist))
 (declare-function org-fill-template "org" (template alist))
@@ -111,7 +114,7 @@ result.  The default value is `org-babel-trim'."
 (defun org-babel-find-file-noselect-refresh (file)
 (defun org-babel-find-file-noselect-refresh (file)
   "Find file ensuring that the latest changes on disk are
   "Find file ensuring that the latest changes on disk are
 represented in the file."
 represented in the file."
-  (find-file-noselect file)
+  (find-file-noselect file 'nowarn)
   (with-current-buffer (get-file-buffer file)
   (with-current-buffer (get-file-buffer file)
     (revert-buffer t t t)))
     (revert-buffer t t t)))
 
 
@@ -135,32 +138,6 @@ evaluating BODY."
        ,temp-result)))
        ,temp-result)))
 (def-edebug-spec org-babel-with-temp-filebuffer (form body))
 (def-edebug-spec org-babel-with-temp-filebuffer (form body))
 
 
-;;;###autoload
-(defun org-babel-load-file (file &optional compile)
-  "Load Emacs Lisp source code blocks in the Org-mode FILE.
-This function exports the source code using `org-babel-tangle'
-and then loads the resulting file using `load-file'.  With prefix
-arg (noninteractively: 2nd arg) COMPILE the tangled Emacs Lisp
-file to byte-code before it is loaded."
-  (interactive "fFile to load: \nP")
-  (let* ((age (lambda (file)
-		(float-time
-		 (time-subtract (current-time)
-				(nth 5 (or (file-attributes (file-truename file))
-					   (file-attributes file)))))))
-	 (base-name (file-name-sans-extension file))
-	 (exported-file (concat base-name ".el")))
-    ;; tangle if the org-mode file is newer than the elisp file
-    (unless (and (file-exists-p exported-file)
-		 (> (funcall age file) (funcall age exported-file)))
-      (org-babel-tangle-file file exported-file "emacs-lisp"))
-    (message "%s %s"
-	     (if compile
-		 (progn (byte-compile-file exported-file 'load)
-			"Compiled and loaded")
-	       (progn (load-file exported-file) "Loaded"))
-	     exported-file)))
-
 ;;;###autoload
 ;;;###autoload
 (defun org-babel-tangle-file (file &optional target-file lang)
 (defun org-babel-tangle-file (file &optional target-file lang)
   "Extract the bodies of source code blocks in FILE.
   "Extract the bodies of source code blocks in FILE.
@@ -211,7 +188,7 @@ used to limit the exported source code blocks by language."
 	       org-babel-default-header-args))
 	       org-babel-default-header-args))
 	    (tangle-file
 	    (tangle-file
 	     (when (equal arg '(16))
 	     (when (equal arg '(16))
-	       (or (cdr (assoc :tangle (nth 2 (org-babel-get-src-block-info))))
+	       (or (cdr (assoc :tangle (nth 2 (org-babel-get-src-block-info 'light))))
 		   (user-error "Point is not in a source code block"))))
 		   (user-error "Point is not in a source code block"))))
 	    path-collector)
 	    path-collector)
 	(mapc ;; map over all languages
 	(mapc ;; map over all languages
@@ -233,6 +210,7 @@ used to limit the exported source code blocks by language."
 		  (let* ((tangle (funcall get-spec :tangle))
 		  (let* ((tangle (funcall get-spec :tangle))
 			 (she-bang ((lambda (sheb) (when (> (length sheb) 0) sheb))
 			 (she-bang ((lambda (sheb) (when (> (length sheb) 0) sheb))
 				    (funcall get-spec :shebang)))
 				    (funcall get-spec :shebang)))
+			 (tangle-mode (funcall get-spec :tangle-mode))
 			 (base-name (cond
 			 (base-name (cond
 				     ((string= "yes" tangle)
 				     ((string= "yes" tangle)
 				      (file-name-sans-extension
 				      (file-name-sans-extension
@@ -250,7 +228,7 @@ used to limit the exported source code blocks by language."
 			(make-directory (file-name-directory file-name) 'parents))
 			(make-directory (file-name-directory file-name) 'parents))
 		      ;; delete any old versions of file
 		      ;; delete any old versions of file
 		      (when (and (file-exists-p file-name)
 		      (when (and (file-exists-p file-name)
-				 (not (member file-name path-collector)))
+				 (not (member file-name (mapcar #'car path-collector))))
 			(delete-file file-name))
 			(delete-file file-name))
 		      ;; drop source-block to file
 		      ;; drop source-block to file
 		      (with-temp-buffer
 		      (with-temp-buffer
@@ -268,10 +246,14 @@ used to limit the exported source code blocks by language."
 			    (insert content)
 			    (insert content)
 			    (write-region nil nil file-name))))
 			    (write-region nil nil file-name))))
 		      ;; if files contain she-bangs, then make the executable
 		      ;; if files contain she-bangs, then make the executable
-		      (when she-bang (set-file-modes file-name #o755))
+		      (when she-bang
+			(unless tangle-mode (setq tangle-mode #o755)))
 		      ;; update counter
 		      ;; update counter
 		      (setq block-counter (+ 1 block-counter))
 		      (setq block-counter (+ 1 block-counter))
-		      (add-to-list 'path-collector file-name)))))
+		      (add-to-list 'path-collector
+				   (cons file-name tangle-mode)
+				   nil
+				   (lambda (a b) (equal (car a) (car b))))))))
 	      specs)))
 	      specs)))
 	 (if (equal arg '(4))
 	 (if (equal arg '(4))
 	     (org-babel-tangle-single-block 1 t)
 	     (org-babel-tangle-single-block 1 t)
@@ -279,15 +261,20 @@ used to limit the exported source code blocks by language."
 	(message "Tangled %d code block%s from %s" block-counter
 	(message "Tangled %d code block%s from %s" block-counter
 		 (if (= block-counter 1) "" "s")
 		 (if (= block-counter 1) "" "s")
 		 (file-name-nondirectory
 		 (file-name-nondirectory
-		  (buffer-file-name (or (buffer-base-buffer) (current-buffer)))))
+		  (buffer-file-name
+		   (or (buffer-base-buffer) (current-buffer)))))
 	;; run `org-babel-post-tangle-hook' in all tangled files
 	;; run `org-babel-post-tangle-hook' in all tangled files
 	(when org-babel-post-tangle-hook
 	(when org-babel-post-tangle-hook
 	  (mapc
 	  (mapc
 	   (lambda (file)
 	   (lambda (file)
 	     (org-babel-with-temp-filebuffer file
 	     (org-babel-with-temp-filebuffer file
 	       (run-hooks 'org-babel-post-tangle-hook)))
 	       (run-hooks 'org-babel-post-tangle-hook)))
-	   path-collector))
-	path-collector))))
+	   (mapcar #'car path-collector)))
+	;; set permissions on tangled files
+	(mapc (lambda (pair)
+		(when (cdr pair) (set-file-modes (car pair) (cdr pair))))
+	      path-collector)
+	(mapcar #'car path-collector)))))
 
 
 (defun org-babel-tangle-clean ()
 (defun org-babel-tangle-clean ()
   "Remove comments inserted by `org-babel-tangle'.
   "Remove comments inserted by `org-babel-tangle'.
@@ -519,13 +506,15 @@ which enable the original code blocks to be found."
   "Jump from a tangled code file to the related Org-mode file."
   "Jump from a tangled code file to the related Org-mode file."
   (interactive)
   (interactive)
   (let ((mid (point))
   (let ((mid (point))
-	start end done
+	start body-start end done
         target-buffer target-char link path block-name body)
         target-buffer target-char link path block-name body)
     (save-window-excursion
     (save-window-excursion
       (save-excursion
       (save-excursion
 	(while (and (re-search-backward org-bracket-link-analytic-regexp nil t)
 	(while (and (re-search-backward org-bracket-link-analytic-regexp nil t)
 		    (not ; ever wider searches until matching block comments
 		    (not ; ever wider searches until matching block comments
 		     (and (setq start (point-at-eol))
 		     (and (setq start (point-at-eol))
+			  (setq body-start (save-excursion
+					     (forward-line 2) (point-at-bol)))
 			  (setq link (match-string 0))
 			  (setq link (match-string 0))
 			  (setq path (match-string 3))
 			  (setq path (match-string 3))
 			  (setq block-name (match-string 5))
 			  (setq block-name (match-string 5))
@@ -546,8 +535,19 @@ which enable the original code blocks to be found."
           (org-babel-next-src-block
           (org-babel-next-src-block
            (string-to-number (match-string 1 block-name)))
            (string-to-number (match-string 1 block-name)))
         (org-babel-goto-named-src-block block-name))
         (org-babel-goto-named-src-block block-name))
+      ;; position at the beginning of the code block body
+      (goto-char (org-babel-where-is-src-block-head))
+      (forward-line 1)
+      ;; Use org-edit-special to isolate the code.
+      (org-edit-special)
+      ;; Then move forward the correct number of characters in the
+      ;; code buffer.
+      (forward-char (- mid body-start))
+      ;; And return to the Org-mode buffer with the point in the right
+      ;; place.
+      (org-edit-src-exit)
       (setq target-char (point)))
       (setq target-char (point)))
-    (pop-to-buffer target-buffer)
+    (org-src-switch-to-buffer target-buffer t)
     (prog1 body (goto-char target-char))))
     (prog1 body (goto-char target-char))))
 
 
 (provide 'ob-tangle)
 (provide 'ob-tangle)

+ 2 - 0
lisp/ob.el

@@ -22,6 +22,8 @@
 ;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
 ;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
 
 
 ;;; Code:
 ;;; Code:
+(require 'org-macs)
+(require 'org-compat)
 (require 'ob-eval)
 (require 'ob-eval)
 (require 'ob-core)
 (require 'ob-core)
 (require 'ob-comint)
 (require 'ob-comint)

Разница между файлами не показана из-за своего большого размера
+ 310 - 155
lisp/org-agenda.el


+ 8 - 3
lisp/org-bbdb.el

@@ -116,8 +116,10 @@
 (declare-function bbdb-search-name "ext:bbdb-com" (regexp &optional layout))
 (declare-function bbdb-search-name "ext:bbdb-com" (regexp &optional layout))
 (declare-function bbdb-search-organization "ext:bbdb-com" (regexp &optional layout))
 (declare-function bbdb-search-organization "ext:bbdb-com" (regexp &optional layout))
 
 
-;; `bbdb-record-note' is part of BBDB v3.x
+;; `bbdb-record-note' was part of BBDB v3.x
 (declare-function bbdb-record-note "ext:bbdb" (record label))
 (declare-function bbdb-record-note "ext:bbdb" (record label))
+;; `bbdb-record-xfield' replaces it in recent BBDB v3.x+
+(declare-function bbdb-record-xfield "ext:bbdb" (record label))
 
 
 (declare-function calendar-leap-year-p "calendar" (year))
 (declare-function calendar-leap-year-p "calendar" (year))
 (declare-function diary-ordinal-suffix "diary-lib" (n))
 (declare-function diary-ordinal-suffix "diary-lib" (n))
@@ -306,14 +308,17 @@ The hash table is created on first use.")
   "Create a hash with anniversaries extracted from BBDB, for fast access.
   "Create a hash with anniversaries extracted from BBDB, for fast access.
 The anniversaries are assumed to be stored `org-bbdb-anniversary-field'."
 The anniversaries are assumed to be stored `org-bbdb-anniversary-field'."
   (let ((old-bbdb (fboundp 'bbdb-record-getprop))
   (let ((old-bbdb (fboundp 'bbdb-record-getprop))
+	(record-func (if (fboundp 'bbdb-record-xfield)
+			 'bbdb-record-xfield
+		       'bbdb-record-note))
 	split tmp annivs)
 	split tmp annivs)
     (clrhash org-bbdb-anniv-hash)
     (clrhash org-bbdb-anniv-hash)
     (dolist (rec (bbdb-records))
     (dolist (rec (bbdb-records))
       (when (setq annivs (if old-bbdb
       (when (setq annivs (if old-bbdb
 			     (bbdb-record-getprop
 			     (bbdb-record-getprop
 			      rec org-bbdb-anniversary-field)
 			      rec org-bbdb-anniversary-field)
-			   (bbdb-record-note
-			    rec org-bbdb-anniversary-field)))
+			   (funcall record-func
+				    rec org-bbdb-anniversary-field)))
         (setq annivs (if old-bbdb
         (setq annivs (if old-bbdb
 			 (bbdb-split annivs "\n")
 			 (bbdb-split annivs "\n")
 		       ;; parameter order is reversed in new bbdb
 		       ;; parameter order is reversed in new bbdb

+ 4 - 2
lisp/org-bibtex.el

@@ -2,7 +2,7 @@
 ;;
 ;;
 ;; Copyright (C) 2007-2013 Free Software Foundation, Inc.
 ;; Copyright (C) 2007-2013 Free Software Foundation, Inc.
 ;;
 ;;
-;; Authors: Bastien Guerry <bzg at altern dot org>
+;; Authors: Bastien Guerry <bzg at gnu dot org>
 ;;       Carsten Dominik <carsten dot dominik at gmail dot com>
 ;;       Carsten Dominik <carsten dot dominik at gmail dot com>
 ;;       Eric Schulte <schulte dot eric at gmail dot com>
 ;;       Eric Schulte <schulte dot eric at gmail dot com>
 ;; Keywords: org, wp, capture
 ;; Keywords: org, wp, capture
@@ -224,7 +224,9 @@
 For example setting to 'BIB_' would allow interoperability with fireforg."
 For example setting to 'BIB_' would allow interoperability with fireforg."
   :group 'org-bibtex
   :group 'org-bibtex
   :version "24.1"
   :version "24.1"
-  :type  'string)
+  :type  '(choice
+	   (const nil)
+	   (string)))
 
 
 (defcustom org-bibtex-treat-headline-as-title t
 (defcustom org-bibtex-treat-headline-as-title t
   "Treat headline text as title if title property is absent.
   "Treat headline text as title if title property is absent.

+ 19 - 5
lisp/org-capture.el

@@ -181,6 +181,8 @@ properties are:
                      template only needs information that can be added
                      template only needs information that can be added
                      automatically.
                      automatically.
 
 
+ :jump-to-captured   When set, jump to the captured entry when finished.
+
  :empty-lines        Set this to the number of lines the should be inserted
  :empty-lines        Set this to the number of lines the should be inserted
                      before and after the new item.  Default 0, only common
                      before and after the new item.  Default 0, only common
                      other value is 1.
                      other value is 1.
@@ -339,11 +341,15 @@ calendar                |  %:type %:date"
 			 ;; Give the most common options as checkboxes
 			 ;; Give the most common options as checkboxes
 			 :options (((const :format "%v " :prepend) (const t))
 			 :options (((const :format "%v " :prepend) (const t))
 				   ((const :format "%v " :immediate-finish) (const t))
 				   ((const :format "%v " :immediate-finish) (const t))
+				   ((const :format "%v " :jump-to-captured) (const t))
 				   ((const :format "%v " :empty-lines) (const 1))
 				   ((const :format "%v " :empty-lines) (const 1))
+				   ((const :format "%v " :empty-lines-before) (const 1))
+				   ((const :format "%v " :empty-lines-after) (const 1))
 				   ((const :format "%v " :clock-in) (const t))
 				   ((const :format "%v " :clock-in) (const t))
 				   ((const :format "%v " :clock-keep) (const t))
 				   ((const :format "%v " :clock-keep) (const t))
 				   ((const :format "%v " :clock-resume) (const t))
 				   ((const :format "%v " :clock-resume) (const t))
 				   ((const :format "%v " :unnarrowed) (const t))
 				   ((const :format "%v " :unnarrowed) (const t))
+				   ((const :format "%v " :table-line-pos) (const t))
 				   ((const :format "%v " :kill-buffer) (const t))))))))
 				   ((const :format "%v " :kill-buffer) (const t))))))))
 
 
 (defcustom org-capture-before-finalize-hook nil
 (defcustom org-capture-before-finalize-hook nil
@@ -497,7 +503,7 @@ to avoid duplicates.)"
 
 
 (defcustom org-capture-use-agenda-date nil
 (defcustom org-capture-use-agenda-date nil
   "Non-nil means use the date at point when capturing from agendas.
   "Non-nil means use the date at point when capturing from agendas.
-When nil, you can still capturing using the date at point with \\[org-agenda-capture]]."
+When nil, you can still capture using the date at point with \\[org-agenda-capture]."
   :group 'org-capture
   :group 'org-capture
   :version "24.3"
   :version "24.3"
   :type 'boolean)
   :type 'boolean)
@@ -633,6 +639,8 @@ of the day at point (if any) or the current HH:MM time."
 With prefix argument STAY-WITH-CAPTURE, jump to the location of the
 With prefix argument STAY-WITH-CAPTURE, jump to the location of the
 captured item after finalizing."
 captured item after finalizing."
   (interactive "P")
   (interactive "P")
+  (when (org-capture-get :jump-to-captured)
+    (setq stay-with-capture t))
   (unless (and org-capture-mode
   (unless (and org-capture-mode
 	       (buffer-base-buffer (current-buffer)))
 	       (buffer-base-buffer (current-buffer)))
     (error "This does not seem to be a capture buffer for Org-mode"))
     (error "This does not seem to be a capture buffer for Org-mode"))
@@ -1410,7 +1418,8 @@ only the bare key is returned."
 	  (insert title "\n\n")
 	  (insert title "\n\n")
 	  (setq tbl table
 	  (setq tbl table
 		des-keys nil
 		des-keys nil
-		allowed-keys nil)
+		allowed-keys nil
+		cursor-type nil)
 	  (setq prefix (if current (concat current " ") ""))
 	  (setq prefix (if current (concat current " ") ""))
 	  (while tbl
 	  (while tbl
 	    (cond
 	    (cond
@@ -1423,7 +1432,8 @@ only the bare key is returned."
 	      (insert prefix "[" dkey "]" "..." "  " ddesc "..." "\n")
 	      (insert prefix "[" dkey "]" "..." "  " ddesc "..." "\n")
 	      ;; Skip keys which are below this prefix
 	      ;; Skip keys which are below this prefix
 	      (setq re (concat "\\`" (regexp-quote dkey)))
 	      (setq re (concat "\\`" (regexp-quote dkey)))
-	      (while (and tbl (string-match re (caar tbl))) (pop tbl)))
+	      (let (case-fold-search)
+		(while (and tbl (string-match re (caar tbl))) (pop tbl))))
 	     ((= 2 (length (car tbl)))
 	     ((= 2 (length (car tbl)))
 	      ;; Not yet a usable description, skip it
 	      ;; Not yet a usable description, skip it
 	      )
 	      )
@@ -1778,7 +1788,7 @@ Such keywords are prefixed with \"%:\".  See
 		   (position (or (nth 4 entry) org-remember-default-headline))
 		   (position (or (nth 4 entry) org-remember-default-headline))
 		   (type 'entry)
 		   (type 'entry)
 		   (prepend org-reverse-note-order)
 		   (prepend org-reverse-note-order)
-		   immediate target)
+		   immediate target jump-to-captured)
 	       (cond
 	       (cond
 		((member position '(top bottom))
 		((member position '(top bottom))
 		 (setq target (list 'file file)
 		 (setq target (list 'file file)
@@ -1792,9 +1802,13 @@ Such keywords are prefixed with \"%:\".  See
 		 (setq template (replace-match "" t t template)
 		 (setq template (replace-match "" t t template)
 		       immediate t))
 		       immediate t))
 
 
+	       (when (string-match "%&" template)
+		 (setq jump-to-captured t))
+
 	       (append (list key desc type target template)
 	       (append (list key desc type target template)
 		       (if prepend '(:prepend t))
 		       (if prepend '(:prepend t))
-		       (if immediate '(:immediate-finish t)))))
+		       (if immediate '(:immediate-finish t))
+		       (if jump-to-captured '(:jump-to-captured t)))))
 
 
 	   org-remember-templates))))
 	   org-remember-templates))))
 
 

+ 65 - 53
lisp/org-clock.el

@@ -159,7 +159,7 @@ state to switch it to."
 This is the string shown in the mode line when a clock is running.
 This is the string shown in the mode line when a clock is running.
 The function is called with point at the beginning of the headline."
 The function is called with point at the beginning of the headline."
   :group 'org-clock
   :group 'org-clock
-  :type 'function)
+  :type '(choice (const nil) (function)))
 
 
 (defcustom org-clock-string-limit 0
 (defcustom org-clock-string-limit 0
   "Maximum length of clock strings in the mode line.  0 means no limit."
   "Maximum length of clock strings in the mode line.  0 means no limit."
@@ -263,6 +263,7 @@ The function or program will be called with the notification
 string as argument."
 string as argument."
   :group 'org-clock
   :group 'org-clock
   :type '(choice
   :type '(choice
+	  (const nil)
 	  (string :tag "Program")
 	  (string :tag "Program")
 	  (function :tag "Function")))
 	  (function :tag "Function")))
 
 
@@ -514,46 +515,55 @@ of a different task.")
   "Hook called in task selection just before prompting the user.")
   "Hook called in task selection just before prompting the user.")
 
 
 (defun org-clock-select-task (&optional prompt)
 (defun org-clock-select-task (&optional prompt)
-  "Select a task that recently was associated with clocking."
+  "Select a task that was recently associated with clocking."
   (interactive)
   (interactive)
-  (let (sel-list rpl (i 0) s)
-    (save-window-excursion
-      (org-switch-to-buffer-other-window
-       (get-buffer-create "*Clock Task Select*"))
-      (erase-buffer)
-      (when (marker-buffer org-clock-default-task)
-	(insert (org-add-props "Default Task\n" nil 'face 'bold))
-	(setq s (org-clock-insert-selection-line ?d org-clock-default-task))
-	(push s sel-list))
-      (when (marker-buffer org-clock-interrupted-task)
-	(insert (org-add-props "The task interrupted by starting the last one\n" nil 'face 'bold))
-	(setq s (org-clock-insert-selection-line ?i org-clock-interrupted-task))
-	(push s sel-list))
-      (when (org-clocking-p)
-	(insert (org-add-props "Current Clocking Task\n" nil 'face 'bold))
-	(setq s (org-clock-insert-selection-line ?c org-clock-marker))
-	(push s sel-list))
-      (insert (org-add-props "Recent Tasks\n" nil 'face 'bold))
-      (mapc
-       (lambda (m)
-	 (when (marker-buffer m)
-	   (setq i (1+ i)
-		 s (org-clock-insert-selection-line
-		    (if (< i 10)
-			(+ i ?0)
-		      (+ i (- ?A 10))) m))
-	   (if (fboundp 'int-to-char) (setf (car s) (int-to-char (car s))))
-	   (push s sel-list)))
-       org-clock-history)
-      (run-hooks 'org-clock-before-select-task-hook)
-      (org-fit-window-to-buffer)
-      (message (or prompt "Select task for clocking:"))
-      (setq rpl (read-char-exclusive))
-      (cond
-       ((eq rpl ?q) nil)
-       ((eq rpl ?x) nil)
-       ((assoc rpl sel-list) (cdr (assoc rpl sel-list)))
-       (t (error "Invalid task choice %c" rpl))))))
+  (let (och chl sel-list rpl (i 0) s)
+    ;; Remove successive dups from the clock history to consider
+    (mapc (lambda (c) (if (not (equal c (car och))) (push c och)))
+	  org-clock-history)
+    (setq och (reverse och) chl (length och))
+    (if (zerop chl)
+	(user-error "No recent clock")
+      (save-window-excursion
+	(org-switch-to-buffer-other-window
+	 (get-buffer-create "*Clock Task Select*"))
+	(erase-buffer)
+	(when (marker-buffer org-clock-default-task)
+	  (insert (org-add-props "Default Task\n" nil 'face 'bold))
+	  (setq s (org-clock-insert-selection-line ?d org-clock-default-task))
+	  (push s sel-list))
+	(when (marker-buffer org-clock-interrupted-task)
+	  (insert (org-add-props "The task interrupted by starting the last one\n" nil 'face 'bold))
+	  (setq s (org-clock-insert-selection-line ?i org-clock-interrupted-task))
+	  (push s sel-list))
+	(when (org-clocking-p)
+	  (insert (org-add-props "Current Clocking Task\n" nil 'face 'bold))
+	  (setq s (org-clock-insert-selection-line ?c org-clock-marker))
+	  (push s sel-list))
+	(insert (org-add-props "Recent Tasks\n" nil 'face 'bold))
+	(mapc
+	 (lambda (m)
+	   (when (marker-buffer m)
+	     (setq i (1+ i)
+		   s (org-clock-insert-selection-line
+		      (if (< i 10)
+			  (+ i ?0)
+			(+ i (- ?A 10))) m))
+	     (if (fboundp 'int-to-char) (setf (car s) (int-to-char (car s))))
+	     (push s sel-list)))
+	 och)
+	(run-hooks 'org-clock-before-select-task-hook)
+	(goto-char (point-min))
+	;; Set min-height relatively to circumvent a possible but in
+	;; `fit-window-to-buffer'
+	(fit-window-to-buffer nil nil (if (< chl 10) chl (+ 5 chl)))
+	(message (or prompt "Select task for clocking:"))
+	(setq cursor-type nil rpl (read-char-exclusive))
+	(cond
+	 ((eq rpl ?q) nil)
+	 ((eq rpl ?x) nil)
+	 ((assoc rpl sel-list) (cdr (assoc rpl sel-list)))
+	 (t (user-error "Invalid task choice %c" rpl)))))))
 
 
 (defun org-clock-insert-selection-line (i marker)
 (defun org-clock-insert-selection-line (i marker)
   "Insert a line for the clock selection menu.
   "Insert a line for the clock selection menu.
@@ -580,7 +590,7 @@ pointing to it."
 			   org-odd-levels-only)
 			   org-odd-levels-only)
 			  (length prefix)))))))
 			  (length prefix)))))))
       (when (and cat task)
       (when (and cat task)
-	(insert (format "[%c] %-15s %s\n" i cat task))
+	(insert (format "[%c] %-12s  %s\n" i cat task))
 	(cons i marker)))))
 	(cons i marker)))))
 
 
 (defvar org-clock-task-overrun nil
 (defvar org-clock-task-overrun nil
@@ -656,9 +666,12 @@ previous clocking intervals."
   "Add to or set the effort estimate of the item currently being clocked.
   "Add to or set the effort estimate of the item currently being clocked.
 VALUE can be a number of minutes, or a string with format hh:mm or mm.
 VALUE can be a number of minutes, or a string with format hh:mm or mm.
 When the string starts with a + or a - sign, the current value of the effort
 When the string starts with a + or a - sign, the current value of the effort
-property will be changed by that amount.
-This will update the \"Effort\" property of currently clocked item, and
-the mode line."
+property will be changed by that amount.  If the effort value is expressed
+as an `org-effort-durations' (e.g. \"3h\"), the modificied value will be
+converted to a hh:mm duration.
+
+This command will update the \"Effort\" property of the currently
+clocked item, and the value displayed in the mode line."
   (interactive)
   (interactive)
   (if (org-clock-is-active)
   (if (org-clock-is-active)
       (let ((current org-clock-effort) sign)
       (let ((current org-clock-effort) sign)
@@ -926,19 +939,23 @@ was started."
 		(with-output-to-temp-buffer "*Org Clock*"
 		(with-output-to-temp-buffer "*Org Clock*"
 		  (princ "Select a Clock Resolution Command:
 		  (princ "Select a Clock Resolution Command:
 
 
-i/q/C-g  Ignore this question; the same as keeping all the idle time.
+i/q      Ignore this question; the same as keeping all the idle time.
 
 
 k/K      Keep X minutes of the idle time (default is all).  If this
 k/K      Keep X minutes of the idle time (default is all).  If this
          amount is less than the default, you will be clocked out
          amount is less than the default, you will be clocked out
          that many minutes after the time that idling began, and then
          that many minutes after the time that idling began, and then
          clocked back in at the present time.
          clocked back in at the present time.
+
 g/G      Indicate that you \"got back\" X minutes ago.  This is quite
 g/G      Indicate that you \"got back\" X minutes ago.  This is quite
          different from 'k': it clocks you out from the beginning of
          different from 'k': it clocks you out from the beginning of
          the idle period and clock you back in X minutes ago.
          the idle period and clock you back in X minutes ago.
+
 s/S      Subtract the idle time from the current clock.  This is the
 s/S      Subtract the idle time from the current clock.  This is the
          same as keeping 0 minutes.
          same as keeping 0 minutes.
+
 C        Cancel the open timer altogether.  It will be as though you
 C        Cancel the open timer altogether.  It will be as though you
          never clocked in.
          never clocked in.
+
 j/J      Jump to the current clock, to make manual adjustments.
 j/J      Jump to the current clock, to make manual adjustments.
 
 
 For all these options, using uppercase makes your final state
 For all these options, using uppercase makes your final state
@@ -1076,7 +1093,7 @@ This is performed after `org-clock-idle-time' minutes, to check
 if the user really wants to stay clocked in after being idle for
 if the user really wants to stay clocked in after being idle for
 so long."
 so long."
   (when (and org-clock-idle-time (not org-clock-resolving-clocks)
   (when (and org-clock-idle-time (not org-clock-resolving-clocks)
-	     org-clock-marker)
+	     org-clock-marker (marker-buffer org-clock-marker))
     (let* ((org-clock-user-idle-seconds (org-user-idle-seconds))
     (let* ((org-clock-user-idle-seconds (org-user-idle-seconds))
 	   (org-clock-user-idle-start
 	   (org-clock-user-idle-start
 	    (time-subtract (current-time)
 	    (time-subtract (current-time)
@@ -1186,13 +1203,8 @@ make this the default behavior.)"
 	    (goto-char target-pos)
 	    (goto-char target-pos)
 	    (org-back-to-heading t)
 	    (org-back-to-heading t)
 	    (or interrupting (move-marker org-clock-interrupted-task nil))
 	    (or interrupting (move-marker org-clock-interrupted-task nil))
-	    (save-excursion
-	      (forward-char) ;; make sure the marker is not at the
-	      ;; beginning of the heading, since the
-	      ;; user is liking to insert stuff here
-	      ;; manually
-	      (run-hooks 'org-clock-in-prepare-hook)
-	      (org-clock-history-push))
+	    (run-hooks 'org-clock-in-prepare-hook)
+	    (org-clock-history-push)
 	    (setq org-clock-current-task (nth 4 (org-heading-components)))
 	    (setq org-clock-current-task (nth 4 (org-heading-components)))
 	    (cond ((functionp org-clock-in-switch-to-state)
 	    (cond ((functionp org-clock-in-switch-to-state)
 		   (looking-at org-complex-heading-regexp)
 		   (looking-at org-complex-heading-regexp)

+ 35 - 12
lisp/org-compat.el

@@ -113,18 +113,41 @@ any other entries, and any resulting duplicates will be removed entirely."
 
 
 ;;;; Emacs/XEmacs compatibility
 ;;;; Emacs/XEmacs compatibility
 
 
-(defun org-defvaralias (new-alias base-variable &optional docstring)
-  "Compatibility function for defvaralias.
+(eval-and-compile
+  (defun org-defvaralias (new-alias base-variable &optional docstring)
+    "Compatibility function for defvaralias.
 Don't do the aliasing when `defvaralias' is not bound."
 Don't do the aliasing when `defvaralias' is not bound."
-  (declare (indent 1))
-  (when (fboundp 'defvaralias)
-    (defvaralias new-alias base-variable docstring)))
+    (declare (indent 1))
+    (when (fboundp 'defvaralias)
+      (defvaralias new-alias base-variable docstring)))
 
 
-(eval-and-compile
   (when (and (not (boundp 'user-emacs-directory))
   (when (and (not (boundp 'user-emacs-directory))
 	     (boundp 'user-init-directory))
 	     (boundp 'user-init-directory))
     (org-defvaralias 'user-emacs-directory 'user-init-directory)))
     (org-defvaralias 'user-emacs-directory 'user-init-directory)))
 
 
+(when (featurep 'xemacs)
+  (defadvice custom-handle-keyword
+    (around org-custom-handle-keyword
+	    activate preactivate)
+    "Remove custom keywords not recognized to avoid producing an error."
+    (cond
+     ((eq (ad-get-arg 1) :package-version))
+     (t ad-do-it)))
+  (defadvice define-obsolete-variable-alias
+    (around org-define-obsolete-variable-alias
+	    (obsolete-name current-name &optional when docstring)
+	    activate preactivate)
+    "Declare arguments defined in later versions of Emacs."
+    ad-do-it)
+  (defadvice define-obsolete-function-alias
+    (around org-define-obsolete-function-alias
+	    (obsolete-name current-name &optional when docstring)
+	    activate preactivate)
+    "Declare arguments defined in later versions of Emacs."
+    ad-do-it)
+  (defvar customize-package-emacs-version-alist nil)
+  (defvar temporary-file-directory (temp-directory)))
+
 ;; Keys
 ;; Keys
 (defconst org-xemacs-key-equivalents
 (defconst org-xemacs-key-equivalents
   '(([mouse-1] . [button1])
   '(([mouse-1] . [button1])
@@ -238,7 +261,7 @@ ignored in this case."
 ;; Region compatibility
 ;; Region compatibility
 
 
 (defvar org-ignore-region nil
 (defvar org-ignore-region nil
-  "To temporarily disable the active region.")
+  "Non-nil means temporarily disable the active region.")
 
 
 (defun org-region-active-p ()
 (defun org-region-active-p ()
   "Is `transient-mark-mode' on and the region active?
   "Is `transient-mark-mode' on and the region active?
@@ -390,11 +413,11 @@ TIME defaults to the current time."
   "Suppress popup windows.
   "Suppress popup windows.
 Let-bind some variables to nil around BODY to achieve the desired
 Let-bind some variables to nil around BODY to achieve the desired
 effect, which variables to use depends on the Emacs version."
 effect, which variables to use depends on the Emacs version."
-    (if (org-version-check "24.2.50" "" :predicate)
-	`(let (pop-up-frames display-buffer-alist)
-	   ,@body)
-      `(let (pop-up-frames special-display-buffer-names special-display-regexps special-display-function)
-	 ,@body)))
+  (if (org-version-check "24.2.50" "" :predicate)
+      `(let (pop-up-frames display-buffer-alist)
+	 ,@body)
+    `(let (pop-up-frames special-display-buffer-names special-display-regexps special-display-function)
+       ,@body)))
 
 
 (if (fboundp 'string-match-p)
 (if (fboundp 'string-match-p)
     (defalias 'org-string-match-p 'string-match-p)
     (defalias 'org-string-match-p 'string-match-p)

+ 6 - 6
lisp/org-crypt.el

@@ -139,11 +139,11 @@ See `org-crypt-disable-auto-save'."
       (message "org-decrypt: Decrypting entry with auto-save-mode enabled.  This may cause leakage."))
       (message "org-decrypt: Decrypting entry with auto-save-mode enabled.  This may cause leakage."))
      ((eq org-crypt-disable-auto-save 'encrypt)
      ((eq org-crypt-disable-auto-save 'encrypt)
       (message "org-decrypt: Enabling re-encryption on auto-save.")
       (message "org-decrypt: Enabling re-encryption on auto-save.")
-      (add-hook 'auto-save-hook
-		(lambda ()
-		  (message "org-crypt: Re-encrypting all decrypted entries due to auto-save.")
-		  (org-encrypt-entries))
-		nil t))
+      (org-add-hook 'auto-save-hook
+		    (lambda ()
+		      (message "org-crypt: Re-encrypting all decrypted entries due to auto-save.")
+		      (org-encrypt-entries))
+		    nil t))
      (t nil))))
      (t nil))))
 
 
 (defun org-crypt-key-for-heading ()
 (defun org-crypt-key-for-heading ()
@@ -264,7 +264,7 @@ See `org-crypt-disable-auto-save'."
   "Add a hook to automatically encrypt entries before a file is saved to disk."
   "Add a hook to automatically encrypt entries before a file is saved to disk."
   (add-hook
   (add-hook
    'org-mode-hook
    'org-mode-hook
-   (lambda () (add-hook 'before-save-hook 'org-encrypt-entries nil t))))
+   (lambda () (org-add-hook 'before-save-hook 'org-encrypt-entries nil t))))
 
 
 (add-hook 'org-reveal-start-hook 'org-decrypt-entry)
 (add-hook 'org-reveal-start-hook 'org-decrypt-entry)
 
 

+ 2 - 5
lisp/org-ctags.el

@@ -156,11 +156,8 @@ Format is: /REGEXP/TAGNAME/FLAGS,TAGTYPE/
 See the ctags documentation for more information.")
 See the ctags documentation for more information.")
 
 
 (defcustom org-ctags-path-to-ctags
 (defcustom org-ctags-path-to-ctags
-  (case system-type
-    (windows-nt "ctags.exe")
-    (darwin "ctags-exuberant")
-    (t "ctags-exuberant"))
-  "Full path to the ctags executable file."
+  (if (executable-find "ctags-exuberant") "ctags-exuberant" "ctags")
+  "Name of the ctags executable file."
   :group 'org-ctags
   :group 'org-ctags
   :version "24.1"
   :version "24.1"
   :type 'file)
   :type 'file)

+ 4 - 1
lisp/org-datetree.el

@@ -72,7 +72,8 @@ tree can be found."
       (goto-char (prog1 (point) (widen))))))
       (goto-char (prog1 (point) (widen))))))
 
 
 (defun org-datetree-find-year-create (year)
 (defun org-datetree-find-year-create (year)
-  (let ((re "^\\*+[ \t]+\\([12][0-9]\\{3\\}\\)\\(.*?\\([ \t]:[[:alnum:]:_@#%]+:\\)?\\s-*$\\)")
+  "Find the YEAR datetree or create it."
+  (let ((re "^\\*+[ \t]+\\([12][0-9]\\{3\\}\\)\\(\\s-*?\\([ \t]:[[:alnum:]:_@#%]+:\\)?\\s-*$\\)")
 	match)
 	match)
     (goto-char (point-min))
     (goto-char (point-min))
     (while (and (setq match (re-search-forward re nil t))
     (while (and (setq match (re-search-forward re nil t))
@@ -90,6 +91,7 @@ tree can be found."
       (org-datetree-insert-line year)))))
       (org-datetree-insert-line year)))))
 
 
 (defun org-datetree-find-month-create (year month)
 (defun org-datetree-find-month-create (year month)
+  "Find the datetree for YEAR and MONTH or create it."
   (org-narrow-to-subtree)
   (org-narrow-to-subtree)
   (let ((re (format "^\\*+[ \t]+%d-\\([01][0-9]\\) \\w+$" year))
   (let ((re (format "^\\*+[ \t]+%d-\\([01][0-9]\\) \\w+$" year))
 	match)
 	match)
@@ -109,6 +111,7 @@ tree can be found."
       (org-datetree-insert-line year month)))))
       (org-datetree-insert-line year month)))))
 
 
 (defun org-datetree-find-day-create (year month day)
 (defun org-datetree-find-day-create (year month day)
+  "Find the datetree for YEAR, MONTH and DAY or create it."
   (org-narrow-to-subtree)
   (org-narrow-to-subtree)
   (let ((re (format "^\\*+[ \t]+%d-%02d-\\([0123][0-9]\\) \\w+$" year month))
   (let ((re (format "^\\*+[ \t]+%d-%02d-\\([0123][0-9]\\) \\w+$" year month))
 	match)
 	match)

+ 197 - 59
lisp/org-element.el

@@ -160,7 +160,7 @@
           ;; Lists.
           ;; Lists.
           (let ((term (case org-plain-list-ordered-item-terminator
           (let ((term (case org-plain-list-ordered-item-terminator
                         (?\) ")") (?. "\\.") (otherwise "[.)]")))
                         (?\) ")") (?. "\\.") (otherwise "[.)]")))
-                (alpha (and org-alphabetical-lists "\\|[A-Za-z]")))
+                (alpha (and org-list-allow-alphabetical "\\|[A-Za-z]")))
             (concat "\\(?:[-+*]\\|\\(?:[0-9]+" alpha "\\)" term "\\)"
             (concat "\\(?:[-+*]\\|\\(?:[0-9]+" alpha "\\)" term "\\)"
                     "\\(?:[ \t]\\|$\\)"))
                     "\\(?:[ \t]\\|$\\)"))
           "\\)\\)")
           "\\)\\)")
@@ -1146,6 +1146,90 @@ CONTENTS is the contents of the element."
 
 
 ;;;; Plain List
 ;;;; Plain List
 
 
+(defun org-element--list-struct (limit)
+  ;; Return structure of list at point.  Internal function.  See
+  ;; `org-list-struct' for details.
+  (let ((case-fold-search t)
+	(top-ind limit)
+	(item-re (org-item-re))
+	(drawers-re (concat ":\\("
+			    (mapconcat 'regexp-quote org-drawers "\\|")
+			    "\\):[ \t]*$"))
+	(inlinetask-re (and (featurep 'org-inlinetask) "^\\*+ "))
+	items struct)
+    (save-excursion
+      (catch 'exit
+	(while t
+	  (cond
+	   ;; At limit: end all items.
+	   ((>= (point) limit)
+	    (throw 'exit
+		   (let ((end (progn (skip-chars-backward " \r\t\n")
+				     (forward-line)
+				     (point))))
+		     (dolist (item items (sort (nconc items struct)
+					       'car-less-than-car))
+		       (setcar (nthcdr 6 item) end)))))
+	   ;; At list end: end all items.
+	   ((looking-at org-list-end-re)
+	    (throw 'exit (dolist (item items (sort (nconc items struct)
+						   'car-less-than-car))
+			   (setcar (nthcdr 6 item) (point)))))
+	   ;; At a new item: end previous sibling.
+	   ((looking-at item-re)
+	    (let ((ind (save-excursion (skip-chars-forward " \t")
+				       (current-column))))
+	      (setq top-ind (min top-ind ind))
+	      (while (and items (<= ind (nth 1 (car items))))
+		(let ((item (pop items)))
+		  (setcar (nthcdr 6 item) (point))
+		  (push item struct)))
+	      (push (progn (looking-at org-list-full-item-re)
+			   (let ((bullet (match-string-no-properties 1)))
+			     (list (point)
+				   ind
+				   bullet
+				   (match-string-no-properties 2) ; counter
+				   (match-string-no-properties 3) ; checkbox
+				   ;; Description tag.
+				   (and (save-match-data
+					  (string-match "[-+*]" bullet))
+					(match-string-no-properties 4))
+				   ;; Ending position, unknown so far.
+				   nil)))
+		    items))
+	    (forward-line 1))
+	   ;; Skip empty lines.
+	   ((looking-at "^[ \t]*$") (forward-line))
+	   ;; Skip inline tasks and blank lines along the way.
+	   ((and inlinetask-re (looking-at inlinetask-re))
+	    (forward-line)
+	    (let ((origin (point)))
+	      (when (re-search-forward inlinetask-re limit t)
+		(if (looking-at "^\\*+ END[ \t]*$") (forward-line)
+		  (goto-char origin)))))
+	   ;; At some text line.  Check if it ends any previous item.
+	   (t
+	    (let ((ind (progn (skip-chars-forward " \t") (current-column))))
+	      (when (<= ind top-ind)
+		(skip-chars-backward " \r\t\n")
+		(forward-line))
+	      (while (<= ind (nth 1 (car items)))
+		(let ((item (pop items)))
+		  (setcar (nthcdr 6 item) (line-beginning-position))
+		  (push item struct)
+		  (unless items
+		    (throw 'exit (sort struct 'car-less-than-car))))))
+	    ;; Skip blocks (any type) and drawers contents.
+	    (cond
+	     ((and (looking-at "#\\+BEGIN\\(:[ \t]*$\\|_\\S-\\)+")
+		   (re-search-forward
+		    (format "^[ \t]*#\\+END%s[ \t]*$" (match-string 1))
+		    limit t)))
+	     ((and (looking-at drawers-re)
+		   (re-search-forward "^[ \t]*:END:[ \t]*$" limit t))))
+	    (forward-line))))))))
+
 (defun org-element-plain-list-parser (limit affiliated structure)
 (defun org-element-plain-list-parser (limit affiliated structure)
   "Parse a plain list.
   "Parse a plain list.
 
 
@@ -1162,9 +1246,8 @@ containing `:type', `:begin', `:end', `:contents-begin' and
 
 
 Assume point is at the beginning of the list."
 Assume point is at the beginning of the list."
   (save-excursion
   (save-excursion
-    (let* ((struct (or structure (org-list-struct)))
+    (let* ((struct (or structure (org-element--list-struct limit)))
 	   (prevs (org-list-prevs-alist struct))
 	   (prevs (org-list-prevs-alist struct))
-	   (parents (org-list-parents-alist struct))
 	   (type (org-list-get-list-type (point) struct prevs))
 	   (type (org-list-get-list-type (point) struct prevs))
 	   (contents-begin (point))
 	   (contents-begin (point))
 	   (begin (car affiliated))
 	   (begin (car affiliated))
@@ -1353,11 +1436,12 @@ containing `:type', `:begin', `:end', `:hiddenp',
 
 
 Assume point is at the beginning of the block."
 Assume point is at the beginning of the block."
   (let* ((case-fold-search t)
   (let* ((case-fold-search t)
-	 (type (progn (looking-at "[ \t]*#\\+BEGIN_\\(S-+\\)")
+	 (type (progn (looking-at "[ \t]*#\\+BEGIN_\\(\\S-+\\)")
 		      (upcase (match-string-no-properties 1)))))
 		      (upcase (match-string-no-properties 1)))))
     (if (not (save-excursion
     (if (not (save-excursion
 	       (re-search-forward
 	       (re-search-forward
-		(format "^[ \t]*#\\+END_%s[ \t]*$" type) limit t)))
+		(format "^[ \t]*#\\+END_%s[ \t]*$" (regexp-quote type))
+		limit t)))
 	;; Incomplete block: parse it as a paragraph.
 	;; Incomplete block: parse it as a paragraph.
 	(org-element-paragraph-parser limit affiliated)
 	(org-element-paragraph-parser limit affiliated)
       (let ((block-end-line (match-beginning 0)))
       (let ((block-end-line (match-beginning 0)))
@@ -1648,6 +1732,35 @@ CONTENTS is nil."
 
 
 ;;;; Example Block
 ;;;; Example Block
 
 
+(defun org-element--remove-indentation (s &optional n)
+  "Remove maximum common indentation in string S and return it.
+When optional argument N is a positive integer, remove exactly
+that much characters from indentation, if possible, or return
+S as-is otherwise.  Unlike to `org-remove-indentation', this
+function doesn't call `untabify' on S."
+  (catch 'exit
+    (with-temp-buffer
+      (insert s)
+      (goto-char (point-min))
+      ;; Find maximum common indentation, if not specified.
+      (setq n (or n
+                  (let ((min-ind (point-max)))
+		    (save-excursion
+		      (while (re-search-forward "^[ \t]*\\S-" nil t)
+			(let ((ind (1- (current-column))))
+			  (if (zerop ind) (throw 'exit s)
+			    (setq min-ind (min min-ind ind))))))
+		    min-ind)))
+      (if (zerop n) s
+	;; Remove exactly N indentation, but give up if not possible.
+	(while (not (eobp))
+	  (let ((ind (progn (skip-chars-forward " \t") (current-column))))
+	    (cond ((eolp) (delete-region (line-beginning-position) (point)))
+		  ((< ind n) (throw 'exit s))
+		  (t (org-indent-line-to (- ind n))))
+	    (forward-line)))
+	(buffer-string)))))
+
 (defun org-element-example-block-parser (limit affiliated)
 (defun org-element-example-block-parser (limit affiliated)
   "Parse an example block.
   "Parse an example block.
 
 
@@ -1669,13 +1782,17 @@ keywords."
       (let ((contents-end (match-beginning 0)))
       (let ((contents-end (match-beginning 0)))
 	(save-excursion
 	(save-excursion
 	  (let* ((switches
 	  (let* ((switches
-		  (progn (looking-at "^[ \t]*#\\+BEGIN_EXAMPLE\\(?: +\\(.*\\)\\)?")
-			 (org-match-string-no-properties 1)))
+		  (progn
+		    (looking-at "^[ \t]*#\\+BEGIN_EXAMPLE\\(?: +\\(.*\\)\\)?")
+		    (org-match-string-no-properties 1)))
 		 ;; Switches analysis
 		 ;; Switches analysis
-		 (number-lines (cond ((not switches) nil)
-				     ((string-match "-n\\>" switches) 'new)
-				     ((string-match "+n\\>" switches) 'continued)))
-		 (preserve-indent (and switches (string-match "-i\\>" switches)))
+		 (number-lines
+		  (cond ((not switches) nil)
+			((string-match "-n\\>" switches) 'new)
+			((string-match "+n\\>" switches) 'continued)))
+		 (preserve-indent
+		  (or org-src-preserve-indentation
+		      (and switches (string-match "-i\\>" switches))))
 		 ;; Should labels be retained in (or stripped from) example
 		 ;; Should labels be retained in (or stripped from) example
 		 ;; blocks?
 		 ;; blocks?
 		 (retain-labels
 		 (retain-labels
@@ -1686,18 +1803,23 @@ keywords."
 		 ;; line-numbers?
 		 ;; line-numbers?
 		 (use-labels
 		 (use-labels
 		  (or (not switches)
 		  (or (not switches)
-		      (and retain-labels (not (string-match "-k\\>" switches)))))
-		 (label-fmt (and switches
-				 (string-match "-l +\"\\([^\"\n]+\\)\"" switches)
-				 (match-string 1 switches)))
+		      (and retain-labels
+			   (not (string-match "-k\\>" switches)))))
+		 (label-fmt
+		  (and switches
+		       (string-match "-l +\"\\([^\"\n]+\\)\"" switches)
+		       (match-string 1 switches)))
 		 ;; Standard block parsing.
 		 ;; Standard block parsing.
 		 (begin (car affiliated))
 		 (begin (car affiliated))
 		 (post-affiliated (point))
 		 (post-affiliated (point))
+		 (block-ind (progn (skip-chars-forward " \t") (current-column)))
 		 (contents-begin (progn (forward-line) (point)))
 		 (contents-begin (progn (forward-line) (point)))
 		 (hidden (org-invisible-p2))
 		 (hidden (org-invisible-p2))
-		 (value (org-unescape-code-in-string
-			 (buffer-substring-no-properties
-			  contents-begin contents-end)))
+		 (value (org-element--remove-indentation
+			 (org-unescape-code-in-string
+			  (buffer-substring-no-properties
+			   contents-begin contents-end))
+			 (and preserve-indent block-ind)))
 		 (pos-before-blank (progn (goto-char contents-end)
 		 (pos-before-blank (progn (goto-char contents-end)
 					  (forward-line)
 					  (forward-line)
 					  (point)))
 					  (point)))
@@ -1725,9 +1847,8 @@ keywords."
 CONTENTS is nil."
 CONTENTS is nil."
   (let ((switches (org-element-property :switches example-block)))
   (let ((switches (org-element-property :switches example-block)))
     (concat "#+BEGIN_EXAMPLE" (and switches (concat " " switches)) "\n"
     (concat "#+BEGIN_EXAMPLE" (and switches (concat " " switches)) "\n"
-	    (org-remove-indentation
-	     (org-escape-code-in-string
-	      (org-element-property :value example-block)))
+	    (org-escape-code-in-string
+	     (org-element-property :value example-block))
 	    "#+END_EXAMPLE")))
 	    "#+END_EXAMPLE")))
 
 
 
 
@@ -1834,8 +1955,11 @@ Assume point is at the beginning of the fixed-width area."
 (defun org-element-fixed-width-interpreter (fixed-width contents)
 (defun org-element-fixed-width-interpreter (fixed-width contents)
   "Interpret FIXED-WIDTH element as Org syntax.
   "Interpret FIXED-WIDTH element as Org syntax.
 CONTENTS is nil."
 CONTENTS is nil."
-  (replace-regexp-in-string
-   "^" ": " (substring (org-element-property :value fixed-width) 0 -1)))
+  (let ((value (org-element-property :value fixed-width)))
+    (and value
+	 (replace-regexp-in-string
+	  "^" ": "
+	  (if (string-match "\n\\'" value) (substring value 0 -1) value)))))
 
 
 
 
 ;;;; Horizontal Rule
 ;;;; Horizontal Rule
@@ -1970,11 +2094,11 @@ Return a list whose CAR is `node-property' and CDR is a plist
 containing `:key', `:value', `:begin', `:end' and `:post-blank'
 containing `:key', `:value', `:begin', `:end' and `:post-blank'
 keywords."
 keywords."
   (save-excursion
   (save-excursion
+    (looking-at org-property-re)
     (let ((case-fold-search t)
     (let ((case-fold-search t)
 	  (begin (point))
 	  (begin (point))
-	  (key (progn (looking-at "[ \t]*:\\(.*?\\):[ \t]+\\(.*?\\)[ \t]*$")
-		      (org-match-string-no-properties 1)))
-	  (value (org-match-string-no-properties 2))
+	  (key   (org-match-string-no-properties 2))
+	  (value (org-match-string-no-properties 3))
 	  (pos-before-blank (progn (forward-line) (point)))
 	  (pos-before-blank (progn (forward-line) (point)))
 	  (end (progn (skip-chars-forward " \r\t\n" limit)
 	  (end (progn (skip-chars-forward " \r\t\n" limit)
 		      (if (eobp) (point) (point-at-bol)))))
 		      (if (eobp) (point) (point-at-bol)))))
@@ -2221,13 +2345,17 @@ Assume point is at the beginning of the block."
 		 ;; Get parameters.
 		 ;; Get parameters.
 		 (parameters (org-match-string-no-properties 3))
 		 (parameters (org-match-string-no-properties 3))
 		 ;; Switches analysis
 		 ;; Switches analysis
-		 (number-lines (cond ((not switches) nil)
-				     ((string-match "-n\\>" switches) 'new)
-				     ((string-match "+n\\>" switches) 'continued)))
-		 (preserve-indent (and switches (string-match "-i\\>" switches)))
-		 (label-fmt (and switches
-				 (string-match "-l +\"\\([^\"\n]+\\)\"" switches)
-				 (match-string 1 switches)))
+		 (number-lines
+		  (cond ((not switches) nil)
+			((string-match "-n\\>" switches) 'new)
+			((string-match "+n\\>" switches) 'continued)))
+		 (preserve-indent (or org-src-preserve-indentation
+				      (and switches
+					   (string-match "-i\\>" switches))))
+		 (label-fmt
+		  (and switches
+		       (string-match "-l +\"\\([^\"\n]+\\)\"" switches)
+		       (match-string 1 switches)))
 		 ;; Should labels be retained in (or stripped from)
 		 ;; Should labels be retained in (or stripped from)
 		 ;; src blocks?
 		 ;; src blocks?
 		 (retain-labels
 		 (retain-labels
@@ -2238,12 +2366,18 @@ Assume point is at the beginning of the block."
 		 ;; line-numbers?
 		 ;; line-numbers?
 		 (use-labels
 		 (use-labels
 		  (or (not switches)
 		  (or (not switches)
-		      (and retain-labels (not (string-match "-k\\>" switches)))))
+		      (and retain-labels
+			   (not (string-match "-k\\>" switches)))))
+		 ;; Indentation.
+		 (block-ind (progn (skip-chars-forward " \t") (current-column)))
 		 ;; Get visibility status.
 		 ;; Get visibility status.
 		 (hidden (progn (forward-line) (org-invisible-p2)))
 		 (hidden (progn (forward-line) (org-invisible-p2)))
 		 ;; Retrieve code.
 		 ;; Retrieve code.
-		 (value (org-unescape-code-in-string
-			 (buffer-substring-no-properties (point) contents-end)))
+		 (value (org-element--remove-indentation
+			 (org-unescape-code-in-string
+			  (buffer-substring-no-properties
+			   (point) contents-end))
+			 (and preserve-indent block-ind)))
 		 (pos-before-blank (progn (goto-char contents-end)
 		 (pos-before-blank (progn (goto-char contents-end)
 					  (forward-line)
 					  (forward-line)
 					  (point)))
 					  (point)))
@@ -2279,15 +2413,13 @@ CONTENTS is nil."
 	(params (org-element-property :parameters src-block))
 	(params (org-element-property :parameters src-block))
 	(value (let ((val (org-element-property :value src-block)))
 	(value (let ((val (org-element-property :value src-block)))
 		 (cond
 		 (cond
-		  (org-src-preserve-indentation val)
-		  ((zerop org-edit-src-content-indentation)
-		   (org-remove-indentation val))
+		  ((org-element-property :preserve-indent src-block) val)
+		  ((zerop org-edit-src-content-indentation) val)
 		  (t
 		  (t
 		   (let ((ind (make-string
 		   (let ((ind (make-string
 			       org-edit-src-content-indentation 32)))
 			       org-edit-src-content-indentation 32)))
 		     (replace-regexp-in-string
 		     (replace-regexp-in-string
-		      "\\(^\\)[ \t]*\\S-" ind
-		      (org-remove-indentation val) nil nil 1)))))))
+		      "\\(^\\)[ \t]*\\S-" ind val nil nil 1)))))))
     (concat (format "#+BEGIN_SRC%s\n"
     (concat (format "#+BEGIN_SRC%s\n"
 		    (concat (and lang (concat " " lang))
 		    (concat (and lang (concat " " lang))
 			    (and switches (concat " " switches))
 			    (and switches (concat " " switches))
@@ -3117,20 +3249,19 @@ Assume point is at the macro."
 	  (post-blank (progn (goto-char (match-end 0))
 	  (post-blank (progn (goto-char (match-end 0))
 			     (skip-chars-forward " \t")))
 			     (skip-chars-forward " \t")))
 	  (end (point))
 	  (end (point))
-	  (args (let ((args (org-match-string-no-properties 3)) args2)
+	  (args (let ((args (org-match-string-no-properties 3)))
 		  (when args
 		  (when args
 		    ;; Do not use `org-split-string' since empty
 		    ;; Do not use `org-split-string' since empty
 		    ;; strings are meaningful here.
 		    ;; strings are meaningful here.
-		    (setq args (split-string args ","))
-		    (while args
-		      (while (string-match "\\\\\\'" (car args))
-			;; Repair bad splits, when comma is protected,
-                        ;; and thus not a real separator.
-			(setcar (cdr args) (concat (substring (car args) 0 -1)
-						   "," (nth 1 args)))
-			(pop args))
-		      (push (pop args) args2))
-		    (mapcar 'org-trim (nreverse args2))))))
+		    (split-string
+		     (replace-regexp-in-string
+		      "\\(\\\\*\\)\\(,\\)"
+		      (lambda (str)
+			(let ((len (length (match-string 1 str))))
+			  (concat (make-string (/ len 2) ?\\)
+				  (if (zerop (mod len 2)) "\000" ","))))
+		      args nil t)
+		     "\000")))))
       (list 'macro
       (list 'macro
 	    (list :key key
 	    (list :key key
 		  :value value
 		  :value value
@@ -3394,7 +3525,7 @@ LIMIT bounds the search.
 
 
 Return value is a cons cell whose CAR is `table-cell' and CDR is
 Return value is a cons cell whose CAR is `table-cell' and CDR is
 beginning position."
 beginning position."
-  (when (looking-at "[ \t]*.*?[ \t]+|") (cons 'table-cell (point))))
+  (when (looking-at "[ \t]*.*?[ \t]*|") (cons 'table-cell (point))))
 
 
 
 
 ;;;; Target
 ;;;; Target
@@ -3773,7 +3904,8 @@ element it has to parse."
 	      (goto-char (car affiliated))
 	      (goto-char (car affiliated))
 	      (org-element-keyword-parser limit nil))
 	      (org-element-keyword-parser limit nil))
 	     ;; LaTeX Environment.
 	     ;; LaTeX Environment.
-	     ((looking-at "[ \t]*\\\\begin{\\([A-Za-z0-9*]+\\)}[ \t]*$")
+	     ((looking-at
+	       "[ \t]*\\\\begin{[A-Za-z0-9*]+}\\(\\[.*?\\]\\|{.*?}\\)*[ \t]*$")
 	      (org-element-latex-environment-parser limit affiliated))
 	      (org-element-latex-environment-parser limit affiliated))
 	     ;; Drawer and Property Drawer.
 	     ;; Drawer and Property Drawer.
 	     ((looking-at org-drawer-regexp)
 	     ((looking-at org-drawer-regexp)
@@ -3822,7 +3954,8 @@ element it has to parse."
 	     ;; List.
 	     ;; List.
 	     ((looking-at (org-item-re))
 	     ((looking-at (org-item-re))
 	      (org-element-plain-list-parser
 	      (org-element-plain-list-parser
-	       limit affiliated (or structure (org-list-struct))))
+	       limit affiliated
+	       (or structure (org-element--list-struct limit))))
 	     ;; Default element: Paragraph.
 	     ;; Default element: Paragraph.
 	     (t (org-element-paragraph-parser limit affiliated)))))))))
 	     (t (org-element-paragraph-parser limit affiliated)))))))))
 
 
@@ -4197,6 +4330,10 @@ elements.
 Elements are accumulated into ACC."
 Elements are accumulated into ACC."
   (save-excursion
   (save-excursion
     (goto-char beg)
     (goto-char beg)
+    ;; Visible only: skip invisible parts at the beginning of the
+    ;; element.
+    (when (and visible-only (org-invisible-p2))
+      (goto-char (min (1+ (org-find-visible)) end)))
     ;; When parsing only headlines, skip any text before first one.
     ;; When parsing only headlines, skip any text before first one.
     (when (and (eq granularity 'headline) (not (org-at-heading-p)))
     (when (and (eq granularity 'headline) (not (org-at-heading-p)))
       (org-with-limited-levels (outline-next-heading)))
       (org-with-limited-levels (outline-next-heading)))
@@ -4209,12 +4346,13 @@ Elements are accumulated into ACC."
 	     (type (org-element-type element))
 	     (type (org-element-type element))
 	     (cbeg (org-element-property :contents-begin element)))
 	     (cbeg (org-element-property :contents-begin element)))
 	(goto-char (org-element-property :end element))
 	(goto-char (org-element-property :end element))
+	;; Visible only: skip invisible parts between siblings.
+	(when (and visible-only (org-invisible-p2))
+	  (goto-char (min (1+ (org-find-visible)) end)))
 	;; Fill ELEMENT contents by side-effect.
 	;; Fill ELEMENT contents by side-effect.
 	(cond
 	(cond
-	 ;; If VISIBLE-ONLY is true and element is hidden or if it has
-	 ;; no contents, don't modify it.
-	 ((or (and visible-only (org-element-property :hiddenp element))
-	      (not cbeg)))
+	 ;; If element has no contents, don't modify it.
+	 ((not cbeg))
 	 ;; Greater element: parse it between `contents-begin' and
 	 ;; Greater element: parse it between `contents-begin' and
 	 ;; `contents-end'.  Make sure GRANULARITY allows the
 	 ;; `contents-end'.  Make sure GRANULARITY allows the
 	 ;; recursion, or ELEMENT is a headline, in which case going
 	 ;; recursion, or ELEMENT is a headline, in which case going

+ 1 - 0
lisp/org-entities.el

@@ -366,6 +366,7 @@ packages to be loaded, add these packages to `org-latex-packages-alist'."
     ("rfloor" "\\rfloor" t "&rfloor;" "[right floor]" "[right floor]" "⌋")
     ("rfloor" "\\rfloor" t "&rfloor;" "[right floor]" "[right floor]" "⌋")
     ("lang" "\\langle" t "&lang;" "<" "<" "⟨")
     ("lang" "\\langle" t "&lang;" "<" "<" "⟨")
     ("rang" "\\rangle" t "&rang;" ">" ">" "⟩")
     ("rang" "\\rangle" t "&rang;" ">" ">" "⟩")
+    ("hbar" "\\hbar" t "&#8463;" "hbar" "hbar" "ℏ")
 
 
     "** Arrows"
     "** Arrows"
     ("larr" "\\leftarrow" t "&larr;" "<-" "<-" "←")
     ("larr" "\\leftarrow" t "&larr;" "<-" "<-" "←")

+ 11 - 4
lisp/org-faces.el

@@ -693,10 +693,10 @@ month and 365.24 days for a year)."
 
 
 (defface org-agenda-restriction-lock
 (defface org-agenda-restriction-lock
   (org-compatible-face nil
   (org-compatible-face nil
-    '((((class color) (min-colors 88) (background light)) (:background "yellow1"))
-      (((class color) (min-colors 88) (background dark))  (:background "skyblue4"))
-      (((class color) (min-colors 16) (background light)) (:background "yellow1"))
-      (((class color) (min-colors 16) (background dark))  (:background "skyblue4"))
+    '((((class color) (min-colors 88) (background light)) (:background "#eeeeee"))
+      (((class color) (min-colors 88) (background dark))  (:background "#1C1C1C"))
+      (((class color) (min-colors 16) (background light)) (:background "#eeeeee"))
+      (((class color) (min-colors 16) (background dark))  (:background "#1C1C1C"))
       (((class color) (min-colors 8)) (:background "cyan" :foreground "black"))
       (((class color) (min-colors 8)) (:background "cyan" :foreground "black"))
       (t (:inverse-video t))))
       (t (:inverse-video t))))
   "Face for showing the agenda restriction lock."
   "Face for showing the agenda restriction lock."
@@ -790,6 +790,13 @@ level org-n-level-faces"
   :version "24.4"
   :version "24.4"
   :package-version '(Org . "8.0"))
   :package-version '(Org . "8.0"))
 
 
+(defface org-tag-group
+  (org-compatible-face 'org-tag nil)
+  "Face for group tags."
+  :group 'org-faces
+  :version "24.4"
+  :package-version '(Org . "8.0"))
+
 (org-copy-face 'mode-line 'org-mode-line-clock
 (org-copy-face 'mode-line 'org-mode-line-clock
   "Face used for clock display in mode line.")
   "Face used for clock display in mode line.")
 (org-copy-face 'mode-line 'org-mode-line-clock-overrun
 (org-copy-face 'mode-line 'org-mode-line-clock-overrun

+ 6 - 5
lisp/org-footnote.el

@@ -138,13 +138,13 @@ will be used to define the footnote at the reference position."
   "Non-nil means define automatically new labels for footnotes.
   "Non-nil means define automatically new labels for footnotes.
 Possible values are:
 Possible values are:
 
 
-nil        prompt the user for each label
-t          create unique labels of the form [fn:1], [fn:2], ...
-confirm    like t, but let the user edit the created value.  In particular,
-           the label can be removed from the minibuffer, to create
+nil        Prompt the user for each label.
+t          Create unique labels of the form [fn:1], [fn:2], etc.
+confirm    Like t, but let the user edit the created value.
+           The label can be removed from the minibuffer to create
            an anonymous footnote.
            an anonymous footnote.
 random	   Automatically generate a unique, random label.
 random	   Automatically generate a unique, random label.
-plain      Automatically create plain number labels like [1]"
+plain      Automatically create plain number labels like [1]."
   :group 'org-footnote
   :group 'org-footnote
   :type '(choice
   :type '(choice
 	  (const :tag "Prompt for label" nil)
 	  (const :tag "Prompt for label" nil)
@@ -166,6 +166,7 @@ The main values of this variable can be set with in-buffer options:
 #+STARTUP: nofnadjust"
 #+STARTUP: nofnadjust"
   :group 'org-footnote
   :group 'org-footnote
   :type '(choice
   :type '(choice
+	  (const :tag "No adjustment" nil)
 	  (const :tag "Renumber" renumber)
 	  (const :tag "Renumber" renumber)
 	  (const :tag "Sort" sort)
 	  (const :tag "Sort" sort)
 	  (const :tag "Renumber and Sort" t)))
 	  (const :tag "Renumber and Sort" t)))

+ 9 - 2
lisp/org-habit.el

@@ -85,6 +85,12 @@ today's agenda, even if they are not scheduled."
   :version "24.1"
   :version "24.1"
   :type 'character)
   :type 'character)
 
 
+(defcustom org-habit-show-done-always-green nil
+  "Non-nil means DONE days will always be green in the consistency graph.
+It will be green even if it was done after the deadline."
+  :group 'org-habit
+  :type 'boolean)
+
 (defface org-habit-clear-face
 (defface org-habit-clear-face
   '((((background light)) (:background "#8270f9"))
   '((((background light)) (:background "#8270f9"))
     (((background dark)) (:background "blue")))
     (((background dark)) (:background "blue")))
@@ -272,8 +278,9 @@ Habits are assigned colors on the following basis:
       (if donep
       (if donep
 	  '(org-habit-ready-face . org-habit-ready-future-face)
 	  '(org-habit-ready-face . org-habit-ready-future-face)
 	'(org-habit-alert-face . org-habit-alert-future-face)))
 	'(org-habit-alert-face . org-habit-alert-future-face)))
-     (t
-      '(org-habit-overdue-face . org-habit-overdue-future-face)))))
+     ((and org-habit-show-done-always-green donep)
+      '(org-habit-ready-face . org-habit-ready-future-face))
+     (t '(org-habit-overdue-face . org-habit-overdue-future-face)))))
 
 
 (defun org-habit-build-graph (habit starting current ending)
 (defun org-habit-build-graph (habit starting current ending)
   "Build a graph for the given HABIT, from STARTING to ENDING.
   "Build a graph for the given HABIT, from STARTING to ENDING.

+ 4 - 1
lisp/org-id.el

@@ -437,6 +437,7 @@ and time is the usual three-integer representation of time."
 
 
 ;; Storing ID locations (files)
 ;; Storing ID locations (files)
 
 
+;;;###autoload
 (defun org-id-update-id-locations (&optional files silent)
 (defun org-id-update-id-locations (&optional files silent)
   "Scan relevant files for IDs.
   "Scan relevant files for IDs.
 Store the relation between files and corresponding IDs.
 Store the relation between files and corresponding IDs.
@@ -527,7 +528,9 @@ When CHECK is given, prepare detailed information about duplicate IDs."
 		   (org-id-hash-to-alist org-id-locations)
 		   (org-id-hash-to-alist org-id-locations)
 		 org-id-locations)))
 		 org-id-locations)))
       (with-temp-file org-id-locations-file
       (with-temp-file org-id-locations-file
-	(print out (current-buffer))))))
+	(let ((print-level nil)
+	      (print-length nil))
+	  (print out (current-buffer)))))))
 
 
 (defun org-id-locations-load ()
 (defun org-id-locations-load ()
   "Read the data from `org-id-locations-file'."
   "Read the data from `org-id-locations-file'."

+ 5 - 5
lisp/org-indent.el

@@ -182,11 +182,11 @@ during idle time."
       (org-set-local 'org-hide-leading-stars-before-indent-mode
       (org-set-local 'org-hide-leading-stars-before-indent-mode
 		     org-hide-leading-stars)
 		     org-hide-leading-stars)
       (org-set-local 'org-hide-leading-stars t))
       (org-set-local 'org-hide-leading-stars t))
-    (make-local-variable 'filter-buffer-substring-functions)
-    (add-hook 'filter-buffer-substring-functions
-	      (lambda (fun start end delete)
-		(org-indent-remove-properties-from-string
-		 (funcall fun start end delete))))
+    (org-add-hook 'filter-buffer-substring-functions
+		  (lambda (fun start end delete)
+		    (org-indent-remove-properties-from-string
+		     (funcall fun start end delete)))
+		  nil t)
     (org-add-hook 'after-change-functions 'org-indent-refresh-maybe nil 'local)
     (org-add-hook 'after-change-functions 'org-indent-refresh-maybe nil 'local)
     (org-add-hook 'before-change-functions
     (org-add-hook 'before-change-functions
 		  'org-indent-notify-modified-headline nil 'local)
 		  'org-indent-notify-modified-headline nil 'local)

+ 31 - 18
lisp/org-list.el

@@ -217,15 +217,27 @@ Valid values are ?. and ?\).  To get both terminators, use t."
 		 (const :tag "paren like in \"2)\"" ?\))
 		 (const :tag "paren like in \"2)\"" ?\))
 		 (const :tag "both" t)))
 		 (const :tag "both" t)))
 
 
-(org-defvaralias 'org-alphabetical-lists 'org-list-allow-alphabetical) ;; Since 8.0
+(define-obsolete-variable-alias 'org-alphabetical-lists
+  'org-list-allow-alphabetical "24.4") ; Since 8.0
 (defcustom org-list-allow-alphabetical nil
 (defcustom org-list-allow-alphabetical nil
   "Non-nil means single character alphabetical bullets are allowed.
   "Non-nil means single character alphabetical bullets are allowed.
+
 Both uppercase and lowercase are handled.  Lists with more than
 Both uppercase and lowercase are handled.  Lists with more than
 26 items will fallback to standard numbering.  Alphabetical
 26 items will fallback to standard numbering.  Alphabetical
-counters like \"[@c]\" will be recognized."
+counters like \"[@c]\" will be recognized.
+
+This variable needs to be set before org.el is loaded.  If you
+need to make a change while Emacs is running, use the customize
+interface or run the following code, where VALUE stands for the
+new value of the variable, after updating it:
+
+  \(when (featurep 'org-element) (load \"org-element\" t t))"
   :group 'org-plain-lists
   :group 'org-plain-lists
   :version "24.1"
   :version "24.1"
-  :type 'boolean)
+  :type 'boolean
+  :set (lambda (var val)
+	 (when (featurep 'org-element) (load "org-element" t t))
+	 (set var val)))
 
 
 (defcustom org-list-two-spaces-after-bullet-regexp nil
 (defcustom org-list-two-spaces-after-bullet-regexp nil
   "A regular expression matching bullets that should have 2 spaces after them.
   "A regular expression matching bullets that should have 2 spaces after them.
@@ -239,8 +251,8 @@ spaces instead of one after the bullet in each item of the list."
 	  (const :tag "never" nil)
 	  (const :tag "never" nil)
 	  (regexp)))
 	  (regexp)))
 
 
-(org-defvaralias 'org-empty-line-terminates-plain-lists
-  'org-list-empty-line-terminates-plain-lists) ;; Since 8.0
+(define-obsolete-variable-alias 'org-empty-line-terminates-plain-lists
+  'org-list-empty-line-terminates-plain-lists "24.4") ;; Since 8.0
 (defcustom org-list-empty-line-terminates-plain-lists nil
 (defcustom org-list-empty-line-terminates-plain-lists nil
   "Non-nil means an empty line ends all plain list levels.
   "Non-nil means an empty line ends all plain list levels.
 Otherwise, two of them will be necessary."
 Otherwise, two of them will be necessary."
@@ -293,8 +305,8 @@ This hook runs even if checkbox rule in
 implement alternative ways of collecting statistics
 implement alternative ways of collecting statistics
 information.")
 information.")
 
 
-(org-defvaralias 'org-hierarchical-checkbox-statistics
-  'org-checkbox-hierarchical-statistics) ;; Since 8.0
+(define-obsolete-variable-alias 'org-hierarchical-checkbox-statistics
+  'org-checkbox-hierarchical-statistics "24.4") ;; Since 8.0
 (defcustom org-checkbox-hierarchical-statistics t
 (defcustom org-checkbox-hierarchical-statistics t
   "Non-nil means checkbox statistics counts only the state of direct children.
   "Non-nil means checkbox statistics counts only the state of direct children.
 When nil, all boxes below the cookie are counted.
 When nil, all boxes below the cookie are counted.
@@ -363,10 +375,10 @@ specifically, type `block' is determined by the variable
 
 
 ;;; Predicates and regexps
 ;;; Predicates and regexps
 
 
-(defconst org-list-end-re (if org-empty-line-terminates-plain-lists "^[ \t]*\n"
+(defconst org-list-end-re (if org-list-empty-line-terminates-plain-lists "^[ \t]*\n"
 			    "^[ \t]*\n[ \t]*\n")
 			    "^[ \t]*\n[ \t]*\n")
   "Regex corresponding to the end of a list.
   "Regex corresponding to the end of a list.
-It depends on `org-empty-line-terminates-plain-lists'.")
+It depends on `org-list-empty-line-terminates-plain-lists'.")
 
 
 (defconst org-list-full-item-re
 (defconst org-list-full-item-re
   (concat "^[ \t]*\\(\\(?:[-+*]\\|\\(?:[0-9]+\\|[A-Za-z]\\)[.)]\\)\\(?:[ \t]+\\|$\\)\\)"
   (concat "^[ \t]*\\(\\(?:[-+*]\\|\\(?:[0-9]+\\|[A-Za-z]\\)[.)]\\)\\(?:[ \t]+\\|$\\)\\)"
@@ -386,7 +398,7 @@ group 4: description tag")
 	       ((= org-plain-list-ordered-item-terminator ?\)) ")")
 	       ((= org-plain-list-ordered-item-terminator ?\)) ")")
 	       ((= org-plain-list-ordered-item-terminator ?.) "\\.")
 	       ((= org-plain-list-ordered-item-terminator ?.) "\\.")
 	       (t "[.)]")))
 	       (t "[.)]")))
-	(alpha (if org-alphabetical-lists "\\|[A-Za-z]" "")))
+	(alpha (if org-list-allow-alphabetical "\\|[A-Za-z]" "")))
     (concat "\\([ \t]*\\([-+]\\|\\(\\([0-9]+" alpha "\\)" term
     (concat "\\([ \t]*\\([-+]\\|\\(\\([0-9]+" alpha "\\)" term
 	    "\\)\\)\\|[ \t]+\\*\\)\\([ \t]+\\|$\\)")))
 	    "\\)\\)\\|[ \t]+\\*\\)\\([ \t]+\\|$\\)")))
 
 
@@ -400,7 +412,7 @@ group 4: description tag")
        (save-excursion
        (save-excursion
 	 (goto-char (match-end 0))
 	 (goto-char (match-end 0))
 	 (let ((counter-re (concat "\\(?:\\[@\\(?:start:\\)?"
 	 (let ((counter-re (concat "\\(?:\\[@\\(?:start:\\)?"
-				   (if org-alphabetical-lists
+				   (if org-list-allow-alphabetical
 				       "\\([0-9]+\\|[A-Za-z]\\)"
 				       "\\([0-9]+\\|[A-Za-z]\\)"
 				     "[0-9]+")
 				     "[0-9]+")
 				   "\\][ \t]*\\)")))
 				   "\\][ \t]*\\)")))
@@ -1208,7 +1220,7 @@ some heuristics to guess the result."
 				    (point))))))))
 				    (point))))))))
       (cond
       (cond
        ;; Trivial cases where there should be none.
        ;; Trivial cases where there should be none.
-       ((or org-empty-line-terminates-plain-lists (not insert-blank-p)) 0)
+       ((or org-list-empty-line-terminates-plain-lists (not insert-blank-p)) 0)
        ;; When `org-blank-before-new-entry' says so, it is 1.
        ;; When `org-blank-before-new-entry' says so, it is 1.
        ((eq insert-blank-p t) 1)
        ((eq insert-blank-p t) 1)
        ;; `plain-list-item' is 'auto.  Count blank lines separating
        ;; `plain-list-item' is 'auto.  Count blank lines separating
@@ -1613,7 +1625,7 @@ bullets between START and END."
 
 
 STRUCT is list structure.  PREVS is the alist of previous items,
 STRUCT is list structure.  PREVS is the alist of previous items,
 as returned by `org-list-prevs-alist'."
 as returned by `org-list-prevs-alist'."
-  (and org-alphabetical-lists
+  (and org-list-allow-alphabetical
        (catch 'exit
        (catch 'exit
 	 (let ((item first) (ascii 64) (case-fold-search nil))
 	 (let ((item first) (ascii 64) (case-fold-search nil))
 	   ;; Pretend that bullets are uppercase and check if alphabet
 	   ;; Pretend that bullets are uppercase and check if alphabet
@@ -2429,7 +2441,7 @@ With optional prefix argument ALL, do this for the whole buffer."
     (let ((cookie-re "\\(\\(\\[[0-9]*%\\]\\)\\|\\(\\[[0-9]*/[0-9]*\\]\\)\\)")
     (let ((cookie-re "\\(\\(\\[[0-9]*%\\]\\)\\|\\(\\[[0-9]*/[0-9]*\\]\\)\\)")
 	  (box-re "^[ \t]*\\([-+*]\\|\\([0-9]+\\|[A-Za-z]\\)[.)]\\)[ \t]+\\(?:\\[@\\(?:start:\\)?\\([0-9]+\\|[A-Za-z]\\)\\][ \t]*\\)?\\(\\[[- X]\\]\\)")
 	  (box-re "^[ \t]*\\([-+*]\\|\\([0-9]+\\|[A-Za-z]\\)[.)]\\)[ \t]+\\(?:\\[@\\(?:start:\\)?\\([0-9]+\\|[A-Za-z]\\)\\][ \t]*\\)?\\(\\[[- X]\\]\\)")
 	  (recursivep
 	  (recursivep
-	   (or (not org-hierarchical-checkbox-statistics)
+	   (or (not org-checkbox-hierarchical-statistics)
 	       (string-match "\\<recursive\\>"
 	       (string-match "\\<recursive\\>"
 			     (or (org-entry-get nil "COOKIE_DATA") ""))))
 			     (or (org-entry-get nil "COOKIE_DATA") ""))))
 	  (bounds (if all
 	  (bounds (if all
@@ -2835,7 +2847,7 @@ ignores hidden links."
 			 ((= dcst ?t) '<)))
 			 ((= dcst ?t) '<)))
 	     (next-record (lambda ()
 	     (next-record (lambda ()
 			    (skip-chars-forward " \r\t\n")
 			    (skip-chars-forward " \r\t\n")
-			    (beginning-of-line)))
+			    (or (eobp) (beginning-of-line))))
 	     (end-record (lambda ()
 	     (end-record (lambda ()
 			   (goto-char (org-list-get-item-end-before-blank
 			   (goto-char (org-list-get-item-end-before-blank
 				       (point) struct))))
 				       (point) struct))))
@@ -2857,9 +2869,10 @@ ignores hidden links."
 		     ;; If it is a timer list, convert timer to seconds
 		     ;; If it is a timer list, convert timer to seconds
 		     ((org-at-item-timer-p)
 		     ((org-at-item-timer-p)
 		      (org-timer-hms-to-secs (match-string 1)))
 		      (org-timer-hms-to-secs (match-string 1)))
-		     ((or (re-search-forward org-ts-regexp (point-at-eol) t)
-			  (re-search-forward org-ts-regexp-both
-					     (point-at-eol) t))
+		     ((or (save-excursion
+			    (re-search-forward org-ts-regexp (point-at-eol) t))
+			  (save-excursion (re-search-forward org-ts-regexp-both
+							     (point-at-eol) t)))
 		      (org-time-string-to-seconds (match-string 0)))
 		      (org-time-string-to-seconds (match-string 0)))
 		     (t (org-float-time now))))
 		     (t (org-float-time now))))
 		   ((= dcst ?f)
 		   ((= dcst ?f)

+ 41 - 32
lisp/org-macro.el

@@ -37,12 +37,14 @@
 ;; {{{email}}} and {{{title}}} macros.
 ;; {{{email}}} and {{{title}}} macros.
 
 
 ;;; Code:
 ;;; Code:
+(require 'org-macs)
 
 
 (declare-function org-element-at-point "org-element" (&optional keep-trail))
 (declare-function org-element-at-point "org-element" (&optional keep-trail))
 (declare-function org-element-context "org-element" (&optional element))
 (declare-function org-element-context "org-element" (&optional element))
 (declare-function org-element-property "org-element" (property element))
 (declare-function org-element-property "org-element" (property element))
 (declare-function org-element-type "org-element" (element))
 (declare-function org-element-type "org-element" (element))
 (declare-function org-remove-double-quotes "org" (s))
 (declare-function org-remove-double-quotes "org" (s))
+(declare-function org-mode "org" ())
 (declare-function org-file-contents "org" (file &optional noerror))
 (declare-function org-file-contents "org" (file &optional noerror))
 (declare-function org-with-wide-buffer "org-macs" (&rest body))
 (declare-function org-with-wide-buffer "org-macs" (&rest body))
 
 
@@ -61,37 +63,44 @@ directly, use instead:
 
 
 ;;; Functions
 ;;; Functions
 
 
-(defun org-macro--collect-macros (files)
+(defun org-macro--collect-macros ()
   "Collect macro definitions in current buffer and setup files.
   "Collect macro definitions in current buffer and setup files.
-FILES is a list of setup files names read so far, used to avoid
-circular dependencies.  Return an alist containing all macro
-templates found."
-  (let ((case-fold-search t) templates)
-    ;; Install buffer-local macros.  Also enter SETUPFILE keywords.
-    (org-with-wide-buffer
-     (goto-char (point-min))
-     (while (re-search-forward "^[ \t]*#\\+\\(MACRO\\|SETUPFILE\\):" nil t)
-       (let ((element (org-element-at-point)))
-	 (when (eq (org-element-type element) 'keyword)
-	   (let ((val (org-element-property :value element)))
-	     (if (equal (org-element-property :key element) "SETUPFILE")
-		 ;; Enter setup file.
-		 (let ((file (expand-file-name (org-remove-double-quotes val))))
-		   (unless (member file files)
-		     (with-temp-buffer
-		       (org-mode)
-		       (insert (org-file-contents file 'noerror))
-		       (setq templates
-			     (org-macro--collect-macros (cons file files))))))
-	       ;; Install macro in TEMPLATES.
-	       (when (string-match "^\\(.*?\\)\\(?:\\s-+\\(.*\\)\\)?\\s-*$" val)
-		 (let* ((name (match-string 1 val))
-			(template (or (match-string 2 val) ""))
-			(old-cell (assoc name templates)))
-		   (if old-cell (setcdr old-cell template)
-		     (push (cons name template) templates))))))))))
-    ;; Return value.
-    templates))
+Return an alist containing all macro templates found."
+  (let* (collect-macros			; For byte-compiler.
+	 (collect-macros
+	  (lambda (files templates)
+	    ;; Return an alist of macro templates.  FILES is a list of
+	    ;; setup files names read so far, used to avoid circular
+	    ;; dependencies.  TEMPLATES is the alist collected so far.
+	    (let ((case-fold-search t))
+	      (org-with-wide-buffer
+	       (goto-char (point-min))
+	       (while (re-search-forward
+		       "^[ \t]*#\\+\\(MACRO\\|SETUPFILE\\):" nil t)
+		 (let ((element (org-element-at-point)))
+		   (when (eq (org-element-type element) 'keyword)
+		     (let ((val (org-element-property :value element)))
+		       (if (equal (org-element-property :key element) "MACRO")
+			   ;; Install macro in TEMPLATES.
+			   (when (string-match
+				  "^\\(.*?\\)\\(?:\\s-+\\(.*\\)\\)?\\s-*$" val)
+			     (let* ((name (match-string 1 val))
+				    (template (or (match-string 2 val) ""))
+				    (old-cell (assoc name templates)))
+			       (if old-cell (setcdr old-cell template)
+				 (push (cons name template) templates))))
+			 ;; Enter setup file.
+			 (let ((file (expand-file-name
+				      (org-remove-double-quotes val))))
+			   (unless (member file files)
+			     (with-temp-buffer
+			       (org-mode)
+			       (insert (org-file-contents file 'noerror))
+			       (setq templates
+				     (funcall collect-macros (cons file files)
+					      templates)))))))))))
+	      templates))))
+    (funcall collect-macros nil nil)))
 
 
 (defun org-macro-initialize-templates ()
 (defun org-macro-initialize-templates ()
   "Collect macro templates defined in current buffer.
   "Collect macro templates defined in current buffer.
@@ -100,7 +109,7 @@ Templates are stored in buffer-local variable
 function installs the following ones: \"property\",
 function installs the following ones: \"property\",
 \"time\". and, if the buffer is associated to a file,
 \"time\". and, if the buffer is associated to a file,
 \"input-file\" and \"modification-time\"."
 \"input-file\" and \"modification-time\"."
-  (let* ((templates (org-macro--collect-macros nil))
+  (let* ((templates (org-macro--collect-macros))
 	 (update-templates
 	 (update-templates
 	  (lambda (cell)
 	  (lambda (cell)
 	    (let ((old-template (assoc (car cell) templates)))
 	    (let ((old-template (assoc (car cell) templates)))
@@ -137,7 +146,7 @@ default value.  Return nil if no template was found."
                                (org-element-property :args macro))
                                (org-element-property :args macro))
                           ;; No argument: remove place-holder.
                           ;; No argument: remove place-holder.
                           ""))
                           ""))
-                    template)))
+                    template nil 'literal)))
         ;; VALUE starts with "(eval": it is a s-exp, `eval' it.
         ;; VALUE starts with "(eval": it is a s-exp, `eval' it.
         (when (string-match "\\`(eval\\>" value)
         (when (string-match "\\`(eval\\>" value)
           (setq value (eval (read value))))
           (setq value (eval (read value))))

+ 7 - 6
lisp/org-macs.el

@@ -33,7 +33,9 @@
 
 
 (eval-and-compile
 (eval-and-compile
   (unless (fboundp 'declare-function)
   (unless (fboundp 'declare-function)
-    (defmacro declare-function (fn file &optional arglist fileonly)))
+    (defmacro declare-function (fn file &optional arglist fileonly)
+      `(autoload ',fn ,file)))
+
   (if (>= emacs-major-version 23)
   (if (>= emacs-major-version 23)
       (defsubst org-char-to-string(c)
       (defsubst org-char-to-string(c)
 	"Defsubst to decode UTF-8 character values in emacs 23 and beyond."
 	"Defsubst to decode UTF-8 character values in emacs 23 and beyond."
@@ -162,18 +164,17 @@ We use a macro so that the test can happen at compilation time."
   (cons (if (fboundp 'with-no-warnings) 'with-no-warnings 'progn) body))
   (cons (if (fboundp 'with-no-warnings) 'with-no-warnings 'progn) body))
 (def-edebug-spec org-no-warnings (body))
 (def-edebug-spec org-no-warnings (body))
 
 
-;; FIXME: Normalize argument names
-(defmacro org-with-remote-undo (_buffer &rest _body)
+(defmacro org-with-remote-undo (buffer &rest body)
   "Execute BODY while recording undo information in two buffers."
   "Execute BODY while recording undo information in two buffers."
   (org-with-gensyms (cline cmd buf1 buf2 undo1 undo2 c1 c2)
   (org-with-gensyms (cline cmd buf1 buf2 undo1 undo2 c1 c2)
     `(let ((,cline (org-current-line))
     `(let ((,cline (org-current-line))
 	   (,cmd this-command)
 	   (,cmd this-command)
 	   (,buf1 (current-buffer))
 	   (,buf1 (current-buffer))
-	   (,buf2 ,_buffer)
+	   (,buf2 ,buffer)
 	   (,undo1 buffer-undo-list)
 	   (,undo1 buffer-undo-list)
-	   (,undo2 (with-current-buffer ,_buffer buffer-undo-list))
+	   (,undo2 (with-current-buffer ,buffer buffer-undo-list))
 	   ,c1 ,c2)
 	   ,c1 ,c2)
-       ,@_body
+       ,@body
        (when org-agenda-allow-remote-undo
        (when org-agenda-allow-remote-undo
 	 (setq ,c1 (org-verify-change-for-undo
 	 (setq ,c1 (org-verify-change-for-undo
 		    ,undo1 (with-current-buffer ,buf1 buffer-undo-list))
 		    ,undo1 (with-current-buffer ,buf1 buffer-undo-list))

+ 1 - 0
lisp/org-mhe.el

@@ -30,6 +30,7 @@
 
 
 ;;; Code:
 ;;; Code:
 
 
+(require 'org-macs)
 (require 'org)
 (require 'org)
 
 
 ;; Customization variables
 ;; Customization variables

+ 3 - 5
lisp/org-mobile.el

@@ -307,8 +307,6 @@ Also exclude files matching `org-mobile-files-exclude-regexp'."
 	(push (cons file link-name) rtn)))
 	(push (cons file link-name) rtn)))
     (nreverse rtn)))
     (nreverse rtn)))
 
 
-(defvar org-agenda-filter)
-
 ;;;###autoload
 ;;;###autoload
 (defun org-mobile-push ()
 (defun org-mobile-push ()
   "Push the current state of Org affairs to the target directory.
   "Push the current state of Org affairs to the target directory.
@@ -1068,13 +1066,13 @@ be returned that indicates what went wrong."
 	 (t (error "Heading changed in MobileOrg and on the computer")))))
 	 (t (error "Heading changed in MobileOrg and on the computer")))))
 
 
      ((eq what 'addheading)
      ((eq what 'addheading)
-      (if (org-on-heading-p) ; if false we are in top-level of file
+      (if (org-at-heading-p) ; if false we are in top-level of file
 	  (progn
 	  (progn
 	    ;; Workaround a `org-insert-heading-respect-content' bug
 	    ;; Workaround a `org-insert-heading-respect-content' bug
 	    ;; which prevents correct insertion when point is invisible
 	    ;; which prevents correct insertion when point is invisible
 	    (org-show-subtree)
 	    (org-show-subtree)
 	    (end-of-line 1)
 	    (end-of-line 1)
-	    (org-insert-heading-respect-content '(4) t)
+	    (org-insert-heading-respect-content '(16) t)
 	    (org-demote))
 	    (org-demote))
 	(beginning-of-line)
 	(beginning-of-line)
 	(insert "* "))
 	(insert "* "))
@@ -1083,7 +1081,7 @@ be returned that indicates what went wrong."
      ((eq what 'refile)
      ((eq what 'refile)
       (org-copy-subtree)
       (org-copy-subtree)
       (org-with-point-at (org-mobile-locate-entry new)
       (org-with-point-at (org-mobile-locate-entry new)
-	(if (org-on-heading-p) ; if false we are in top-level of file
+	(if (org-at-heading-p) ; if false we are in top-level of file
 	    (progn
 	    (progn
 	      (setq level (org-get-valid-level (funcall outline-level) 1))
 	      (setq level (org-get-valid-level (funcall outline-level) 1))
 	      (org-end-of-subtree t t)
 	      (org-end-of-subtree t t)

+ 1 - 1
lisp/org-mouse.el

@@ -1056,7 +1056,7 @@ This means, between the beginning of line and the point."
 	  ["Convert" org-agenda-convert-date
 	  ["Convert" org-agenda-convert-date
 	   (org-agenda-check-type nil 'agenda 'timeline)]
 	   (org-agenda-check-type nil 'agenda 'timeline)]
 	  "--"
 	  "--"
-	  ["Create iCalendar file" org-export-icalendar-combine-agenda-files t])
+	  ["Create iCalendar file" org-icalendar-combine-agenda-files t])
 	 "--"
 	 "--"
 	 ["Day View" org-agenda-day-view
 	 ["Day View" org-agenda-day-view
 	  :active (org-agenda-check-type nil 'agenda)
 	  :active (org-agenda-check-type nil 'agenda)

+ 2 - 1
lisp/org-pcomplete.el

@@ -239,6 +239,7 @@ When completing for #+STARTUP, for example, this function returns
 		 (cond
 		 (cond
 		  ((eq :startgroup (car x)) "{")
 		  ((eq :startgroup (car x)) "{")
 		  ((eq :endgroup (car x)) "}")
 		  ((eq :endgroup (car x)) "}")
+		  ((eq :grouptags (car x)) ":")
 		  ((eq :newline (car x)) "\\n")
 		  ((eq :newline (car x)) "\\n")
 		  ((cdr x) (format "%s(%c)" (car x) (cdr x)))
 		  ((cdr x) (format "%s(%c)" (car x) (cdr x)))
 		  (t (car x))))
 		  (t (car x))))
@@ -390,7 +391,7 @@ Complete a language in the first field, the header arguments and switches."
 	  '("-n" "-r" "-l"
 	  '("-n" "-r" "-l"
 	    ":cache" ":colnames" ":comments" ":dir" ":eval" ":exports"
 	    ":cache" ":colnames" ":comments" ":dir" ":eval" ":exports"
 	    ":file" ":hlines" ":no-expand" ":noweb" ":results" ":rownames"
 	    ":file" ":hlines" ":no-expand" ":noweb" ":results" ":rownames"
-	    ":session" ":shebang" ":tangle" ":var"))))
+	    ":session" ":shebang" ":tangle" ":tangle-mode" ":var"))))
 
 
 (defun pcomplete/org-mode/block-option/clocktable ()
 (defun pcomplete/org-mode/block-option/clocktable ()
   "Complete keywords in a clocktable line."
   "Complete keywords in a clocktable line."

+ 1 - 1
lisp/org-protocol.el

@@ -265,7 +265,7 @@ Here is an example:
 This is usually a single character string but can also be a
 This is usually a single character string but can also be a
 string with two characters."
 string with two characters."
   :group 'org-protocol
   :group 'org-protocol
-  :type 'string)
+  :type '(choice (const nil) (string)))
 
 
 (defcustom org-protocol-data-separator "/+\\|\\?"
 (defcustom org-protocol-data-separator "/+\\|\\?"
   "The default data separator to use.
   "The default data separator to use.

+ 24 - 8
lisp/org-src.el

@@ -64,10 +64,25 @@ there are kept outside the narrowed region."
 		   (const :tag "from `lang' element")
 		   (const :tag "from `lang' element")
 		   (const :tag "from `style' element")))))
 		   (const :tag "from `style' element")))))
 
 
+(defcustom org-edit-src-turn-on-auto-save nil
+  "Non-nil means turn `auto-save-mode' on when editing a source block.
+This will save the content of the source code editing buffer into
+a newly created file, not the base buffer for this source block.
+
+If you want to regularily save the base buffer instead of the source
+code editing buffer, see `org-edit-src-auto-save-idle-delay' instead."
+  :group 'org-edit-structure
+  :version "24.4"
+  :package-version '(Org . "8.0")
+  :type 'boolean)
+
 (defcustom org-edit-src-auto-save-idle-delay 0
 (defcustom org-edit-src-auto-save-idle-delay 0
-  "Delay of idle time before auto-saving src code buffers.
+  "Delay before saving a source code buffer back into its base buffer.
 When a positive integer N, save after N seconds of idle time.
 When a positive integer N, save after N seconds of idle time.
-When 0 (the default), don't auto-save."
+When 0 (the default), don't auto-save.
+
+If you want to save the source code buffer itself, don't use this.
+Check `org-edit-src-turn-on-auto-save' instead."
   :group 'org-edit-structure
   :group 'org-edit-structure
   :version "24.4"
   :version "24.4"
   :package-version '(Org . "8.0")
   :package-version '(Org . "8.0")
@@ -350,10 +365,11 @@ the display of windows containing the Org buffer and the code buffer."
 	 (if org-src-preserve-indentation col (max 0 (- col total-nindent))))
 	 (if org-src-preserve-indentation col (max 0 (- col total-nindent))))
 	(org-src-mode)
 	(org-src-mode)
 	(set-buffer-modified-p nil)
 	(set-buffer-modified-p nil)
-	(setq buffer-file-name nil
-	      buffer-auto-save-file-name
-	      (concat (make-temp-name "org-src-")
-		      (format-time-string "-%Y-%d-%m") ".txt"))
+	(setq buffer-file-name nil)
+	(when org-edit-src-turn-on-auto-save
+	  (setq buffer-auto-save-file-name
+		(concat (make-temp-name "org-src-")
+			(format-time-string "-%Y-%d-%m") ".txt")))
 	(and org-edit-src-persistent-message
 	(and org-edit-src-persistent-message
 	     (org-set-local 'header-line-format msg))
 	     (org-set-local 'header-line-format msg))
 	(let ((edit-prep-func (intern (concat "org-babel-edit-prep:" lang))))
 	(let ((edit-prep-func (intern (concat "org-babel-edit-prep:" lang))))
@@ -877,9 +893,9 @@ issued in the language major mode buffer."
 
 
 (defun org-src-native-tab-command-maybe ()
 (defun org-src-native-tab-command-maybe ()
   "Perform language-specific TAB action.
   "Perform language-specific TAB action.
-Alter code block according to effect of TAB in the language major
-mode."
+Alter code block according to what TAB does in the language major mode."
   (and org-src-tab-acts-natively
   (and org-src-tab-acts-natively
+       (org-in-src-block-p)
        (not (equal this-command 'org-shifttab))
        (not (equal this-command 'org-shifttab))
        (let ((org-src-strip-leading-and-trailing-blank-lines nil))
        (let ((org-src-strip-leading-and-trailing-blank-lines nil))
 	 (org-babel-do-key-sequence-in-edit-buffer (kbd "TAB")))))
 	 (org-babel-do-key-sequence-in-edit-buffer (kbd "TAB")))))

+ 82 - 94
lisp/org-table.el

@@ -52,6 +52,8 @@ This can be used to add additional functionality after the table is sent
 to the receiver position, otherwise, if table is not sent, the functions
 to the receiver position, otherwise, if table is not sent, the functions
 are not run.")
 are not run.")
 
 
+(defvar org-table-TBLFM-begin-regexp "|\n[ \t]*#\\+TBLFM: ")
+
 (defcustom orgtbl-optimized (eq org-enable-table-editor 'optimized)
 (defcustom orgtbl-optimized (eq org-enable-table-editor 'optimized)
   "Non-nil means use the optimized table editor version for `orgtbl-mode'.
   "Non-nil means use the optimized table editor version for `orgtbl-mode'.
 In the optimized version, the table editor takes over all simple keys that
 In the optimized version, the table editor takes over all simple keys that
@@ -417,68 +419,38 @@ available parameters."
 			 (org-split-string (match-string 1 line)
 			 (org-split-string (match-string 1 line)
 					   "[ \t]*|[ \t]*")))))))
 					   "[ \t]*|[ \t]*")))))))
 
 
-(defvar org-table-colgroup-info nil)	; Dynamically scoped.
+(defvar org-table-clean-did-remove-column nil) ; dynamically scoped
 (defun org-table-clean-before-export (lines &optional maybe-quoted)
 (defun org-table-clean-before-export (lines &optional maybe-quoted)
   "Check if the table has a marking column.
   "Check if the table has a marking column.
 If yes remove the column and the special lines."
 If yes remove the column and the special lines."
-  (setq org-table-colgroup-info nil)
-  (if (memq nil
-	    (mapcar
-	     (lambda (x) (or (string-match "^[ \t]*|-" x)
-			     (string-match
-			      (if maybe-quoted
-				  "^[ \t]*| *\\\\?\\([\#!$*_^ /]\\) *|"
-				"^[ \t]*| *\\([\#!$*_^ /]\\) *|")
-			      x)))
-	     lines))
-      ;; No special marking column
-      (progn
-	(setq org-table-clean-did-remove-column nil)
-	(delq nil
-	      (mapcar
-	       (lambda (x)
-		 (cond
-		  ((org-table-colgroup-line-p x)
-		   ;; This line contains colgroup info, extract it
-		   ;; and then discard the line
-		   (setq org-table-colgroup-info
-			 (mapcar (lambda (x)
-				   (cond ((member x '("<" "&lt;")) :start)
-					 ((member x '(">" "&gt;")) :end)
-					 ((member x '("<>" "&lt;&gt;")) :startend)))
-				 (org-split-string x "[ \t]*|[ \t]*")))
-		   nil)
-		  ((org-table-cookie-line-p x)
-		   ;; This line contains formatting cookies, discard it
-		   nil)
-		  (t x)))
-	       lines)))
-    ;; there is a special marking column
-    (setq org-table-clean-did-remove-column t)
+  (let ((special (if maybe-quoted
+		     "^[ \t]*| *\\\\?[\#!$*_^/ ] *|"
+		   "^[ \t]*| *[\#!$*_^/ ] *|"))
+	(ignore  (if maybe-quoted
+		     "^[ \t]*| *\\\\?[!$_^/] *|"
+		   "^[ \t]*| *[!$_^/] *|")))
+    (setq org-table-clean-did-remove-column
+	  (not (memq nil
+		     (mapcar
+		      (lambda (line)
+			(or (string-match org-table-hline-regexp line)
+			    (string-match special                line)))
+		      lines))))
     (delq nil
     (delq nil
 	  (mapcar
 	  (mapcar
-	   (lambda (x)
+	   (lambda (line)
 	     (cond
 	     (cond
-	      ((org-table-colgroup-line-p x)
-	       ;; This line contains colgroup info, extract it
-	       ;; and then discard the line
-	       (setq org-table-colgroup-info
-		     (mapcar (lambda (x)
-			       (cond ((member x '("<" "&lt;")) :start)
-				     ((member x '(">" "&gt;")) :end)
-				     ((member x '("<>" "&lt;&gt;")) :startend)))
-			     (cdr (org-split-string x "[ \t]*|[ \t]*"))))
+	      ((or (org-table-colgroup-line-p line)  ;; colgroup info
+		   (org-table-cookie-line-p line)    ;; formatting cookies
+		   (and org-table-clean-did-remove-column
+			(string-match ignore line))) ;; non-exportable data
 	       nil)
 	       nil)
-	      ((org-table-cookie-line-p x)
-	       ;; This line contains formatting cookies, discard it
-	       nil)
-	      ((string-match "^[ \t]*| *\\([!_^/$]\\|\\\\\\$\\) *|" x)
-	       ;; ignore this line
-	       nil)
-	      ((or (string-match "^\\([ \t]*\\)|-+\\+" x)
-		   (string-match "^\\([ \t]*\\)|[^|]*|" x))
+	      ((and org-table-clean-did-remove-column
+		    (or (string-match "^\\([ \t]*\\)|-+\\+" line)
+			(string-match "^\\([ \t]*\\)|[^|]*|" line)))
 	       ;; remove the first column
 	       ;; remove the first column
-	       (replace-match "\\1|" t nil x))))
+	       (replace-match "\\1|" t nil line))
+	      (t line)))
 	   lines))))
 	   lines))))
 
 
 (defconst org-table-translate-regexp
 (defconst org-table-translate-regexp
@@ -565,7 +537,7 @@ nil      When nil, the command tries to be smart and figure out the
          - when each line contains a TAB, assume TAB-separated material
          - when each line contains a TAB, assume TAB-separated material
          - when each line contains a comma, assume CSV material
          - when each line contains a comma, assume CSV material
          - else, assume one or more SPACE characters as separator."
          - else, assume one or more SPACE characters as separator."
-  (interactive "rP")
+  (interactive "r\nP")
   (let* ((beg (min beg0 end0))
   (let* ((beg (min beg0 end0))
 	 (end (max beg0 end0))
 	 (end (max beg0 end0))
 	 re)
 	 re)
@@ -1116,7 +1088,7 @@ copying.  In the case of a timestamp, increment by one day."
   (interactive "p")
   (interactive "p")
   (let* ((colpos (org-table-current-column))
   (let* ((colpos (org-table-current-column))
 	 (col (current-column))
 	 (col (current-column))
-	 (field (org-table-get-field))
+	 (field (save-excursion (org-table-get-field)))
 	 (non-empty (string-match "[^ \t]" field))
 	 (non-empty (string-match "[^ \t]" field))
 	 (beg (org-table-begin))
 	 (beg (org-table-begin))
 	 (orig-n n)
 	 (orig-n n)
@@ -2927,7 +2899,10 @@ list, 'literal is for the format specifier L."
       (if lispp
       (if lispp
 	  (if (eq lispp 'literal)
 	  (if (eq lispp 'literal)
 	      elements
 	      elements
-	    (prin1-to-string (if numbers (string-to-number elements) elements)))
+	    (if (and (eq elements "") (not keep-empty))
+		""
+	      (prin1-to-string
+	       (if numbers (string-to-number elements) elements))))
 	(if (string-match "\\S-" elements)
 	(if (string-match "\\S-" elements)
 	    (progn
 	    (progn
 	      (when numbers (setq elements (number-to-string
 	      (when numbers (setq elements (number-to-string
@@ -2940,7 +2915,7 @@ list, 'literal is for the format specifier L."
 	    (delq nil
 	    (delq nil
 		  (mapcar (lambda (x) (if (string-match "\\S-" x) x nil))
 		  (mapcar (lambda (x) (if (string-match "\\S-" x) x nil))
 			  elements))))
 			  elements))))
-    (setq elements (or elements '("")))
+    (setq elements (or elements '()))  ; if delq returns nil then we need '()
     (if lispp
     (if lispp
 	(mapconcat
 	(mapconcat
 	 (lambda (x)
 	 (lambda (x)
@@ -3169,6 +3144,39 @@ with the prefix ARG."
 	      (setq checksum c1)))
 	      (setq checksum c1)))
 	  (user-error "No convergence after %d iterations" imax))))))
 	  (user-error "No convergence after %d iterations" imax))))))
 
 
+(defun org-table-calc-current-TBLFM (&optional arg)
+  "Apply the #+TBLFM in the line at point to the table."
+  (interactive "P")
+  (unless (org-at-TBLFM-p) (user-error "Not at a #+TBLFM line"))
+  (let ((formula (buffer-substring
+		  (point-at-bol)
+		  (point-at-eol)))
+	s e)
+    (save-excursion
+      ;; Insert a temporary formula at right after the table
+      (goto-char (org-table-TBLFM-begin))
+      (setq s (set-marker (make-marker) (point)))
+      (insert (concat formula "\n"))
+      (setq e (set-marker (make-marker) (point)))
+      ;; Recalculate the table
+      (beginning-of-line 0)		; move to the inserted line
+      (skip-chars-backward " \r\n\t")
+      (if (org-at-table-p)
+	  (unwind-protect
+	      (org-call-with-arg 'org-table-recalculate (or arg t))
+	    ;; delete the formula inserted temporarily
+	    (delete-region s e))))))
+
+(defun org-table-TBLFM-begin ()
+  "Find the beginning of the TBLFM lines and return its position.
+Return nil when the beginning of TBLFM line was not found."
+  (save-excursion
+    (when (progn (forward-line 1)
+	      (re-search-backward
+	       org-table-TBLFM-begin-regexp
+	       nil t))
+	  (point-at-bol 2))))
+
 (defun org-table-expand-lhs-ranges (equations)
 (defun org-table-expand-lhs-ranges (equations)
   "Expand list of formulas.
   "Expand list of formulas.
 If some of the RHS in the formulas are ranges or a row reference, expand
 If some of the RHS in the formulas are ranges or a row reference, expand
@@ -4364,30 +4372,6 @@ overwritten, and the table is not marked as requiring realignment."
 (defvar orgtbl-exp-regexp "^\\([-+]?[0-9][0-9.]*\\)[eE]\\([-+]?[0-9]+\\)$"
 (defvar orgtbl-exp-regexp "^\\([-+]?[0-9][0-9.]*\\)[eE]\\([-+]?[0-9]+\\)$"
   "Regular expression matching exponentials as produced by calc.")
   "Regular expression matching exponentials as produced by calc.")
 
 
-(defun orgtbl-export (table target)
-  (let ((func (intern (concat "orgtbl-to-" (symbol-name target))))
-	(lines (org-split-string table "[ \t]*\n[ \t]*"))
-	org-table-last-alignment org-table-last-column-widths
-	maxcol column)
-    (if (not (fboundp func))
-	(user-error "Cannot export orgtbl table to %s" target))
-    (setq lines (org-table-clean-before-export lines))
-    (setq table
-	  (mapcar
-	   (lambda (x)
-	     (if (string-match org-table-hline-regexp x)
-		 'hline
-	       (org-split-string (org-trim x) "\\s-*|\\s-*")))
-	   lines))
-    (setq maxcol (apply 'max (mapcar (lambda (x) (if (listp x) (length x) 0))
-				     table)))
-    (loop for i from (1- maxcol) downto 0 do
-	  (setq column (mapcar (lambda (x) (if (listp x) (nth i x) nil)) table))
-	  (setq column (delq nil column))
-	  (push (apply 'max (mapcar 'string-width column)) org-table-last-column-widths)
-	  (push (> (/ (apply '+ (mapcar (lambda (x) (if (string-match org-table-number-regexp x) 1 0)) column)) maxcol) org-table-number-fraction) org-table-last-alignment))
-    (funcall func table nil)))
-
 (defun orgtbl-gather-send-defs ()
 (defun orgtbl-gather-send-defs ()
   "Gather a plist of :name, :transform, :params for each destination before
   "Gather a plist of :name, :transform, :params for each destination before
 a radio table."
 a radio table."
@@ -4573,7 +4557,8 @@ First element has index 0, or I0 if given."
     fmt))
     fmt))
 
 
 (defsubst orgtbl-apply-fmt (fmt &rest args)
 (defsubst orgtbl-apply-fmt (fmt &rest args)
-  "Apply format FMT to the arguments.  NIL FMTs return the first argument."
+  "Apply format FMT to arguments ARGS.
+When FMT is nil, return the first argument from ARGS."
   (cond ((functionp fmt) (apply fmt args))
   (cond ((functionp fmt) (apply fmt args))
 	(fmt (apply 'format fmt args))
 	(fmt (apply 'format fmt args))
 	(args (car args))
 	(args (car args))
@@ -4603,7 +4588,7 @@ First element has index 0, or I0 if given."
 				   f)))
 				   f)))
 	     line)))
 	     line)))
       (push (if *orgtbl-lfmt*
       (push (if *orgtbl-lfmt*
-		(orgtbl-apply-fmt *orgtbl-lfmt* line)
+		(apply #'orgtbl-apply-fmt *orgtbl-lfmt* line)
 	      (concat (orgtbl-eval-str *orgtbl-lstart*)
 	      (concat (orgtbl-eval-str *orgtbl-lstart*)
 		      (mapconcat 'identity line *orgtbl-sep*)
 		      (mapconcat 'identity line *orgtbl-sep*)
 		      (orgtbl-eval-str *orgtbl-lend*)))
 		      (orgtbl-eval-str *orgtbl-lend*)))
@@ -4706,10 +4691,12 @@ directly by `orgtbl-send-table'.  See manual."
       (setq *orgtbl-table*
       (setq *orgtbl-table*
 	    (mapcar
 	    (mapcar
 	     (lambda(r)
 	     (lambda(r)
-	       (mapcar
-		(lambda (c)
-		  (org-trim (org-export-string-as c backend t '(:with-tables t))))
-		r))
+	       (if (listp r)
+		   (mapcar
+		    (lambda (c)
+		      (org-trim (org-export-string-as c backend t '(:with-tables t))))
+		    r)
+		 r))
 	     *orgtbl-table*)))
 	     *orgtbl-table*)))
     ;; Put header
     ;; Put header
     (unless splicep
     (unless splicep
@@ -4921,16 +4908,16 @@ it here: http://gnuvola.org/software/j/aa2u/ascii-art-to-unicode.el."
 (defun org-table-get-remote-range (name-or-id form)
 (defun org-table-get-remote-range (name-or-id form)
   "Get a field value or a list of values in a range from table at ID.
   "Get a field value or a list of values in a range from table at ID.
 
 
-NAME-OR-ID may be the name of a table in the current file as set by
-a \"#+TBLNAME:\" directive.  The first table following this line
+NAME-OR-ID may be the name of a table in the current file as set
+by a \"#+NAME:\" directive.  The first table following this line
 will then be used.  Alternatively, it may be an ID referring to
 will then be used.  Alternatively, it may be an ID referring to
-any entry, also in a different file.  In this case, the first table
-in that entry will be referenced.
+any entry, also in a different file.  In this case, the first
+table in that entry will be referenced.
 FORM is a field or range descriptor like \"@2$3\" or \"B3\" or
 FORM is a field or range descriptor like \"@2$3\" or \"B3\" or
 \"@I$2..@II$2\".  All the references must be absolute, not relative.
 \"@I$2..@II$2\".  All the references must be absolute, not relative.
 
 
 The return value is either a single string for a single field, or a
 The return value is either a single string for a single field, or a
-list of the fields in the rectangle ."
+list of the fields in the rectangle."
   (save-match-data
   (save-match-data
     (let ((case-fold-search t) (id-loc nil)
     (let ((case-fold-search t) (id-loc nil)
 	  ;; Protect a bunch of variables from being overwritten
 	  ;; Protect a bunch of variables from being overwritten
@@ -4951,7 +4938,8 @@ list of the fields in the rectangle ."
 	  (save-excursion
 	  (save-excursion
 	    (goto-char (point-min))
 	    (goto-char (point-min))
 	    (if (re-search-forward
 	    (if (re-search-forward
-		 (concat "^[ \t]*#\\+tblname:[ \t]*" (regexp-quote name-or-id) "[ \t]*$")
+		 (concat "^[ \t]*#\\+\\(tbl\\)?name:[ \t]*"
+			 (regexp-quote name-or-id) "[ \t]*$")
 		 nil t)
 		 nil t)
 		(setq buffer (current-buffer) loc (match-beginning 0))
 		(setq buffer (current-buffer) loc (match-beginning 0))
 	      (setq id-loc (org-id-find name-or-id 'marker))
 	      (setq id-loc (org-id-find name-or-id 'marker))

+ 1 - 1
contrib/lisp/org-w3m.el → lisp/org-w3m.el

@@ -6,7 +6,7 @@
 ;; Keywords: outlines, hypermedia, calendar, wp
 ;; Keywords: outlines, hypermedia, calendar, wp
 ;; Homepage: http://orgmode.org
 ;; Homepage: http://orgmode.org
 ;;
 ;;
-;; This file is not part of GNU Emacs.
+;; This file is part of GNU Emacs.
 ;;
 ;;
 ;; This program is free software: you can redistribute it and/or modify
 ;; 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
 ;; it under the terms of the GNU General Public License as published by

Разница между файлами не показана из-за своего большого размера
+ 457 - 305
lisp/org.el


+ 39 - 32
lisp/ox-ascii.el

@@ -68,7 +68,6 @@
     (export-block . org-ascii-export-block)
     (export-block . org-ascii-export-block)
     (export-snippet . org-ascii-export-snippet)
     (export-snippet . org-ascii-export-snippet)
     (fixed-width . org-ascii-fixed-width)
     (fixed-width . org-ascii-fixed-width)
-    (footnote-definition . org-ascii-footnote-definition)
     (footnote-reference . org-ascii-footnote-reference)
     (footnote-reference . org-ascii-footnote-reference)
     (headline . org-ascii-headline)
     (headline . org-ascii-headline)
     (horizontal-rule . org-ascii-horizontal-rule)
     (horizontal-rule . org-ascii-horizontal-rule)
@@ -880,7 +879,7 @@ INFO is a plist used as a communication channel."
 	 (email (and (plist-get info :with-email)
 	 (email (and (plist-get info :with-email)
 		     (org-export-data (plist-get info :email) info)))
 		     (org-export-data (plist-get info :email) info)))
 	 (date (and (plist-get info :with-date)
 	 (date (and (plist-get info :with-date)
-		    (org-export-data (plist-get info :date) info))))
+		    (org-export-data (org-export-get-date info) info))))
     ;; There are two types of title blocks depending on the presence
     ;; There are two types of title blocks depending on the presence
     ;; of a title to display.
     ;; of a title to display.
     (if (string= title "")
     (if (string= title "")
@@ -1147,7 +1146,7 @@ CONTENTS is nil.  INFO is a plist holding contextual information."
 ;;;; Footnote Definition
 ;;;; Footnote Definition
 
 
 ;; Footnote Definitions are ignored.  They are compiled at the end of
 ;; Footnote Definitions are ignored.  They are compiled at the end of
-;; the document, by `org-ascii-template'.
+;; the document, by `org-ascii-inner-template'.
 
 
 
 
 ;;;; Footnote Reference
 ;;;; Footnote Reference
@@ -1424,16 +1423,14 @@ INFO is a plist holding contextual information."
      ;; targets.
      ;; targets.
      ((string= type "fuzzy")
      ((string= type "fuzzy")
       (let ((destination (org-export-resolve-fuzzy-link link info)))
       (let ((destination (org-export-resolve-fuzzy-link link info)))
-	;; Ignore invisible "#+TARGET: path".
-	(unless (eq (org-element-type destination) 'keyword)
-	  (if (org-string-nw-p desc) desc
-	    (when destination
-	      (let ((number
-		     (org-export-get-ordinal
-		      destination info nil 'org-ascii--has-caption-p)))
-		(when number
-		  (if (atom number) (number-to-string number)
-		    (mapconcat 'number-to-string number ".")))))))))
+	(if (org-string-nw-p desc) desc
+	  (when destination
+	    (let ((number
+		   (org-export-get-ordinal
+		    destination info nil 'org-ascii--has-caption-p)))
+	      (when number
+		(if (atom number) (number-to-string number)
+		  (mapconcat 'number-to-string number "."))))))))
      (t
      (t
       (if (not (org-string-nw-p desc)) (format "[%s]" raw-link)
       (if (not (org-string-nw-p desc)) (format "[%s]" raw-link)
 	(concat
 	(concat
@@ -1675,25 +1672,35 @@ column.
 
 
 When `org-ascii-table-widen-columns' is non-nil, width cookies
 When `org-ascii-table-widen-columns' is non-nil, width cookies
 are ignored."
 are ignored."
-  (or (and (not org-ascii-table-widen-columns)
-	   (org-export-table-cell-width table-cell info))
-      (let* ((max-width 0)
-	     (table (org-export-get-parent-table table-cell))
-	     (specialp (org-export-table-has-special-column-p table))
-	     (col (cdr (org-export-table-cell-address table-cell info))))
-	(org-element-map table 'table-row
-	  (lambda (row)
-	    (setq max-width
-		  (max (length
-			(org-export-data
-			 (org-element-contents
-			  (elt (if specialp (cdr (org-element-contents row))
-				 (org-element-contents row))
-			       col))
-			 info))
-		       max-width)))
-	  info)
-	max-width)))
+  (let* ((row (org-export-get-parent table-cell))
+	 (table (org-export-get-parent row))
+	 (col (let ((cells (org-element-contents row)))
+		(- (length cells) (length (memq table-cell cells)))))
+	 (cache
+	  (or (plist-get info :ascii-table-cell-width-cache)
+	      (plist-get (setq info
+			       (plist-put info :ascii-table-cell-width-cache
+					  (make-hash-table :test 'equal)))
+			 :ascii-table-cell-width-cache)))
+	 (key (cons table col)))
+    (or (gethash key cache)
+	(puthash
+	 key
+	 (or (and (not org-ascii-table-widen-columns)
+		  (org-export-table-cell-width table-cell info))
+	     (let* ((max-width 0))
+	       (org-element-map table 'table-row
+		 (lambda (row)
+		   (setq max-width
+			 (max (length
+			       (org-export-data
+				(org-element-contents
+				 (elt (org-element-contents row) col))
+				info))
+			      max-width)))
+		 info)
+	       max-width))
+	 cache))))
 
 
 (defun org-ascii-table-cell (table-cell contents info)
 (defun org-ascii-table-cell (table-cell contents info)
   "Transcode a TABLE-CELL object from Org to ASCII.
   "Transcode a TABLE-CELL object from Org to ASCII.

+ 23 - 18
lisp/ox-beamer.el

@@ -116,6 +116,18 @@
 (eval-when-compile (require 'cl))
 (eval-when-compile (require 'cl))
 (require 'ox-latex)
 (require 'ox-latex)
 
 
+;; Install a default set-up for Beamer export.
+(unless (assoc "beamer" org-latex-classes)
+  (add-to-list 'org-latex-classes
+	       '("beamer"
+		 "\\documentclass[presentation]{beamer}
+     \[DEFAULT-PACKAGES]
+     \[PACKAGES]
+     \[EXTRA]"
+		 ("\\section{%s}" . "\\section*{%s}")
+		 ("\\subsection{%s}" . "\\subsection*{%s}")
+		 ("\\subsubsection{%s}" . "\\subsubsection*{%s}"))))
+
 
 
 
 
 ;;; User-Configurable Variables
 ;;; User-Configurable Variables
@@ -311,7 +323,9 @@ Return overlay specification, as a string, or nil."
     (:beamer-inner-theme "BEAMER_INNER_THEME" nil nil t)
     (:beamer-inner-theme "BEAMER_INNER_THEME" nil nil t)
     (:beamer-outer-theme "BEAMER_OUTER_THEME" nil nil t)
     (:beamer-outer-theme "BEAMER_OUTER_THEME" nil nil t)
     (:beamer-header-extra "BEAMER_HEADER" nil nil newline)
     (:beamer-header-extra "BEAMER_HEADER" nil nil newline)
-    (:headline-levels nil "H" org-beamer-frame-level))
+    ;; Modify existing properties.
+    (:headline-levels nil "H" org-beamer-frame-level)
+    (:latex-class "LATEX_CLASS" nil "beamer" t))
   :translate-alist '((bold . org-beamer-bold)
   :translate-alist '((bold . org-beamer-bold)
 		     (export-block . org-beamer-export-block)
 		     (export-block . org-beamer-export-block)
 		     (export-snippet . org-beamer-export-snippet)
 		     (export-snippet . org-beamer-export-snippet)
@@ -407,19 +421,19 @@ INFO is a plist used as a communication channel."
    (catch 'exit
    (catch 'exit
      (mapc (lambda (parent)
      (mapc (lambda (parent)
 	     (let ((env (org-element-property :BEAMER_ENV parent)))
 	     (let ((env (org-element-property :BEAMER_ENV parent)))
-	       (when (and env (member (downcase env) '("frame" "fullframe")))
+	       (when (and env (member-ignore-case env '("frame" "fullframe")))
 		 (throw 'exit (org-export-get-relative-level parent info)))))
 		 (throw 'exit (org-export-get-relative-level parent info)))))
 	   (nreverse (org-export-get-genealogy headline)))
 	   (nreverse (org-export-get-genealogy headline)))
      nil)
      nil)
    ;; 2. Look for "frame" environment in HEADLINE.
    ;; 2. Look for "frame" environment in HEADLINE.
    (let ((env (org-element-property :BEAMER_ENV headline)))
    (let ((env (org-element-property :BEAMER_ENV headline)))
-     (and env (member (downcase env) '("frame" "fullframe"))
+     (and env (member-ignore-case env '("frame" "fullframe"))
 	  (org-export-get-relative-level headline info)))
 	  (org-export-get-relative-level headline info)))
    ;; 3. Look for "frame" environment in sub-tree.
    ;; 3. Look for "frame" environment in sub-tree.
    (org-element-map headline 'headline
    (org-element-map headline 'headline
      (lambda (hl)
      (lambda (hl)
        (let ((env (org-element-property :BEAMER_ENV hl)))
        (let ((env (org-element-property :BEAMER_ENV hl)))
-	 (when (and env (member (downcase env) '("frame" "fullframe")))
+	 (when (and env (member-ignore-case env '("frame" "fullframe")))
 	   (org-export-get-relative-level hl info))))
 	   (org-export-get-relative-level hl info))))
      info 'first-match)
      info 'first-match)
    ;; 4. No "frame" environment in tree: use default value.
    ;; 4. No "frame" environment in tree: use default value.
@@ -504,7 +518,7 @@ used as a communication channel."
 	    ;; remove the first word from the contents in the PDF
 	    ;; remove the first word from the contents in the PDF
 	    ;; output.
 	    ;; output.
 	    (if (not fragilep) contents
 	    (if (not fragilep) contents
-	      (replace-regexp-in-string "\\`\n*" "\\& " contents))
+	      (replace-regexp-in-string "\\`\n*" "\\& " (or contents "")))
 	    "\\end{frame}")))
 	    "\\end{frame}")))
 
 
 (defun org-beamer--format-block (headline contents info)
 (defun org-beamer--format-block (headline contents info)
@@ -523,7 +537,7 @@ used as a communication channel."
 			 ;; "column" only.
 			 ;; "column" only.
 			 ((not env) "column")
 			 ((not env) "column")
 			 ;; Use specified environment.
 			 ;; Use specified environment.
-			 (t (downcase env)))))
+			 (t env))))
 	 (env-format (unless (member environment '("column" "columns"))
 	 (env-format (unless (member environment '("column" "columns"))
 		       (assoc environment
 		       (assoc environment
 			      (append org-beamer-environments-special
 			      (append org-beamer-environments-special
@@ -611,7 +625,7 @@ as a communication channel."
     (let ((level (org-export-get-relative-level headline info))
     (let ((level (org-export-get-relative-level headline info))
 	  (frame-level (org-beamer--frame-level headline info))
 	  (frame-level (org-beamer--frame-level headline info))
 	  (environment (let ((env (org-element-property :BEAMER_ENV headline)))
 	  (environment (let ((env (org-element-property :BEAMER_ENV headline)))
-			 (if (stringp env) (downcase env) "block"))))
+			 (or (org-string-nw-p env) "block"))))
       (cond
       (cond
        ;; Case 1: Resume frame specified by "BEAMER_ref" property.
        ;; Case 1: Resume frame specified by "BEAMER_ref" property.
        ((equal environment "againframe")
        ((equal environment "againframe")
@@ -899,17 +913,8 @@ holding export options."
 	     (author (format "\\author{%s}\n" author))
 	     (author (format "\\author{%s}\n" author))
 	     (t "\\author{}\n")))
 	     (t "\\author{}\n")))
      ;; 6. Date.
      ;; 6. Date.
-     (let ((date (and (plist-get info :with-date) (plist-get info :date))))
-       (format "\\date{%s}\n"
-	       (cond ((not date) "")
-		     ;; If `:date' consists in a single timestamp and
-		     ;; `:date-format' is provided, apply it.
-		     ((and (plist-get info :date-format)
-			   (not (cdr date))
-			   (eq (org-element-type (car date)) 'timestamp))
-		      (org-timestamp-format
-		       (car date) (plist-get info :date-format)))
-		     (t (org-export-data date info)))))
+     (let ((date (and (plist-get info :with-date) (org-export-get-date info))))
+       (format "\\date{%s}\n" (org-export-data date info)))
      ;; 7. Title
      ;; 7. Title
      (format "\\title{%s}\n" title)
      (format "\\title{%s}\n" title)
      ;; 8. Hyperref options.
      ;; 8. Hyperref options.

Разница между файлами не показана из-за своего большого размера
+ 345 - 233
lisp/ox-html.el


+ 17 - 10
lisp/ox-icalendar.el

@@ -257,10 +257,13 @@ re-read the iCalendar file.")
 
 
 (org-export-define-derived-backend 'icalendar 'ascii
 (org-export-define-derived-backend 'icalendar 'ascii
   :translate-alist '((clock . ignore)
   :translate-alist '((clock . ignore)
+		     (footnote-definition . ignore)
+		     (footnote-reference . ignore)
 		     (headline . org-icalendar-entry)
 		     (headline . org-icalendar-entry)
 		     (inlinetask . ignore)
 		     (inlinetask . ignore)
 		     (planning . ignore)
 		     (planning . ignore)
 		     (section . ignore)
 		     (section . ignore)
+		     (inner-template . (lambda (c i) c))
 		     (template . org-icalendar-template))
 		     (template . org-icalendar-template))
   :options-alist
   :options-alist
   '((:exclude-tags
   '((:exclude-tags
@@ -360,8 +363,7 @@ or the day by one (if it does not contain a time) when no
 explicit ending time is specified.
 explicit ending time is specified.
 
 
 When optional argument UTC is non-nil, time will be expressed in
 When optional argument UTC is non-nil, time will be expressed in
-Universal Time, ignoring `org-icalendar-date-time-format'.
-This is mandatory for \"DTSTAMP\" property."
+Universal Time, ignoring `org-icalendar-date-time-format'."
   (let* ((year-start (org-element-property :year-start timestamp))
   (let* ((year-start (org-element-property :year-start timestamp))
 	 (year-end (org-element-property :year-end timestamp))
 	 (year-end (org-element-property :year-end timestamp))
 	 (month-start (org-element-property :month-start timestamp))
 	 (month-start (org-element-property :month-start timestamp))
@@ -406,6 +408,10 @@ This is mandatory for \"DTSTAMP\" property."
       (encode-time 0 mi h d m y)
       (encode-time 0 mi h d m y)
       (or utc (and with-time-p (org-icalendar-use-UTC-date-time-p)))))))
       (or utc (and with-time-p (org-icalendar-use-UTC-date-time-p)))))))
 
 
+(defun org-icalendar-dtstamp ()
+  "Return DTSTAMP property, as a string."
+  (format-time-string "DTSTAMP:%Y%m%dT%H%M%SZ" nil t))
+
 (defun org-icalendar-get-categories (entry info)
 (defun org-icalendar-get-categories (entry info)
   "Return categories according to `org-icalendar-categories'.
   "Return categories according to `org-icalendar-categories'.
 ENTRY is a headline or an inlinetask element.  INFO is a plist
 ENTRY is a headline or an inlinetask element.  INFO is a plist
@@ -644,7 +650,7 @@ Return VEVENT component as a string."
        (org-icalendar-transcode-diary-sexp
        (org-icalendar-transcode-diary-sexp
 	(org-element-property :raw-value timestamp) uid summary)
 	(org-element-property :raw-value timestamp) uid summary)
      (concat "BEGIN:VEVENT\n"
      (concat "BEGIN:VEVENT\n"
-	     (org-icalendar-convert-timestamp timestamp "DTSTAMP" nil t) "\n"
+	     (org-icalendar-dtstamp) "\n"
 	     "UID:" uid "\n"
 	     "UID:" uid "\n"
 	     (org-icalendar-convert-timestamp timestamp "DTSTART") "\n"
 	     (org-icalendar-convert-timestamp timestamp "DTSTART") "\n"
 	     (org-icalendar-convert-timestamp timestamp "DTEND" t) "\n"
 	     (org-icalendar-convert-timestamp timestamp "DTEND" t) "\n"
@@ -690,7 +696,7 @@ Return VTODO component as a string."
     (org-icalendar-fold-string
     (org-icalendar-fold-string
      (concat "BEGIN:VTODO\n"
      (concat "BEGIN:VTODO\n"
 	     "UID:TODO-" uid "\n"
 	     "UID:TODO-" uid "\n"
-	     (org-icalendar-convert-timestamp start "DTSTAMP" nil t) "\n"
+	     (org-icalendar-dtstamp) "\n"
 	     (org-icalendar-convert-timestamp start "DTSTART") "\n"
 	     (org-icalendar-convert-timestamp start "DTSTART") "\n"
 	     (and (memq 'todo-due org-icalendar-use-deadline)
 	     (and (memq 'todo-due org-icalendar-use-deadline)
 		  (org-element-property :deadline entry)
 		  (org-element-property :deadline entry)
@@ -894,7 +900,8 @@ The file is stored under the name chosen in
   "Export current agenda view to an iCalendar FILE.
   "Export current agenda view to an iCalendar FILE.
 This function assumes major mode for current buffer is
 This function assumes major mode for current buffer is
 `org-agenda-mode'."
 `org-agenda-mode'."
-  (let ((org-icalendar-combined-agenda-file file)
+  (let (org-export-babel-evaluate ; Don't evaluate Babel block
+	(org-icalendar-combined-agenda-file file)
 	(marker-list
 	(marker-list
 	 ;; Collect the markers pointing to entries in the current
 	 ;; Collect the markers pointing to entries in the current
 	 ;; agenda buffer.
 	 ;; agenda buffer.
@@ -941,9 +948,8 @@ files to build the calendar from."
 	    ;; Owner.
 	    ;; Owner.
 	    user-full-name
 	    user-full-name
 	    ;; Timezone.
 	    ;; Timezone.
-	    (if (org-string-nw-p org-icalendar-timezone)
-		org-icalendar-timezone
-	      (cadr (current-time-zone)))
+	    (or (org-string-nw-p org-icalendar-timezone)
+		(cadr (current-time-zone)))
 	    ;; Description.
 	    ;; Description.
 	    org-icalendar-combined-description
 	    org-icalendar-combined-description
 	    ;; Contents.
 	    ;; Contents.
@@ -954,7 +960,8 @@ files to build the calendar from."
 		(catch 'nextfile
 		(catch 'nextfile
 		  (org-check-agenda-file file)
 		  (org-check-agenda-file file)
 		  (with-current-buffer (org-get-agenda-file-buffer file)
 		  (with-current-buffer (org-get-agenda-file-buffer file)
-		    (let ((marks (cdr (assoc (expand-file-name file) restriction))))
+		    (let ((marks (cdr (assoc (expand-file-name file)
+					     restriction))))
 		      ;; Create ID if necessary.
 		      ;; Create ID if necessary.
 		      (when org-icalendar-store-UID
 		      (when org-icalendar-store-UID
 			(org-icalendar-create-uid file t marks))
 			(org-icalendar-create-uid file t marks))
@@ -968,7 +975,7 @@ files to build the calendar from."
 				      (lambda (m-list dummy)
 				      (lambda (m-list dummy)
 					(mapc (lambda (m)
 					(mapc (lambda (m)
 						(org-entry-put
 						(org-entry-put
-						 m "ICALENDAR_MARK" "t"))
+						 m "ICALENDAR-MARK" "t"))
 					      m-list))
 					      m-list))
 				      (sort marks '>))
 				      (sort marks '>))
 				     org-export-before-processing-hook)))
 				     org-export-before-processing-hook)))

+ 278 - 345
lisp/ox-latex.el

@@ -20,86 +20,7 @@
 
 
 ;;; Commentary:
 ;;; Commentary:
 ;;
 ;;
-;; This library implements a LaTeX back-end for Org generic exporter.
-;;
-;; Depending on the desired output format, three commands are provided
-;; for export: `org-latex-export-as-latex' (temporary buffer),
-;; `org-latex-export-to-latex' ("tex" file) and
-;; `org-latex-export-to-pdf' ("pdf" file).  Also, two publishing
-;; functions are available: `org-latex-publish-to-latex' and
-;; `org-latex-publish-to-pdf'.
-;;
-;; The library introduces four new buffer keywords: "LATEX_CLASS",
-;; "LATEX_CLASS_OPTIONS", "LATEX_HEADER" and "LATEX_HEADER_EXTRA" (the
-;; latter will not be used to build LaTeX snippets).  It also
-;; introduces a new OPTIONS item: "textht".
-;;
-;; Table export can be controlled with a number of attributes (through
-;; ATTR_LATEX keyword).
-;;
-;; - The main one is the `:mode' attribute, which can be set to
-;;   `table', `math', `inline-math' and `verbatim'.  In particular,
-;;   when in `math' or `inline-math' mode, every cell is exported
-;;   as-is, horizontal rules are ignored and the table will be wrapped
-;;   in a math environment.  Also, contiguous tables sharing the same
-;;   math mode will be wrapped within the same environment.  Default
-;;   mode is stored in `org-latex-default-table-mode'.
-;;
-;; - The second most important attribute is `:environment'.  It is the
-;;   environment used for the table and defaults to
-;;   `org-latex-default-table-environment' value.  It can be set to
-;;   anything, including "tabularx", "longtable", "array",
-;;   "bmatrix"...
-;;
-;; - `:float' attribute defines a float environment for the table.
-;;   Possible values are `sidewaystable', `multicolumn' and `table'.
-;;   If unspecified, a table with a caption will have a `table'
-;;   environment.  Moreover, `:placement' attribute can specify the
-;;   positioning of the float
-;;
-;; - `:align', `:font' and `:width' attributes set, respectively, the
-;;   alignment string of the table, its font size and its width.  They
-;;   only apply on regular tables.
-;;
-;; - `:booktabs', `:center' and `:rmlines' values are booleans.  They
-;;   toggle, respectively "booktabs" usage (assuming the package is
-;;   properly loaded), table centering and removal of every horizontal
-;;   rule but the first one (in a "table.el" table only).
-;;
-;; - `:math-prefix', `:math-suffix' and `:math-arguments' are string
-;;   which will be inserted, respectively, before the table within the
-;;   math environment, after the table within the math environment,
-;;   and between the macro name and the contents of the table.  The
-;;   latter attribute is necessary to matrix macros that require more
-;;   than one argument (i.e. "qbordermatrix").
-;;
-;; Plain lists accept two optional attributes: `:environment' and
-;; `:options'.  The first one allows to use a non-standard environment
-;; (i.e. "inparaenum").  The second one allows to specify optional
-;; arguments for that environment (square brackets are not mandatory).
-;;
-;; Images accept `:float', `:placement', `:comment-include', `:width',
-;; and `:height', and `:options' as attributes.  `:float' accepts
-;; a symbol among `wrap', `multicolumn', and `figure', which defines
-;; the float environment for the image (if unspecified, an image with
-;; a caption will be set in a "figure" environment).
-;; `:comment-include' is a boolean that toggles whether to comment out
-;; the code which actually includes the image. `:placement' is
-;; a string that will be used as argument for the environment chosen.
-;; `:width' and `:height' control the width and height of the image.
-;; `:options' is a string that will be used as the optional argument
-;; for "includegraphics" macro or, in the case of tikz images, used as
-;; the optional argument for a `tikzpicture' environment which will
-;; surround the "\input" picture code.
-;;
-;; Special blocks accept `:options' as attribute.  Its value will be
-;; appended as-is to the opening string of the environment created.
-;;
-;; This back-end also offers enhanced support for footnotes.  Thus, it
-;; handles nested footnotes, footnotes in tables and footnotes in item
-;; descriptions.
-;;
-;; Smart quotes are activated by default.
+;; See Org manual for details.
 
 
 ;;; Code:
 ;;; Code:
 
 
@@ -176,15 +97,13 @@
 	    (lambda (a s v b)
 	    (lambda (a s v b)
 	      (if a (org-latex-export-to-pdf t s v b)
 	      (if a (org-latex-export-to-pdf t s v b)
 		(org-open-file (org-latex-export-to-pdf nil s v b)))))))
 		(org-open-file (org-latex-export-to-pdf nil s v b)))))))
-  :options-alist '((:date-format nil nil org-latex-date-timestamp-format)
-		   (:latex-class "LATEX_CLASS" nil org-latex-default-class t)
+  :options-alist '((:latex-class "LATEX_CLASS" nil org-latex-default-class t)
 		   (:latex-class-options "LATEX_CLASS_OPTIONS" nil nil t)
 		   (:latex-class-options "LATEX_CLASS_OPTIONS" nil nil t)
 		   (:latex-header "LATEX_HEADER" nil nil newline)
 		   (:latex-header "LATEX_HEADER" nil nil newline)
 		   (:latex-header-extra "LATEX_HEADER_EXTRA" nil nil newline)
 		   (:latex-header-extra "LATEX_HEADER_EXTRA" nil nil newline)
 		   (:latex-hyperref-p nil "texht" org-latex-with-hyperref t)
 		   (:latex-hyperref-p nil "texht" org-latex-with-hyperref t)
 		   ;; Redefine regular options.
 		   ;; Redefine regular options.
-		   (:date "DATE" nil "\\today" t)
-		   (:with-smart-quotes nil "'" t)))
+		   (:date "DATE" nil "\\today" t)))
 
 
 
 
 
 
@@ -286,13 +205,13 @@
      ("\\subsection{%s}" . "\\subsection*{%s}")
      ("\\subsection{%s}" . "\\subsection*{%s}")
      ("\\subsubsection{%s}" . "\\subsubsection*{%s}")))
      ("\\subsubsection{%s}" . "\\subsubsection*{%s}")))
   "Alist of LaTeX classes and associated header and structure.
   "Alist of LaTeX classes and associated header and structure.
-If #+LaTeX_CLASS is set in the buffer, use its value and the
+If #+LATEX_CLASS is set in the buffer, use its value and the
 associated information.  Here is the structure of each cell:
 associated information.  Here is the structure of each cell:
 
 
   \(class-name
   \(class-name
     header-string
     header-string
-    \(numbered-section . unnumbered-section\)
-    ...\)
+    \(numbered-section . unnumbered-section)
+    ...)
 
 
 The header string
 The header string
 -----------------
 -----------------
@@ -307,7 +226,8 @@ following commands will be added:
   `org-latex-packages-alist'.  Thus, your header definitions
   `org-latex-packages-alist'.  Thus, your header definitions
   should avoid to also request these packages.
   should avoid to also request these packages.
 
 
-- Lines specified via \"#+LaTeX_HEADER:\"
+- Lines specified via \"#+LATEX_HEADER:\" and
+  \"#+LATEX_HEADER_EXTRA:\" keywords.
 
 
 If you need more control about the sequence in which the header
 If you need more control about the sequence in which the header
 is built up, or if you want to exclude one of these building
 is built up, or if you want to exclude one of these building
@@ -318,8 +238,8 @@ macro-like placeholders.
  [NO-DEFAULT-PACKAGES]   do not include any of the default packages
  [NO-DEFAULT-PACKAGES]   do not include any of the default packages
  [PACKAGES]              \\usepackage statements for packages
  [PACKAGES]              \\usepackage statements for packages
  [NO-PACKAGES]           do not include the packages
  [NO-PACKAGES]           do not include the packages
- [EXTRA]                 the stuff from #+LaTeX_HEADER
- [NO-EXTRA]              do not include #+LaTeX_HEADER stuff
+ [EXTRA]                 the stuff from #+LATEX_HEADER(_EXTRA)
+ [NO-EXTRA]              do not include #+LATEX_HEADER(_EXTRA) stuff
 
 
 So a header like
 So a header like
 
 
@@ -330,17 +250,22 @@ So a header like
   [PACKAGES]
   [PACKAGES]
 
 
 will omit the default packages, and will include the
 will omit the default packages, and will include the
-#+LaTeX_HEADER lines, then have a call to \\providecommand, and
-then place \\usepackage commands based on the content of
-`org-latex-packages-alist'.
+#+LATEX_HEADER and #+LATEX_HEADER_EXTRA lines, then have a call
+to \\providecommand, and then place \\usepackage commands based
+on the content of `org-latex-packages-alist'.
 
 
 If your header, `org-latex-default-packages-alist' or
 If your header, `org-latex-default-packages-alist' or
-`org-latex-packages-alist' inserts
-\"\\usepackage[AUTO]{inputenc}\", AUTO will automatically be
-replaced with a coding system derived from
-`buffer-file-coding-system'.  See also the variable
+`org-latex-packages-alist' inserts \"\\usepackage[AUTO]{inputenc}\",
+AUTO will automatically be replaced with a coding system derived
+from `buffer-file-coding-system'.  See also the variable
 `org-latex-inputenc-alist' for a way to influence this mechanism.
 `org-latex-inputenc-alist' for a way to influence this mechanism.
 
 
+Likewise, if your header contains \"\\usepackage[AUTO]{babel}\",
+AUTO will be replaced with the language related to the language
+code specified by `org-export-default-language', which see.  Note
+that constructions such as \"\\usepackage[french,AUTO,english]{babel}\"
+are permitted.
+
 The sectioning structure
 The sectioning structure
 ------------------------
 ------------------------
 
 
@@ -349,14 +274,14 @@ following the header string.  For each sectioning level, a number
 of strings is specified.  A %s formatter is mandatory in each
 of strings is specified.  A %s formatter is mandatory in each
 section string and will be replaced by the title of the section.
 section string and will be replaced by the title of the section.
 
 
-Instead of a cons cell \(numbered . unnumbered\), you can also
+Instead of a cons cell (numbered . unnumbered), you can also
 provide a list of 2 or 4 elements,
 provide a list of 2 or 4 elements,
 
 
-  \(numbered-open numbered-close\)
+  \(numbered-open numbered-close)
 
 
 or
 or
 
 
-  \(numbered-open numbered-close unnumbered-open unnumbered-close\)
+  \(numbered-open numbered-close unnumbered-open unnumbered-close)
 
 
 providing opening and closing strings for a LaTeX environment
 providing opening and closing strings for a LaTeX environment
 that should represent the document section.  The opening clause
 that should represent the document section.  The opening clause
@@ -364,7 +289,7 @@ should have a %s to represent the section title.
 
 
 Instead of a list of sectioning commands, you can also specify
 Instead of a list of sectioning commands, you can also specify
 a function name.  That function will be called with two
 a function name.  That function will be called with two
-parameters, the \(reduced) level of the headline, and a predicate
+parameters, the (reduced) level of the headline, and a predicate
 non-nil when the headline should be numbered.  It must return
 non-nil when the headline should be numbered.  It must return
 a format string in which the section title will be added."
 a format string in which the section title will be added."
   :group 'org-export-latex
   :group 'org-export-latex
@@ -397,19 +322,6 @@ are written as utf8 files."
 	   (string :tag "Derived from buffer")
 	   (string :tag "Derived from buffer")
 	   (string :tag "Use this instead"))))
 	   (string :tag "Use this instead"))))
 
 
-(defcustom org-latex-date-timestamp-format nil
-  "Time-stamp format string to use for DATE keyword.
-
-The format string, when specified, only applies if date consists
-in a single time-stamp.  Otherwise its value will be ignored.
-
-See `format-time-string' for details on how to build this
-string."
-  :group 'org-export-latex
-  :type '(choice
-	  (string :tag "Time-stamp format string")
-	  (const :tag "No format string" nil)))
-
 (defcustom org-latex-title-command "\\maketitle"
 (defcustom org-latex-title-command "\\maketitle"
   "The command used to insert the title just after \\begin{document}.
   "The command used to insert the title just after \\begin{document}.
 If this string contains the formatting specification \"%s\" then
 If this string contains the formatting specification \"%s\" then
@@ -513,7 +425,7 @@ environment."
   :type 'string)
   :type 'string)
 
 
 (defcustom org-latex-inline-image-rules
 (defcustom org-latex-inline-image-rules
-  '(("file" . "\\.\\(pdf\\|jpeg\\|jpg\\|png\\|ps\\|eps\\|tikz\\)\\'"))
+  '(("file" . "\\.\\(pdf\\|jpeg\\|jpg\\|png\\|ps\\|eps\\|tikz\\|pgf\\)\\'"))
   "Rules characterizing image files that can be inlined into LaTeX.
   "Rules characterizing image files that can be inlined into LaTeX.
 
 
 A rule consists in an association whose key is the type of link
 A rule consists in an association whose key is the type of link
@@ -617,8 +529,8 @@ When nil, no transformation is made."
 (defcustom org-latex-text-markup-alist '((bold . "\\textbf{%s}")
 (defcustom org-latex-text-markup-alist '((bold . "\\textbf{%s}")
 					 (code . verb)
 					 (code . verb)
 					 (italic . "\\emph{%s}")
 					 (italic . "\\emph{%s}")
-					 (strike-through . "\\st{%s}")
-					 (underline . "\\underline{%s}")
+					 (strike-through . "\\sout{%s}")
+					 (underline . "\\uline{%s}")
 					 (verbatim . protectedtexttt))
 					 (verbatim . protectedtexttt))
   "Alist of LaTeX expressions to convert text markup.
   "Alist of LaTeX expressions to convert text markup.
 
 
@@ -744,7 +656,7 @@ passed to pdflatex."
     (fortran "fortran")
     (fortran "fortran")
     (perl "Perl") (cperl "Perl") (python "Python") (ruby "Ruby")
     (perl "Perl") (cperl "Perl") (python "Python") (ruby "Ruby")
     (html "HTML") (xml "XML")
     (html "HTML") (xml "XML")
-    (tex "TeX") (latex "TeX")
+    (tex "TeX") (latex "[LaTeX]TeX")
     (shell-script "bash")
     (shell-script "bash")
     (gnuplot "Gnuplot")
     (gnuplot "Gnuplot")
     (ocaml "Caml") (caml "Caml")
     (ocaml "Caml") (caml "Caml")
@@ -872,8 +784,12 @@ the infamous egrep/locale bug:
 
 
      http://lists.gnu.org/archive/html/bug-texinfo/2010-03/msg00031.html
      http://lists.gnu.org/archive/html/bug-texinfo/2010-03/msg00031.html
 
 
-then `texi2dvi' is the superior choice.  Org does offer it as one
-of the customize options.
+then `texi2dvi' is the superior choice as it automates the LaTeX
+build process by calling the \"correct\" combinations of
+auxiliary programs.  Org does offer `texi2dvi' as one of the
+customize options.  Alternatively, `rubber' and `latexmk' also
+provide similar functionality.  The latter supports `biber' out
+of the box.
 
 
 Alternatively, this may be a Lisp function that does the
 Alternatively, this may be a Lisp function that does the
 processing, so you could use this to apply the machinery of
 processing, so you could use this to apply the machinery of
@@ -908,9 +824,11 @@ file name as its single argument."
 		  "xelatex -interaction nonstopmode -output-directory %o %f"
 		  "xelatex -interaction nonstopmode -output-directory %o %f"
 		  "xelatex -interaction nonstopmode -output-directory %o %f"))
 		  "xelatex -interaction nonstopmode -output-directory %o %f"))
 	  (const :tag "texi2dvi"
 	  (const :tag "texi2dvi"
-		 ("texi2dvi -p -b -c -V %f"))
+		 ("texi2dvi -p -b -V %f"))
 	  (const :tag "rubber"
 	  (const :tag "rubber"
 		 ("rubber -d --into %o %f"))
 		 ("rubber -d --into %o %f"))
+	  (const :tag "latexmk"
+		 ("latexmk -g -pdf %f"))
 	  (function)))
 	  (function)))
 
 
 (defcustom org-latex-logfiles-extensions
 (defcustom org-latex-logfiles-extensions
@@ -1003,6 +921,10 @@ Insertion of guessed language only happens when Babel package has
 explicitly been loaded.  Then it is added to the rest of
 explicitly been loaded.  Then it is added to the rest of
 package's options.
 package's options.
 
 
+The argument to Babel may be \"AUTO\" which is then replaced with
+the language of the document or `org-export-default-language'
+unless language in question is already loaded.
+
 Return the new header."
 Return the new header."
   (let ((language-code (plist-get info :language)))
   (let ((language-code (plist-get info :language)))
     ;; If no language is set or Babel package is not loaded, return
     ;; If no language is set or Babel package is not loaded, return
@@ -1011,16 +933,19 @@ Return the new header."
 	    (not (string-match "\\\\usepackage\\[\\(.*\\)\\]{babel}" header)))
 	    (not (string-match "\\\\usepackage\\[\\(.*\\)\\]{babel}" header)))
 	header
 	header
       (let ((options (save-match-data
       (let ((options (save-match-data
-		       (org-split-string (match-string 1 header) ",")))
+		       (org-split-string (match-string 1 header) ",[ \t]*")))
 	    (language (cdr (assoc language-code
 	    (language (cdr (assoc language-code
 				  org-latex-babel-language-alist))))
 				  org-latex-babel-language-alist))))
-	;; If LANGUAGE is already loaded, return header.  Otherwise,
-	;; append LANGUAGE to other options.
-	(if (member language options) header
-	  (replace-match (mapconcat 'identity
-				    (append options (list language))
-				    ",")
-			 nil nil header 1))))))
+	;; If LANGUAGE is already loaded, return header without AUTO.
+	;; Otherwise, replace AUTO with language or append language if
+	;; AUTO is not present.
+	(replace-match
+	 (mapconcat (lambda (option) (if (equal "AUTO" option) language option))
+		    (cond ((member language options) (delete "AUTO" options))
+			  ((member "AUTO" options) options)
+			  (t (append options (list language))))
+		    ", ")
+	 t nil header 1)))))
 
 
 (defun org-latex--find-verb-separator (s)
 (defun org-latex--find-verb-separator (s)
   "Return a character not used in string S.
   "Return a character not used in string S.
@@ -1176,17 +1101,8 @@ holding export options."
 	      (format "\\author{%s\\thanks{%s}}\n" author email))
 	      (format "\\author{%s\\thanks{%s}}\n" author email))
 	     ((or author email) (format "\\author{%s}\n" (or author email)))))
 	     ((or author email) (format "\\author{%s}\n" (or author email)))))
      ;; Date.
      ;; Date.
-     (let ((date (and (plist-get info :with-date) (plist-get info :date))))
-       (format "\\date{%s}\n"
-	       (cond ((not date) "")
-		     ;; If `:date' consists in a single timestamp and
-		     ;; `:date-format' is provided, apply it.
-		     ((and (plist-get info :date-format)
-			   (not (cdr date))
-			   (eq (org-element-type (car date)) 'timestamp))
-		      (org-timestamp-format
-		       (car date) (plist-get info :date-format)))
-		     (t (org-export-data date info)))))
+     (let ((date (and (plist-get info :with-date) (org-export-get-date info))))
+       (format "\\date{%s}\n" (org-export-data date info)))
      ;; Title
      ;; Title
      (format "\\title{%s}\n" title)
      (format "\\title{%s}\n" title)
      ;; Hyperref options.
      ;; Hyperref options.
@@ -1354,55 +1270,6 @@ CONTENTS is nil.  INFO is a plist holding contextual information."
 
 
 
 
 ;;;; Footnote Reference
 ;;;; Footnote Reference
-;;
-;; Footnote reference export is handled by
-;; `org-latex-footnote-reference'.
-;;
-;; Internally, `org-latex--get-footnote-counter' is used to restore
-;; the value of the LaTeX "footnote" counter after a jump due to
-;; a reference to an already defined footnote.  It is only needed in
-;; item tags since the optional argument to \footnotemark is not
-;; allowed there.
-
-(defun org-latex--get-footnote-counter (footnote-reference info)
-  "Return \"footnote\" counter before FOOTNOTE-REFERENCE is encountered.
-INFO is a plist used as a communication channel."
-  ;; Find original counter value by counting number of footnote
-  ;; references appearing for the first time before the current
-  ;; footnote reference.
-  (let* ((label (org-element-property :label footnote-reference))
-	 seen-refs
-	 search-ref			; For byte-compiler.
-	 (search-ref
-	  (function
-	   (lambda (data)
-	     ;; Search footnote references through DATA, filling
-	     ;; SEEN-REFS along the way.
-	     (org-element-map data 'footnote-reference
-	       (lambda (fn)
-		 (let ((fn-lbl (org-element-property :label fn)))
-		   (cond
-		    ;; Anonymous footnote match: return number.
-		    ((eq fn footnote-reference) (length seen-refs))
-		    ;; Anonymous footnote: it's always a new one.
-		    ;; Also, be sure to return nil from the `cond' so
-		    ;; `first-match' doesn't get us out of the loop.
-		    ((not fn-lbl) (push 'inline seen-refs) nil)
-		    ;; Label not seen so far: add it so SEEN-REFS.
-		    ;;
-		    ;; Also search for subsequent references in
-		    ;; footnote definition so numbering follows
-		    ;; reading logic.  Note that we don't care about
-		    ;; inline definitions, since `org-element-map'
-		    ;; already traverses them at the right time.
-		    ((not (member fn-lbl seen-refs))
-		     (push fn-lbl seen-refs)
-		     (funcall search-ref
-			      (org-export-get-footnote-definition fn info))))))
-	       ;; Don't enter footnote definitions since it will
-	       ;; happen when their first reference is found.
-	       info 'first-match 'footnote-definition)))))
-    (funcall search-ref (plist-get info :parse-tree))))
 
 
 (defun org-latex-footnote-reference (footnote-reference contents info)
 (defun org-latex-footnote-reference (footnote-reference contents info)
   "Transcode a FOOTNOTE-REFERENCE element from Org to LaTeX.
   "Transcode a FOOTNOTE-REFERENCE element from Org to LaTeX.
@@ -1413,20 +1280,6 @@ CONTENTS is nil.  INFO is a plist holding contextual information."
      (when (eq (org-element-type prev) 'footnote-reference)
      (when (eq (org-element-type prev) 'footnote-reference)
        org-latex-footnote-separator))
        org-latex-footnote-separator))
    (cond
    (cond
-    ;; Use \footnotemark if reference is within an item's tag.
-    ((eq (org-element-type (org-export-get-parent-element footnote-reference))
-	 'item)
-     (if (org-export-footnote-first-reference-p footnote-reference info)
-	 "\\footnotemark"
-       ;; Since we can't specify footnote number as an optional
-       ;; argument within an item tag, some extra work has to be done
-       ;; when the footnote has already been referenced.  In that
-       ;; case, set footnote counter to the desired number, use the
-       ;; footnotemark, then set counter back to its original value.
-       (format
-	"\\setcounter{footnote}{%s}\\footnotemark\\setcounter{footnote}{%s}"
-	(1- (org-export-get-footnote-number footnote-reference info))
-	(org-latex--get-footnote-counter footnote-reference info))))
     ;; Use \footnotemark if the footnote has already been defined.
     ;; Use \footnotemark if the footnote has already been defined.
     ((not (org-export-footnote-first-reference-p footnote-reference info))
     ((not (org-export-footnote-first-reference-p footnote-reference info))
      (format "\\footnotemark[%s]{}"
      (format "\\footnotemark[%s]{}"
@@ -1523,7 +1376,8 @@ holding contextual information."
 	       (format "\n\\\\end{%s}" (if numberedp 'enumerate 'itemize))
 	       (format "\n\\\\end{%s}" (if numberedp 'enumerate 'itemize))
 	       low-level-body)))
 	       low-level-body)))
 	;; This is a standard headline.  Export it as a section.  Add
 	;; This is a standard headline.  Export it as a section.  Add
-	;; an alternative heading when possible.
+	;; an alternative heading when possible, and when this is not
+	;; identical to the usual heading.
 	(let ((opt-title
 	(let ((opt-title
 	       (funcall org-latex-format-headline-function
 	       (funcall org-latex-format-headline-function
 			todo todo-type priority
 			todo todo-type priority
@@ -1531,6 +1385,7 @@ holding contextual information."
 			 (org-export-get-alt-title headline info) info)
 			 (org-export-get-alt-title headline info) info)
 			(and (eq (plist-get info :with-tags) t) tags))))
 			(and (eq (plist-get info :with-tags) t) tags))))
 	  (if (and numberedp opt-title
 	  (if (and numberedp opt-title
+		   (not (equal opt-title full-text))
 		   (string-match "\\`\\\\\\(.*?[^*]\\){" section-fmt))
 		   (string-match "\\`\\\\\\(.*?[^*]\\){" section-fmt))
 	      (format (replace-match "\\1[%s]" nil nil section-fmt 1)
 	      (format (replace-match "\\1[%s]" nil nil section-fmt 1)
 		      ;; Replace square brackets with parenthesis
 		      ;; Replace square brackets with parenthesis
@@ -1698,7 +1553,7 @@ contextual information."
 		     (trans "$\\boxminus$ ")))
 		     (trans "$\\boxminus$ ")))
 	 (tag (let ((tag (org-element-property :tag item)))
 	 (tag (let ((tag (org-element-property :tag item)))
 		;; Check-boxes must belong to the tag.
 		;; Check-boxes must belong to the tag.
-		(and tag (format "[%s] "
+		(and tag (format "[{%s}] "
 				 (concat checkbox
 				 (concat checkbox
 					 (org-export-data tag info)))))))
 					 (org-export-data tag info)))))))
     (concat counter "\\item" (or tag (concat " " checkbox))
     (concat counter "\\item" (or tag (concat " " checkbox))
@@ -1722,8 +1577,6 @@ CONTENTS is nil.  INFO is a plist holding contextual information."
     (cond
     (cond
      ((string= key "LATEX") value)
      ((string= key "LATEX") value)
      ((string= key "INDEX") (format "\\index{%s}" value))
      ((string= key "INDEX") (format "\\index{%s}" value))
-     ;; Invisible targets.
-     ((string= key "TARGET") nil)
      ((string= key "TOC")
      ((string= key "TOC")
       (let ((value (downcase value)))
       (let ((value (downcase value)))
 	(cond
 	(cond
@@ -1799,10 +1652,10 @@ used as a communication channel."
 	 ;; Retrieve latex attributes from the element around.
 	 ;; Retrieve latex attributes from the element around.
 	 (attr (org-export-read-attribute :attr_latex parent))
 	 (attr (org-export-read-attribute :attr_latex parent))
 	 (float (let ((float (plist-get attr :float)))
 	 (float (let ((float (plist-get attr :float)))
-		  (cond ((string= float "wrap") 'wrap)
+		  (cond ((and (not float) (plist-member attr :float)) nil)
+			((string= float "wrap") 'wrap)
 			((string= float "multicolumn") 'multicolumn)
 			((string= float "multicolumn") 'multicolumn)
-			((or (string= float "figure")
-			     (org-element-property :caption parent))
+			((or float (org-element-property :caption parent))
 			 'figure))))
 			 'figure))))
 	 (placement
 	 (placement
 	  (let ((place (plist-get attr :placement)))
 	  (let ((place (plist-get attr :placement)))
@@ -1816,7 +1669,6 @@ used as a communication channel."
 	 ;; ATTR_LATEX line, and also via default variables.
 	 ;; ATTR_LATEX line, and also via default variables.
 	 (width (cond ((plist-get attr :width))
 	 (width (cond ((plist-get attr :width))
 		      ((plist-get attr :height) "")
 		      ((plist-get attr :height) "")
-		      ((eq float 'figure) "0.7\\textwidth")
 		      ((eq float 'wrap) "0.48\\textwidth")
 		      ((eq float 'wrap) "0.48\\textwidth")
 		      (t org-latex-image-default-width)))
 		      (t org-latex-image-default-width)))
 	 (height (cond ((plist-get attr :height))
 	 (height (cond ((plist-get attr :height))
@@ -1828,7 +1680,7 @@ used as a communication channel."
 		    (if (not (string-match "\\`\\[\\(.*\\)\\]\\'" opt)) opt
 		    (if (not (string-match "\\`\\[\\(.*\\)\\]\\'" opt)) opt
 		      (match-string 1 opt))))
 		      (match-string 1 opt))))
 	 image-code)
 	 image-code)
-    (if (equal filetype "tikz")
+    (if (member filetype '("tikz" "pgf"))
 	;; For tikz images:
 	;; For tikz images:
 	;; - use \input to read in image file.
 	;; - use \input to read in image file.
 	;; - if options are present, wrap in a tikzpicture environment.
 	;; - if options are present, wrap in a tikzpicture environment.
@@ -1892,9 +1744,8 @@ INFO is a plist holding contextual information.  See
 		((member type '("http" "https" "ftp" "mailto"))
 		((member type '("http" "https" "ftp" "mailto"))
 		 (concat type ":" raw-path))
 		 (concat type ":" raw-path))
 		((string= type "file")
 		((string= type "file")
-		 (if (file-name-absolute-p raw-path)
-		     (concat "file://" (expand-file-name raw-path))
-		   (concat "file://" raw-path)))
+		 (if (not (file-name-absolute-p raw-path)) raw-path
+		   (concat "file://" (expand-file-name raw-path))))
 		(t raw-path)))
 		(t raw-path)))
 	 protocol)
 	 protocol)
     (cond
     (cond
@@ -1917,16 +1768,14 @@ INFO is a plist holding contextual information.  See
 	(case (org-element-type destination)
 	(case (org-element-type destination)
 	  ;; Id link points to an external file.
 	  ;; Id link points to an external file.
 	  (plain-text
 	  (plain-text
-	   (if desc (format "\\href{file://%s}{%s}" destination desc)
-	     (format "\\url{file://%s}" destination)))
+	   (if desc (format "\\href{%s}{%s}" destination desc)
+	     (format "\\url{%s}" destination)))
 	  ;; Fuzzy link points nowhere.
 	  ;; Fuzzy link points nowhere.
 	  ('nil
 	  ('nil
 	   (format org-latex-link-with-unknown-path-format
 	   (format org-latex-link-with-unknown-path-format
 		   (or desc
 		   (or desc
 		       (org-export-data
 		       (org-export-data
 			(org-element-property :raw-link link) info))))
 			(org-element-property :raw-link link) info))))
-	  ;; Fuzzy link points to an invisible target.
-	  (keyword nil)
 	  ;; LINK points to a headline.  If headlines are numbered
 	  ;; LINK points to a headline.  If headlines are numbered
 	  ;; and the link has no description, display headline's
 	  ;; and the link has no description, display headline's
 	  ;; number.  Otherwise, display description or headline's
 	  ;; number.  Otherwise, display description or headline's
@@ -2009,18 +1858,26 @@ TEXT is the string to transcode.  INFO is a plist holding
 contextual information."
 contextual information."
   (let ((specialp (plist-get info :with-special-strings))
   (let ((specialp (plist-get info :with-special-strings))
 	(output text))
 	(output text))
-    ;; Protect %, #, &, $, ~, ^, _,  { and }.
-    (while (string-match "\\([^\\]\\|^\\)\\([%$#&{}~^_]\\)" output)
+    ;; Protect %, #, &, $, _, { and }.
+    (while (string-match "\\([^\\]\\|^\\)\\([%$#&{}_]\\)" output)
       (setq output
       (setq output
 	    (replace-match
 	    (replace-match
 	     (format "\\%s" (match-string 2 output)) nil t output 2)))
 	     (format "\\%s" (match-string 2 output)) nil t output 2)))
+    ;; Protect ^.
+    (setq output
+	  (replace-regexp-in-string
+	   "\\([^\\]\\|^\\)\\(\\^\\)" "\\\\^{}" output nil nil 2))
     ;; Protect \.  If special strings are used, be careful not to
     ;; Protect \.  If special strings are used, be careful not to
     ;; protect "\" in "\-" constructs.
     ;; protect "\" in "\-" constructs.
-    (let ((symbols (if specialp "-%$#&{}~^_\\" "%$#&{}~^_\\")))
+    (let ((symbols (if specialp "-%$#&{}^_\\" "%$#&{}^_\\")))
       (setq output
       (setq output
 	    (replace-regexp-in-string
 	    (replace-regexp-in-string
 	     (format "\\(?:[^\\]\\|^\\)\\(\\\\\\)\\(?:[^%s]\\|$\\)" symbols)
 	     (format "\\(?:[^\\]\\|^\\)\\(\\\\\\)\\(?:[^%s]\\|$\\)" symbols)
 	     "$\\backslash$" output nil t 1)))
 	     "$\\backslash$" output nil t 1)))
+    ;; Protect ~.
+    (setq output
+	  (replace-regexp-in-string
+	   "\\([^\\]\\|^\\)\\(~\\)" "\\textasciitilde{}" output nil t 2))
     ;; Activate smart quotes.  Be sure to provide original TEXT string
     ;; Activate smart quotes.  Be sure to provide original TEXT string
     ;; since OUTPUT may have been modified.
     ;; since OUTPUT may have been modified.
     (when (plist-get info :with-smart-quotes)
     (when (plist-get info :with-smart-quotes)
@@ -2156,16 +2013,26 @@ contextual information."
 	   (num-start (case (org-element-property :number-lines src-block)
 	   (num-start (case (org-element-property :number-lines src-block)
 			(continued (org-export-get-loc src-block info))
 			(continued (org-export-get-loc src-block info))
 			(new 0)))
 			(new 0)))
-	   (retain-labels (org-element-property :retain-labels src-block)))
+	   (retain-labels (org-element-property :retain-labels src-block))
+	   (attributes (org-export-read-attribute :attr_latex src-block))
+	   (float (plist-get attributes :float)))
       (cond
       (cond
        ;; Case 1.  No source fontification.
        ;; Case 1.  No source fontification.
        ((not org-latex-listings)
        ((not org-latex-listings)
-	(let ((caption-str (org-latex--caption/label-string src-block info))
-	      (float-env (and caption "\\begin{figure}[H]\n%s\n\\end{figure}")))
+	(let* ((caption-str (org-latex--caption/label-string src-block info))
+	       (float-env
+		(cond ((and (not float) (plist-member attributes :float)) "%s")
+		      ((string= "multicolumn" float)
+		       (format "\\begin{figure*}[%s]\n%s%%s\n\\end{figure*}"
+			       org-latex-default-figure-position
+			       caption-str))
+		      ((or caption float)
+		       (format "\\begin{figure}[H]\n%s%%s\n\\end{figure}"
+			       caption-str))
+		      (t "%s"))))
 	  (format
 	  (format
-	   (or float-env "%s")
-	   (concat caption-str
-		   (format "\\begin{verbatim}\n%s\\end{verbatim}"
+	   float-env
+	   (concat (format "\\begin{verbatim}\n%s\\end{verbatim}"
 			   (org-export-format-code-default src-block info))))))
 			   (org-export-format-code-default src-block info))))))
        ;; Case 2.  Custom environment.
        ;; Case 2.  Custom environment.
        (custom-env (format "\\begin{%s}\n%s\\end{%s}\n"
        (custom-env (format "\\begin{%s}\n%s\\end{%s}\n"
@@ -2174,45 +2041,52 @@ contextual information."
 			   custom-env))
 			   custom-env))
        ;; Case 3.  Use minted package.
        ;; Case 3.  Use minted package.
        ((eq org-latex-listings 'minted)
        ((eq org-latex-listings 'minted)
-	(let ((float-env
-	       (when (or label caption)
-		 (format "\\begin{listing}[H]\n%%s\n%s\\end{listing}"
-			 (org-latex--caption/label-string src-block info))))
-	      (body
-	       (format
-		"\\begin{minted}[%s]{%s}\n%s\\end{minted}"
-		;; Options.
-		(org-latex--make-option-string
-		 (if (or (not num-start)
-			 (assoc "linenos" org-latex-minted-options))
-		     org-latex-minted-options
-		   (append `(("linenos")
-			     ("firstnumber" ,(number-to-string (1+ num-start))))
-			   org-latex-minted-options)))
-		;; Language.
-		(or (cadr (assq (intern lang) org-latex-minted-langs)) lang)
-		;; Source code.
-		(let* ((code-info (org-export-unravel-code src-block))
-		       (max-width
-			(apply 'max
-			       (mapcar 'length
-				       (org-split-string (car code-info)
-							 "\n")))))
-		  (org-export-format-code
-		   (car code-info)
-		   (lambda (loc num ref)
-		     (concat
-		      loc
-		      (when ref
-			;; Ensure references are flushed to the right,
-			;; separated with 6 spaces from the widest line
-			;; of code.
-			(concat (make-string (+ (- max-width (length loc)) 6)
-					     ?\s)
-				(format "(%s)" ref)))))
-		   nil (and retain-labels (cdr code-info)))))))
+	(let* ((caption-str (org-latex--caption/label-string src-block info))
+	       (float-env
+		(cond ((and (not float) (plist-member attributes :float)) "%s")
+		      ((string= "multicolumn" float)
+		       (format "\\begin{listing*}\n%%s\n%s\\end{listing*}"
+			       caption-str))
+		      ((or caption float)
+		       (format "\\begin{listing}[H]\n%%s\n%s\\end{listing}"
+			       caption-str))
+		      (t "%s")))
+	       (body
+		(format
+		 "\\begin{minted}[%s]{%s}\n%s\\end{minted}"
+		 ;; Options.
+		 (org-latex--make-option-string
+		  (if (or (not num-start)
+			  (assoc "linenos" org-latex-minted-options))
+		      org-latex-minted-options
+		    (append
+		     `(("linenos")
+		       ("firstnumber" ,(number-to-string (1+ num-start))))
+		     org-latex-minted-options)))
+		 ;; Language.
+		 (or (cadr (assq (intern lang) org-latex-minted-langs)) lang)
+		 ;; Source code.
+		 (let* ((code-info (org-export-unravel-code src-block))
+			(max-width
+			 (apply 'max
+				(mapcar 'length
+					(org-split-string (car code-info)
+							  "\n")))))
+		   (org-export-format-code
+		    (car code-info)
+		    (lambda (loc num ref)
+		      (concat
+		       loc
+		       (when ref
+			 ;; Ensure references are flushed to the right,
+			 ;; separated with 6 spaces from the widest line
+			 ;; of code.
+			 (concat (make-string (+ (- max-width (length loc)) 6)
+					      ?\s)
+				 (format "(%s)" ref)))))
+		    nil (and retain-labels (cdr code-info)))))))
 	  ;; Return value.
 	  ;; Return value.
-	  (if float-env (format float-env body) body)))
+	  (format float-env body)))
        ;; Case 4.  Use listings package.
        ;; Case 4.  Use listings package.
        (t
        (t
 	(let ((lst-lang
 	(let ((lst-lang
@@ -2228,19 +2102,25 @@ contextual information."
 			     (org-export-data main info)))))))
 			     (org-export-data main info)))))))
 	  (concat
 	  (concat
 	   ;; Options.
 	   ;; Options.
-	   (format "\\lstset{%s}\n"
-		   (org-latex--make-option-string
-		    (append
-		     org-latex-listings-options
-		     `(("language" ,lst-lang))
-		     (when label `(("label" ,label)))
-		     (when caption-str `(("caption" ,caption-str)))
-		     (cond ((assoc "numbers" org-latex-listings-options) nil)
-			   ((not num-start) '(("numbers" "none")))
-			   ((zerop num-start) '(("numbers" "left")))
-			   (t `(("numbers" "left")
-				("firstnumber"
-				 ,(number-to-string (1+ num-start)))))))))
+	   (format
+	    "\\lstset{%s}\n"
+	    (org-latex--make-option-string
+	     (append
+	      org-latex-listings-options
+	      (cond
+	       ((and (not float) (plist-member attributes :float)) nil)
+	       ((string= "multicolumn" float) '(("float" "*")))
+	       ((and float (not (assoc "float" org-latex-listings-options)))
+		`(("float" ,org-latex-default-figure-position))))
+	      `(("language" ,lst-lang))
+	      (when label `(("label" ,label)))
+	      (when caption-str `(("caption" ,caption-str)))
+	      (cond ((assoc "numbers" org-latex-listings-options) nil)
+		    ((not num-start) '(("numbers" "none")))
+		    ((zerop num-start) '(("numbers" "left")))
+		    (t `(("numbers" "left")
+			 ("firstnumber"
+			  ,(number-to-string (1+ num-start)))))))))
 	   ;; Source code.
 	   ;; Source code.
 	   (format
 	   (format
 	    "\\begin{lstlisting}\n%s\\end{lstlisting}"
 	    "\\begin{lstlisting}\n%s\\end{lstlisting}"
@@ -2283,35 +2163,77 @@ holding contextual information."
 
 
 ;;;; Subscript
 ;;;; Subscript
 
 
+(defun org-latex--script-size (object info)
+  "Transcode a subscript or superscript object.
+OBJECT is an Org object.  INFO is a plist used as a communication
+channel."
+  (let ((in-script-p
+	 ;; Non-nil if object is already in a sub/superscript.
+	 (let ((parent object))
+	   (catch 'exit
+	     (while (setq parent (org-export-get-parent parent))
+	       (let ((type (org-element-type parent)))
+		 (cond ((memq type '(subscript superscript))
+			(throw 'exit t))
+		       ((memq type org-element-all-elements)
+			(throw 'exit nil))))))))
+	(type (org-element-type object))
+	(output ""))
+    (org-element-map (org-element-contents object)
+	(cons 'plain-text org-element-all-objects)
+      (lambda (obj)
+	(case (org-element-type obj)
+	  ((entity latex-fragment)
+	   (let ((data (org-trim (org-export-data obj info))))
+	     (string-match
+	      "\\`\\(?:\\\\[([]\\|\\$+\\)?\\(.*?\\)\\(?:\\\\[])]\\|\\$+\\)?\\'"
+	      data)
+	     (setq output
+		   (concat output
+			   (match-string 1 data)
+			   (let ((blank (org-element-property :post-blank obj)))
+			     (and blank (> blank 0) "\\ "))))))
+	  (plain-text
+	   (setq output
+		 (format "%s\\text{%s}" output (org-export-data obj info))))
+	  (otherwise
+	   (setq output
+		 (concat output
+			 (org-export-data obj info)
+			 (let ((blank (org-element-property :post-blank obj)))
+			   (and blank (> blank 0) "\\ ")))))))
+      info nil org-element-recursive-objects)
+    ;; Result.  Do not wrap into math mode if already in a subscript
+    ;; or superscript.  Do not wrap into curly brackets if OUTPUT is
+    ;; a single character.  Also merge consecutive subscript and
+    ;; superscript into the same math snippet.
+    (concat (and (not in-script-p)
+		 (let ((prev (org-export-get-previous-element object info)))
+		   (or (not prev)
+		       (not (eq (org-element-type prev)
+				(if (eq type 'subscript) 'superscript
+				  'subscript)))
+		       (let ((blank (org-element-property :post-blank prev)))
+			 (and blank (> blank 0)))))
+		 "$")
+	    (if (eq (org-element-type object) 'subscript) "_" "^")
+	    (and (> (length output) 1) "{")
+	    output
+	    (and (> (length output) 1) "}")
+	    (and (not in-script-p)
+		 (or (let ((blank (org-element-property :post-blank object)))
+		       (and blank (> blank 0)))
+		     (not (eq (org-element-type
+			       (org-export-get-next-element object info))
+			      (if (eq type 'subscript) 'superscript
+				'subscript))))
+		 "$"))))
+
 (defun org-latex-subscript (subscript contents info)
 (defun org-latex-subscript (subscript contents info)
   "Transcode a SUBSCRIPT object from Org to LaTeX.
   "Transcode a SUBSCRIPT object from Org to LaTeX.
 CONTENTS is the contents of the object.  INFO is a plist holding
 CONTENTS is the contents of the object.  INFO is a plist holding
 contextual information."
 contextual information."
-  (if (= (length contents) 1) (format "$_%s$" contents)
-    ;; Handle multiple objects in SUBSCRIPT by creating a subscript
-    ;; command for each of them.
-    (let ((prev-blanks 0))
-      (mapconcat
-       (lambda (obj)
-	 (case (org-element-type obj)
-	   ((entity latex-fragment)
-	    (setq prev-blanks (org-element-property :post-blank obj))
-	    (let ((data (org-trim (org-export-data obj info))))
-	      (string-match
-	       "\\`\\(?:\\\\[([]\\|\\$+\\)?\\(.*?\\)\\(?:\\\\[])]\\|\\$+\\)?\\'"
-	       data)
-	      (format "$_{%s}$" (match-string 1 data))))
-	   (plain-text
-	    (format "$_\\mathrm{%s}$"
-		    (concat (make-string prev-blanks ? )
-			    ;; mathrm command doesn't handle spaces,
-			    ;; so we have to enforce them.
-			    (replace-regexp-in-string
-			     " " "\\\\ " (org-export-data obj info)))))
-	   (otherwise
-	    (setq prev-blanks (org-element-property :post-blank obj))
-	    (format "$_{%s}$" (org-export-data obj info)))))
-       (org-element-contents subscript) ""))))
+  (org-latex--script-size subscript info))
 
 
 
 
 ;;;; Superscript
 ;;;; Superscript
@@ -2320,31 +2242,7 @@ contextual information."
   "Transcode a SUPERSCRIPT object from Org to LaTeX.
   "Transcode a SUPERSCRIPT object from Org to LaTeX.
 CONTENTS is the contents of the object.  INFO is a plist holding
 CONTENTS is the contents of the object.  INFO is a plist holding
 contextual information."
 contextual information."
-  (if (= (length contents) 1) (format "$^%s$" contents)
-    ;; Handle multiple objects in SUPERSCRIPT by creating
-    ;; a superscript command for each of them.
-    (let ((prev-blanks 0))
-      (mapconcat
-       (lambda (obj)
-	 (case (org-element-type obj)
-	   ((entity latex-fragment)
-	    (setq prev-blanks (org-element-property :post-blank obj))
-	    (let ((data (org-trim (org-export-data obj info))))
-	      (string-match
-	       "\\`\\(?:\\\\[([]\\|\\$+\\)?\\(.*?\\)\\(?:\\\\[])]\\|\\$+\\)?\\'"
-	       data)
-	      (format "$^{%s}$" (match-string 1 data))))
-	   (plain-text
-	    (format "$^\\mathrm{%s}$"
-		    (concat (make-string prev-blanks ? )
-			    ;; mathrm command doesn't handle spaces,
-			    ;; so we have to enforce them.
-			    (replace-regexp-in-string
-			     " " "\\\\ " (org-export-data obj info)))))
-	   (otherwise
-	    (setq prev-blanks (org-element-property :post-blank obj))
-	    (format "$^{%s}$" (org-export-data obj info)))))
-       (org-element-contents superscript) ""))))
+  (org-latex--script-size superscript info))
 
 
 
 
 ;;;; Table
 ;;;; Table
@@ -2429,18 +2327,19 @@ This function assumes TABLE has `org' as its `:type' property and
 			org-latex-default-table-environment))
 			org-latex-default-table-environment))
 	 ;; If table is a float, determine environment: table, table*
 	 ;; If table is a float, determine environment: table, table*
 	 ;; or sidewaystable.
 	 ;; or sidewaystable.
-	 (float-env (unless (equal "longtable" table-env)
+	 (float-env (unless (member table-env '("longtable" "longtabu"))
 		      (let ((float (plist-get attr :float)))
 		      (let ((float (plist-get attr :float)))
 			(cond
 			(cond
+			 ((and (not float) (plist-member attr :float)) nil)
 			 ((string= float "sidewaystable") "sidewaystable")
 			 ((string= float "sidewaystable") "sidewaystable")
 			 ((string= float "multicolumn") "table*")
 			 ((string= float "multicolumn") "table*")
-			 ((or (string= float "table")
-			      (org-element-property :caption table))
+			 ((or float (org-element-property :caption table))
 			  "table")))))
 			  "table")))))
 	 ;; Extract others display options.
 	 ;; Extract others display options.
 	 (fontsize (let ((font (plist-get attr :font)))
 	 (fontsize (let ((font (plist-get attr :font)))
 		     (and font (concat font "\n"))))
 		     (and font (concat font "\n"))))
 	 (width (plist-get attr :width))
 	 (width (plist-get attr :width))
+	 (spreadp (plist-get attr :spread))
 	 (placement (or (plist-get attr :placement)
 	 (placement (or (plist-get attr :placement)
 			(format "[%s]" org-latex-default-figure-position)))
 			(format "[%s]" org-latex-default-figure-position)))
 	 (centerp (if (plist-member attr :center) (plist-get attr :center)
 	 (centerp (if (plist-member attr :center) (plist-get attr :center)
@@ -2460,6 +2359,23 @@ This function assumes TABLE has `org' as its `:type' property and
 		   (concat caption "\\\\\n"))
 		   (concat caption "\\\\\n"))
 	      "\\end{longtable}\n"
 	      "\\end{longtable}\n"
 	      (and fontsize "}")))
 	      (and fontsize "}")))
+     ;; Longtabu
+     ((equal "longtabu" table-env)
+      (concat (and fontsize (concat "{" fontsize))
+	      (format "\\begin{longtabu}%s{%s}\n"
+		      (if width
+			  (format " %s %s "
+				  (if spreadp "spread" "to") width) "")
+		      alignment)
+	      (and org-latex-table-caption-above
+		   (org-string-nw-p caption)
+		   (concat caption "\\\\\n"))
+	      contents
+	      (and (not org-latex-table-caption-above)
+		   (org-string-nw-p caption)
+		   (concat caption "\\\\\n"))
+	      "\\end{longtabu}\n"
+	      (and fontsize "}")))
      ;; Others.
      ;; Others.
      (t (concat (cond
      (t (concat (cond
 		 (float-env
 		 (float-env
@@ -2469,12 +2385,19 @@ This function assumes TABLE has `org' as its `:type' property and
 			  fontsize))
 			  fontsize))
 		 (centerp (concat "\\begin{center}\n" fontsize))
 		 (centerp (concat "\\begin{center}\n" fontsize))
 		 (fontsize (concat "{" fontsize)))
 		 (fontsize (concat "{" fontsize)))
-		(format "\\begin{%s}%s{%s}\n%s\\end{%s}"
-			table-env
-			(if width (format "{%s}" width) "")
-			alignment
-			contents
-			table-env)
+		(cond ((equal "tabu" table-env)
+		       (format "\\begin{tabu}%s{%s}\n%s\\end{tabu}"
+			       (if width (format
+					  (if spreadp " spread %s " " to %s ")
+					  width) "")
+			       alignment
+			       contents))
+		      (t (format "\\begin{%s}%s{%s}\n%s\\end{%s}"
+				 table-env
+				 (if width (format "{%s}" width) "")
+				 alignment
+				 contents
+				 table-env)))
 		(cond
 		(cond
 		 (float-env
 		 (float-env
 		  (concat (if org-latex-table-caption-above "" caption)
 		  (concat (if org-latex-table-caption-above "" caption)
@@ -2529,7 +2452,7 @@ This function assumes TABLE has `org' as its `:type' property and
 `inline-math' or `math' as its `:mode' attribute.."
 `inline-math' or `math' as its `:mode' attribute.."
   (let* ((caption (org-latex--caption/label-string table info))
   (let* ((caption (org-latex--caption/label-string table info))
 	 (attr (org-export-read-attribute :attr_latex table))
 	 (attr (org-export-read-attribute :attr_latex table))
-	 (inlinep (eq (plist-get attr :mode) 'inline-math))
+	 (inlinep (equal (plist-get attr :mode) "inline-math"))
 	 (env (or (plist-get attr :environment)
 	 (env (or (plist-get attr :environment)
 		  org-latex-default-table-environment))
 		  org-latex-default-table-environment))
 	 (contents
 	 (contents
@@ -2634,9 +2557,9 @@ a communication channel."
   (when (eq (org-element-property :type table-row) 'standard)
   (when (eq (org-element-property :type table-row) 'standard)
     (let* ((attr (org-export-read-attribute :attr_latex
     (let* ((attr (org-export-read-attribute :attr_latex
 					    (org-export-get-parent table-row)))
 					    (org-export-get-parent table-row)))
-	   (longtablep (string= (or (plist-get attr :environment)
+	   (longtablep (member (or (plist-get attr :environment)
 				    org-latex-default-table-environment)
 				    org-latex-default-table-environment)
-				"longtable"))
+				'("longtable" "longtabu")))
 	   (booktabsp (if (plist-member attr :booktabs)
 	   (booktabsp (if (plist-member attr :booktabs)
 			  (plist-get attr :booktabs)
 			  (plist-get attr :booktabs)
 			org-latex-tables-booktabs))
 			org-latex-tables-booktabs))
@@ -2789,6 +2712,15 @@ is non-nil."
       (when org-export-show-temporary-export-buffer
       (when org-export-show-temporary-export-buffer
 	(switch-to-buffer-other-window outbuf)))))
 	(switch-to-buffer-other-window outbuf)))))
 
 
+;;;###autoload
+(defun org-latex-convert-region-to-latex ()
+  "Assume the current region has org-mode syntax, and convert it to LaTeX.
+This can be used in any buffer.  For example, you can write an
+itemized list in org-mode syntax in an LaTeX buffer and use this
+command to convert it."
+  (interactive)
+  (org-export-replace-region-by 'latex))
+
 ;;;###autoload
 ;;;###autoload
 (defun org-latex-export-to-latex
 (defun org-latex-export-to-latex
   (&optional async subtreep visible-only body-only ext-plist)
   (&optional async subtreep visible-only body-only ext-plist)
@@ -2886,11 +2818,12 @@ Return PDF file name or an error if it couldn't be produced."
   (let* ((base-name (file-name-sans-extension (file-name-nondirectory texfile)))
   (let* ((base-name (file-name-sans-extension (file-name-nondirectory texfile)))
 	 (full-name (file-truename texfile))
 	 (full-name (file-truename texfile))
 	 (out-dir (file-name-directory texfile))
 	 (out-dir (file-name-directory texfile))
-	 ;; Make sure `default-directory' is set to TEXFILE directory,
-	 ;; not to whatever value the current buffer may have.
-	 (default-directory (file-name-directory full-name))
+	 ;; Properly set working directory for compilation.
+	 (default-directory (if (file-name-absolute-p texfile)
+				(file-name-directory full-name)
+			      default-directory))
 	 errors)
 	 errors)
-    (unless snippet (message (format "Processing LaTeX file %s ..." texfile)))
+    (unless snippet (message (format "Processing LaTeX file %s..." texfile)))
     (save-window-excursion
     (save-window-excursion
       (cond
       (cond
        ;; A function is provided: Apply it.
        ;; A function is provided: Apply it.

+ 5 - 6
lisp/ox-man.el

@@ -618,8 +618,6 @@ CONTENTS is nil.  INFO is a plist holding contextual information."
     (cond
     (cond
      ((string= key "MAN") value)
      ((string= key "MAN") value)
      ((string= key "INDEX") nil)
      ((string= key "INDEX") nil)
-     ;; Invisible targets.
-     ((string= key "TARGET") nil)
      ((string= key "TOC"   ) nil))))
      ((string= key "TOC"   ) nil))))
 
 
 
 
@@ -1206,11 +1204,12 @@ Return PDF file name or an error if it couldn't be produced."
   (let* ((base-name (file-name-sans-extension (file-name-nondirectory file)))
   (let* ((base-name (file-name-sans-extension (file-name-nondirectory file)))
 	 (full-name (file-truename file))
 	 (full-name (file-truename file))
 	 (out-dir (file-name-directory file))
 	 (out-dir (file-name-directory file))
-	 ;; Make sure `default-directory' is set to FILE directory,
-	 ;; not to whatever value the current buffer may have.
-	 (default-directory (file-name-directory full-name))
+	 ;; Properly set working directory for compilation.
+	 (default-directory (if (file-name-absolute-p file)
+				(file-name-directory full-name)
+			      default-directory))
          errors)
          errors)
-    (message (format "Processing Groff file %s ..." file))
+    (message (format "Processing Groff file %s..." file))
     (save-window-excursion
     (save-window-excursion
       (cond
       (cond
        ;; A function is provided: Apply it.
        ;; A function is provided: Apply it.

+ 15 - 9
lisp/ox-md.el

@@ -69,7 +69,6 @@ This variable can be set to either `atx' or `setext'."
 		(org-open-file (org-md-export-to-markdown nil s v)))))))
 		(org-open-file (org-md-export-to-markdown nil s v)))))))
   :translate-alist '((bold . org-md-bold)
   :translate-alist '((bold . org-md-bold)
 		     (code . org-md-verbatim)
 		     (code . org-md-verbatim)
-		     (underline . org-md-verbatim)
 		     (comment . (lambda (&rest args) ""))
 		     (comment . (lambda (&rest args) ""))
 		     (comment-block . (lambda (&rest args) ""))
 		     (comment-block . (lambda (&rest args) ""))
 		     (example-block . org-md-example-block)
 		     (example-block . org-md-example-block)
@@ -310,14 +309,12 @@ a communication channel."
 	     (org-export-data (org-element-contents destination) info)))
 	     (org-export-data (org-element-contents destination) info)))
 	  ((equal type "fuzzy")
 	  ((equal type "fuzzy")
 	   (let ((destination (org-export-resolve-fuzzy-link link info)))
 	   (let ((destination (org-export-resolve-fuzzy-link link info)))
-	     ;; Ignore invisible "#+TARGET: path".
-	     (unless (eq (org-element-type destination) 'keyword)
-	       (if (org-string-nw-p contents) contents
-		 (when destination
-		   (let ((number (org-export-get-ordinal destination info)))
-		     (when number
-		       (if (atom number) (number-to-string number)
-			 (mapconcat 'number-to-string number ".")))))))))
+	     (if (org-string-nw-p contents) contents
+	       (when destination
+		 (let ((number (org-export-get-ordinal destination info)))
+		   (when number
+		     (if (atom number) (number-to-string number)
+		       (mapconcat 'number-to-string number "."))))))))
 	  (t (let* ((raw-path (org-element-property :path link))
 	  (t (let* ((raw-path (org-element-property :path link))
 		    (path (cond
 		    (path (cond
 			   ((member type '("http" "https" "ftp"))
 			   ((member type '("http" "https" "ftp"))
@@ -457,6 +454,15 @@ non-nil."
       (when org-export-show-temporary-export-buffer
       (when org-export-show-temporary-export-buffer
 	(switch-to-buffer-other-window outbuf)))))
 	(switch-to-buffer-other-window outbuf)))))
 
 
+;;;###autoload
+(defun org-md-convert-region-to-md ()
+  "Assume the current region has org-mode syntax, and convert it to 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 'md))
+
 
 
 ;;;###autoload
 ;;;###autoload
 (defun org-md-export-to-markdown (&optional async subtreep visible-only)
 (defun org-md-export-to-markdown (&optional async subtreep visible-only)

+ 44 - 26
lisp/ox-odt.el

@@ -27,7 +27,7 @@
 
 
 (eval-when-compile
 (eval-when-compile
   (require 'cl)
   (require 'cl)
-  (require 'table))
+  (require 'table nil 'noerror))
 (require 'format-spec)
 (require 'format-spec)
 (require 'ox)
 (require 'ox)
 (require 'org-compat)
 (require 'org-compat)
@@ -454,7 +454,8 @@ The exporter embeds the exported content just before
 
 
 If unspecified, the file named \"OrgOdtContentTemplate.xml\"
 If unspecified, the file named \"OrgOdtContentTemplate.xml\"
 under `org-odt-styles-dir' is used."
 under `org-odt-styles-dir' is used."
-  :type 'file
+  :type '(choice (const nil)
+		 (file))
   :group 'org-export-odt
   :group 'org-export-odt
   :version "24.1")
   :version "24.1")
 
 
@@ -1750,9 +1751,17 @@ CONTENTS is nil.  INFO is a plist holding contextual information."
 	;; Inline definitions are secondary strings.
 	;; Inline definitions are secondary strings.
 	;; Non-inline footnotes definitions are full Org data.
 	;; Non-inline footnotes definitions are full Org data.
 	(t
 	(t
-	 (let* ((raw (org-export-get-footnote-definition footnote-reference
-							 info))
-		(def (let ((def (org-trim (org-export-data raw info))))
+	 (let* ((raw (org-export-get-footnote-definition
+		      footnote-reference info))
+		(translations
+		 (cons (cons 'paragraph
+			     (lambda (p c i)
+			       (org-odt--format-paragraph
+				p c "Footnote" "OrgFootnoteCenter"
+				"OrgFootnoteQuotations")))
+		       (org-export-backend-translate-table 'odt)))
+		(def (let ((def (org-trim (org-export-data-with-translations
+					   raw translations info))))
 		       (if (eq (org-element-type raw) 'org-data) def
 		       (if (eq (org-element-type raw) 'org-data) def
 			 (format "\n<text:p text:style-name=\"%s\">%s</text:p>"
 			 (format "\n<text:p text:style-name=\"%s\">%s</text:p>"
 				 "Footnote" def)))))
 				 "Footnote" def)))))
@@ -2014,7 +2023,6 @@ CONTENTS is nil.  INFO is a plist holding contextual information."
      ((string= key "INDEX")
      ((string= key "INDEX")
       ;; FIXME
       ;; FIXME
       (ignore))
       (ignore))
-     ((string= key "TARGET") nil)
      ((string= key "TOC")
      ((string= key "TOC")
       (let ((value (downcase value)))
       (let ((value (downcase value)))
 	(cond
 	(cond
@@ -2232,7 +2240,7 @@ CONTENTS is nil.  INFO is a plist holding contextual information."
 	 (target-file
 	 (target-file
 	  (format "%s%04d.%s" target-dir
 	  (format "%s%04d.%s" target-dir
 		  (incf org-odt-embedded-images-count) image-type)))
 		  (incf org-odt-embedded-images-count) image-type)))
-    (message "Embedding %s as %s ..."
+    (message "Embedding %s as %s..."
 	     (substring-no-properties path) target-file)
 	     (substring-no-properties path) target-file)
 
 
     (when (= 1 org-odt-embedded-images-count)
     (when (= 1 org-odt-embedded-images-count)
@@ -2440,7 +2448,7 @@ used as a communication channel."
      "application/vnd.oasis.opendocument.formula" target-dir "1.2")
      "application/vnd.oasis.opendocument.formula" target-dir "1.2")
     ;; Copy over the formula file from user directory to zip
     ;; Copy over the formula file from user directory to zip
     ;; directory.
     ;; directory.
-    (message "Embedding %s as %s ..." src-file target-file)
+    (message "Embedding %s as %s..." src-file target-file)
     (let ((case-fold-search nil))
     (let ((case-fold-search nil))
       (cond
       (cond
        ;; Case 1: Mathml.
        ;; Case 1: Mathml.
@@ -2753,6 +2761,8 @@ INFO is a plist holding contextual information.  See
 		     (concat "file://" (expand-file-name raw-path))
 		     (concat "file://" (expand-file-name raw-path))
 		   (concat "file://" raw-path)))
 		   (concat "file://" raw-path)))
 		(t raw-path)))
 		(t raw-path)))
+	 ;; Convert & to &amp; for correct XML representation
+	 (path (replace-regexp-in-string "&" "&amp;" path))
 	 protocol)
 	 protocol)
     (cond
     (cond
      ;; Image file.
      ;; Image file.
@@ -2828,10 +2838,10 @@ INFO is a plist holding contextual information.  See
 	     (let ((label (org-element-property :value destination)))
 	     (let ((label (org-element-property :value destination)))
 	       (format "<text:a xlink:type=\"simple\" xlink:href=\"#%s\">%s</text:a>"
 	       (format "<text:a xlink:type=\"simple\" xlink:href=\"#%s\">%s</text:a>"
 		       (org-export-solidify-link-text label) desc))))
 		       (org-export-solidify-link-text label) desc))))
-	 ;; LINK has no description. It points to either a HEADLINE, a
-	 ;; TARGET or an ELEMENT with a #+NAME: LABEL attached to it.
-	 ;; LINK to DESTINATION, but make a best effort to provide a
-	 ;; *meaningful* description.
+	 ;; LINK has no description. It points to either a HEADLINE or
+	 ;; an ELEMENT with a #+NAME: LABEL attached to it.  LINK to
+	 ;; DESTINATION, but make a best effort to provide
+	 ;; a *meaningful* description.
 	 (org-odt-link--infer-description destination info))))
 	 (org-odt-link--infer-description destination info))))
      ;; Coderef: replace link with the reference name or the
      ;; Coderef: replace link with the reference name or the
      ;; equivalent line number.
      ;; equivalent line number.
@@ -2872,27 +2882,37 @@ INFO is a plist holding contextual information.  See
 
 
 ;;;; Paragraph
 ;;;; Paragraph
 
 
-(defun org-odt-paragraph (paragraph contents info)
-  "Transcode a PARAGRAPH element from Org to ODT.
-CONTENTS is the contents of the paragraph, as a string.  INFO is
-the plist used as a communication channel."
+(defun org-odt--format-paragraph (paragraph contents default center quote)
+  "Format paragraph according to given styles.
+PARAGRAPH is a paragraph type element.  CONTENTS is the
+transcoded contents of that paragraph, as a string.  DEFAULT,
+CENTER and QUOTE are, respectively, style to use when paragraph
+belongs to no special environment, a center block, or a quote
+block."
   (let* ((parent (org-export-get-parent paragraph))
   (let* ((parent (org-export-get-parent paragraph))
 	 (parent-type (org-element-type parent))
 	 (parent-type (org-element-type parent))
 	 (style (case parent-type
 	 (style (case parent-type
-		  (quote-block "Quotations")
-		  (center-block "OrgCenter")
-		  (footnote-definition "Footnote")
-		  (t (or (org-element-property :style paragraph)
-			 "Text_20_body")))))
+		  (quote-block quote)
+		  (center-block center)
+		  (t default))))
     ;; If this paragraph is a leading paragraph in an item and the
     ;; If this paragraph is a leading paragraph in an item and the
     ;; item has a checkbox, splice the checkbox and paragraph contents
     ;; item has a checkbox, splice the checkbox and paragraph contents
     ;; together.
     ;; together.
     (when (and (eq (org-element-type parent) 'item)
     (when (and (eq (org-element-type parent) 'item)
-    	       (eq paragraph (car (org-element-contents parent))))
+	       (eq paragraph (car (org-element-contents parent))))
       (setq contents (concat (org-odt--checkbox parent) contents)))
       (setq contents (concat (org-odt--checkbox parent) contents)))
-    (assert style)
     (format "\n<text:p text:style-name=\"%s\">%s</text:p>" style contents)))
     (format "\n<text:p text:style-name=\"%s\">%s</text:p>" style contents)))
 
 
+(defun org-odt-paragraph (paragraph contents info)
+  "Transcode a PARAGRAPH element from Org to ODT.
+CONTENTS is the contents of the paragraph, as a string.  INFO is
+the plist used as a communication channel."
+  (org-odt--format-paragraph
+   paragraph contents
+   (or (org-element-property :style paragraph) "Text_20_body")
+   "OrgCenter"
+   "Quotations"))
+
 
 
 ;;;; Plain List
 ;;;; Plain List
 
 
@@ -3066,9 +3086,7 @@ holding contextual information."
 	     (date (or (plist-get attributes :date)
 	     (date (or (plist-get attributes :date)
 		       ;; FIXME: Is `car' right thing to do below?
 		       ;; FIXME: Is `car' right thing to do below?
 		       (car (plist-get info :date)))))
 		       (car (plist-get info :date)))))
-
-	(format "\n<text:p text:style-name=\"%s\">%s</text:p>"
-		"Text_20_body"
+	(format "\n<text:p>%s</text:p>"
 		(format "<office:annotation>\n%s\n</office:annotation>"
 		(format "<office:annotation>\n%s\n</office:annotation>"
 			(concat
 			(concat
 			 (and author
 			 (and author

+ 107 - 11
lisp/ox-org.el

@@ -20,9 +20,13 @@
 
 
 ;;; Commentary:
 ;;; Commentary:
 
 
-;; This library implements an Org back-end for Org exporter.  Since
-;; its usage is mainly internal, it doesn't provide any interactive
-;; function.
+;; This library implements an Org back-end for Org exporter.
+;;
+;; It introduces two interactive functions, `org-org-export-as-org'
+;; and `org-org-export-to-org', which export, respectively, to
+;; a temporary buffer and to a file.
+;;
+;; A publishing function is also provided: `org-org-publish-to-org'.
 
 
 ;;; Code:
 ;;; Code:
 (require 'ox)
 (require 'ox)
@@ -102,16 +106,24 @@ setting of `org-html-htmlize-output-type' is 'css."
     (timestamp . org-org-identity)
     (timestamp . org-org-identity)
     (underline . org-org-identity)
     (underline . org-org-identity)
     (verbatim . org-org-identity)
     (verbatim . org-org-identity)
-    (verse-block . org-org-identity)))
+    (verse-block . org-org-identity))
+  :menu-entry
+  '(?O "Export to Org"
+       ((?O "As Org buffer" org-org-export-as-org)
+	(?o "As Org file" org-org-export-to-org)
+	(?v "As Org file and open"
+	    (lambda (a s v b)
+	      (if a (org-org-export-to-org t s v b)
+		(org-open-file (org-org-export-to-org nil s v b))))))))
 
 
 (defun org-org-identity (blob contents info)
 (defun org-org-identity (blob contents info)
-  "Transcode BLOB element or object back into Org syntax."
-  (funcall
-   (intern (format "org-element-%s-interpreter" (org-element-type blob)))
-   blob contents))
+  "Transcode BLOB element or object back into Org syntax.
+CONTENTS is its contents, as a string or nil.  INFO is ignored."
+  (org-export-expand blob contents t))
 
 
 (defun org-org-headline (headline contents info)
 (defun org-org-headline (headline contents info)
-  "Transcode HEADLINE element back into Org syntax."
+  "Transcode HEADLINE element back into Org syntax.
+CONTENTS is its contents, as a string or nil.  INFO is ignored."
   (unless (plist-get info :with-todo-keywords)
   (unless (plist-get info :with-todo-keywords)
     (org-element-put-property headline :todo-keyword nil))
     (org-element-put-property headline :todo-keyword nil))
   (unless (plist-get info :with-tags)
   (unless (plist-get info :with-tags)
@@ -122,7 +134,8 @@ setting of `org-html-htmlize-output-type' is 'css."
 
 
 (defun org-org-keyword (keyword contents info)
 (defun org-org-keyword (keyword contents info)
   "Transcode KEYWORD element back into Org syntax.
   "Transcode KEYWORD element back into Org syntax.
-Ignore keywords targeted at other export back-ends."
+CONTENTS is nil.  INFO is ignored.  This function ignores
+keywords targeted at other export back-ends."
   (unless (member (org-element-property :key keyword)
   (unless (member (org-element-property :key keyword)
 		  (mapcar
 		  (mapcar
 		   (lambda (block-cons)
 		   (lambda (block-cons)
@@ -131,6 +144,86 @@ Ignore keywords targeted at other export back-ends."
 		   org-element-block-name-alist))
 		   org-element-block-name-alist))
     (org-element-keyword-interpreter keyword nil)))
     (org-element-keyword-interpreter keyword nil)))
 
 
+;;;###autoload
+(defun org-org-export-as-org (&optional async subtreep visible-only ext-plist)
+  "Export current buffer to an Org 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.
+
+EXT-PLIST, when provided, is a property list with external
+parameters overriding Org default settings, but still inferior to
+file-local settings.
+
+Export is done in a buffer named \"*Org ORG Export*\", which will
+be displayed when `org-export-show-temporary-export-buffer' is
+non-nil."
+  (interactive)
+  (if async
+      (org-export-async-start
+	  (lambda (output)
+	    (with-current-buffer (get-buffer-create "*Org ORG Export*")
+	      (erase-buffer)
+	      (insert output)
+	      (goto-char (point-min))
+	      (org-mode)
+	      (org-export-add-to-stack (current-buffer) 'org)))
+	`(org-export-as 'org ,subtreep ,visible-only nil ',ext-plist))
+    (let ((outbuf
+	   (org-export-to-buffer
+	    'org "*Org ORG Export*" subtreep visible-only nil ext-plist)))
+      (with-current-buffer outbuf (org-mode))
+      (when org-export-show-temporary-export-buffer
+	(switch-to-buffer-other-window outbuf)))))
+
+;;;###autoload
+(defun org-org-export-to-org (&optional async subtreep visible-only ext-plist)
+  "Export current buffer to an org 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.
+
+EXT-PLIST, when provided, is a property list with external
+parameters overriding Org default settings, but still inferior to
+file-local settings.
+
+Return output file name."
+  (interactive)
+  (let ((outfile (org-export-output-file-name ".org" subtreep)))
+    (if async
+	(org-export-async-start
+	    (lambda (f) (org-export-add-to-stack f 'org))
+	  `(expand-file-name
+	    (org-export-to-file
+	     'org ,outfile ,subtreep ,visible-only nil ',ext-plist)))
+      (org-export-to-file 'org outfile subtreep visible-only nil ext-plist))))
+
 ;;;###autoload
 ;;;###autoload
 (defun org-org-publish-to-org (plist filename pub-dir)
 (defun org-org-publish-to-org (plist filename pub-dir)
   "Publish an org file to org.
   "Publish an org file to org.
@@ -146,6 +239,8 @@ Return output file name."
     (require 'ox-html)
     (require 'ox-html)
     (let* ((org-inhibit-startup t)
     (let* ((org-inhibit-startup t)
 	   (htmlize-output-type 'css)
 	   (htmlize-output-type 'css)
+	   (html-ext (concat "." (or (plist-get plist :html-extension)
+				     org-html-extension "html")))
 	   (visitingp (find-buffer-visiting filename))
 	   (visitingp (find-buffer-visiting filename))
 	   (work-buffer (or visitingp (find-file filename)))
 	   (work-buffer (or visitingp (find-file filename)))
 	   newbuf)
 	   newbuf)
@@ -160,11 +255,12 @@ Return output file name."
 		(format
 		(format
 		 "<link rel=\"stylesheet\" type=\"text/css\" href=\"%s\">"
 		 "<link rel=\"stylesheet\" type=\"text/css\" href=\"%s\">"
 		 org-org-htmlized-css-url) t t)))
 		 org-org-htmlized-css-url) t t)))
-	(write-file (concat pub-dir (file-name-nondirectory filename) ".html")))
+	(write-file (concat pub-dir (file-name-nondirectory filename) html-ext)))
       (kill-buffer newbuf)
       (kill-buffer newbuf)
       (unless visitingp (kill-buffer work-buffer)))
       (unless visitingp (kill-buffer work-buffer)))
     (set-buffer-modified-p nil)))
     (set-buffer-modified-p nil)))
 
 
+
 (provide 'ox-org)
 (provide 'ox-org)
 
 
 ;; Local variables:
 ;; Local variables:

+ 17 - 8
lisp/ox-publish.el

@@ -179,6 +179,7 @@ included.  See the back-end documentation for more information.
   :with-tags                `org-export-with-tags'
   :with-tags                `org-export-with-tags'
   :with-tasks               `org-export-with-tasks'
   :with-tasks               `org-export-with-tasks'
   :with-timestamps          `org-export-with-timestamps'
   :with-timestamps          `org-export-with-timestamps'
+  :with-planning            `org-export-with-planning'
   :with-todo-keywords       `org-export-with-todo-keywords'
   :with-todo-keywords       `org-export-with-todo-keywords'
 
 
 The following properties may be used to control publishing of
 The following properties may be used to control publishing of
@@ -810,22 +811,30 @@ Default for SITEMAP-FILENAME is 'sitemap.org'."
 
 
 (defun org-publish-find-date (file)
 (defun org-publish-find-date (file)
   "Find the date of FILE in project.
   "Find the date of FILE in project.
-If FILE provides a #+date keyword use it else use the file
-system's modification time.
-
-It returns time in `current-time' format."
+If FILE provides a DATE keyword use it else use the file system's
+modification time.  Return time in `current-time' format."
   (let* ((org-inhibit-startup t)
   (let* ((org-inhibit-startup t)
 	 (visiting (find-buffer-visiting file))
 	 (visiting (find-buffer-visiting file))
 	 (file-buf (or visiting (find-file-noselect file nil)))
 	 (file-buf (or visiting (find-file-noselect file nil)))
 	 (date (plist-get
 	 (date (plist-get
 		(with-current-buffer file-buf
 		(with-current-buffer file-buf
 		  (org-mode)
 		  (org-mode)
-		  (org-export--get-inbuffer-options))
+		  (org-export-get-environment))
 		:date)))
 		:date)))
     (unless visiting (kill-buffer file-buf))
     (unless visiting (kill-buffer file-buf))
-    (if date (org-time-string-to-time date)
-      (when (file-exists-p file)
-	(nth 5 (file-attributes file))))))
+    ;; DATE is either a timestamp object or a secondary string.  If it
+    ;; is a timestamp or if the secondary string contains a timestamp,
+    ;; convert it to internal format.  Otherwise, use FILE
+    ;; modification time.
+    (cond ((eq (org-element-type date) 'timestamp)
+	   (org-time-string-to-time (org-element-interpret-data date)))
+	  ((let ((ts (and (consp date) (assq 'timestamp date))))
+	     (and ts
+		  (let ((value (org-element-interpret-data ts)))
+		    (and (org-string-nw-p value)
+			 (org-time-string-to-time value))))))
+	  ((file-exists-p file) (nth 5 (file-attributes file)))
+	  (t (error "No such file: \"%s\"" file)))))
 
 
 
 
 
 

+ 23 - 10
lisp/ox-texinfo.el

@@ -149,7 +149,9 @@
   :type '(string :tag "Export Filename"))
   :type '(string :tag "Export Filename"))
 
 
 (defcustom org-texinfo-coding-system nil
 (defcustom org-texinfo-coding-system nil
-  "Default document encoding for Texinfo output."
+  "Default document encoding for Texinfo output.
+
+If `nil' it will default to `buffer-file-coding-system'."
   :group 'org-export-texinfo
   :group 'org-export-texinfo
   :type 'coding-system)
   :type 'coding-system)
 
 
@@ -693,7 +695,9 @@ holding export options."
 	 ;; `.' in text.
 	 ;; `.' in text.
 	 (dirspacing (- 29 (length dirtitle)))
 	 (dirspacing (- 29 (length dirtitle)))
 	 (menu (org-texinfo-make-menu info 'main))
 	 (menu (org-texinfo-make-menu info 'main))
-	 (detail-menu (org-texinfo-make-menu info 'detailed)))
+	 (detail-menu (org-texinfo-make-menu info 'detailed))
+	 (coding-system (or org-texinfo-coding-system
+			    buffer-file-coding-system)))
     (concat
     (concat
      ;; Header
      ;; Header
      header "\n"
      header "\n"
@@ -701,9 +705,8 @@ holding export options."
      ;; Filename and Title
      ;; Filename and Title
      "@setfilename " info-filename "\n"
      "@setfilename " info-filename "\n"
      "@settitle " title "\n"
      "@settitle " title "\n"
-     (if org-texinfo-coding-system
-       (format "@documentencoding %s\n"
-	       (upcase (symbol-name org-texinfo-coding-system))) "\n")
+     (format "@documentencoding %s\n"
+	     (upcase (symbol-name coding-system))) "\n"
      (format "@documentlanguage %s\n" lang)
      (format "@documentlanguage %s\n" lang)
      "\n\n"
      "\n\n"
      "@c Version and Contact Info\n"
      "@c Version and Contact Info\n"
@@ -1547,7 +1550,7 @@ a communication channel."
 		      (nth count item))) counts)
 		      (nth count item))) counts)
     (mapconcat (lambda (size)
     (mapconcat (lambda (size)
 		 (make-string size ?a)) (mapcar (lambda (ref)
 		 (make-string size ?a)) (mapcar (lambda (ref)
-						  (apply 'max `,@ref)) (car counts))
+						  (apply 'max `(,@ref))) (car counts))
 		 "} {")))
 		 "} {")))
 
 
 (defun org-texinfo-table--org-table (table contents info)
 (defun org-texinfo-table--org-table (table contents info)
@@ -1779,6 +1782,15 @@ publishing directory.
 Return output file name."
 Return output file name."
   (org-publish-org-to 'texinfo filename ".texi" plist pub-dir))
   (org-publish-org-to 'texinfo filename ".texi" plist pub-dir))
 
 
+;;;###autoload
+(defun org-texinfo-convert-region-to-texinfo ()
+  "Assume the current region has org-mode syntax, and convert it to Texinfo.
+This can be used in any buffer.  For example, you can write an
+itemized list in org-mode syntax in an Texinfo buffer and use
+this command to convert it."
+  (interactive)
+  (org-export-replace-region-by 'texinfo))
+
 (defun org-texinfo-compile (file)
 (defun org-texinfo-compile (file)
   "Compile a texinfo file.
   "Compile a texinfo file.
 
 
@@ -1789,11 +1801,12 @@ Return INFO file name or an error if it couldn't be produced."
   (let* ((base-name (file-name-sans-extension (file-name-nondirectory file)))
   (let* ((base-name (file-name-sans-extension (file-name-nondirectory file)))
 	 (full-name (file-truename file))
 	 (full-name (file-truename file))
 	 (out-dir (file-name-directory file))
 	 (out-dir (file-name-directory file))
-	 ;; Make sure `default-directory' is set to FILE directory,
-	 ;; not to whatever value the current buffer may have.
-	 (default-directory (file-name-directory full-name))
+	 ;; Properly set working directory for compilation.
+	 (default-directory (if (file-name-absolute-p file)
+				(file-name-directory full-name)
+			      default-directory))
 	 errors)
 	 errors)
-    (message (format "Processing Texinfo file %s ..." file))
+    (message (format "Processing Texinfo file %s..." file))
     (save-window-excursion
     (save-window-excursion
       (cond
       (cond
        ;; A function is provided: Apply it.
        ;; A function is provided: Apply it.

Разница между файлами не показана из-за своего большого размера
+ 422 - 233
lisp/ox.el


+ 1 - 1
mk/default.mk

@@ -39,7 +39,7 @@ BTEST_POST  =
               # -L <path-to>/ert      # needed for Emacs23, Emacs24 has ert built in
               # -L <path-to>/ert      # needed for Emacs23, Emacs24 has ert built in
               # -L <path-to>/ess      # needed for running R tests
               # -L <path-to>/ess      # needed for running R tests
               # -L <path-to>/htmlize  # need at least version 1.34 for source code formatting
               # -L <path-to>/htmlize  # need at least version 1.34 for source code formatting
-BTEST_OB_LANGUAGES = awk C fortran maxima lilypond octave python sh
+BTEST_OB_LANGUAGES = awk C fortran maxima lilypond octave python sh perl
               # R                     # requires ESS to be installed and configured
               # R                     # requires ESS to be installed and configured
 # extra packages to require for testing
 # extra packages to require for testing
 BTEST_EXTRA =
 BTEST_EXTRA =

+ 7 - 5
mk/server.mk

@@ -31,7 +31,7 @@ SERVERMK ?= true # or just any value at all, really
 
 
 #----------------------------------------------------------------------
 #----------------------------------------------------------------------
 
 
-ORGFULL   = README COPYING AUTHORS lisp/ \
+ORGFULL   = README COPYING lisp/ \
 		Makefile request-assign-future.txt \
 		Makefile request-assign-future.txt \
 		mk/default.mk mk/targets.mk mk/version.mk \
 		mk/default.mk mk/targets.mk mk/version.mk \
 		mk/org-fixup.el \
 		mk/org-fixup.el \
@@ -80,7 +80,7 @@ archive-contents:
 	echo "   (org-plus-contrib . [($(PKG_TAG)) ($(PKG_REQ)) \"$(PKG_DOC)\" tar]))" >> $@
 	echo "   (org-plus-contrib . [($(PKG_TAG)) ($(PKG_REQ)) \"$(PKG_DOC)\" tar]))" >> $@
 
 
 elpaplus:		cleanall info card elpaplus-dirty
 elpaplus:		cleanall info card elpaplus-dirty
-elpaplus-dirty elpaplus-up:	ORG_ADD_CONTRIB=org-*
+elpaplus-dirty elpaplus-up:	ORG_ADD_CONTRIB=org-* ob-* ox-*
 elpaplus-dirty elpaplus-up:	ORGDIR=org-plus-contrib-$(PKG_TAG)
 elpaplus-dirty elpaplus-up:	ORGDIR=org-plus-contrib-$(PKG_TAG)
 elpaplus-dirty:
 elpaplus-dirty:
 	@$(MAKE) GITVERSION=$(GITVERSION:release_%=%)-elpaplus version autoloads
 	@$(MAKE) GITVERSION=$(GITVERSION:release_%=%)-elpaplus version autoloads
@@ -117,9 +117,11 @@ cleanrel:
 
 
 doc-up:	info pdf card html
 doc-up:	info pdf card html
 	$(MAKE) -C doc manual guide
 	$(MAKE) -C doc manual guide
-	$(CP) doc/org.html $(SERVROOT)
-	$(CP) doc/manual/* $(SERVROOT)/manual
-	$(CP) doc/guide/*  $(SERVROOT)/guide
+	$(CP) doc/org.html     $(SERVROOT)
+	$(CP) doc/org.pdf      $(SERVROOT)
+	$(CP) doc/orgguide.pdf $(SERVROOT)
+	$(CP) doc/manual/*     $(SERVROOT)/manual
+	$(CP) doc/guide/*      $(SERVROOT)/guide
 
 
 upload:			cleanall rel-up doc-up elpa-up elpaplus-up
 upload:			cleanall rel-up doc-up elpa-up elpaplus-up
 upload-elpa:		cleanall elpa-up
 upload-elpa:		cleanall elpa-up

+ 2 - 4
testing/examples/babel-dangerous.org

@@ -9,9 +9,7 @@
 There is no default value assigned to =x= variable. This is not permitted
 There is no default value assigned to =x= variable. This is not permitted
 anymore.
 anymore.
 
 
-#+name: carre(x)
-#+begin_src python
+#+name: carre
+#+begin_src python :var x
   return x*x
   return x*x
 #+end_src
 #+end_src
-
-#+name: carre

+ 1 - 1
testing/examples/babel.org

@@ -224,7 +224,7 @@ src_sh{echo 3} Here is one at the beginning of a line.
   :noweb-sep: ""
   :noweb-sep: ""
   :END:
   :END:
 
 
-#+begin_src sh :tangle yes :noweb yes :shebang #!/bin/sh
+#+begin_src sh :tangle yes :noweb yes :shebang "#!/bin/sh"
   <<fullest-disk>>
   <<fullest-disk>>
 #+end_src
 #+end_src
 
 

+ 27 - 1
testing/examples/ob-C-test.org

@@ -24,7 +24,7 @@
 
 
 #+source: string_var
 #+source: string_var
 #+begin_src cpp :var q="word" :includes '(<iostream> <cstring>) :results silent
 #+begin_src cpp :var q="word" :includes '(<iostream> <cstring>) :results silent
-  std::cout << q << ' ' << strlen(q);
+  std::cout << q << ' ' << std::strlen(q);
   return 0;
   return 0;
 #+end_src
 #+end_src
 
 
@@ -35,6 +35,9 @@
 #+end_src
 #+end_src
 
 
 * Array
 * Array
+  :PROPERTIES:
+  :ID:       2df1ab83-3fa3-462a-a1f3-3aef6044a874
+  :END:
 #+source: array
 #+source: array
 #+begin_src cpp :includes "<iostream>" :results vector :results silent
 #+begin_src cpp :includes "<iostream>" :results vector :results silent
   for (int i=1; i<3; i++) {
   for (int i=1; i<3; i++) {
@@ -42,3 +45,26 @@
   }
   }
   return 0;
   return 0;
 #+end_src
 #+end_src
+* Matrix
+  :PROPERTIES:
+  :ID:       cc65d6b3-8e8e-4f9c-94cd-f5a00cdeceb5
+  :END:
+#+name: C-matrix
+| 1 | 2 |
+| 3 | 4 |
+
+#+source: list_var
+#+begin_src cpp :var a='("abc" "def") :includes "<iostream>" :results silent
+  std::cout << a[0] << a[1] << sizeof(a)/sizeof(*a) << '\n';
+#+end_src
+
+#+source: vector_var
+#+begin_src cpp :var a='[1 2] :includes "<iostream>" :results silent
+  std::cout << a[0] << a[1] << sizeof(a)/sizeof(*a) << '\n';
+#+end_src
+
+#+source: list_list_var
+#+begin_src cpp :var q=C-matrix :includes "<iostream>" :results silent
+  std::cout << q[0][0] << ' ' << q[1][0] << '\n'
+            << q[0][1] << ' ' << q[1][1] << '\n'; // transpose
+#+end_src

+ 22 - 0
testing/examples/ob-fortran-test.org

@@ -50,6 +50,28 @@ write (*, '(3f5.2)'), s
 write (*, '(2f5.2)'), s
 write (*, '(2f5.2)'), s
 #+end_src
 #+end_src
 
 
+* matrix
+  :PROPERTIES:
+  :ID:       3f73ab19-d25a-428d-8c26-e8c6aa933976
+  :END:
+Real matrix as input
+#+name: fortran-input-matrix1
+| 0.0 | 42.0 |
+| 0.0 |  0.0 |
+| 0.0 |  0.0 |
+
+#+name: fortran-input-matrix2
+| 0.0 | 0.0 | 0.0 |
+| 0.0 | 0.0 | 42.0 |
+
+#+begin_src fortran :var s=fortran-input-matrix1 :results silent
+write (*, '(i2)'), nint(s(1,2))
+#+end_src
+
+#+begin_src fortran :var s=fortran-input-matrix2 :results silent
+write (*, '(i2)'), nint(s(2,3))
+#+end_src
+
 * failing
 * failing
   :PROPERTIES:
   :PROPERTIES:
   :ID:       891ead4a-f87a-473c-9ae0-1cf348bcd04f
   :ID:       891ead4a-f87a-473c-9ae0-1cf348bcd04f

+ 126 - 0
testing/examples/ob-header-arg-defaults.org

@@ -0,0 +1,126 @@
+#+TITLE: Tests for default header arguments to Babel source blocks
+#+OPTIONS: ^:nil
+#+PROPERTY: var  t1="go1" t3="go3_clobbered"
+#+PROPERTY: var+ t2="go2" t3="go3"
+#+PROPERTY: header-args  :var t1="gh1" t2="gh2_clobbered"
+#+PROPERTY: header-args+ :var t4="gh4" t2="gh2" :var end=9
+#+PROPERTY: header-args:emacs-lisp  :var t1="ge1" t4="ge4_clobbered"
+#+PROPERTY: header-args:emacs-lisp+ :var t4="ge4" :var t5="ge5"
+#+PROPERTY: header-args:emacs-lisp+ :results silent :noweb yes
+
+#+NAME: showvar
+#+BEGIN_SRC emacs-lisp :execute no
+  (mapconcat (lambda (n)
+               (let* ((n (string (+ 48 n)))
+                      (p (intern (concat "t" n))))
+                 (if (boundp p) (eval p) (concat "--" n))))
+             (number-sequence 1 end)
+             "/")
+#+END_SRC
+
+* Global property
+  :PROPERTIES:
+  :ID:       3fdadb69-5d15-411e-aad0-f7860cdd7816
+  :END:
+
+| Global                 | t1  | t2  | t3  | t4  | t5  | t6  | t7  | t8  | t9  |
+|------------------------+-----+-----+-----+-----+-----+-----+-----+-----+-----|
+| var property           | go1 | go2 | go3 | --- | --- | --- | --- | --- | --- |
+| header-args            | gh1 | gh2 | --- | gh4 | --- | --- | --- | --- | --- |
+| header-args:emacs-lisp | ge1 | --- | --- | ge4 | ge5 | --- | --- | --- | --- |
+|------------------------+-----+-----+-----+-----+-----+-----+-----+-----+-----|
+| Result                 | ge1 | gh2 | go3 | ge4 | ge5 | --6 | --7 | --8 | --9 |
+
+#+CALL: showvar() :results silent
+#+BEGIN_SRC emacs-lisp :var end=7
+<<showvar>>
+#+END_SRC
+
+* Tree property
+** Overwrite
+  :PROPERTIES:
+  :ID:       a9cdfeda-9f31-4bb5-b694-2cf452f07dfd
+  :var: t6="to6"
+  :header-args: :var t7="th7"
+  :header-args:emacs-lisp: :var t8="te8"
+  :header-args:emacs-lisp+: :results silent :noweb yes :var end=9
+  :END:
+
+| Global                 | t1  | t2  | t3  | t4  | t5  | t6  | t7  | t8  | t9  |
+|------------------------+-----+-----+-----+-----+-----+-----+-----+-----+-----|
+| var property           | go1 | go2 | go3 | --- | --- | --- | --- | --- | --- |
+| header-args            | gh1 | gh2 | --- | gh4 | --- | --- | --- | --- | --- |
+| header-args:emacs-lisp | ge1 | --- | --- | ge4 | ge5 | --- | --- | --- | --- |
+|------------------------+-----+-----+-----+-----+-----+-----+-----+-----+-----|
+| Tree                   | t1  | t2  | t3  | t4  | t5  | t6  | t7  | t8  | t9  |
+|------------------------+-----+-----+-----+-----+-----+-----+-----+-----+-----|
+| var property           | --- | --- | --- | --- | --- | to6 | --- | --- | --- |
+| header-args            | --- | --- | --- | --- | --- | --- | th7 | --- | --- |
+| header-args:emacs-lisp | --- | --- | --- | --- | --- | --- | --- | te8 | --- |
+|------------------------+-----+-----+-----+-----+-----+-----+-----+-----+-----|
+| Result #+CALL          | go1 | go2 | go3 | --4 | --5 | --- | th7 | te8 | --9 |
+| Result noweb           | --1 | --2 | --3 | --4 | --5 | to6 | th7 | te8 | --9 |
+
+#+CALL: showvar() :results silent
+#+BEGIN_SRC emacs-lisp
+<<showvar>>
+#+END_SRC
+
+** Accumulate
+  :PROPERTIES:
+  :ID:       1d97d258-fd50-4107-a095-e4625bffc57b
+  :var+: t1="to1"
+  :var+: t6="to6"
+  :header-args+: :var t2="th2" t3="th3"
+  :header-args:emacs-lisp+: :var t5="te5" end=8
+  :END:
+
+| Global                  | t1  | t2  | t3  | t4  | t5  | t6  | t7  | t8  | t9  |
+|-------------------------+-----+-----+-----+-----+-----+-----+-----+-----+-----|
+| var property            | go1 | go2 | go3 | --- | --- | --- | --- | --- | --- |
+| header-args             | gh1 | gh2 | --- | gh4 | --- | --- | --- | --- | --- |
+| header-args:emacs-lisp  | ge1 | --- | --- | ge4 | ge5 | --- | --- | --- | --- |
+|-------------------------+-----+-----+-----+-----+-----+-----+-----+-----+-----|
+| Tree                    | t1  | t2  | t3  | t4  | t5  | t6  | t7  | t8  | t9  |
+|-------------------------+-----+-----+-----+-----+-----+-----+-----+-----+-----|
+| var+ property           | to1 | --- | --- | --- | --- | to6 | --- | --- | --- |
+| header-args+            | --- | th2 | th3 | --- | --- | --- | --- | --- | --- |
+| header-args:emacs-lisp+ | --- | --- | --- | --- | te5 | --- | --- | --- | --- |
+|-------------------------+-----+-----+-----+-----+-----+-----+-----+-----+-----|
+| Result #+CALL           | ge1 | th2 | th3 | ge4 | te5 | --6 | --7 | --8 | --9 |
+| Result noweb            | ge1 | th2 | th3 | ge4 | te5 | to6 | --7 | --8 | --9 |
+
+#+CALL: showvar(end=6) :results silent
+#+BEGIN_SRC emacs-lisp
+<<showvar>>
+#+END_SRC
+
+** Complex
+  :PROPERTIES:
+  :ID:       fa0e912d-d9b4-47b0-9f9e-1cbb39f7cbc2
+  :var: t1="to1"
+  :var+: t6="to6"
+  :header-args+: :var t2="th2"
+  :header-args:emacs-lisp: :var t5="te5" end=7
+  :header-args:emacs-lisp+: :results silent :noweb yes :var end=9
+  :END:
+
+| Global                 | t1  | t2  | t3  | t4  | t5  | t6  | t7  | t8  | t9  |
+|------------------------+-----+-----+-----+-----+-----+-----+-----+-----+-----|
+| var property           | go1 | go2 | go3 | --- | --- | --- | --- | --- | --- |
+| header-args            | gh1 | gh2 | --- | gh4 | --- | --- | --- | --- | --- |
+| header-args:emacs-lisp | ge1 | --- | --- | ge4 | ge5 | --- | --- | --- | --- |
+|------------------------+-----+-----+-----+-----+-----+-----+-----+-----+-----|
+| Tree                   | t1  | t2  | t3  | t4  | t5  | t6  | t7  | t8  | t9  |
+|------------------------+-----+-----+-----+-----+-----+-----+-----+-----+-----|
+| var property           | to1 | --- | --- | --- | --- | to6 | --- | --- | --- |
+| header-args+           | --- | th2 | --- | --- | --- | --- | --- | --- | --- |
+| header-args:emacs-lisp | --- | --- | --- | --- | te5 | --- | --- | --- | --- |
+|------------------------+-----+-----+-----+-----+-----+-----+-----+-----+-----|
+| Result #+CALL          | gh1 | th2 | go3 | gh4 | te5 | --6 | --7 | --8 | --9 |
+| Result noweb           | gh1 | th2 | --3 | gh4 | te5 | to6 | --7 | --8 | --9 |
+
+#+CALL: showvar(end=6) :results silent
+#+BEGIN_SRC emacs-lisp
+<<showvar>>
+#+END_SRC

Некоторые файлы не были показаны из-за большого количества измененных файлов